From a9b517c6143a8fab3f704448022e7381b02090ba Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Mon, 16 May 2016 10:24:13 +0300 Subject: [PATCH] Check if generator object is created by GENERATOR_CREATE when throw exceptions from generator function. --- .../generators/generator_with_type_check.phpt | 13 +++++++++++ .../generator_with_type_check_2.phpt | 22 +++++++++++++++++++ Zend/zend_vm_def.h | 5 ++++- Zend/zend_vm_execute.h | 5 ++++- 4 files changed, 43 insertions(+), 2 deletions(-) create mode 100644 Zend/tests/generators/generator_with_type_check.phpt create mode 100644 Zend/tests/generators/generator_with_type_check_2.phpt diff --git a/Zend/tests/generators/generator_with_type_check.phpt b/Zend/tests/generators/generator_with_type_check.phpt new file mode 100644 index 0000000000..871742a888 --- /dev/null +++ b/Zend/tests/generators/generator_with_type_check.phpt @@ -0,0 +1,13 @@ +--TEST-- +Generator wit type check +--FILE-- + +--EXPECTF-- +Fatal error: Uncaught TypeError: Argument 1 passed to gen() must be of the type array, integer given, called in %sgenerator_with_type_check.php on line 3 and defined in %sgenerator_with_type_check.php:2 +Stack trace: +#0 %sgenerator_with_type_check.php(3): gen(42) +#1 {main} + thrown in %sgenerator_with_type_check.php on line 2 \ No newline at end of file diff --git a/Zend/tests/generators/generator_with_type_check_2.phpt b/Zend/tests/generators/generator_with_type_check_2.phpt new file mode 100644 index 0000000000..352a3760c2 --- /dev/null +++ b/Zend/tests/generators/generator_with_type_check_2.phpt @@ -0,0 +1,22 @@ +--TEST-- +Generator wit type check +--FILE-- +getMessage()."\n"; +} + +try { + foreach (gen(42) as $val) { + var_dump($val); + } +} catch (TypeError $e) { + echo $e->getMessage()."\n"; +} +?> +--EXPECTF-- +Argument 1 passed to gen() must be of the type array, integer given, called in %sgenerator_with_type_check_2.php on line 4 +Argument 1 passed to gen() must be of the type array, integer given, called in %sgenerator_with_type_check_2.php on line 10 \ No newline at end of file diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 2750d8e60a..2723503b54 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -7159,7 +7159,10 @@ ZEND_VM_HANDLER(149, ZEND_HANDLE_EXCEPTION, ANY, ANY) if (catch_op_num) { ZEND_VM_SET_OPCODE(&EX(func)->op_array.opcodes[catch_op_num]); ZEND_VM_CONTINUE(); - } else if (UNEXPECTED((EX(func)->op_array.fn_flags & ZEND_ACC_GENERATOR) != 0)) { + } else if (UNEXPECTED((EX(func)->op_array.fn_flags & ZEND_ACC_GENERATOR) != 0) + /* check if generator object is created by GENERATOR_CREATE */ + && EX(return_value) + && Z_TYPE_P(EX(return_value)) == IS_OBJECT) { zend_generator *generator = zend_get_running_generator(execute_data); zend_generator_close(generator, 1); ZEND_VM_RETURN(); diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 5b09255f30..cbcb7333bd 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -1756,7 +1756,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_HANDLE_EXCEPTION_SPEC_HANDLER( if (catch_op_num) { ZEND_VM_SET_OPCODE(&EX(func)->op_array.opcodes[catch_op_num]); ZEND_VM_CONTINUE(); - } else if (UNEXPECTED((EX(func)->op_array.fn_flags & ZEND_ACC_GENERATOR) != 0)) { + } else if (UNEXPECTED((EX(func)->op_array.fn_flags & ZEND_ACC_GENERATOR) != 0) + /* check if generator object is created by GENERATOR_CREATE */ + && EX(return_value) + && Z_TYPE_P(EX(return_value)) == IS_OBJECT) { zend_generator *generator = zend_get_running_generator(execute_data); zend_generator_close(generator, 1); ZEND_VM_RETURN(); -- 2.40.0