Skip to content

Commit e2941e2

Browse files
committed
ext/phar: improve .phar madic directory preservation logic in phar::addEmptyDir()
1 parent 5dd3909 commit e2941e2

3 files changed

Lines changed: 24 additions & 3 deletions

File tree

NEWS

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,11 @@ PHP NEWS
1515
IntlCalendar::equals(), ::before(), ::after(), and ::isEquivalentTo().
1616
(Weilin Du)
1717

18+
- Phar:
19+
. Fixed a bypass of the magic ".phar" directory protection in
20+
Phar::addEmptyDir() for paths starting with "/.phar", while allowing
21+
non-magic directory names that merely share the ".phar" prefix. (Weilin Du)
22+
1823
- Zlib:
1924
. Fixed memory leak if deflate initialization fails and there is a dict.
2025
(ndossche)

ext/phar/phar_object.c

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

38643864
PHAR_ARCHIVE_OBJECT();
38653865

3866-
if (zend_string_starts_with_literal(dir_name, ".phar")) {
3867-
zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "Cannot create a directory in magic \".phar\" directory");
3868-
RETURN_THROWS();
3866+
if (
3867+
zend_string_starts_with_literal(dir_name, ".phar")
3868+
|| zend_string_starts_with_literal(dir_name, "/.phar")
3869+
) {
3870+
size_t prefix_len = (ZSTR_VAL(dir_name)[0] == '/') + sizeof(".phar")-1;
3871+
char next_char = ZSTR_VAL(dir_name)[prefix_len];
3872+
if (next_char == '/' || next_char == '\\' || next_char == '\0') {
3873+
zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "Cannot create a directory in magic \".phar\" directory");
3874+
RETURN_THROWS();
3875+
}
38693876
}
38703877

38713878
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)