diff --git a/NEWS b/NEWS index 26118955d01..520633f0086 100644 --- a/NEWS +++ b/NEWS @@ -77,6 +77,7 @@ PHP NEWS . Fixed bug GH-16464 (Use-after-free in SplDoublyLinkedList::offsetSet()). (ilutov) . Fixed bug GH-16479 (Use-after-free in SplObjectStorage::setInfo()). (ilutov) + . Fixed bug GH-16478 (Use-after-free in SplFixedArray::unset()). (ilutov) - Standard: . Fixed bug GH-16293 (Failed assertion when throwing in assert() callback with diff --git a/ext/spl/spl_fixedarray.c b/ext/spl/spl_fixedarray.c index 14be941cd33..49eb8841de1 100644 --- a/ext/spl/spl_fixedarray.c +++ b/ext/spl/spl_fixedarray.c @@ -470,8 +470,10 @@ static void spl_fixedarray_object_unset_dimension_helper(spl_fixedarray_object * zend_throw_exception(spl_ce_RuntimeException, "Index invalid or out of range", 0); return; } else { - 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 00000000000..5a708b36fe8 --- /dev/null +++ b/ext/spl/tests/gh16478.phpt @@ -0,0 +1,21 @@ +--TEST-- +GH-16478: 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) { +}