mirror of
https://github.com/php/php-src.git
synced 2024-09-22 10:27:25 +00:00
Fixed bug #45178 (memory corruption on assignment result of "new" by reference)
This commit is contained in:
parent
fe8c688313
commit
fd2c7c2105
29
Zend/tests/bug45178.phpt
Executable file
29
Zend/tests/bug45178.phpt
Executable file
@ -0,0 +1,29 @@
|
||||
--TEST--
|
||||
Bug #45178 memory corruption on assignment result of "new" by reference
|
||||
--FILE--
|
||||
<?php
|
||||
class Foo {
|
||||
function __construct() {
|
||||
$this->error = array($this,$this);
|
||||
}
|
||||
}
|
||||
$a =& new Foo();
|
||||
|
||||
class Bar {
|
||||
function __construct() {
|
||||
$this->_rme2 = $this;
|
||||
}
|
||||
}
|
||||
|
||||
$b =& new Bar();
|
||||
$b->_rme2 = 0;
|
||||
var_dump($b);
|
||||
?>
|
||||
--EXPECTF--
|
||||
Deprecated: Assigning the return value of new by reference is deprecated in %sbug45178.php on line 7
|
||||
|
||||
Deprecated: Assigning the return value of new by reference is deprecated in %sbug45178.php on line 15
|
||||
object(Bar)#%d (1) {
|
||||
[u"_rme2"]=>
|
||||
int(0)
|
||||
}
|
@ -737,6 +737,8 @@ void zend_do_assign_ref(znode *result, znode *lvar, znode *rvar TSRMLS_DC) /* {{
|
||||
opline->opcode = ZEND_ASSIGN_REF;
|
||||
if (zend_is_function_or_method_call(rvar)) {
|
||||
opline->extended_value = ZEND_RETURNS_FUNCTION;
|
||||
} else if (rvar->u.EA.type & ZEND_PARSED_NEW) {
|
||||
opline->extended_value = ZEND_RETURNS_NEW;
|
||||
} else {
|
||||
opline->extended_value = 0;
|
||||
}
|
||||
|
@ -578,7 +578,7 @@ expr_without_variable:
|
||||
T_LIST '(' { zend_do_list_init(TSRMLS_C); } assignment_list ')' '=' expr { zend_do_list_end(&$$, &$7 TSRMLS_CC); }
|
||||
| variable '=' expr { zend_check_writable_variable(&$1); zend_do_assign(&$$, &$1, &$3 TSRMLS_CC); }
|
||||
| variable '=' '&' variable { zend_check_writable_variable(&$1); zend_do_end_variable_parse(&$4, BP_VAR_W, 1 TSRMLS_CC); zend_do_end_variable_parse(&$1, BP_VAR_W, 0 TSRMLS_CC); zend_do_assign_ref(&$$, &$1, &$4 TSRMLS_CC); }
|
||||
| variable '=' '&' T_NEW class_name_reference { zend_error(E_DEPRECATED, "Assigning the return value of new by reference is deprecated"); zend_check_writable_variable(&$1); zend_do_extended_fcall_begin(TSRMLS_C); zend_do_begin_new_object(&$4, &$5 TSRMLS_CC); } ctor_arguments { zend_do_end_new_object(&$3, &$4, &$7 TSRMLS_CC); zend_do_extended_fcall_end(TSRMLS_C); zend_do_end_variable_parse(&$1, BP_VAR_W, 0 TSRMLS_CC); zend_do_assign_ref(&$$, &$1, &$3 TSRMLS_CC); }
|
||||
| variable '=' '&' T_NEW class_name_reference { zend_error(E_DEPRECATED, "Assigning the return value of new by reference is deprecated"); zend_check_writable_variable(&$1); zend_do_extended_fcall_begin(TSRMLS_C); zend_do_begin_new_object(&$4, &$5 TSRMLS_CC); } ctor_arguments { zend_do_end_new_object(&$3, &$4, &$7 TSRMLS_CC); zend_do_extended_fcall_end(TSRMLS_C); zend_do_end_variable_parse(&$1, BP_VAR_W, 0 TSRMLS_CC); $3.u.EA.type = ZEND_PARSED_NEW; zend_do_assign_ref(&$$, &$1, &$3 TSRMLS_CC); }
|
||||
| T_NEW class_name_reference { zend_do_extended_fcall_begin(TSRMLS_C); zend_do_begin_new_object(&$1, &$2 TSRMLS_CC); } ctor_arguments { zend_do_end_new_object(&$$, &$1, &$4 TSRMLS_CC); zend_do_extended_fcall_end(TSRMLS_C); $$.u.EA.type = ZEND_PARSED_NEW; }
|
||||
| T_CLONE expr { zend_do_clone(&$$, &$2 TSRMLS_CC); }
|
||||
| variable T_PLUS_EQUAL expr { zend_check_writable_variable(&$1); zend_do_end_variable_parse(&$1, BP_VAR_RW, 0 TSRMLS_CC); zend_do_binary_assign_op(ZEND_ASSIGN_ADD, &$$, &$1, &$3 TSRMLS_CC); }
|
||||
|
@ -1665,6 +1665,8 @@ ZEND_VM_HANDLER(39, ZEND_ASSIGN_REF, VAR|CV, VAR|CV)
|
||||
}
|
||||
zend_error(E_STRICT, "Only variables should be assigned by reference");
|
||||
ZEND_VM_DISPATCH_TO_HANDLER(ZEND_ASSIGN);
|
||||
} else if (OP2_TYPE == IS_VAR && opline->extended_value == ZEND_RETURNS_NEW) {
|
||||
PZVAL_LOCK(*value_ptr_ptr);
|
||||
}
|
||||
if (OP1_TYPE == IS_VAR && EX_T(opline->op1.u.var).var.ptr_ptr == &EX_T(opline->op1.u.var).var.ptr) {
|
||||
zend_error(E_ERROR, "Cannot assign by reference to overloaded object");
|
||||
@ -1677,6 +1679,10 @@ ZEND_VM_HANDLER(39, ZEND_ASSIGN_REF, VAR|CV, VAR|CV)
|
||||
}
|
||||
zend_assign_to_variable_reference(variable_ptr_ptr, value_ptr_ptr TSRMLS_CC);
|
||||
|
||||
if (OP2_TYPE == IS_VAR && opline->extended_value == ZEND_RETURNS_NEW) {
|
||||
Z_DELREF_PP(variable_ptr_ptr);
|
||||
}
|
||||
|
||||
if (!RETURN_VALUE_UNUSED(&opline->result)) {
|
||||
AI_SET_PTR(EX_T(opline->result.u.var).var, *variable_ptr_ptr);
|
||||
PZVAL_LOCK(*variable_ptr_ptr);
|
||||
|
@ -14338,6 +14338,8 @@ static int ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDL
|
||||
}
|
||||
zend_error(E_STRICT, "Only variables should be assigned by reference");
|
||||
return ZEND_ASSIGN_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
|
||||
} else if (IS_VAR == IS_VAR && opline->extended_value == ZEND_RETURNS_NEW) {
|
||||
PZVAL_LOCK(*value_ptr_ptr);
|
||||
}
|
||||
if (IS_VAR == IS_VAR && EX_T(opline->op1.u.var).var.ptr_ptr == &EX_T(opline->op1.u.var).var.ptr) {
|
||||
zend_error(E_ERROR, "Cannot assign by reference to overloaded object");
|
||||
@ -14350,6 +14352,10 @@ static int ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDL
|
||||
}
|
||||
zend_assign_to_variable_reference(variable_ptr_ptr, value_ptr_ptr TSRMLS_CC);
|
||||
|
||||
if (IS_VAR == IS_VAR && opline->extended_value == ZEND_RETURNS_NEW) {
|
||||
Z_DELREF_PP(variable_ptr_ptr);
|
||||
}
|
||||
|
||||
if (!RETURN_VALUE_UNUSED(&opline->result)) {
|
||||
AI_SET_PTR(EX_T(opline->result.u.var).var, *variable_ptr_ptr);
|
||||
PZVAL_LOCK(*variable_ptr_ptr);
|
||||
@ -16820,6 +16826,8 @@ static int ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLE
|
||||
}
|
||||
zend_error(E_STRICT, "Only variables should be assigned by reference");
|
||||
return ZEND_ASSIGN_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
|
||||
} else if (IS_CV == IS_VAR && opline->extended_value == ZEND_RETURNS_NEW) {
|
||||
PZVAL_LOCK(*value_ptr_ptr);
|
||||
}
|
||||
if (IS_VAR == IS_VAR && EX_T(opline->op1.u.var).var.ptr_ptr == &EX_T(opline->op1.u.var).var.ptr) {
|
||||
zend_error(E_ERROR, "Cannot assign by reference to overloaded object");
|
||||
@ -16832,6 +16840,10 @@ static int ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLE
|
||||
}
|
||||
zend_assign_to_variable_reference(variable_ptr_ptr, value_ptr_ptr TSRMLS_CC);
|
||||
|
||||
if (IS_CV == IS_VAR && opline->extended_value == ZEND_RETURNS_NEW) {
|
||||
Z_DELREF_PP(variable_ptr_ptr);
|
||||
}
|
||||
|
||||
if (!RETURN_VALUE_UNUSED(&opline->result)) {
|
||||
AI_SET_PTR(EX_T(opline->result.u.var).var, *variable_ptr_ptr);
|
||||
PZVAL_LOCK(*variable_ptr_ptr);
|
||||
@ -28214,6 +28226,8 @@ static int ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLE
|
||||
}
|
||||
zend_error(E_STRICT, "Only variables should be assigned by reference");
|
||||
return ZEND_ASSIGN_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
|
||||
} else if (IS_VAR == IS_VAR && opline->extended_value == ZEND_RETURNS_NEW) {
|
||||
PZVAL_LOCK(*value_ptr_ptr);
|
||||
}
|
||||
if (IS_CV == IS_VAR && EX_T(opline->op1.u.var).var.ptr_ptr == &EX_T(opline->op1.u.var).var.ptr) {
|
||||
zend_error(E_ERROR, "Cannot assign by reference to overloaded object");
|
||||
@ -28226,6 +28240,10 @@ static int ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLE
|
||||
}
|
||||
zend_assign_to_variable_reference(variable_ptr_ptr, value_ptr_ptr TSRMLS_CC);
|
||||
|
||||
if (IS_VAR == IS_VAR && opline->extended_value == ZEND_RETURNS_NEW) {
|
||||
Z_DELREF_PP(variable_ptr_ptr);
|
||||
}
|
||||
|
||||
if (!RETURN_VALUE_UNUSED(&opline->result)) {
|
||||
AI_SET_PTR(EX_T(opline->result.u.var).var, *variable_ptr_ptr);
|
||||
PZVAL_LOCK(*variable_ptr_ptr);
|
||||
@ -30467,6 +30485,8 @@ static int ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER
|
||||
}
|
||||
zend_error(E_STRICT, "Only variables should be assigned by reference");
|
||||
return ZEND_ASSIGN_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
|
||||
} else if (IS_CV == IS_VAR && opline->extended_value == ZEND_RETURNS_NEW) {
|
||||
PZVAL_LOCK(*value_ptr_ptr);
|
||||
}
|
||||
if (IS_CV == IS_VAR && EX_T(opline->op1.u.var).var.ptr_ptr == &EX_T(opline->op1.u.var).var.ptr) {
|
||||
zend_error(E_ERROR, "Cannot assign by reference to overloaded object");
|
||||
@ -30479,6 +30499,10 @@ static int ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER
|
||||
}
|
||||
zend_assign_to_variable_reference(variable_ptr_ptr, value_ptr_ptr TSRMLS_CC);
|
||||
|
||||
if (IS_CV == IS_VAR && opline->extended_value == ZEND_RETURNS_NEW) {
|
||||
Z_DELREF_PP(variable_ptr_ptr);
|
||||
}
|
||||
|
||||
if (!RETURN_VALUE_UNUSED(&opline->result)) {
|
||||
AI_SET_PTR(EX_T(opline->result.u.var).var, *variable_ptr_ptr);
|
||||
PZVAL_LOCK(*variable_ptr_ptr);
|
||||
|
Loading…
Reference in New Issue
Block a user