Skip to content

Commit 14e862e

Browse files
committed
ext/phar: improve .phar madic directory preservation logic in phar::addEmptyDir()
1 parent 769441b commit 14e862e

4 files changed

Lines changed: 28 additions & 3 deletions

File tree

NEWS

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,10 @@ PHP NEWS
126126
. Support reference values in Phar::mungServer(). (ndossche)
127127
. Invalid values now throw in Phar::mungServer() instead of being silently
128128
ignored. (ndossche)
129+
. Fixed a bypass of the magic ".phar" directory protection in
130+
Phar::addEmptyDir() for paths starting with "/.phar". (Weilin Du)
131+
. Phar::addEmptyDir() now allows non-magic directory names that merely
132+
share the ".phar" prefix. (Weilin Du)
129133
. Support overridden methods in SplFileInfo for getMTime() and getPathname()
130134
when building a phar. (ndossche)
131135
. Mark Phar::buildFromIterator() base directory argument as a path.

UPGRADING

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,11 @@ PHP 8.6 UPGRADE NOTES
5252
- Phar:
5353
. Phar::mungServer() now raises a ValueError when an invalid
5454
argument value is passed instead of being silently ignored.
55+
. Phar::addEmptyDir() now rejects `/.phar` paths in addition to `.phar`
56+
paths, and raises the same BadMethodCallException for attempts to create
57+
the reserved magic ".phar" directory through that form.
58+
. Phar::addEmptyDir() now treats non-magic names that merely share the
59+
`.phar` prefix as ordinary directories.
5560

5661
- PGSQL:
5762
. pg_fetch_object() now reports the ValueError for a non-empty

ext/phar/phar_object.c

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3789,9 +3789,16 @@ PHP_METHOD(Phar, addEmptyDir)
37893789

37903790
PHAR_ARCHIVE_OBJECT();
37913791

3792-
if (zend_string_starts_with_literal(dir_name, ".phar")) {
3793-
zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "Cannot create a directory in magic \".phar\" directory");
3794-
RETURN_THROWS();
3792+
if (
3793+
zend_string_starts_with_literal(dir_name, ".phar")
3794+
|| zend_string_starts_with_literal(dir_name, "/.phar")
3795+
) {
3796+
size_t prefix_len = (ZSTR_VAL(dir_name)[0] == '/') + sizeof(".phar") - 1;
3797+
char next_char = ZSTR_VAL(dir_name)[prefix_len];
3798+
if (next_char == '/' || next_char == '\\' || next_char == '\0') {
3799+
zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "Cannot create a directory in magic \".phar\" directory");
3800+
RETURN_THROWS();
3801+
}
37953802
}
37963803

37973804
phar_mkdir(&phar_obj->archive, dir_name);

ext/phar/tests/mkdir.phpt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,13 @@ $a->addEmptyDir('.phar');
2424
} catch (Exception $e) {
2525
echo $e->getMessage(),"\n";
2626
}
27+
try {
28+
$a->addEmptyDir('/.phar');
29+
} catch (Exception $e) {
30+
echo $e->getMessage(),"\n";
31+
}
32+
$a->addEmptyDir('/.pharx');
33+
var_dump(is_dir($pname . '/.pharx'));
2734
?>
2835
--CLEAN--
2936
<?php
@@ -43,3 +50,5 @@ Warning: rmdir(): phar error: cannot remove directory "" in phar "foo.phar", dir
4350

4451
Warning: rmdir(): phar error: cannot remove directory "a" in phar "%smkdir.phar.php", phar error: path "a" exists and is a not a directory in %smkdir.php on line %d
4552
Cannot create a directory in magic ".phar" directory
53+
Cannot create a directory in magic ".phar" directory
54+
bool(true)

0 commit comments

Comments
 (0)