Merge branch 'PHP-8.3'

* PHP-8.3:
  Fix GH-11876: ini_parse_quantity() accepts invalid quantities
This commit is contained in:
George Peter Banyard 2023-08-30 21:23:36 +01:00
commit a3725f12a3
2 changed files with 91 additions and 0 deletions

View File

@ -0,0 +1,51 @@
--TEST--
Invalid INI quantities, base prefix followed by stuff eaten by strtoull()
--EXTENSIONS--
zend_test
--FILE--
<?php
var_dump(zend_test_zend_ini_parse_quantity('0x0x12'));
var_dump(zend_test_zend_ini_parse_quantity('0b+10'));
var_dump(zend_test_zend_ini_parse_quantity('0o+10'));
var_dump(zend_test_zend_ini_parse_quantity('0x+10'));
var_dump(zend_test_zend_ini_parse_quantity('0b 10'));
var_dump(zend_test_zend_ini_parse_quantity('0o 10'));
var_dump(zend_test_zend_ini_parse_quantity('0x 10'));
var_dump(zend_test_zend_ini_parse_quantity('0g10'));
var_dump(zend_test_zend_ini_parse_quantity('0m10'));
var_dump(zend_test_zend_ini_parse_quantity('0k10'));
--EXPECTF--
Warning: Invalid quantity "0x0x12": no digits after base prefix, interpreting as "0" for backwards compatibility in %s on line %d
int(0)
Warning: Invalid quantity "0b+10": no digits after base prefix, interpreting as "0" for backwards compatibility in %s on line %d
int(0)
Warning: Invalid quantity "0o+10": no digits after base prefix, interpreting as "0" for backwards compatibility in %s on line %d
int(0)
Warning: Invalid quantity "0x+10": no digits after base prefix, interpreting as "0" for backwards compatibility in %s on line %d
int(0)
Warning: Invalid quantity "0b 10": no digits after base prefix, interpreting as "0" for backwards compatibility in %s on line %d
int(0)
Warning: Invalid quantity "0o 10": no digits after base prefix, interpreting as "0" for backwards compatibility in %s on line %d
int(0)
Warning: Invalid quantity "0x 10": no digits after base prefix, interpreting as "0" for backwards compatibility in %s on line %d
int(0)
Warning: Invalid quantity "0g10": unknown multiplier "0", interpreting as "0" for backwards compatibility in %s on line %d
int(0)
Warning: Invalid quantity "0m10": unknown multiplier "0", interpreting as "0" for backwards compatibility in %s on line %d
int(0)
Warning: Invalid quantity "0k10": unknown multiplier "0", interpreting as "0" for backwards compatibility in %s on line %d
int(0)

View File

@ -587,6 +587,34 @@ typedef enum {
ZEND_INI_PARSE_QUANTITY_UNSIGNED, ZEND_INI_PARSE_QUANTITY_UNSIGNED,
} zend_ini_parse_quantity_signed_result_t; } zend_ini_parse_quantity_signed_result_t;
static const char *zend_ini_consume_quantity_prefix(const char *const digits, const char *const str_end) {
const char *digits_consumed = digits;
/* Ignore leading whitespace. */
while (digits_consumed < str_end && zend_is_whitespace(*digits_consumed)) {++digits_consumed;}
if (digits_consumed[0] == '+' || digits_consumed[0] == '-') {
++digits_consumed;
}
if (digits_consumed[0] == '0' && !isdigit(digits_consumed[1])) {
/* Value is just 0 */
if ((digits_consumed+1) == str_end) {
return digits;
}
switch (digits_consumed[1]) {
case 'x':
case 'X':
case 'o':
case 'O':
case 'b':
case 'B':
digits_consumed += 2;
break;
}
}
return digits_consumed;
}
static zend_ulong zend_ini_parse_quantity_internal(zend_string *value, zend_ini_parse_quantity_signed_result_t signed_result, zend_string **errstr) /* {{{ */ static zend_ulong zend_ini_parse_quantity_internal(zend_string *value, zend_ini_parse_quantity_signed_result_t signed_result, zend_string **errstr) /* {{{ */
{ {
char *digits_end = NULL; char *digits_end = NULL;
@ -674,6 +702,18 @@ static zend_ulong zend_ini_parse_quantity_internal(zend_string *value, zend_ini_
smart_str_append_escaped(&invalid, ZSTR_VAL(value), ZSTR_LEN(value)); smart_str_append_escaped(&invalid, ZSTR_VAL(value), ZSTR_LEN(value));
smart_str_0(&invalid); 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))) {
/* 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", *errstr = zend_strpprintf(0, "Invalid quantity \"%s\": no digits after base prefix, interpreting as \"0\" for backwards compatibility",
ZSTR_VAL(invalid.s)); ZSTR_VAL(invalid.s));