Skip to content

Commit 37272e4

Browse files
committed
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 eefefdd commit 37272e4

3 files changed

Lines changed: 88 additions & 0 deletions

File tree

UPGRADING

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -450,6 +450,9 @@ UPGRADE NOTES - PHP X.Y
450450
- SplFileObject
451451
- SplFileObject::fputcsv()
452452

453+
- SplFixedArray
454+
- SplFixedArray::__wakeup()
455+
453456
i. New class constants
454457

455458
-

ext/spl/spl_fixedarray.c

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -579,6 +579,38 @@ SPL_METHOD(SplFixedArray, __construct)
579579
}
580580
/* }}} */
581581

582+
/* {{{ proto void SplFixedArray::__wakeup()
583+
*/
584+
SPL_METHOD(SplFixedArray, __wakeup)
585+
{
586+
spl_fixedarray_object *intern = (spl_fixedarray_object *) zend_object_store_get_object(getThis() TSRMLS_CC);
587+
HashPosition ptr;
588+
HashTable *intern_ht = zend_std_get_properties(getThis() TSRMLS_CC);
589+
zval **data;
590+
591+
if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "")) {
592+
return;
593+
}
594+
595+
if (!intern->array) {
596+
int index = 0;
597+
int size = zend_hash_num_elements(intern_ht);
598+
599+
intern->array = emalloc(sizeof(spl_fixedarray));
600+
spl_fixedarray_init(intern->array, size TSRMLS_CC);
601+
602+
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)) {
603+
Z_ADDREF_PP(data);
604+
intern->array->elements[index++] = *data;
605+
}
606+
607+
/* Remove the unserialised properties, since we now have the elements
608+
* within the spl_fixedarray_object structure. */
609+
zend_hash_clean(intern_ht);
610+
}
611+
}
612+
/* }}} */
613+
582614
/* {{{ proto int SplFixedArray::count(void)
583615
*/
584616
SPL_METHOD(SplFixedArray, count)
@@ -1056,6 +1088,7 @@ ZEND_END_ARG_INFO()
10561088

10571089
static zend_function_entry spl_funcs_SplFixedArray[] = { /* {{{ */
10581090
SPL_ME(SplFixedArray, __construct, arginfo_splfixedarray_construct,ZEND_ACC_PUBLIC)
1091+
SPL_ME(SplFixedArray, __wakeup, arginfo_splfixedarray_void, ZEND_ACC_PUBLIC)
10591092
SPL_ME(SplFixedArray, count, arginfo_splfixedarray_void, ZEND_ACC_PUBLIC)
10601093
SPL_ME(SplFixedArray, toArray, arginfo_splfixedarray_void, ZEND_ACC_PUBLIC)
10611094
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)