Skip to content

Commit e03480b

Browse files
committed
Fixed bug #72813 (Segfault with __get returned by ref)
This should be safe change, as we don't dereference value and member after calling setter/getter. And compare to adding unref codes, this is much cheaper.
1 parent bb955ec commit e03480b

File tree

3 files changed

+44
-10
lines changed

3 files changed

+44
-10
lines changed

NEWS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ PHP NEWS
33
?? ??? 2016 PHP 7.0.11
44

55
- Core:
6+
. Fixed bug #72813 (Segfault with __get returned by ref). (Laruence)
67
. Fixed bug #72767 (PHP Segfaults when trying to expand an infinite operator).
78
(Nikita)
89

Zend/tests/bug72813.phpt

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
--TEST--
2+
Bug #72813 (Segfault with __get returned by ref)
3+
--FILE--
4+
<?php
5+
class Test
6+
{
7+
private $props = ['a' => 'text', 'b' => 1];
8+
9+
public function &__get($prop)
10+
{
11+
return $this->props[$prop];
12+
}
13+
14+
public function __set($prop, $value)
15+
{
16+
if ($prop === 'b') $value = [$value];
17+
$this->props[$prop] = $value;
18+
}
19+
20+
public function getProperties()
21+
{
22+
return [$this->props];
23+
}
24+
}
25+
26+
$obj = new Test;
27+
$obj->b = $obj->b;
28+
print_r($obj->getProperties());
29+
?>
30+
--EXPECT--
31+
Array
32+
(
33+
[0] => Array
34+
(
35+
[a] => text
36+
[b] => Array
37+
(
38+
[0] => 1
39+
)
40+
41+
)
42+
43+
)

Zend/zend_object_handlers.c

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -197,11 +197,7 @@ static void zend_std_call_getter(zval *object, zval *member, zval *retval) /* {{
197197
198198
it should return whether the call was successful or not
199199
*/
200-
if (Z_REFCOUNTED_P(member)) Z_ADDREF_P(member);
201-
202200
zend_call_method_with_1_params(object, ce, &ce->__get, ZEND_GET_FUNC_NAME, retval, member);
203-
204-
zval_ptr_dtor(member);
205201
}
206202
/* }}} */
207203

@@ -211,9 +207,6 @@ static int zend_std_call_setter(zval *object, zval *member, zval *value) /* {{{
211207
int result;
212208
zend_class_entry *ce = Z_OBJCE_P(object);
213209

214-
if (Z_REFCOUNTED_P(member)) Z_ADDREF_P(member);
215-
if (Z_REFCOUNTED_P(value)) Z_ADDREF_P(value);
216-
217210
/* __set handler is called with two arguments:
218211
property name
219212
value to be set
@@ -222,9 +215,6 @@ static int zend_std_call_setter(zval *object, zval *member, zval *value) /* {{{
222215
*/
223216
zend_call_method_with_2_params(object, ce, &ce->__set, ZEND_SET_FUNC_NAME, &retval, member, value);
224217

225-
zval_ptr_dtor(member);
226-
zval_ptr_dtor(value);
227-
228218
if (Z_TYPE(retval) != IS_UNDEF) {
229219
result = i_zend_is_true(&retval) ? SUCCESS : FAILURE;
230220
zval_ptr_dtor(&retval);

0 commit comments

Comments
 (0)