Fix #81429: Handle resizing in SplFixedArray::offsetSet (#7487)

offsetSet did not account for the fact that the array may no longer exist after
the field is overwritten. This fixes that.

Add test of resizing both to the empty array and a smaller array - there should
be no valgrind warnings with a proper fix.

Alternate approach to #7486 (described in https://bugs.php.net/bug.php?id=81429)
This commit is contained in:
Tyson Andre 2021-09-13 20:59:06 -04:00 committed by GitHub
parent a2471383fe
commit b053192a03
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 61 additions and 4 deletions

View File

@ -389,10 +389,12 @@ static inline void spl_fixedarray_object_write_dimension_helper(spl_fixedarray_o
zend_throw_exception(spl_ce_RuntimeException, "Index invalid or out of range", 0);
return;
} else {
if (!Z_ISUNDEF(intern->array.elements[index])) {
zval_ptr_dtor(&(intern->array.elements[index]));
}
ZVAL_COPY_DEREF(&intern->array.elements[index], value);
/* Fix #81429 */
zval *ptr = &(intern->array.elements[index]);
zval tmp;
ZVAL_COPY_VALUE(&tmp, ptr);
ZVAL_COPY_DEREF(ptr, value);
zval_ptr_dtor(&tmp);
}
}
/* }}} */

View File

@ -0,0 +1,55 @@
--TEST--
SplFixedArray::setSize in offsetSet destructor (#81429)
--FILE--
<?php
$values = new SplFixedArray(1);
$values->offsetSet(0, new HasDestructor());
$values->offsetSet(0, false);
echo "Done\n";
class HasDestructor {
public function __destruct() {
global $values;
var_dump($values);
$values->setSize($values->getSize() - 1);
var_dump($values);
}
}
$values->setSize(5);
$values->offsetSet(4, new HasDestructor());
echo "Done\n";
--EXPECT--
object(SplFixedArray)#1 (1) {
[0]=>
bool(false)
}
object(SplFixedArray)#1 (1) {
[0]=>
bool(false)
}
Done
Done
object(SplFixedArray)#1 (5) {
[0]=>
NULL
[1]=>
NULL
[2]=>
NULL
[3]=>
NULL
[4]=>
object(HasDestructor)#2 (0) {
}
}
object(SplFixedArray)#1 (4) {
[0]=>
NULL
[1]=>
NULL
[2]=>
NULL
[3]=>
NULL
}