mirror of
https://github.com/php/php-src.git
synced 2025-08-16 14:08:47 +02:00
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:
parent
337973fccc
commit
a082696699
3 changed files with 148 additions and 2 deletions
2
NEWS
2
NEWS
|
@ -62,6 +62,8 @@ PHP NEWS
|
|||
|
||||
- SPL:
|
||||
. 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:
|
||||
. Fixed bug GH-10885 (stream_socket_server context leaks). (ilutov)
|
||||
|
|
|
@ -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);
|
||||
/* 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();
|
||||
}
|
||||
}
|
||||
|
|
139
ext/spl/tests/gh10907.phpt
Normal file
139
ext/spl/tests/gh10907.phpt
Normal 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
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue