Skip to content

Commit c1bb4f6

Browse files
Merge branch '6.0' into 6
2 parents eaf2023 + d97a0a0 commit c1bb4f6

File tree

2 files changed

+20
-4
lines changed

2 files changed

+20
-4
lines changed

src/Core/Path.php

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,16 +29,24 @@ public static function join(...$parts)
2929
$parts = $parts[0];
3030
}
3131

32-
// Cleanup and join all parts
33-
$parts = array_filter(array_map('trim', array_filter($parts ?? [])));
32+
// Remove empty parts and trim all parts
33+
// Explicitly allow zero as a segment in the path (e.g. /some/path/0/file.txt)
34+
$notEmpty = fn(mixed $part) => ($part === 0 || $part === '0' || (bool) $part);
35+
$parts = array_filter(array_map('trim', array_filter($parts ?? [], $notEmpty)), $notEmpty);
36+
37+
// Normalise and join parts
3438
$fullPath = static::normalise(implode(DIRECTORY_SEPARATOR, $parts));
3539

3640
// Protect against directory traversal vulnerability (OTG-AUTHZ-001)
3741
if ($fullPath === '..' || str_ends_with($fullPath, '/..') || str_contains($fullPath, '../')) {
3842
throw new InvalidArgumentException('Can not collapse relative folders');
3943
}
4044

41-
return $fullPath ?: DIRECTORY_SEPARATOR;
45+
if ($fullPath === '') {
46+
return DIRECTORY_SEPARATOR;
47+
}
48+
49+
return $fullPath;
4250
}
4351

4452
/**

tests/php/Core/PathTest.php

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ class PathTest extends SapphireTest
1818
#[DataProvider('providerTestJoinPaths')]
1919
public function testJoinPaths($args, $expected)
2020
{
21-
$joined = Path::join($args);
21+
$joined = Path::join(...$args);
2222
$this->assertEquals($expected, $joined);
2323
}
2424

@@ -47,10 +47,18 @@ public static function providerTestJoinPaths()
4747
[['', '/root', '/', ' ', '/', '\\'], '/root'],
4848
[['', 'root', '/', ' ', '/', '\\'], 'root'],
4949
[['\\', '', '/root', '/', ' ', '/', '\\'], '/root'],
50+
[[' one ', ' ', 'two', null], 'one/two'],
5051
// join blocks of paths
5152
[['/root/dir', 'another/path\\to/join'], '/root/dir/another/path/to/join'],
5253
// Double dot is fine if it's not attempting directory traversal
5354
[['/root/my..name/', 'another/path\\to/join'], '/root/my..name/another/path/to/join'],
55+
// Don't remove zero
56+
[['0'], '0'],
57+
[[0], '0'],
58+
[['1', '0', 'a'], '1/0/a'],
59+
[[1, 0, 'a'], '1/0/a'],
60+
// first arg is array
61+
[[['one', 'two', 'three']], 'one/two/three'],
5462
];
5563

5664
// Rewrite tests for other filesystems (output arg only)

0 commit comments

Comments
 (0)