Skip to content

Commit ce9169e

Browse files
committed
Fixed bug Bug #65372 (Segfault in gc_zval_possible_root when return reference fails)
1 parent cb13f83 commit ce9169e

File tree

4 files changed

+67
-15
lines changed

4 files changed

+67
-15
lines changed

NEWS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ PHP NEWS
33
?? ??? 2013, PHP 5.4.19
44

55
- Core.
6+
. Fixed bug #65372 (Segfault in gc_zval_possible_root when return reference
7+
fails). (Laruence)
68
. Fixed bug #65304 (Use of max int in array_sum). (Laruence)
79
. Fixed bug #65291 (get_defined_constants() causes PHP to crash in a very
810
limited case). (Arpad)

Zend/tests/bug65372.phpt

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
--TEST--
2+
Bug #65372 (Segfault in gc_zval_possible_root when return reference fails)
3+
--FILE--
4+
<?php
5+
6+
class ParentClass
7+
{
8+
private static $_OBJECTS;
9+
10+
public static function Get()
11+
{
12+
self::$_OBJECTS[1] = new ChildClass();
13+
return self::$_OBJECTS[1];
14+
}
15+
}
16+
17+
class ChildClass extends ParentClass
18+
{
19+
public $Manager;
20+
21+
function __construct()
22+
{
23+
$this->Manager = $this;
24+
}
25+
26+
public static function &GetCurrent()
27+
{
28+
return ChildClass::Get();
29+
}
30+
31+
public static function &Get()
32+
{
33+
return parent::Get();
34+
}
35+
}
36+
37+
$staff = ChildClass::GetCurrent();
38+
?>
39+
--EXPECTF--
40+
Notice: Only variable references should be returned by reference in %sbug65372.php on line 30

Zend/zend_vm_def.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2910,9 +2910,11 @@ ZEND_VM_HANDLER(111, ZEND_RETURN_BY_REF, CONST|TMP|VAR|CV, ANY)
29102910
} else if (EX_T(opline->op1.var).var.ptr_ptr == &EX_T(opline->op1.var).var.ptr) {
29112911
zend_error(E_NOTICE, "Only variable references should be returned by reference");
29122912
if (EG(return_value_ptr_ptr)) {
2913-
retval_ptr = *retval_ptr_ptr;
2914-
*EG(return_value_ptr_ptr) = retval_ptr;
2915-
Z_ADDREF_P(retval_ptr);
2913+
zval *ret;
2914+
2915+
ALLOC_ZVAL(ret);
2916+
INIT_PZVAL_COPY(ret, *retval_ptr_ptr);
2917+
*EG(return_value_ptr_ptr) = ret;
29162918
}
29172919
break;
29182920
}

Zend/zend_vm_execute.h

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2324,9 +2324,11 @@ static int ZEND_FASTCALL ZEND_RETURN_BY_REF_SPEC_CONST_HANDLER(ZEND_OPCODE_HAND
23242324
} else if (EX_T(opline->op1.var).var.ptr_ptr == &EX_T(opline->op1.var).var.ptr) {
23252325
zend_error(E_NOTICE, "Only variable references should be returned by reference");
23262326
if (EG(return_value_ptr_ptr)) {
2327-
retval_ptr = *retval_ptr_ptr;
2328-
*EG(return_value_ptr_ptr) = retval_ptr;
2329-
Z_ADDREF_P(retval_ptr);
2327+
zval *ret;
2328+
2329+
ALLOC_ZVAL(ret);
2330+
INIT_PZVAL_COPY(ret, *retval_ptr_ptr);
2331+
*EG(return_value_ptr_ptr) = ret;
23302332
}
23312333
break;
23322334
}
@@ -6743,9 +6745,11 @@ static int ZEND_FASTCALL ZEND_RETURN_BY_REF_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLE
67436745
} else if (EX_T(opline->op1.var).var.ptr_ptr == &EX_T(opline->op1.var).var.ptr) {
67446746
zend_error(E_NOTICE, "Only variable references should be returned by reference");
67456747
if (EG(return_value_ptr_ptr)) {
6746-
retval_ptr = *retval_ptr_ptr;
6747-
*EG(return_value_ptr_ptr) = retval_ptr;
6748-
Z_ADDREF_P(retval_ptr);
6748+
zval *ret;
6749+
6750+
ALLOC_ZVAL(ret);
6751+
INIT_PZVAL_COPY(ret, *retval_ptr_ptr);
6752+
*EG(return_value_ptr_ptr) = ret;
67496753
}
67506754
break;
67516755
}
@@ -11055,9 +11059,11 @@ static int ZEND_FASTCALL ZEND_RETURN_BY_REF_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLE
1105511059
} else if (EX_T(opline->op1.var).var.ptr_ptr == &EX_T(opline->op1.var).var.ptr) {
1105611060
zend_error(E_NOTICE, "Only variable references should be returned by reference");
1105711061
if (EG(return_value_ptr_ptr)) {
11058-
retval_ptr = *retval_ptr_ptr;
11059-
*EG(return_value_ptr_ptr) = retval_ptr;
11060-
Z_ADDREF_P(retval_ptr);
11062+
zval *ret;
11063+
11064+
ALLOC_ZVAL(ret);
11065+
INIT_PZVAL_COPY(ret, *retval_ptr_ptr);
11066+
*EG(return_value_ptr_ptr) = ret;
1106111067
}
1106211068
break;
1106311069
}
@@ -27030,9 +27036,11 @@ static int ZEND_FASTCALL ZEND_RETURN_BY_REF_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER
2703027036
} else if (EX_T(opline->op1.var).var.ptr_ptr == &EX_T(opline->op1.var).var.ptr) {
2703127037
zend_error(E_NOTICE, "Only variable references should be returned by reference");
2703227038
if (EG(return_value_ptr_ptr)) {
27033-
retval_ptr = *retval_ptr_ptr;
27034-
*EG(return_value_ptr_ptr) = retval_ptr;
27035-
Z_ADDREF_P(retval_ptr);
27039+
zval *ret;
27040+
27041+
ALLOC_ZVAL(ret);
27042+
INIT_PZVAL_COPY(ret, *retval_ptr_ptr);
27043+
*EG(return_value_ptr_ptr) = ret;
2703627044
}
2703727045
break;
2703827046
}

0 commit comments

Comments
 (0)