From 66ce20571836659dab569d6b81973d78ca3b1b00 Mon Sep 17 00:00:00 2001 From: Ilija Tovilo Date: Wed, 29 Mar 2023 14:37:52 +0200 Subject: [PATCH] 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 --- NEWS | 3 +++ ext/pcre/php_pcre.c | 7 ++++++- ext/pcre/tests/gh10968.phpt | 11 +++++++++++ 3 files changed, 20 insertions(+), 1 deletion(-) create mode 100644 ext/pcre/tests/gh10968.phpt diff --git a/NEWS b/NEWS index 99ef4c45288..ec9ae488a2a 100644 --- a/NEWS +++ b/NEWS @@ -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: diff --git a/ext/pcre/php_pcre.c b/ext/pcre/php_pcre.c index a8d3559ef5b..6249a807970 100644 --- a/ext/pcre/php_pcre.c +++ b/ext/pcre/php_pcre.c @@ -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); } diff --git a/ext/pcre/tests/gh10968.phpt b/ext/pcre/tests/gh10968.phpt new file mode 100644 index 00000000000..873d17e79da --- /dev/null +++ b/ext/pcre/tests/gh10968.phpt @@ -0,0 +1,11 @@ +--TEST-- +GH-10968: preg_replace_callback_array() segmentation fault +--FILE-- + +--EXPECT-- +array(0) { +} +string(0) ""