mirror of
https://github.com/php/php-src.git
synced 2025-08-17 14:38:49 +02:00
Fix leak when generator ignores sent value
When the return value of yield wasn't used it was leaked. This is fixed by using a TMP_VAR return value instead of VAR. TMP_VARs are automatically freed when they aren't used.
This commit is contained in:
parent
19f8bba10d
commit
d53f1bf8ab
5 changed files with 47 additions and 61 deletions
17
Zend/tests/generators/ignored_send_leak.phpt
Normal file
17
Zend/tests/generators/ignored_send_leak.phpt
Normal file
|
@ -0,0 +1,17 @@
|
|||
--TEST--
|
||||
Ignoring a sent value shouldn't leak memory
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
function gen() {
|
||||
yield;
|
||||
}
|
||||
|
||||
$gen = gen();
|
||||
$gen->send(NULL);
|
||||
|
||||
echo "DONE";
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
DONE
|
|
@ -2736,7 +2736,7 @@ void zend_do_yield(znode *result, znode *value, const znode *key, zend_bool is_v
|
|||
SET_UNUSED(opline->op2);
|
||||
}
|
||||
|
||||
opline->result_type = IS_VAR;
|
||||
opline->result_type = IS_TMP_VAR;
|
||||
opline->result.var = get_temporary_variable(CG(active_op_array));
|
||||
GET_NODE(result, opline->result);
|
||||
}
|
||||
|
|
|
@ -319,7 +319,7 @@ static void zend_generator_clone_storage(zend_generator *orig, zend_generator **
|
|||
if (orig->send_target) {
|
||||
size_t offset = (char *) orig->send_target - (char *)execute_data;
|
||||
clone->send_target = EX_TMP_VAR(clone->execute_data, offset);
|
||||
Z_ADDREF_P(clone->send_target->var.ptr);
|
||||
zval_copy_ctor(&clone->send_target->tmp_var);
|
||||
}
|
||||
|
||||
if (execute_data->current_this) {
|
||||
|
@ -641,13 +641,8 @@ ZEND_METHOD(Generator, send)
|
|||
return;
|
||||
}
|
||||
|
||||
/* The sent value was initialized to NULL, so dtor that */
|
||||
zval_ptr_dtor(&generator->send_target->var.ptr);
|
||||
|
||||
/* Set new sent value */
|
||||
Z_ADDREF_P(value);
|
||||
generator->send_target->var.ptr = value;
|
||||
generator->send_target->var.ptr_ptr = &value;
|
||||
/* Put sent value into the TMP_VAR slot */
|
||||
MAKE_COPY_ZVAL(&value, &generator->send_target->tmp_var);
|
||||
|
||||
zend_generator_resume(generator TSRMLS_CC);
|
||||
|
||||
|
|
|
@ -5371,8 +5371,7 @@ ZEND_VM_HANDLER(160, ZEND_YIELD, CONST|TMP|VAR|CV|UNUSED, CONST|TMP|VAR|CV|UNUSE
|
|||
generator->send_target = &EX_T(opline->result.var);
|
||||
|
||||
/* Initialize the sent value to NULL */
|
||||
Z_ADDREF(EG(uninitialized_zval));
|
||||
AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval));
|
||||
EX_T(opline->result.var).tmp_var = EG(uninitialized_zval);
|
||||
|
||||
/* We increment to the next op, so we are at the correct position when the
|
||||
* generator is resumed. */
|
||||
|
|
|
@ -4183,8 +4183,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLE
|
|||
generator->send_target = &EX_T(opline->result.var);
|
||||
|
||||
/* Initialize the sent value to NULL */
|
||||
Z_ADDREF(EG(uninitialized_zval));
|
||||
AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval));
|
||||
EX_T(opline->result.var).tmp_var = EG(uninitialized_zval);
|
||||
|
||||
/* We increment to the next op, so we are at the correct position when the
|
||||
* generator is resumed. */
|
||||
|
@ -4879,8 +4878,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_
|
|||
generator->send_target = &EX_T(opline->result.var);
|
||||
|
||||
/* Initialize the sent value to NULL */
|
||||
Z_ADDREF(EG(uninitialized_zval));
|
||||
AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval));
|
||||
EX_T(opline->result.var).tmp_var = EG(uninitialized_zval);
|
||||
|
||||
/* We increment to the next op, so we are at the correct position when the
|
||||
* generator is resumed. */
|
||||
|
@ -5901,8 +5899,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_
|
|||
generator->send_target = &EX_T(opline->result.var);
|
||||
|
||||
/* Initialize the sent value to NULL */
|
||||
Z_ADDREF(EG(uninitialized_zval));
|
||||
AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval));
|
||||
EX_T(opline->result.var).tmp_var = EG(uninitialized_zval);
|
||||
|
||||
/* We increment to the next op, so we are at the correct position when the
|
||||
* generator is resumed. */
|
||||
|
@ -6616,8 +6613,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HANDL
|
|||
generator->send_target = &EX_T(opline->result.var);
|
||||
|
||||
/* Initialize the sent value to NULL */
|
||||
Z_ADDREF(EG(uninitialized_zval));
|
||||
AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval));
|
||||
EX_T(opline->result.var).tmp_var = EG(uninitialized_zval);
|
||||
|
||||
/* We increment to the next op, so we are at the correct position when the
|
||||
* generator is resumed. */
|
||||
|
@ -7371,8 +7367,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_A
|
|||
generator->send_target = &EX_T(opline->result.var);
|
||||
|
||||
/* Initialize the sent value to NULL */
|
||||
Z_ADDREF(EG(uninitialized_zval));
|
||||
AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval));
|
||||
EX_T(opline->result.var).tmp_var = EG(uninitialized_zval);
|
||||
|
||||
/* We increment to the next op, so we are at the correct position when the
|
||||
* generator is resumed. */
|
||||
|
@ -9417,8 +9412,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_
|
|||
generator->send_target = &EX_T(opline->result.var);
|
||||
|
||||
/* Initialize the sent value to NULL */
|
||||
Z_ADDREF(EG(uninitialized_zval));
|
||||
AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval));
|
||||
EX_T(opline->result.var).tmp_var = EG(uninitialized_zval);
|
||||
|
||||
/* We increment to the next op, so we are at the correct position when the
|
||||
* generator is resumed. */
|
||||
|
@ -10113,8 +10107,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_AR
|
|||
generator->send_target = &EX_T(opline->result.var);
|
||||
|
||||
/* Initialize the sent value to NULL */
|
||||
Z_ADDREF(EG(uninitialized_zval));
|
||||
AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval));
|
||||
EX_T(opline->result.var).tmp_var = EG(uninitialized_zval);
|
||||
|
||||
/* We increment to the next op, so we are at the correct position when the
|
||||
* generator is resumed. */
|
||||
|
@ -11135,8 +11128,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR
|
|||
generator->send_target = &EX_T(opline->result.var);
|
||||
|
||||
/* Initialize the sent value to NULL */
|
||||
Z_ADDREF(EG(uninitialized_zval));
|
||||
AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval));
|
||||
EX_T(opline->result.var).tmp_var = EG(uninitialized_zval);
|
||||
|
||||
/* We increment to the next op, so we are at the correct position when the
|
||||
* generator is resumed. */
|
||||
|
@ -11714,8 +11706,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HANDLER
|
|||
generator->send_target = &EX_T(opline->result.var);
|
||||
|
||||
/* Initialize the sent value to NULL */
|
||||
Z_ADDREF(EG(uninitialized_zval));
|
||||
AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval));
|
||||
EX_T(opline->result.var).tmp_var = EG(uninitialized_zval);
|
||||
|
||||
/* We increment to the next op, so we are at the correct position when the
|
||||
* generator is resumed. */
|
||||
|
@ -12407,8 +12398,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARG
|
|||
generator->send_target = &EX_T(opline->result.var);
|
||||
|
||||
/* Initialize the sent value to NULL */
|
||||
Z_ADDREF(EG(uninitialized_zval));
|
||||
AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval));
|
||||
EX_T(opline->result.var).tmp_var = EG(uninitialized_zval);
|
||||
|
||||
/* We increment to the next op, so we are at the correct position when the
|
||||
* generator is resumed. */
|
||||
|
@ -16315,8 +16305,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_
|
|||
generator->send_target = &EX_T(opline->result.var);
|
||||
|
||||
/* Initialize the sent value to NULL */
|
||||
Z_ADDREF(EG(uninitialized_zval));
|
||||
AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval));
|
||||
EX_T(opline->result.var).tmp_var = EG(uninitialized_zval);
|
||||
|
||||
/* We increment to the next op, so we are at the correct position when the
|
||||
* generator is resumed. */
|
||||
|
@ -18403,8 +18392,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_AR
|
|||
generator->send_target = &EX_T(opline->result.var);
|
||||
|
||||
/* Initialize the sent value to NULL */
|
||||
Z_ADDREF(EG(uninitialized_zval));
|
||||
AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval));
|
||||
EX_T(opline->result.var).tmp_var = EG(uninitialized_zval);
|
||||
|
||||
/* We increment to the next op, so we are at the correct position when the
|
||||
* generator is resumed. */
|
||||
|
@ -20872,8 +20860,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR
|
|||
generator->send_target = &EX_T(opline->result.var);
|
||||
|
||||
/* Initialize the sent value to NULL */
|
||||
Z_ADDREF(EG(uninitialized_zval));
|
||||
AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval));
|
||||
EX_T(opline->result.var).tmp_var = EG(uninitialized_zval);
|
||||
|
||||
/* We increment to the next op, so we are at the correct position when the
|
||||
* generator is resumed. */
|
||||
|
@ -22014,8 +22001,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER
|
|||
generator->send_target = &EX_T(opline->result.var);
|
||||
|
||||
/* Initialize the sent value to NULL */
|
||||
Z_ADDREF(EG(uninitialized_zval));
|
||||
AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval));
|
||||
EX_T(opline->result.var).tmp_var = EG(uninitialized_zval);
|
||||
|
||||
/* We increment to the next op, so we are at the correct position when the
|
||||
* generator is resumed. */
|
||||
|
@ -24151,8 +24137,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARG
|
|||
generator->send_target = &EX_T(opline->result.var);
|
||||
|
||||
/* Initialize the sent value to NULL */
|
||||
Z_ADDREF(EG(uninitialized_zval));
|
||||
AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval));
|
||||
EX_T(opline->result.var).tmp_var = EG(uninitialized_zval);
|
||||
|
||||
/* We increment to the next op, so we are at the correct position when the
|
||||
* generator is resumed. */
|
||||
|
@ -25642,8 +25627,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDL
|
|||
generator->send_target = &EX_T(opline->result.var);
|
||||
|
||||
/* Initialize the sent value to NULL */
|
||||
Z_ADDREF(EG(uninitialized_zval));
|
||||
AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval));
|
||||
EX_T(opline->result.var).tmp_var = EG(uninitialized_zval);
|
||||
|
||||
/* We increment to the next op, so we are at the correct position when the
|
||||
* generator is resumed. */
|
||||
|
@ -26957,8 +26941,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER
|
|||
generator->send_target = &EX_T(opline->result.var);
|
||||
|
||||
/* Initialize the sent value to NULL */
|
||||
Z_ADDREF(EG(uninitialized_zval));
|
||||
AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval));
|
||||
EX_T(opline->result.var).tmp_var = EG(uninitialized_zval);
|
||||
|
||||
/* We increment to the next op, so we are at the correct position when the
|
||||
* generator is resumed. */
|
||||
|
@ -28273,8 +28256,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_HANDLER
|
|||
generator->send_target = &EX_T(opline->result.var);
|
||||
|
||||
/* Initialize the sent value to NULL */
|
||||
Z_ADDREF(EG(uninitialized_zval));
|
||||
AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval));
|
||||
EX_T(opline->result.var).tmp_var = EG(uninitialized_zval);
|
||||
|
||||
/* We increment to the next op, so we are at the correct position when the
|
||||
* generator is resumed. */
|
||||
|
@ -28696,8 +28678,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HAND
|
|||
generator->send_target = &EX_T(opline->result.var);
|
||||
|
||||
/* Initialize the sent value to NULL */
|
||||
Z_ADDREF(EG(uninitialized_zval));
|
||||
AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval));
|
||||
EX_T(opline->result.var).tmp_var = EG(uninitialized_zval);
|
||||
|
||||
/* We increment to the next op, so we are at the correct position when the
|
||||
* generator is resumed. */
|
||||
|
@ -30008,8 +29989,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_
|
|||
generator->send_target = &EX_T(opline->result.var);
|
||||
|
||||
/* Initialize the sent value to NULL */
|
||||
Z_ADDREF(EG(uninitialized_zval));
|
||||
AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval));
|
||||
EX_T(opline->result.var).tmp_var = EG(uninitialized_zval);
|
||||
|
||||
/* We increment to the next op, so we are at the correct position when the
|
||||
* generator is resumed. */
|
||||
|
@ -33513,8 +33493,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_A
|
|||
generator->send_target = &EX_T(opline->result.var);
|
||||
|
||||
/* Initialize the sent value to NULL */
|
||||
Z_ADDREF(EG(uninitialized_zval));
|
||||
AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval));
|
||||
EX_T(opline->result.var).tmp_var = EG(uninitialized_zval);
|
||||
|
||||
/* We increment to the next op, so we are at the correct position when the
|
||||
* generator is resumed. */
|
||||
|
@ -35468,8 +35447,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARG
|
|||
generator->send_target = &EX_T(opline->result.var);
|
||||
|
||||
/* Initialize the sent value to NULL */
|
||||
Z_ADDREF(EG(uninitialized_zval));
|
||||
AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval));
|
||||
EX_T(opline->result.var).tmp_var = EG(uninitialized_zval);
|
||||
|
||||
/* We increment to the next op, so we are at the correct position when the
|
||||
* generator is resumed. */
|
||||
|
@ -37803,8 +37781,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG
|
|||
generator->send_target = &EX_T(opline->result.var);
|
||||
|
||||
/* Initialize the sent value to NULL */
|
||||
Z_ADDREF(EG(uninitialized_zval));
|
||||
AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval));
|
||||
EX_T(opline->result.var).tmp_var = EG(uninitialized_zval);
|
||||
|
||||
/* We increment to the next op, so we are at the correct position when the
|
||||
* generator is resumed. */
|
||||
|
@ -38802,8 +38779,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_
|
|||
generator->send_target = &EX_T(opline->result.var);
|
||||
|
||||
/* Initialize the sent value to NULL */
|
||||
Z_ADDREF(EG(uninitialized_zval));
|
||||
AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval));
|
||||
EX_T(opline->result.var).tmp_var = EG(uninitialized_zval);
|
||||
|
||||
/* We increment to the next op, so we are at the correct position when the
|
||||
* generator is resumed. */
|
||||
|
@ -40805,8 +40781,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS
|
|||
generator->send_target = &EX_T(opline->result.var);
|
||||
|
||||
/* Initialize the sent value to NULL */
|
||||
Z_ADDREF(EG(uninitialized_zval));
|
||||
AI_SET_PTR(&EX_T(opline->result.var), &EG(uninitialized_zval));
|
||||
EX_T(opline->result.var).tmp_var = EG(uninitialized_zval);
|
||||
|
||||
/* We increment to the next op, so we are at the correct position when the
|
||||
* generator is resumed. */
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue