Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion ext/spl/spl_array.c
Original file line number Diff line number Diff line change
Expand Up @@ -1565,7 +1565,7 @@ static zval *spl_array_it_get_current_data(zend_object_iterator *iter) /* {{{ */
}
// ZEND_FE_FETCH_RW converts the value to a reference but doesn't know the source is a property.
// Typed properties must add a type source to the reference, and readonly properties must fail.
if (array_iter->by_ref
if (data && array_iter->by_ref
&& Z_TYPE_P(data) != IS_REFERENCE
&& Z_TYPE(object->array) == IS_OBJECT
&& !(object->ar_flags & (SPL_ARRAY_IS_SELF|SPL_ARRAY_USE_OTHER))) {
Expand Down
35 changes: 35 additions & 0 deletions ext/spl/tests/pr23720.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
--TEST--
PR-23720: ArrayIterator segfault in spl_array_it_get_current_data when data is NULL and by_ref is set
--CREDITS--
Georgij Tsarin crystarm@altlinux.org
Artem Burke aiburke@fobos-nt.ru
--FILE--
<?php
class Aggregator implements IteratorAggregate {
public function getIterator(): Traversable {
return new ArrayIterator($GLOBALS['backing']);
}

public function __destruct() {
/* Runs while the temporary operand of the foreach is released by
* ZEND_FE_RESET_RW, i.e. after the iterator has been validated but
* before the first fetch asks for the current element. */
unset($GLOBALS['backing']->p);
}
}

function makeAggregator(): IteratorAggregate {
return new Aggregator;
}

$GLOBALS['backing'] = new stdClass;
$GLOBALS['backing']->p = 1;

foreach (makeAggregator() as &$value) {
echo "iterated\n";
}
echo "done\n";
?>
--EXPECTF--
Deprecated: ArrayIterator::__construct(): Using an object as a backing array for ArrayIterator is deprecated, as it allows violating class constraints and invariants in %s on line %d
done
Loading