Skip to content

Commit

Permalink
Merge branch 'PHP-8.4'
Browse files Browse the repository at this point in the history
* PHP-8.4:
  Fix GH-17409: Assertion failure Zend/zend_hash.c:1730
  NEWS
  Add comment
  Fix GH-16892: ini_parse_quantity() fails to parse inputs starting with 0x0b
  Fix GH-16886: ini_parse_quantity() fails to emit warning for 0x+0
  Merge duplicate code blocks
  • Loading branch information
nielsdos committed Jan 9, 2025
2 parents cc3a729 + 3eb79e1 commit 5d4707e
Show file tree
Hide file tree
Showing 5 changed files with 97 additions and 18 deletions.
41 changes: 41 additions & 0 deletions Zend/tests/zend_ini/gh16886.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
--TEST--
GH-16886 (ini_parse_quantity() fails to emit warning for 0x+0)
--FILE--
<?php
echo ini_parse_quantity('0x 0'), "\n";
echo ini_parse_quantity('0x+0'), "\n";
echo ini_parse_quantity('0x-0'), "\n";
echo ini_parse_quantity('0b 0'), "\n";
echo ini_parse_quantity('0b+0'), "\n";
echo ini_parse_quantity('0b-0'), "\n";
echo ini_parse_quantity('0o 0'), "\n";
echo ini_parse_quantity('0o+0'), "\n";
echo ini_parse_quantity('0o-0'), "\n";
?>
--EXPECTF--
Warning: Invalid quantity "0x 0": no digits after base prefix, interpreting as "0" for backwards compatibility in %s on line %d
0

Warning: Invalid quantity "0x+0": no digits after base prefix, interpreting as "0" for backwards compatibility in %s on line %d
0

Warning: Invalid quantity "0x-0": no digits after base prefix, interpreting as "0" for backwards compatibility in %s on line %d
0

Warning: Invalid quantity "0b 0": no digits after base prefix, interpreting as "0" for backwards compatibility in %s on line %d
0

Warning: Invalid quantity "0b+0": no digits after base prefix, interpreting as "0" for backwards compatibility in %s on line %d
0

Warning: Invalid quantity "0b-0": no digits after base prefix, interpreting as "0" for backwards compatibility in %s on line %d
0

Warning: Invalid quantity "0o 0": no digits after base prefix, interpreting as "0" for backwards compatibility in %s on line %d
0

Warning: Invalid quantity "0o+0": no digits after base prefix, interpreting as "0" for backwards compatibility in %s on line %d
0

Warning: Invalid quantity "0o-0": no digits after base prefix, interpreting as "0" for backwards compatibility in %s on line %d
0
22 changes: 22 additions & 0 deletions Zend/tests/zend_ini/gh16892.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
--TEST--
GH-16892 (ini_parse_quantity() fails to parse inputs starting with 0x0b)
--FILE--
<?php
echo ini_parse_quantity('0x0b'), "\n";
echo ini_parse_quantity('0xb'), "\n";
echo ini_parse_quantity('-0x0B'), "\n";
echo ini_parse_quantity('-0xB'), "\n";
echo ini_parse_quantity('0x0beef'), "\n";
echo ini_parse_quantity('0xbeef'), "\n";
echo ini_parse_quantity('-0x0BEEF'), "\n";
echo ini_parse_quantity('-0xBEEF'), "\n";
?>
--EXPECT--
11
11
-11
-11
48879
48879
-48879
-48879
26 changes: 10 additions & 16 deletions Zend/zend_ini.c
Original file line number Diff line number Diff line change
Expand Up @@ -587,7 +587,7 @@ typedef enum {
ZEND_INI_PARSE_QUANTITY_UNSIGNED,
} zend_ini_parse_quantity_signed_result_t;

static const char *zend_ini_consume_quantity_prefix(const char *const digits, const char *const str_end) {
static const char *zend_ini_consume_quantity_prefix(const char *const digits, const char *const str_end, int base) {
const char *digits_consumed = digits;
/* Ignore leading whitespace. */
while (digits_consumed < str_end && zend_is_whitespace(*digits_consumed)) {++digits_consumed;}
Expand All @@ -598,17 +598,22 @@ static const char *zend_ini_consume_quantity_prefix(const char *const digits, co
if (digits_consumed[0] == '0' && !isdigit(digits_consumed[1])) {
/* Value is just 0 */
if ((digits_consumed+1) == str_end) {
return digits;
return digits_consumed;
}

switch (digits_consumed[1]) {
case 'x':
case 'X':
case 'o':
case 'O':
digits_consumed += 2;
break;
case 'b':
case 'B':
digits_consumed += 2;
if (base != 16) {
/* 0b or 0B is valid in base 16, but not in the other supported bases. */
digits_consumed += 2;
}
break;
}
}
Expand Down Expand Up @@ -696,19 +701,8 @@ static zend_ulong zend_ini_parse_quantity_internal(zend_string *value, zend_ini_
return 0;
}
digits += 2;
if (UNEXPECTED(digits == str_end)) {
/* Escape the string to avoid null bytes and to make non-printable chars
* visible */
smart_str_append_escaped(&invalid, ZSTR_VAL(value), ZSTR_LEN(value));
smart_str_0(&invalid);

*errstr = zend_strpprintf(0, "Invalid quantity \"%s\": no digits after base prefix, interpreting as \"0\" for backwards compatibility",
ZSTR_VAL(invalid.s));

smart_str_free(&invalid);
return 0;
}
if (UNEXPECTED(digits != zend_ini_consume_quantity_prefix(digits, str_end))) {
/* STRTOULL may silently ignore a prefix of whitespace, sign, and base prefix, which would be invalid at this position */
if (UNEXPECTED(digits == str_end || digits != zend_ini_consume_quantity_prefix(digits, str_end, base))) {
/* Escape the string to avoid null bytes and to make non-printable chars
* visible */
smart_str_append_escaped(&invalid, ZSTR_VAL(value), ZSTR_LEN(value));
Expand Down
4 changes: 2 additions & 2 deletions ext/simplexml/simplexml.c
Original file line number Diff line number Diff line change
Expand Up @@ -2120,8 +2120,8 @@ static void sxe_object_free_storage(zend_object *object)
sxe_object_free_iterxpath(sxe);

if (sxe->properties) {
zend_hash_destroy(sxe->properties);
FREE_HASHTABLE(sxe->properties);
ZEND_ASSERT(!(GC_FLAGS(sxe->properties) & IS_ARRAY_IMMUTABLE));
zend_hash_release(sxe->properties);
}
}
/* }}} */
Expand Down
22 changes: 22 additions & 0 deletions ext/simplexml/tests/gh17409.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
--TEST--
GH-17409 (Assertion failure Zend/zend_hash.c)
--EXTENSIONS--
simplexml
--CREDITS--
YuanchengJiang
--FILE--
<?php
$root = simplexml_load_string('<?xml version="1.0"?>
<root xmlns:reserved="reserved-ns">
<child reserved:attribute="Sample" />
</root>
');
// Need to use $GLOBALS such that simplexml object is destroyed
var_dump(array_merge_recursive($GLOBALS, $GLOBALS)["root"]);
?>
--EXPECT--
array(1) {
["child"]=>
array(0) {
}
}

0 comments on commit 5d4707e

Please sign in to comment.