diff --git a/ext/spl/spl_fixedarray.c b/ext/spl/spl_fixedarray.c index 7c08a189c6fcf..bbee2b9370626 100644 --- a/ext/spl/spl_fixedarray.c +++ b/ext/spl/spl_fixedarray.c @@ -484,8 +484,10 @@ static void spl_fixedarray_object_unset_dimension_helper(spl_fixedarray_object * return; } else { intern->array.should_rebuild_properties = true; - zval_ptr_dtor(&(intern->array.elements[index])); + zval garbage; + ZVAL_COPY_VALUE(&garbage, &intern->array.elements[index]); ZVAL_NULL(&intern->array.elements[index]); + zval_ptr_dtor(&garbage); } } diff --git a/ext/spl/tests/gh16478.phpt b/ext/spl/tests/gh16478.phpt new file mode 100644 index 0000000000000..b6b7a0ce4caa3 --- /dev/null +++ b/ext/spl/tests/gh16478.phpt @@ -0,0 +1,21 @@ +--TEST-- +GH-16478: Fix use-after-free in SplFixedArray::unset() +--FILE-- +setSize(0); + } +} + +$arr = new SplFixedArray(2); +$arr[0] = new C; +unset($arr[0]); +var_dump($arr); + +?> +--EXPECT-- +object(SplFixedArray)#1 (0) { +}