Skip to content

Commit 3becd38

Browse files
LawnGnomesmalyshev
authored andcommitted
Add a __wakeup() method to SplFixedArray, thereby fixing serialising an
SplFixedArray object and bug #60560 (SplFixedArray un-/serialize, getSize(), count() return 0, keys are strings).
1 parent e00ed6b commit 3becd38

File tree

3 files changed

+87
-0
lines changed

3 files changed

+87
-0
lines changed

NEWS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ PHP NEWS
4949
. Fixed bug #65136 (RecursiveDirectoryIterator segfault). (Laruence)
5050
. Fixed bug #61828 (Memleak when calling Directory(Recursive)Iterator
5151
/Spl(Temp)FileObject ctor twice). (Laruence)
52+
. Fixed bug #60560 (SplFixedArray un-/serialize, getSize(), count() return 0,
53+
keys are strings). (Adam)
5254

5355
?? ??? 2013, PHP 5.4.17
5456

ext/spl/spl_fixedarray.c

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -604,6 +604,38 @@ SPL_METHOD(SplFixedArray, __construct)
604604
}
605605
/* }}} */
606606

607+
/* {{{ proto void SplFixedArray::__wakeup()
608+
*/
609+
SPL_METHOD(SplFixedArray, __wakeup)
610+
{
611+
spl_fixedarray_object *intern = (spl_fixedarray_object *) zend_object_store_get_object(getThis() TSRMLS_CC);
612+
HashPosition ptr;
613+
HashTable *intern_ht = zend_std_get_properties(getThis() TSRMLS_CC);
614+
zval **data;
615+
616+
if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "")) {
617+
return;
618+
}
619+
620+
if (!intern->array) {
621+
int index = 0;
622+
int size = zend_hash_num_elements(intern_ht);
623+
624+
intern->array = emalloc(sizeof(spl_fixedarray));
625+
spl_fixedarray_init(intern->array, size TSRMLS_CC);
626+
627+
for (zend_hash_internal_pointer_reset_ex(intern_ht, &ptr); zend_hash_get_current_data_ex(intern_ht, (void **) &data, &ptr) == SUCCESS; zend_hash_move_forward_ex(intern_ht, &ptr)) {
628+
Z_ADDREF_PP(data);
629+
intern->array->elements[index++] = *data;
630+
}
631+
632+
/* Remove the unserialised properties, since we now have the elements
633+
* within the spl_fixedarray_object structure. */
634+
zend_hash_clean(intern_ht);
635+
}
636+
}
637+
/* }}} */
638+
607639
/* {{{ proto int SplFixedArray::count(void)
608640
*/
609641
SPL_METHOD(SplFixedArray, count)
@@ -1086,6 +1118,7 @@ ZEND_END_ARG_INFO()
10861118

10871119
static zend_function_entry spl_funcs_SplFixedArray[] = { /* {{{ */
10881120
SPL_ME(SplFixedArray, __construct, arginfo_splfixedarray_construct,ZEND_ACC_PUBLIC)
1121+
SPL_ME(SplFixedArray, __wakeup, arginfo_splfixedarray_void, ZEND_ACC_PUBLIC)
10891122
SPL_ME(SplFixedArray, count, arginfo_splfixedarray_void, ZEND_ACC_PUBLIC)
10901123
SPL_ME(SplFixedArray, toArray, arginfo_splfixedarray_void, ZEND_ACC_PUBLIC)
10911124
SPL_ME(SplFixedArray, fromArray, arginfo_fixedarray_fromArray, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
--TEST--
2+
SplFixedArray serialisation
3+
--FILE--
4+
<?php
5+
6+
$array = new SplFixedArray(5);
7+
8+
$obj = new stdClass;
9+
$obj->prop = 'value';
10+
11+
$array[0] = 'foo';
12+
$array[2] = 42;
13+
$array[3] = $obj;
14+
$array[4] = range(1, 5);
15+
16+
$ser = serialize($array);
17+
echo "$ser\n";
18+
$unser = unserialize($ser);
19+
20+
printf("count: %d\n", count($unser));
21+
printf("getSize(): %d\n", $unser->getSize());
22+
23+
var_dump($unser[0], $unser[1], $unser[2], $unser[3], $unser[4]);
24+
25+
$unser[4] = 'quux';
26+
var_dump($unser[4]);
27+
28+
?>
29+
--EXPECT--
30+
O:13:"SplFixedArray":5:{i:0;s:3:"foo";i:1;N;i:2;i:42;i:3;O:8:"stdClass":1:{s:4:"prop";s:5:"value";}i:4;a:5:{i:0;i:1;i:1;i:2;i:2;i:3;i:3;i:4;i:4;i:5;}}
31+
count: 5
32+
getSize(): 5
33+
string(3) "foo"
34+
NULL
35+
int(42)
36+
object(stdClass)#4 (1) {
37+
["prop"]=>
38+
string(5) "value"
39+
}
40+
array(5) {
41+
[0]=>
42+
int(1)
43+
[1]=>
44+
int(2)
45+
[2]=>
46+
int(3)
47+
[3]=>
48+
int(4)
49+
[4]=>
50+
int(5)
51+
}
52+
string(4) "quux"

0 commit comments

Comments
 (0)