Skip to content

Commit

Permalink
Fix incorrect zval type_flags in preg_replace_callback_array() for im…
Browse files Browse the repository at this point in the history
…mutable 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
  • Loading branch information
iluuu1994 committed Mar 31, 2023
1 parent 41bbb11 commit 66ce205
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 1 deletion.
3 changes: 3 additions & 0 deletions NEWS
Expand Up @@ -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:
Expand Down
7 changes: 6 additions & 1 deletion ext/pcre/php_pcre.c
Expand Up @@ -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);
}
Expand Down
11 changes: 11 additions & 0 deletions ext/pcre/tests/gh10968.phpt
@@ -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) ""

0 comments on commit 66ce205

Please sign in to comment.