Skip to content

Commit 620d63c

Browse files
committed
Check for ref in SplObjectStorage->__unserialize, check for ref.
SplObjectStorage->unserialize may be a different cause of references for malformed inputs, so continue checking In internally used methods, convert references to non-references if they're found.
1 parent 13f46bf commit 620d63c

File tree

2 files changed

+45
-4
lines changed

2 files changed

+45
-4
lines changed

ext/spl/spl_observer.c

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,6 @@ static spl_SplObjectStorageElement *spl_object_storage_attach_handle(spl_SplObje
158158
ZEND_ASSERT(Z_TYPE_P(entry_zv) == IS_PTR);
159159
pelement = Z_PTR_P(entry_zv);
160160
ZVAL_COPY_VALUE(&zv_inf, &pelement->inf);
161-
ZEND_ASSERT(Z_TYPE(zv_inf) != IS_REFERENCE);
162161
if (inf) {
163162
ZVAL_COPY(&pelement->inf, inf);
164163
} else {
@@ -192,7 +191,6 @@ spl_SplObjectStorageElement *spl_object_storage_attach(spl_SplObjectStorage *int
192191
if (pelement) {
193192
zval zv_inf;
194193
ZVAL_COPY_VALUE(&zv_inf, &pelement->inf);
195-
ZEND_ASSERT(Z_TYPE(zv_inf) != IS_REFERENCE);
196194
if (inf) {
197195
ZVAL_COPY(&pelement->inf, inf);
198196
} else {
@@ -481,7 +479,7 @@ static zval *spl_object_storage_read_dimension(zend_object *object, zval *offset
481479
/* This deliberately returns a non-reference, even for BP_VAR_W and BP_VAR_RW, to behave the same way as SplObjectStorage did when using the default zend_std_read_dimension behavior.
482480
* i.e. This prevents taking a reference to an entry of SplObjectStorage because offsetGet would return a non-reference. */
483481
ZEND_ASSERT(Z_TYPE(element->inf) != IS_REFERENCE);
484-
ZVAL_COPY(rv, &element->inf);
482+
ZVAL_COPY_DEREF(rv, &element->inf);
485483
return rv;
486484
}
487485
}
@@ -556,7 +554,7 @@ PHP_METHOD(SplObjectStorage, offsetGet)
556554
if (!element) {
557555
zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0, "Object not found");
558556
} else {
559-
RETURN_COPY(&element->inf);
557+
RETURN_COPY_VALUE(&element->inf);
560558
}
561559
} /* }}} */
562560

@@ -996,6 +994,7 @@ PHP_METHOD(SplObjectStorage, __unserialize)
996994
RETURN_THROWS();
997995
}
998996

997+
ZVAL_DEREF(val);
999998
spl_object_storage_attach(intern, Z_OBJ_P(key), val);
1000999
key = NULL;
10011000
} else {
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
--TEST--
2+
SPL: Test that __unserialize converts references to non-references
3+
--FILE--
4+
<?php
5+
6+
$s = new SplObjectStorage();
7+
$y = 1;
8+
$o = new stdClass();
9+
$x = [$o, &$y];
10+
$s->__unserialize([$x, []]);
11+
var_dump($s);
12+
$val = $s[$o];
13+
$val = 123;
14+
var_dump($s);
15+
?>
16+
--EXPECT--
17+
object(SplObjectStorage)#1 (1) {
18+
["storage":"SplObjectStorage":private]=>
19+
array(1) {
20+
[0]=>
21+
array(2) {
22+
["obj"]=>
23+
object(stdClass)#2 (0) {
24+
}
25+
["inf"]=>
26+
int(1)
27+
}
28+
}
29+
}
30+
object(SplObjectStorage)#1 (1) {
31+
["storage":"SplObjectStorage":private]=>
32+
array(1) {
33+
[0]=>
34+
array(2) {
35+
["obj"]=>
36+
object(stdClass)#2 (0) {
37+
}
38+
["inf"]=>
39+
int(1)
40+
}
41+
}
42+
}

0 commit comments

Comments
 (0)