Fix incorrect zval type_flags in preg_replace_callback_array() for immutable arrays

The ZVAL_ARR macro always set the zval type_info to IS_ARRAY_EX, even if the
hash table is immutable. Since in preg_replace_callback_array() we can return
the passed array directly, and that passed array can be immutable, we need to
reset the type_flags to keep the VM from performing ref-counting on the array.

Fixes GH-10968
Closes GH-10970
This commit is contained in:
Ilija Tovilo 2023-03-29 14:37:52 +02:00
parent 41bbb116dd
commit 66ce205718
No known key found for this signature in database
GPG Key ID: A4F5D403F118200A
3 changed files with 20 additions and 1 deletions

3
NEWS
View File

@ -9,6 +9,9 @@ PHP NEWS
. Fixed bug #80602 (Segfault when using DOMChildNode::before()).
(Nathan Freeman)
- PCRE:
. Fixed bug GH-10968 (Segfault in preg_replace_callback_array()). (ilutov)
13 Apr 2023, PHP 8.1.18
- Core:

View File

@ -2479,7 +2479,12 @@ PHP_FUNCTION(preg_replace_callback_array)
}
if (subject_ht) {
RETURN_ARR(subject_ht);
RETVAL_ARR(subject_ht);
// Unset the type_flags of immutable arrays to prevent the VM from performing refcounting
if (GC_FLAGS(subject_ht) & IS_ARRAY_IMMUTABLE) {
Z_TYPE_FLAGS_P(return_value) = 0;
}
return;
} else {
RETURN_STR(subject_str);
}

View File

@ -0,0 +1,11 @@
--TEST--
GH-10968: preg_replace_callback_array() segmentation fault
--FILE--
<?php
var_dump(preg_replace_callback_array([], []));
var_dump(preg_replace_callback_array([], ''));
?>
--EXPECT--
array(0) {
}
string(0) ""