Skip to content

Commit f66677e

Browse files
committed
Merge branch 'PHP-8.3'
* PHP-8.3: Fix GH-11972: RecursiveCallbackFilterIterator regression in 8.1.18
2 parents da0e057 + dc72ced commit f66677e

File tree

2 files changed

+198
-3
lines changed

2 files changed

+198
-3
lines changed

ext/spl/spl_array.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1060,13 +1060,12 @@ static void spl_array_set_array(zval *object, spl_array_object *intern, zval *ar
10601060
ZVAL_ARR(&intern->array, zend_array_dup(Z_ARR_P(array)));
10611061

10621062
if (intern->is_child) {
1063-
Z_TRY_DELREF_P(&intern->bucket->val);
1063+
Z_TRY_DELREF(intern->bucket->val);
10641064
/*
10651065
* replace bucket->val with copied array, so the changes between
10661066
* parent and child object can affect each other.
10671067
*/
1068-
intern->bucket->val = intern->array;
1069-
Z_TRY_ADDREF_P(&intern->array);
1068+
ZVAL_COPY(&intern->bucket->val, &intern->array);
10701069
}
10711070
}
10721071
} else {

ext/spl/tests/gh11972.phpt

Lines changed: 196 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,196 @@
1+
--TEST--
2+
GH-11972 (RecursiveCallbackFilterIterator regression in 8.1.18)
3+
--EXTENSIONS--
4+
spl
5+
--FILE--
6+
<?php
7+
8+
class RecursiveFilterTest {
9+
public function traverse(array $variables): array {
10+
$array_iterator = new \RecursiveArrayIterator($variables);
11+
$filter_iterator = new \RecursiveCallbackFilterIterator($array_iterator, [
12+
$this, 'isCyclic',
13+
]);
14+
$recursive_iterator = new \RecursiveIteratorIterator($filter_iterator, \RecursiveIteratorIterator::SELF_FIRST);
15+
$recursive_iterator->setMaxDepth(20);
16+
foreach ($recursive_iterator as $value) {
17+
// Avoid recursion by marking where we've been.
18+
$value['#override_mode_breadcrumb'] = true;
19+
}
20+
return \iterator_to_array($recursive_iterator);
21+
}
22+
23+
public function isCyclic($current, string $key, \RecursiveArrayIterator $iterator): bool {
24+
var_dump($current);
25+
if (!is_array($current)) {
26+
return false;
27+
}
28+
// Avoid infinite loops by checking if we've been here before.
29+
// e.g. View > query > view > query ...
30+
if (isset($current['#override_mode_breadcrumb'])) {
31+
return false;
32+
}
33+
return true;
34+
}
35+
}
36+
37+
$test_array['e']['p'][] = ['a', 'a'];
38+
$test_array['e']['p'][] = ['b', 'b'];
39+
$test_array['e']['p'][] = ['c', 'c'];
40+
$serialized = serialize($test_array);
41+
$unserialized = unserialize($serialized);
42+
43+
$test_class = new RecursiveFilterTest();
44+
$test_class->traverse($unserialized);
45+
46+
echo "Done\n";
47+
48+
?>
49+
--EXPECT--
50+
array(1) {
51+
["p"]=>
52+
array(3) {
53+
[0]=>
54+
array(2) {
55+
[0]=>
56+
string(1) "a"
57+
[1]=>
58+
string(1) "a"
59+
}
60+
[1]=>
61+
array(2) {
62+
[0]=>
63+
string(1) "b"
64+
[1]=>
65+
string(1) "b"
66+
}
67+
[2]=>
68+
array(2) {
69+
[0]=>
70+
string(1) "c"
71+
[1]=>
72+
string(1) "c"
73+
}
74+
}
75+
}
76+
array(3) {
77+
[0]=>
78+
array(2) {
79+
[0]=>
80+
string(1) "a"
81+
[1]=>
82+
string(1) "a"
83+
}
84+
[1]=>
85+
array(2) {
86+
[0]=>
87+
string(1) "b"
88+
[1]=>
89+
string(1) "b"
90+
}
91+
[2]=>
92+
array(2) {
93+
[0]=>
94+
string(1) "c"
95+
[1]=>
96+
string(1) "c"
97+
}
98+
}
99+
array(2) {
100+
[0]=>
101+
string(1) "a"
102+
[1]=>
103+
string(1) "a"
104+
}
105+
string(1) "a"
106+
string(1) "a"
107+
array(2) {
108+
[0]=>
109+
string(1) "b"
110+
[1]=>
111+
string(1) "b"
112+
}
113+
string(1) "b"
114+
string(1) "b"
115+
array(2) {
116+
[0]=>
117+
string(1) "c"
118+
[1]=>
119+
string(1) "c"
120+
}
121+
string(1) "c"
122+
string(1) "c"
123+
array(1) {
124+
["p"]=>
125+
array(3) {
126+
[0]=>
127+
array(2) {
128+
[0]=>
129+
string(1) "a"
130+
[1]=>
131+
string(1) "a"
132+
}
133+
[1]=>
134+
array(2) {
135+
[0]=>
136+
string(1) "b"
137+
[1]=>
138+
string(1) "b"
139+
}
140+
[2]=>
141+
array(2) {
142+
[0]=>
143+
string(1) "c"
144+
[1]=>
145+
string(1) "c"
146+
}
147+
}
148+
}
149+
array(3) {
150+
[0]=>
151+
array(2) {
152+
[0]=>
153+
string(1) "a"
154+
[1]=>
155+
string(1) "a"
156+
}
157+
[1]=>
158+
array(2) {
159+
[0]=>
160+
string(1) "b"
161+
[1]=>
162+
string(1) "b"
163+
}
164+
[2]=>
165+
array(2) {
166+
[0]=>
167+
string(1) "c"
168+
[1]=>
169+
string(1) "c"
170+
}
171+
}
172+
array(2) {
173+
[0]=>
174+
string(1) "a"
175+
[1]=>
176+
string(1) "a"
177+
}
178+
string(1) "a"
179+
string(1) "a"
180+
array(2) {
181+
[0]=>
182+
string(1) "b"
183+
[1]=>
184+
string(1) "b"
185+
}
186+
string(1) "b"
187+
string(1) "b"
188+
array(2) {
189+
[0]=>
190+
string(1) "c"
191+
[1]=>
192+
string(1) "c"
193+
}
194+
string(1) "c"
195+
string(1) "c"
196+
Done

0 commit comments

Comments
 (0)