feat: establish catalog identity and atomic file ownership
This commit is contained in:
1 parent
390a7a557a
commit
6b9fb54b4f
16 files changed
+1381
-23
No files matched your search
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace MeshVault\Catalog;
|
||||
|
||||
use InvalidArgumentException;
|
||||
|
||||
/** Lexical identity only; filesystem authorization remains PathSafety's responsibility. */
|
||||
final class ManagedPath
|
||||
{
|
||||
public static function validate(string $path): string
|
||||
{
|
||||
if (
|
||||
$path === '' || str_starts_with($path, '/') || str_contains($path, '\\')
|
||||
|| str_contains($path, "\0") || preg_match('/^[a-zA-Z][a-zA-Z0-9+.-]*:/', $path)
|
||||
) {
|
||||
throw new InvalidArgumentException('Managed path must be a canonical relative path.');
|
||||
}
|
||||
foreach (explode('/', $path) as $segment) {
|
||||
if (
|
||||
$segment === '' || $segment === '.' || $segment === '..'
|
||||
|| (PHP_OS_FAMILY === 'Windows'
|
||||
&& (str_contains($segment, ':') || rtrim($segment, '. ') !== $segment))
|
||||
) {
|
||||
throw new InvalidArgumentException('Managed path contains a noncanonical segment.');
|
||||
}
|
||||
}
|
||||
return $path;
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user