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

The properties table can also contain numeric entries after a rebuild of
the table based on the array. Since the array can only contain numeric
entries, and the properties table can contain a mix of both, we'll add
the numeric entries from the array and only the string entries from the
properties table. To implement this we simply check if the key from the
properties table is a string.

Closes GH-10921.
This commit is contained in:
Niels Dossche 2023-03-22 20:44:54 +01:00
parent 337973fccc
commit a082696699
3 changed files with 148 additions and 2 deletions

2
NEWS
View file

@ -62,6 +62,8 @@ PHP NEWS
- SPL: - SPL:
. Fixed bug GH-10519 (Array Data Address Reference Issue). (Nathan Freeman) . Fixed bug GH-10519 (Array Data Address Reference Issue). (Nathan Freeman)
. Fixed bug GH-10907 (Unable to serialize processed SplFixedArrays in
PHP 8.2.4). (nielsdos)
- Standard: - Standard:
. Fixed bug GH-10885 (stream_socket_server context leaks). (ilutov) . Fixed bug GH-10885 (stream_socket_server context leaks). (ilutov)

View file

@ -611,8 +611,13 @@ PHP_METHOD(SplFixedArray, __serialize)
/* members */ /* members */
if (intern->std.properties) { if (intern->std.properties) {
ZEND_HASH_FOREACH_STR_KEY_VAL(intern->std.properties, key, current) { ZEND_HASH_FOREACH_STR_KEY_VAL(intern->std.properties, key, current) {
zend_hash_add(Z_ARRVAL_P(return_value), key, current); /* The properties hash table can also contain the array elements if the properties table was already rebuilt.
Z_TRY_ADDREF_P(current); * 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(); } ZEND_HASH_FOREACH_END();
} }
} }

139
ext/spl/tests/gh10907.phpt Normal file
View file

@ -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
}