diff --git a/ext/standard/array.c b/ext/standard/array.c index 7382e1e9f8bd9..b89deb241f046 100644 --- a/ext/standard/array.c +++ b/ext/standard/array.c @@ -1863,8 +1863,10 @@ static zend_long php_extract_ref_overwrite(zend_array *arr, zend_array *symbol_t } else { ZVAL_MAKE_REF_EX(entry, 2); } - zval_ptr_dtor(orig_var); + zval garbage; + ZVAL_COPY_VALUE(&garbage, orig_var); ZVAL_REF(orig_var, Z_REF_P(entry)); + zval_ptr_dtor(&garbage); } else { if (Z_ISREF_P(entry)) { Z_ADDREF_P(entry); diff --git a/ext/standard/tests/gh18209.phpt b/ext/standard/tests/gh18209.phpt new file mode 100644 index 0000000000000..6a759639f7dcb --- /dev/null +++ b/ext/standard/tests/gh18209.phpt @@ -0,0 +1,23 @@ +--TEST-- +GH-18209: Use-after-free in extract() with EXTR_REFS +--CREDITS-- +Noam Rathaus (nrathaus) +--FILE-- + 42]; +extract($array, EXTR_REFS); +var_dump($b); + +?> +--EXPECT-- +int(42) +int(43)