Skip to content

Commit 3eb81f5

Browse files
author
aiburke
committed
ext/spl: Add regression test for NULL deref in spl_array_it_get_current_data()
Reproduces the SIGSEGV when a by-ref foreach releases a temporary IteratorAggregate whose destructor shrinks the object backing the ArrayIterator, leaving data == NULL while by_ref is set.
1 parent 6a8a1d4 commit 3eb81f5

1 file changed

Lines changed: 35 additions & 0 deletions

File tree

‎ext/spl/tests/pr23720.phpt‎

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
--TEST--
2+
PR-23720: ArrayIterator segfault in spl_array_it_get_current_data when data is NULL and by_ref is set
3+
--CREDITS--
4+
Georgij Tsarin crystarm@altlinux.org
5+
Artem Burke aiburke@fobos-nt.ru
6+
--FILE--
7+
<?php
8+
class Aggregator implements IteratorAggregate {
9+
public function getIterator(): Traversable {
10+
return new ArrayIterator($GLOBALS['backing']);
11+
}
12+
13+
public function __destruct() {
14+
/* Runs while the temporary operand of the foreach is released by
15+
* ZEND_FE_RESET_RW, i.e. after the iterator has been validated but
16+
* before the first fetch asks for the current element. */
17+
unset($GLOBALS['backing']->p);
18+
}
19+
}
20+
21+
function makeAggregator(): IteratorAggregate {
22+
return new Aggregator;
23+
}
24+
25+
$GLOBALS['backing'] = new stdClass;
26+
$GLOBALS['backing']->p = 1;
27+
28+
foreach (makeAggregator() as &$value) {
29+
echo "iterated\n";
30+
}
31+
echo "done\n";
32+
?>
33+
--EXPECTF--
34+
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
35+
done

0 commit comments

Comments
 (0)