45 lines
1.2 KiB
PHP
45 lines
1.2 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Service\Share;
|
|
|
|
use App\Service\Share\Exception\InvalidPathException;
|
|
|
|
final class SharePathResolver
|
|
{
|
|
/**
|
|
* Normalise un chemin relatif et rejette toute tentative de sortie de racine.
|
|
*/
|
|
public function normalizeRelative(string $path): string
|
|
{
|
|
$path = str_replace('\\', '/', $path);
|
|
$segments = [];
|
|
|
|
foreach (explode('/', $path) as $segment) {
|
|
if ('' === $segment || '.' === $segment) {
|
|
continue;
|
|
}
|
|
if ('..' === $segment) {
|
|
throw new InvalidPathException('Path traversal is not allowed.');
|
|
}
|
|
$segments[] = $segment;
|
|
}
|
|
|
|
return implode('/', $segments);
|
|
}
|
|
|
|
/**
|
|
* Construit le chemin SMB absolu (toujours sous basePath).
|
|
*/
|
|
public function fullPath(string $basePath, string $relativePath): string
|
|
{
|
|
$base = trim(str_replace('\\', '/', $basePath), '/');
|
|
$relative = $this->normalizeRelative($relativePath);
|
|
|
|
$parts = array_values(array_filter([$base, $relative], static fn (string $p): bool => '' !== $p));
|
|
|
|
return '/'.implode('/', $parts);
|
|
}
|
|
}
|