1
0
mirror of https://github.com/php/php-src.git synced 2026-03-24 00:02:20 +01:00

Merge branch 'PHP-8.2' into PHP-8.3

* PHP-8.2:
  Fix GH-11972: RecursiveCallbackFilterIterator regression in 8.1.18
This commit is contained in:
Niels Dossche
2023-08-30 22:27:06 +02:00
3 changed files with 202 additions and 3 deletions

4
NEWS
View File

@@ -11,6 +11,10 @@ PHP NEWS
. Fixed GH-12077 (PHP 8.3.0RC1 borked socket-close-on-exec.phpt).
(Jakub Zelenka)
- SPL:
. Fixed bug GH-11972 (RecursiveCallbackFilterIterator regression in 8.1.18).
(nielsdos)
31 Aug 2023, PHP 8.3.0RC1
- Core:

View File

@@ -1060,13 +1060,12 @@ static void spl_array_set_array(zval *object, spl_array_object *intern, zval *ar
ZVAL_ARR(&intern->array, zend_array_dup(Z_ARR_P(array)));
if (intern->is_child) {
Z_TRY_DELREF_P(&intern->bucket->val);
Z_TRY_DELREF(intern->bucket->val);
/*
* replace bucket->val with copied array, so the changes between
* parent and child object can affect each other.
*/
intern->bucket->val = intern->array;
Z_TRY_ADDREF_P(&intern->array);
ZVAL_COPY(&intern->bucket->val, &intern->array);
}
}
} else {

196
ext/spl/tests/gh11972.phpt Normal file
View File

@@ -0,0 +1,196 @@
--TEST--
GH-11972 (RecursiveCallbackFilterIterator regression in 8.1.18)
--EXTENSIONS--
spl
--FILE--
<?php
class RecursiveFilterTest {
public function traverse(array $variables): array {
$array_iterator = new \RecursiveArrayIterator($variables);
$filter_iterator = new \RecursiveCallbackFilterIterator($array_iterator, [
$this, 'isCyclic',
]);
$recursive_iterator = new \RecursiveIteratorIterator($filter_iterator, \RecursiveIteratorIterator::SELF_FIRST);
$recursive_iterator->setMaxDepth(20);
foreach ($recursive_iterator as $value) {
// Avoid recursion by marking where we've been.
$value['#override_mode_breadcrumb'] = true;
}
return \iterator_to_array($recursive_iterator);
}
public function isCyclic($current, string $key, \RecursiveArrayIterator $iterator): bool {
var_dump($current);
if (!is_array($current)) {
return false;
}
// Avoid infinite loops by checking if we've been here before.
// e.g. View > query > view > query ...
if (isset($current['#override_mode_breadcrumb'])) {
return false;
}
return true;
}
}
$test_array['e']['p'][] = ['a', 'a'];
$test_array['e']['p'][] = ['b', 'b'];
$test_array['e']['p'][] = ['c', 'c'];
$serialized = serialize($test_array);
$unserialized = unserialize($serialized);
$test_class = new RecursiveFilterTest();
$test_class->traverse($unserialized);
echo "Done\n";
?>
--EXPECT--
array(1) {
["p"]=>
array(3) {
[0]=>
array(2) {
[0]=>
string(1) "a"
[1]=>
string(1) "a"
}
[1]=>
array(2) {
[0]=>
string(1) "b"
[1]=>
string(1) "b"
}
[2]=>
array(2) {
[0]=>
string(1) "c"
[1]=>
string(1) "c"
}
}
}
array(3) {
[0]=>
array(2) {
[0]=>
string(1) "a"
[1]=>
string(1) "a"
}
[1]=>
array(2) {
[0]=>
string(1) "b"
[1]=>
string(1) "b"
}
[2]=>
array(2) {
[0]=>
string(1) "c"
[1]=>
string(1) "c"
}
}
array(2) {
[0]=>
string(1) "a"
[1]=>
string(1) "a"
}
string(1) "a"
string(1) "a"
array(2) {
[0]=>
string(1) "b"
[1]=>
string(1) "b"
}
string(1) "b"
string(1) "b"
array(2) {
[0]=>
string(1) "c"
[1]=>
string(1) "c"
}
string(1) "c"
string(1) "c"
array(1) {
["p"]=>
array(3) {
[0]=>
array(2) {
[0]=>
string(1) "a"
[1]=>
string(1) "a"
}
[1]=>
array(2) {
[0]=>
string(1) "b"
[1]=>
string(1) "b"
}
[2]=>
array(2) {
[0]=>
string(1) "c"
[1]=>
string(1) "c"
}
}
}
array(3) {
[0]=>
array(2) {
[0]=>
string(1) "a"
[1]=>
string(1) "a"
}
[1]=>
array(2) {
[0]=>
string(1) "b"
[1]=>
string(1) "b"
}
[2]=>
array(2) {
[0]=>
string(1) "c"
[1]=>
string(1) "c"
}
}
array(2) {
[0]=>
string(1) "a"
[1]=>
string(1) "a"
}
string(1) "a"
string(1) "a"
array(2) {
[0]=>
string(1) "b"
[1]=>
string(1) "b"
}
string(1) "b"
string(1) "b"
array(2) {
[0]=>
string(1) "c"
[1]=>
string(1) "c"
}
string(1) "c"
string(1) "c"
Done