From: Dmitry Stogov Date: Mon, 16 May 2016 09:42:13 +0000 (+0300) Subject: Check if generator object is created by GENERATOR_CREATE when throw exceptions from... X-Git-Tag: php-7.1.0alpha1~121 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=97bf4e0b12db6ee8dbbb448117d696becc2923fa;p=php Check if generator object is created by GENERATOR_CREATE when throw exceptions from generator function --- 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..2aa16532dc --- /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 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..d8ea4fbf0d --- /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 diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h index 61e537e64a..344293273a 100644 --- a/Zend/zend_compile.h +++ b/Zend/zend_compile.h @@ -472,6 +472,7 @@ struct _zend_execute_data { #define ZEND_CALL_CLOSURE (1 << 5) #define ZEND_CALL_RELEASE_THIS (1 << 6) #define ZEND_CALL_ALLOCATED (1 << 7) +#define ZEND_CALL_GENERATOR (1 << 8) #define ZEND_CALL_INFO_SHIFT 16 diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 2750d8e60a..bb430dccd5 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -4028,7 +4028,7 @@ ZEND_VM_HANDLER(41, ZEND_GENERATOR_CREATE, ANY, ANY) ZEND_ADD_CALL_FLAG_EX(call_info, ZEND_CALL_RELEASE_THIS); Z_ADDREF(gen_execute_data->This); } - ZEND_ADD_CALL_FLAG_EX(call_info, (ZEND_CALL_TOP_FUNCTION | ZEND_CALL_ALLOCATED)); + ZEND_ADD_CALL_FLAG_EX(call_info, (ZEND_CALL_TOP_FUNCTION | ZEND_CALL_ALLOCATED | ZEND_CALL_GENERATOR)); Z_TYPE_INFO(gen_execute_data->This) = call_info; gen_execute_data->prev_execute_data = NULL; @@ -7159,7 +7159,7 @@ 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_CALL_INFO() & ZEND_CALL_GENERATOR) != 0)) { zend_generator *generator = zend_get_running_generator(execute_data); zend_generator_close(generator, 1); ZEND_VM_RETURN(); @@ -7191,7 +7191,7 @@ ZEND_VM_HANDLER(150, ZEND_USER_OPCODE, ANY, ANY) case ZEND_USER_OPCODE_CONTINUE: ZEND_VM_CONTINUE(); case ZEND_USER_OPCODE_RETURN: - if (UNEXPECTED((EX(func)->op_array.fn_flags & ZEND_ACC_GENERATOR) != 0)) { + if (UNEXPECTED((EX_CALL_INFO() & ZEND_CALL_GENERATOR) != 0)) { zend_generator *generator = zend_get_running_generator(execute_data); zend_generator_close(generator, 1); ZEND_VM_RETURN(); @@ -7581,7 +7581,7 @@ ZEND_VM_HANDLER(163, ZEND_FAST_RET, ANY, TRY_CATCH, FAST_RET) ZEND_VM_CONTINUE(); } else { cleanup_live_vars(execute_data, opline - EX(func)->op_array.opcodes, 0); - if (UNEXPECTED((EX(func)->op_array.fn_flags & ZEND_ACC_GENERATOR) != 0)) { + if (UNEXPECTED((EX_CALL_INFO() & ZEND_CALL_GENERATOR) != 0)) { 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..d729f83ac3 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -1190,7 +1190,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_GENERATOR_CREATE_SPEC_HANDLER( ZEND_ADD_CALL_FLAG_EX(call_info, ZEND_CALL_RELEASE_THIS); Z_ADDREF(gen_execute_data->This); } - ZEND_ADD_CALL_FLAG_EX(call_info, (ZEND_CALL_TOP_FUNCTION | ZEND_CALL_ALLOCATED)); + ZEND_ADD_CALL_FLAG_EX(call_info, (ZEND_CALL_TOP_FUNCTION | ZEND_CALL_ALLOCATED | ZEND_CALL_GENERATOR)); Z_TYPE_INFO(gen_execute_data->This) = call_info; gen_execute_data->prev_execute_data = NULL; @@ -1756,7 +1756,7 @@ 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_CALL_INFO() & ZEND_CALL_GENERATOR) != 0)) { zend_generator *generator = zend_get_running_generator(execute_data); zend_generator_close(generator, 1); ZEND_VM_RETURN(); @@ -1788,7 +1788,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_USER_OPCODE_SPEC_HANDLER(ZEND_ case ZEND_USER_OPCODE_CONTINUE: ZEND_VM_CONTINUE(); case ZEND_USER_OPCODE_RETURN: - if (UNEXPECTED((EX(func)->op_array.fn_flags & ZEND_ACC_GENERATOR) != 0)) { + if (UNEXPECTED((EX_CALL_INFO() & ZEND_CALL_GENERATOR) != 0)) { zend_generator *generator = zend_get_running_generator(execute_data); zend_generator_close(generator, 1); ZEND_VM_RETURN(); @@ -1872,7 +1872,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_RET_SPEC_HANDLER(ZEND_OPC ZEND_VM_CONTINUE(); } else { cleanup_live_vars(execute_data, opline - EX(func)->op_array.opcodes, 0); - if (UNEXPECTED((EX(func)->op_array.fn_flags & ZEND_ACC_GENERATOR) != 0)) { + if (UNEXPECTED((EX_CALL_INFO() & ZEND_CALL_GENERATOR) != 0)) { zend_generator *generator = zend_get_running_generator(execute_data); zend_generator_close(generator, 1); ZEND_VM_RETURN();