Use specialised functions in SplFixedArray dimension handlers

This is more efficient than manually dealing with a garbage copy.
This commit is contained in:
Niels Dossche 2025-03-30 20:26:57 +02:00
parent 5a4c460329
commit 9e52d1698a
No known key found for this signature in database
GPG key ID: B8A8AD166DF0E2E5

View file

@ -377,7 +377,7 @@ static zval *spl_fixedarray_object_read_dimension_helper(spl_fixedarray_object *
{ {
/* we have to return NULL on error here to avoid memleak because of /* we have to return NULL on error here to avoid memleak because of
* ZE duplicating uninitialized_zval_ptr */ * ZE duplicating uninitialized_zval_ptr */
if (!offset) { if (UNEXPECTED(!offset)) {
zend_throw_error(NULL, "[] operator not supported for SplFixedArray"); zend_throw_error(NULL, "[] operator not supported for SplFixedArray");
return NULL; return NULL;
} }
@ -422,7 +422,7 @@ static zval *spl_fixedarray_object_read_dimension(zend_object *object, zval *off
static void spl_fixedarray_object_write_dimension_helper(spl_fixedarray_object *intern, zval *offset, zval *value) static void spl_fixedarray_object_write_dimension_helper(spl_fixedarray_object *intern, zval *offset, zval *value)
{ {
if (!offset) { if (UNEXPECTED(!offset)) {
/* '$array[] = value' syntax is not supported */ /* '$array[] = value' syntax is not supported */
zend_throw_error(NULL, "[] operator not supported for SplFixedArray"); zend_throw_error(NULL, "[] operator not supported for SplFixedArray");
return; return;
@ -438,10 +438,10 @@ static void spl_fixedarray_object_write_dimension_helper(spl_fixedarray_object *
} else { } else {
/* Fix #81429 */ /* Fix #81429 */
zval *ptr = &(intern->array.elements[index]); zval *ptr = &(intern->array.elements[index]);
zval tmp; /* This should be guaranteed by the VM handler or argument parsing. */
ZVAL_COPY_VALUE(&tmp, ptr); ZEND_ASSERT(Z_TYPE_P(value) != IS_REFERENCE);
ZVAL_COPY_DEREF(ptr, value); Z_TRY_ADDREF_P(value);
zval_ptr_dtor(&tmp); zend_safe_assign_to_variable_noref(ptr, value);
} }
} }
@ -472,10 +472,9 @@ static void spl_fixedarray_object_unset_dimension_helper(spl_fixedarray_object *
if (UNEXPECTED(index >= intern->array.size)) { if (UNEXPECTED(index >= intern->array.size)) {
zend_throw_exception(spl_ce_OutOfBoundsException, "Index invalid or out of range", 0); zend_throw_exception(spl_ce_OutOfBoundsException, "Index invalid or out of range", 0);
} else { } else {
zval garbage; zval null = {0};
ZVAL_COPY_VALUE(&garbage, &intern->array.elements[index]); ZVAL_NULL(&null);
ZVAL_NULL(&intern->array.elements[index]); zend_safe_assign_to_variable_noref(&intern->array.elements[index], &null);
zval_ptr_dtor(&garbage);
} }
} }