'/', '/etc' => '/', '/etc/' => '/', '/etc/file.txt' => '/etc', '//etc//file.txt' => '//etc', '/folder with spaces/item.txt' => '/folder with spaces', 'folder/file.txt' => 'folder', 'file.txt' => '.', '/a\\b/file.txt' => '/a\\b', // Backslash is a valid POSIX filename character. ]; foreach ($parents as $path => $expected) { if (remoteDirname($path) !== $expected) throw new RuntimeException('Incorrect parent for ' . $path); } foreach (['/' => '/', '//etc/../' => '/', '/etc/../../' => '/', '/etc/./ssh/' => '/etc/ssh'] as $path => $expected) { if (normalizePath($path) !== $expected) throw new RuntimeException('Incorrect normalized path for ' . $path); } // Round trips must remain correct on both Windows/XAMPP and Linux. foreach (['/etc', '/mnt/raid', '/folder with spaces'] as $directory) { $parent = normalizePath(remoteDirname($directory)); if ($parent !== ($directory === '/mnt/raid' ? '/mnt' : '/')) throw new RuntimeException('Invalid navigation round trip'); } // ZIP paths keep the top-level directory name when it is directly under root. foreach (['/etc' => '/etc/config.txt', '/mnt/raid' => '/mnt/raid/config.txt'] as $base => $file) { $relative = substr($file, strlen(rtrim(remoteDirname($base), '/')) + 1); if ($relative !== ($base === '/etc' ? 'etc/config.txt' : 'raid/config.txt')) throw new RuntimeException('Incorrect ZIP member path'); } foreach ([ ['/mnt/raid', '/mnt/raid', true], ['/mnt/raid/folder', '/mnt/raid/', true], ['/mnt/raid-other/file', '/mnt/raid', false], ['/mnt/raid/../private', '/mnt/raid', false], ['/mnt/raid/sub/../../private', '/mnt/raid', false], ['/mnt/raid/sub/../file', '/mnt/raid', true], ['/etc', '/', true], ] as [$path, $basePath, $expected]) { if (isRemotePathWithin($path, $basePath) !== $expected) throw new RuntimeException('Incorrect path boundary: ' . $path); } foreach (['' => false, '.' => false, '..' => false, 'a/b' => false, "a\0b" => false, 'file.txt' => true, '0' => true, 'a\\b' => true] as $name => $expected) { if (isRemoteNameValid((string) $name) !== $expected) throw new RuntimeException('Incorrect filename validation'); } echo "Remote paths: POSIX parents, normalization, workspace boundaries, names and ZIP paths passed.\n";