diff --git a/NEWS b/NEWS index ad524d0bb94c..f623e277f489 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,10 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| ?? ??? ????, PHP 8.2.36 +- Standard: + . Fixed use-after-free in parse_str() when an error handler replaces the + result variable. (cataphract) + 21 Oct 2026, PHP 8.2.35 diff --git a/ext/standard/string.c b/ext/standard/string.c index 19b6e9d92ea6..6e345d789775 100644 --- a/ext/standard/string.c +++ b/ext/standard/string.c @@ -4875,6 +4875,7 @@ PHP_FUNCTION(parse_str) { char *arg; zval *arrayArg = NULL; + zval array; char *res = NULL; size_t arglen; @@ -4883,13 +4884,14 @@ PHP_FUNCTION(parse_str) Z_PARAM_ZVAL(arrayArg) ZEND_PARSE_PARAMETERS_END(); - arrayArg = zend_try_array_init(arrayArg); - if (!arrayArg) { + if (!zend_try_array_init(arrayArg)) { RETURN_THROWS(); } + array_init(&array); res = estrndup(arg, arglen); - sapi_module.treat_data(PARSE_STRING, res, arrayArg); + sapi_module.treat_data(PARSE_STRING, res, &array); + ZEND_TRY_ASSIGN_REF_VALUE(arrayArg, &array); } /* }}} */ diff --git a/ext/standard/tests/strings/parse_str_error_handler_uaf.phpt b/ext/standard/tests/strings/parse_str_error_handler_uaf.phpt new file mode 100644 index 000000000000..d31b9f2b874b --- /dev/null +++ b/ext/standard/tests/strings/parse_str_error_handler_uaf.phpt @@ -0,0 +1,30 @@ +--TEST-- +parse_str() remains safe when its error handler replaces the result array +--INI-- +display_errors=0 +max_input_nesting_level=1 +--FILE-- + +--EXPECT-- +int(1) +done