mirror of
https://github.com/php/php-src.git
synced 2026-03-24 00:02:20 +01:00
Fix memory leak when edge case is hit when registering xpath callback
This can happen if you have a valid callable name with a NUL byte in it, on a non-interned string entry. This can be done by abusing anonymous classes. Closes GH-20452.
This commit is contained in:
4
NEWS
4
NEWS
@@ -11,6 +11,10 @@ PHP NEWS
|
|||||||
. Fix crashes when trying to instantiate uninstantiable classes via date
|
. Fix crashes when trying to instantiate uninstantiable classes via date
|
||||||
static constructors. (ndossche)
|
static constructors. (ndossche)
|
||||||
|
|
||||||
|
- DOM:
|
||||||
|
. Fix memory leak when edge case is hit when registering xpath callback.
|
||||||
|
(ndossche)
|
||||||
|
|
||||||
- Opcache:
|
- Opcache:
|
||||||
. Fixed bug GH-20329 (opcache.file_cache broken with full interned string
|
. Fixed bug GH-20329 (opcache.file_cache broken with full interned string
|
||||||
buffer). (Arnaud)
|
buffer). (Arnaud)
|
||||||
|
|||||||
@@ -57,6 +57,19 @@ try {
|
|||||||
echo $e->getMessage(), "\n";
|
echo $e->getMessage(), "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$x = new class {
|
||||||
|
public static function dump() {}
|
||||||
|
};
|
||||||
|
|
||||||
|
$classes = get_declared_classes();
|
||||||
|
|
||||||
|
try {
|
||||||
|
$str = str_repeat($classes[count($classes) - 1] . '::dump', random_int(1, 1));
|
||||||
|
$xpath->registerPhpFunctions([$str]);
|
||||||
|
} catch (Throwable $e) {
|
||||||
|
echo $e->getMessage(), "\n";
|
||||||
|
}
|
||||||
|
|
||||||
?>
|
?>
|
||||||
--EXPECT--
|
--EXPECT--
|
||||||
DOMXPath::registerPhpFunctions(): Argument #1 ($restrict) must be a callable, function "nonexistent" not found or invalid function name
|
DOMXPath::registerPhpFunctions(): Argument #1 ($restrict) must be a callable, function "nonexistent" not found or invalid function name
|
||||||
@@ -67,3 +80,4 @@ DOMXPath::registerPhpFunctions(): Argument #1 ($restrict) must be an array with
|
|||||||
DOMXPath::registerPhpFunctions(): Argument #1 ($restrict) must be an array containing valid callback names
|
DOMXPath::registerPhpFunctions(): Argument #1 ($restrict) must be an array containing valid callback names
|
||||||
DOMXPath::registerPhpFunctions(): Argument #1 ($restrict) must be an array containing valid callback names
|
DOMXPath::registerPhpFunctions(): Argument #1 ($restrict) must be an array containing valid callback names
|
||||||
DOMXPath::registerPhpFunctions(): Argument #1 ($restrict) must be a valid callback name
|
DOMXPath::registerPhpFunctions(): Argument #1 ($restrict) must be a valid callback name
|
||||||
|
DOMXPath::registerPhpFunctions(): Argument #1 ($restrict) must be an array containing valid callback names
|
||||||
|
|||||||
@@ -206,14 +206,16 @@ static zend_result php_dom_xpath_callback_ns_update_method_handler(
|
|||||||
ZVAL_PTR(®istered_value, fcc);
|
ZVAL_PTR(®istered_value, fcc);
|
||||||
|
|
||||||
if (!key) {
|
if (!key) {
|
||||||
zend_string *str = zval_try_get_string(entry);
|
zend_string *tmp_str;
|
||||||
|
zend_string *str = zval_try_get_tmp_string(entry, &tmp_str);
|
||||||
if (str && php_dom_xpath_is_callback_name_valid_and_throw(str, name_validation, true)) {
|
if (str && php_dom_xpath_is_callback_name_valid_and_throw(str, name_validation, true)) {
|
||||||
zend_hash_update(&ns->functions, str, ®istered_value);
|
zend_hash_update(&ns->functions, str, ®istered_value);
|
||||||
if (register_func) {
|
if (register_func) {
|
||||||
register_func(ctxt, namespace, str);
|
register_func(ctxt, namespace, str);
|
||||||
}
|
}
|
||||||
zend_string_release_ex(str, false);
|
zend_tmp_string_release(tmp_str);
|
||||||
} else {
|
} else {
|
||||||
|
zend_tmp_string_release(tmp_str);
|
||||||
zend_fcc_dtor(fcc);
|
zend_fcc_dtor(fcc);
|
||||||
efree(fcc);
|
efree(fcc);
|
||||||
return FAILURE;
|
return FAILURE;
|
||||||
|
|||||||
Reference in New Issue
Block a user