Skip to content

Commit 930db2b

Browse files
committed
Merge branch 'PHP-8.2'
* PHP-8.2: Handle indirect zvals and use up-to-date properties in SplFixedArray::__serialize [ci skip] NEWS
2 parents da96aa8 + 47b3fe4 commit 930db2b

File tree

4 files changed

+87
-21
lines changed

4 files changed

+87
-21
lines changed

ext/spl/spl_fixedarray.c

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -586,8 +586,8 @@ PHP_METHOD(SplFixedArray, __serialize)
586586
RETURN_THROWS();
587587
}
588588

589-
uint32_t num_properties =
590-
intern->std.properties ? zend_hash_num_elements(intern->std.properties) : 0;
589+
HashTable *ht = zend_std_get_properties(&intern->std);
590+
uint32_t num_properties = zend_hash_num_elements(ht);
591591
array_init_size(return_value, intern->array.size + num_properties);
592592

593593
/* elements */
@@ -598,17 +598,15 @@ PHP_METHOD(SplFixedArray, __serialize)
598598
}
599599

600600
/* members */
601-
if (intern->std.properties) {
602-
ZEND_HASH_FOREACH_STR_KEY_VAL(intern->std.properties, key, current) {
603-
/* The properties hash table can also contain the array elements if the properties table was already rebuilt.
604-
* In this case we'd have a NULL key. We can't simply use the properties table in all cases because it's
605-
* potentially out of sync (missing elements, or containing removed elements) and might need a rebuild. */
606-
if (key != NULL) {
607-
zend_hash_add_new(Z_ARRVAL_P(return_value), key, current);
608-
Z_TRY_ADDREF_P(current);
609-
}
610-
} ZEND_HASH_FOREACH_END();
611-
}
601+
ZEND_HASH_FOREACH_STR_KEY_VAL_IND(ht, key, current) {
602+
/* If the properties table was already rebuild, it will also contain the
603+
* array elements. The array elements are already added in the above loop.
604+
* We can detect array elements by the fact that their key == NULL. */
605+
if (key != NULL) {
606+
zend_hash_add_new(Z_ARRVAL_P(return_value), key, current);
607+
Z_TRY_ADDREF_P(current);
608+
}
609+
} ZEND_HASH_FOREACH_END();
612610
}
613611

614612
PHP_METHOD(SplFixedArray, __unserialize)

ext/spl/tests/SplFixedArray_get_properties_for.phpt

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -71,16 +71,15 @@ array(3) {
7171
}
7272
}
7373
[{},{}]
74-
O:15:"MySplFixedArray":5:{i:0;O:8:"stdClass":0:{}i:1;O:1:"Y":0:{}s:1:"x";i:0;s:1:"y";i:0;s:1:"0";O:1:"X":0:{}}
75-
object(MySplFixedArray)#6 (4) {
74+
O:15:"MySplFixedArray":4:{i:0;O:8:"stdClass":0:{}i:1;O:1:"Y":0:{}s:1:"x";O:13:"SplFixedArray":0:{}s:1:"0";O:1:"X":0:{}}
75+
object(MySplFixedArray)#6 (3) {
7676
[0]=>
77-
object(X)#9 (0) {
77+
object(X)#10 (0) {
7878
}
7979
[1]=>
8080
object(Y)#8 (0) {
8181
}
8282
["x"]=>
83-
int(0)
84-
["y"]=>
85-
int(0)
83+
object(SplFixedArray)#9 (0) {
84+
}
8685
}

ext/spl/tests/gh10907.phpt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ object(SplFixedArray)#1 (3) {
112112
}
113113
=================
114114
Test with adding members
115-
string(161) "O:15:"MySplFixedArray":5:{i:0;s:12:"test value 1";i:1;s:12:"test value 2";i:2;N;s:9:"my_string";i:0;s:19:"my_dynamic_property";s:25:"my_dynamic_property_value";}"
115+
string(180) "O:15:"MySplFixedArray":5:{i:0;s:12:"test value 1";i:1;s:12:"test value 2";i:2;N;s:9:"my_string";s:15:"my_string_value";s:19:"my_dynamic_property";s:25:"my_dynamic_property_value";}"
116116
object(MySplFixedArray)#1 (5) {
117117
[0]=>
118118
string(12) "test value 1"
@@ -121,7 +121,7 @@ object(MySplFixedArray)#1 (5) {
121121
[2]=>
122122
NULL
123123
["my_string"]=>
124-
int(0)
124+
string(15) "my_string_value"
125125
["my_dynamic_property"]=>
126126
string(25) "my_dynamic_property_value"
127127
}

ext/spl/tests/gh10925.phpt

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
--TEST--
2+
Properties serialization for SplFixedArray should have updated properties
3+
--FILE--
4+
<?php
5+
#[AllowDynamicProperties]
6+
class MySplFixedArray extends SplFixedArray {
7+
public $x;
8+
public int $y = 3;
9+
}
10+
11+
$x = new MySplFixedArray(2);
12+
var_dump($x->y);
13+
$x->y = 2;
14+
var_dump($x->y);
15+
$serialized = serialize($x);
16+
var_dump($serialized);
17+
var_dump(unserialize($serialized));
18+
19+
$x->dynamic_property = "dynamic_property_value";
20+
$serialized = serialize($x);
21+
var_dump($serialized);
22+
var_dump(unserialize($serialized));
23+
24+
$x->dynamic_property = "dynamic_property_value2";
25+
$x->y = 4;
26+
$serialized = serialize($x);
27+
var_dump($serialized);
28+
var_dump(unserialize($serialized));
29+
?>
30+
--EXPECT--
31+
int(3)
32+
int(2)
33+
string(61) "O:15:"MySplFixedArray":4:{i:0;N;i:1;N;s:1:"x";N;s:1:"y";i:2;}"
34+
object(MySplFixedArray)#2 (4) {
35+
[0]=>
36+
NULL
37+
[1]=>
38+
NULL
39+
["x"]=>
40+
NULL
41+
["y"]=>
42+
int(2)
43+
}
44+
string(115) "O:15:"MySplFixedArray":5:{i:0;N;i:1;N;s:1:"x";N;s:1:"y";i:2;s:16:"dynamic_property";s:22:"dynamic_property_value";}"
45+
object(MySplFixedArray)#2 (5) {
46+
[0]=>
47+
NULL
48+
[1]=>
49+
NULL
50+
["x"]=>
51+
NULL
52+
["y"]=>
53+
int(2)
54+
["dynamic_property"]=>
55+
string(22) "dynamic_property_value"
56+
}
57+
string(116) "O:15:"MySplFixedArray":5:{i:0;N;i:1;N;s:1:"x";N;s:1:"y";i:4;s:16:"dynamic_property";s:23:"dynamic_property_value2";}"
58+
object(MySplFixedArray)#2 (5) {
59+
[0]=>
60+
NULL
61+
[1]=>
62+
NULL
63+
["x"]=>
64+
NULL
65+
["y"]=>
66+
int(4)
67+
["dynamic_property"]=>
68+
string(23) "dynamic_property_value2"
69+
}

0 commit comments

Comments
 (0)