Commit: d53f1bf8ab326a6fd3596a5f265d04bf49de74fe
Author: Nikita Popov <ni...@php.net> Tue, 18 Dec 2012 21:36:48 +0100
Parents: 19f8bba10d3580308bfe19234a5a26a4f71ecd9a
Branches: PHP-5.5 master
Link:
http://git.php.net/?p=php-src.git;a=commitdiff;h=d53f1bf8ab326a6fd3596a5f265d04bf49de74fe
Log:
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.
Changed paths:
A Zend/tests/generators/ignored_send_leak.phpt
M Zend/zend_compile.c
M Zend/zend_generators.c
M Zend/zend_vm_def.h
M Zend/zend_vm_execute.h
diff --git a/Zend/tests/generators/ignored_send_leak.phpt
b/Zend/tests/generators/ignored_send_leak.phpt
new file mode 100644
index 0000000..352ba40
--- /dev/null
+++ b/Zend/tests/generators/ignored_send_leak.phpt
@@ -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
diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c
index ac3e633..d28b65a 100644
--- a/Zend/zend_compile.c
+++ b/Zend/zend_compile.c
@@ -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);
}
diff --git a/Zend/zend_generators.c b/Zend/zend_generators.c
index 9eae2c7..d4254e0 100644
--- a/Zend/zend_generators.c
+++ b/Zend/zend_generators.c
@@ -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);
diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h
index f7b10a2..c933a48 100644
--- a/Zend/zend_vm_def.h
+++ b/Zend/zend_vm_def.h
@@ -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. */
diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h
index c077d5d..dab0df3 100644
--- a/Zend/zend_vm_execute.h
+++ b/Zend/zend_vm_execute.h
@@ -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. */
--
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php