From a6d84dbb82ce5b118846c7fde6472676414e7c1f Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Thu, 16 Jun 2005 14:20:00 +0000 Subject: [PATCH] Fixed bug #33318 (throw 1; results in Invalid opcode 108/1/8) --- NEWS | 1 + Zend/tests/bug33318.phpt | 8 +++ Zend/zend_vm_def.h | 15 ++--- Zend/zend_vm_execute.h | 128 +++++++++++++++++++++++++-------------- 4 files changed, 97 insertions(+), 55 deletions(-) create mode 100755 Zend/tests/bug33318.phpt diff --git a/NEWS b/NEWS index 9faa8dca99..9341043962 100644 --- a/NEWS +++ b/NEWS @@ -9,6 +9,7 @@ PHP NEWS - Fixed PECL bug #3714 (beginTransaction doesn't work if you're in auto-commit mode). (Wez) - Fixed bug #33340 (CLI Crash when calling php:function from XSLT). (Rob) +- Fixed bug #33318 (throw 1; results in Invalid opcode 108/1/8). (Dmitry) - Fixed bug #33312 (ReflectionParameter methods do not work correctly). (Dmitry) - Fixed bug #33212 ([GCC 4]: 'zend_error_noreturn' aliased to external symbol diff --git a/Zend/tests/bug33318.phpt b/Zend/tests/bug33318.phpt new file mode 100755 index 0000000000..dc1afbb153 --- /dev/null +++ b/Zend/tests/bug33318.phpt @@ -0,0 +1,8 @@ +--TEST-- +Bug #33318 (throw 1; results in Invalid opcode 108/1/8) +--FILE-- + +--EXPECTF-- +Fatal error: Can only throw objects in %sbug33318.php on line 2 \ No newline at end of file diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 09434f88e7..419098a6a3 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -1734,9 +1734,6 @@ ZEND_VM_HANDLER(59, ZEND_INIT_FCALL_BY_NAME, ANY, CONST|TMP|VAR|CV) zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), EX(calling_scope)); if (OP2_TYPE == IS_CONST) { -#ifndef ZEND_VM_SPEC - free_op2.var = NULL; -#endif function_name_strval = opline->op2.u.constant.value.str.val; function_name_strlen = opline->op2.u.constant.value.str.len; } else { @@ -1756,7 +1753,9 @@ ZEND_VM_HANDLER(59, ZEND_INIT_FCALL_BY_NAME, ANY, CONST|TMP|VAR|CV) } efree(lcname); - FREE_OP2(); + if (OP2_TYPE != IS_CONST) { + FREE_OP2(); + } EX(calling_scope) = function->common.scope; EX(object) = NULL; @@ -2045,7 +2044,7 @@ ZEND_VM_C_LABEL(return_by_value): ZEND_VM_RETURN_FROM_EXECUTE_LOOP(); } -ZEND_VM_HANDLER(108, ZEND_THROW, VAR|CV, ANY) +ZEND_VM_HANDLER(108, ZEND_THROW, CONST|TMP|VAR|CV, ANY) { zend_op *opline = EX(opline); zval *value; @@ -3380,13 +3379,11 @@ ZEND_VM_HANDLER(148, ZEND_ISSET_ISEMPTY_PROP_OBJ, VAR|UNUSED|CV, CONST|TMP|VAR|C ZEND_VM_HANDLER(79, ZEND_EXIT, CONST|TMP|VAR|UNUSED|CV, ANY) { - zend_op *opline = EX(opline); - if (OP1_TYPE != IS_UNUSED) { - zval *ptr; + zend_op *opline = EX(opline); zend_free_op free_op1; + zval *ptr = GET_OP1_ZVAL_PTR(BP_VAR_R); - ptr = GET_OP1_ZVAL_PTR(BP_VAR_R); if (Z_TYPE_P(ptr) == IS_LONG) { EG(exit_status) = Z_LVAL_P(ptr); } else { diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 89053d3dac..d91900a6f0 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -659,14 +659,11 @@ static int ZEND_INIT_FCALL_BY_NAME_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_function *function; char *function_name_strval, *lcname; int function_name_strlen; - zend_free_op free_op2; + zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), EX(calling_scope)); if (IS_CONST == IS_CONST) { -#if 0 - free_op2.var = NULL; -#endif function_name_strval = opline->op2.u.constant.value.str.val; function_name_strlen = opline->op2.u.constant.value.str.len; } else { @@ -686,6 +683,9 @@ static int ZEND_INIT_FCALL_BY_NAME_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) } efree(lcname); + if (IS_CONST != IS_CONST) { + + } EX(calling_scope) = function->common.scope; EX(object) = NULL; @@ -861,9 +861,6 @@ static int ZEND_INIT_FCALL_BY_NAME_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), EX(calling_scope)); if (IS_TMP_VAR == IS_CONST) { -#if 0 - free_op2.var = NULL; -#endif function_name_strval = opline->op2.u.constant.value.str.val; function_name_strlen = opline->op2.u.constant.value.str.len; } else { @@ -883,7 +880,9 @@ static int ZEND_INIT_FCALL_BY_NAME_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) } efree(lcname); - zval_dtor(free_op2.var); + if (IS_TMP_VAR != IS_CONST) { + zval_dtor(free_op2.var); + } EX(calling_scope) = function->common.scope; EX(object) = NULL; @@ -1016,9 +1015,6 @@ static int ZEND_INIT_FCALL_BY_NAME_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), EX(calling_scope)); if (IS_VAR == IS_CONST) { -#if 0 - free_op2.var = NULL; -#endif function_name_strval = opline->op2.u.constant.value.str.val; function_name_strlen = opline->op2.u.constant.value.str.len; } else { @@ -1038,7 +1034,9 @@ static int ZEND_INIT_FCALL_BY_NAME_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) } efree(lcname); - if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + if (IS_VAR != IS_CONST) { + if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + } EX(calling_scope) = function->common.scope; EX(object) = NULL; @@ -1248,14 +1246,11 @@ static int ZEND_INIT_FCALL_BY_NAME_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_function *function; char *function_name_strval, *lcname; int function_name_strlen; - zend_free_op free_op2; + zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), EX(calling_scope)); if (IS_CV == IS_CONST) { -#if 0 - free_op2.var = NULL; -#endif function_name_strval = opline->op2.u.constant.value.str.val; function_name_strlen = opline->op2.u.constant.value.str.len; } else { @@ -1275,6 +1270,9 @@ static int ZEND_INIT_FCALL_BY_NAME_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) } efree(lcname); + if (IS_CV != IS_CONST) { + + } EX(calling_scope) = function->common.scope; EX(object) = NULL; @@ -1665,6 +1663,30 @@ return_by_value: ZEND_VM_RETURN_FROM_EXECUTE_LOOP(); } +static int ZEND_THROW_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + zend_op *opline = EX(opline); + zval *value; + zval *exception; + + + value = &opline->op1.u.constant; + + if (value->type != IS_OBJECT) { + zend_error_noreturn(E_ERROR, "Can only throw objects"); + } + /* Not sure if a complete copy is what we want here */ + ALLOC_ZVAL(exception); + INIT_PZVAL_COPY(exception, value); + if (!0) { + zval_copy_ctor(exception); + } + + zend_throw_exception_object(exception TSRMLS_CC); + + ZEND_VM_NEXT_OPCODE(); +} + static int ZEND_SEND_VAL_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { zend_op *opline = EX(opline); @@ -2140,13 +2162,11 @@ static int ZEND_ISSET_ISEMPTY_VAR_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) static int ZEND_EXIT_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - zend_op *opline = EX(opline); - if (IS_CONST != IS_UNUSED) { - zval *ptr; + zend_op *opline = EX(opline); + zval *ptr = &opline->op1.u.constant; - ptr = &opline->op1.u.constant; if (Z_TYPE_P(ptr) == IS_LONG) { EG(exit_status) = Z_LVAL_P(ptr); } else { @@ -4042,6 +4062,30 @@ return_by_value: ZEND_VM_RETURN_FROM_EXECUTE_LOOP(); } +static int ZEND_THROW_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + zend_op *opline = EX(opline); + zval *value; + zval *exception; + zend_free_op free_op1; + + value = _get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC); + + if (value->type != IS_OBJECT) { + zend_error_noreturn(E_ERROR, "Can only throw objects"); + } + /* Not sure if a complete copy is what we want here */ + ALLOC_ZVAL(exception); + INIT_PZVAL_COPY(exception, value); + if (!1) { + zval_copy_ctor(exception); + } + + zend_throw_exception_object(exception TSRMLS_CC); + + ZEND_VM_NEXT_OPCODE(); +} + static int ZEND_SEND_VAL_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { zend_op *opline = EX(opline); @@ -4525,13 +4569,11 @@ static int ZEND_ISSET_ISEMPTY_VAR_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) static int ZEND_EXIT_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - zend_op *opline = EX(opline); - if (IS_TMP_VAR != IS_UNUSED) { - zval *ptr; + zend_op *opline = EX(opline); zend_free_op free_op1; + zval *ptr = _get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC); - ptr = _get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC); if (Z_TYPE_P(ptr) == IS_LONG) { EG(exit_status) = Z_LVAL_P(ptr); } else { @@ -7676,13 +7718,11 @@ static int ZEND_ISSET_ISEMPTY_VAR_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) static int ZEND_EXIT_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - zend_op *opline = EX(opline); - if (IS_VAR != IS_UNUSED) { - zval *ptr; + zend_op *opline = EX(opline); zend_free_op free_op1; + zval *ptr = _get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC); - ptr = _get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC); if (Z_TYPE_P(ptr) == IS_LONG) { EG(exit_status) = Z_LVAL_P(ptr); } else { @@ -13891,13 +13931,11 @@ static int ZEND_CLONE_SPEC_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) static int ZEND_EXIT_SPEC_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - zend_op *opline = EX(opline); - if (IS_UNUSED != IS_UNUSED) { - zval *ptr; + zend_op *opline = EX(opline); + zval *ptr = NULL; - ptr = NULL; if (Z_TYPE_P(ptr) == IS_LONG) { EG(exit_status) = Z_LVAL_P(ptr); } else { @@ -19544,13 +19582,11 @@ static int ZEND_ISSET_ISEMPTY_VAR_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) static int ZEND_EXIT_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - zend_op *opline = EX(opline); - if (IS_CV != IS_UNUSED) { - zval *ptr; + zend_op *opline = EX(opline); + zval *ptr = _get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC); - ptr = _get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC); if (Z_TYPE_P(ptr) == IS_LONG) { EG(exit_status) = Z_LVAL_P(ptr); } else { @@ -28376,16 +28412,16 @@ void zend_init_opcodes_handlers() ZEND_CATCH_SPEC_HANDLER, ZEND_CATCH_SPEC_HANDLER, ZEND_CATCH_SPEC_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, + ZEND_THROW_SPEC_CONST_HANDLER, + ZEND_THROW_SPEC_CONST_HANDLER, + ZEND_THROW_SPEC_CONST_HANDLER, + ZEND_THROW_SPEC_CONST_HANDLER, + ZEND_THROW_SPEC_CONST_HANDLER, + ZEND_THROW_SPEC_TMP_HANDLER, + ZEND_THROW_SPEC_TMP_HANDLER, + ZEND_THROW_SPEC_TMP_HANDLER, + ZEND_THROW_SPEC_TMP_HANDLER, + ZEND_THROW_SPEC_TMP_HANDLER, ZEND_THROW_SPEC_VAR_HANDLER, ZEND_THROW_SPEC_VAR_HANDLER, ZEND_THROW_SPEC_VAR_HANDLER, -- 2.40.0