Skip to content

Fix GH-10907: Unable to serialize processed SplFixedArrays in PHP 8.2.4 #10921

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from
Closed
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
9 changes: 7 additions & 2 deletions ext/spl/spl_fixedarray.c
Original file line number Diff line number Diff line change
Expand Up @@ -611,8 +611,13 @@ PHP_METHOD(SplFixedArray, __serialize)
/* members */
if (intern->std.properties) {
ZEND_HASH_FOREACH_STR_KEY_VAL(intern->std.properties, key, current) {
zend_hash_add(Z_ARRVAL_P(return_value), key, current);
Z_TRY_ADDREF_P(current);
/* The properties hash table can also contain the array elements if the properties table was already rebuilt.
* In this case we'd have a NULL key. We can't simply use the properties table in all cases because it's
* potentially out of sync (missing elements, or containing removed elements) and might need a rebuild. */
if (key != NULL) {
zend_hash_add_new(Z_ARRVAL_P(return_value), key, current);
Z_TRY_ADDREF_P(current);
}
} ZEND_HASH_FOREACH_END();
}
}
Expand Down
139 changes: 139 additions & 0 deletions ext/spl/tests/gh10907.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
--TEST--
GH-10907 (Unable to serialize processed SplFixedArrays in PHP 8.2.4)
--FILE--
<?php
echo "Test without rebuilding properties\n";
$array = new SplFixedArray(2);
$array[0] = "test value 1";
$array[1] = "test value 2";
var_dump(serialize($array));
var_dump(unserialize(serialize($array)));
var_dump($array);

echo "=================\n";

echo "Test with rebuilding properties\n";
$array = new SplFixedArray(2);
$array[0] = "test value 1";
$array[1] = "test value 2";
var_dump($array); // Rebuilds properties
var_dump(serialize($array));
var_dump(unserialize(serialize($array)));
var_dump($array);

echo "=================\n";

echo "Test with partially rebuilding properties\n";
$array = new SplFixedArray(3);
$array[0] = "test value 1";
var_dump($array); // Rebuilds properties
$array[1] = "test value 2";
var_dump(serialize($array));
var_dump(unserialize(serialize($array)));
var_dump($array);

echo "=================\n";

echo "Test with adding members\n";
#[AllowDynamicProperties]
class MySplFixedArray extends SplFixedArray {
public string $my_string = "my_string_value";
}
$array = new MySplFixedArray(3);
$array->my_dynamic_property = "my_dynamic_property_value";
$array[0] = "test value 1";
$array[1] = "test value 2";
var_dump(serialize($array));
var_dump(unserialize(serialize($array)));
var_dump($array);
?>
--EXPECT--
Test without rebuilding properties
string(73) "O:13:"SplFixedArray":2:{i:0;s:12:"test value 1";i:1;s:12:"test value 2";}"
object(SplFixedArray)#2 (2) {
[0]=>
string(12) "test value 1"
[1]=>
string(12) "test value 2"
}
object(SplFixedArray)#1 (2) {
[0]=>
string(12) "test value 1"
[1]=>
string(12) "test value 2"
}
=================
Test with rebuilding properties
object(SplFixedArray)#2 (2) {
[0]=>
string(12) "test value 1"
[1]=>
string(12) "test value 2"
}
string(73) "O:13:"SplFixedArray":2:{i:0;s:12:"test value 1";i:1;s:12:"test value 2";}"
object(SplFixedArray)#1 (2) {
[0]=>
string(12) "test value 1"
[1]=>
string(12) "test value 2"
}
object(SplFixedArray)#2 (2) {
[0]=>
string(12) "test value 1"
[1]=>
string(12) "test value 2"
}
=================
Test with partially rebuilding properties
object(SplFixedArray)#1 (3) {
[0]=>
string(12) "test value 1"
[1]=>
NULL
[2]=>
NULL
}
string(79) "O:13:"SplFixedArray":3:{i:0;s:12:"test value 1";i:1;s:12:"test value 2";i:2;N;}"
object(SplFixedArray)#2 (3) {
[0]=>
string(12) "test value 1"
[1]=>
string(12) "test value 2"
[2]=>
NULL
}
object(SplFixedArray)#1 (3) {
[0]=>
string(12) "test value 1"
[1]=>
string(12) "test value 2"
[2]=>
NULL
}
=================
Test with adding members
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";}"
object(MySplFixedArray)#1 (5) {
["my_string"]=>
int(0)
["my_dynamic_property"]=>
string(25) "my_dynamic_property_value"
[0]=>
string(12) "test value 1"
[1]=>
string(12) "test value 2"
[2]=>
NULL
}
object(MySplFixedArray)#2 (5) {
["my_string"]=>
string(15) "my_string_value"
["my_dynamic_property"]=>
string(25) "my_dynamic_property_value"
[0]=>
string(12) "test value 1"
[1]=>
string(12) "test value 2"
[2]=>
NULL
}