diff options
| author | Antony Dovgal <tony2001@php.net> | 2005-09-22 19:03:18 +0000 |
|---|---|---|
| committer | Antony Dovgal <tony2001@php.net> | 2005-09-22 19:03:18 +0000 |
| commit | f8e8c5534b0a1e75e389deba6e5a885919e2e6ed (patch) | |
| tree | 8535833c3ab10f284d8ae25f75130f760f977a70 | |
| parent | 0823526afeac361aa70d24939bf735e6e87714b2 (diff) | |
| download | php-git-f8e8c5534b0a1e75e389deba6e5a885919e2e6ed.tar.gz | |
MFH: fix #33771 (error_reporting falls to 0 when @ was used inside try/catch block)
| -rw-r--r-- | Zend/tests/bug33771.phpt | 40 | ||||
| -rw-r--r-- | Zend/zend_compile.h | 1 | ||||
| -rw-r--r-- | Zend/zend_vm_def.h | 20 | ||||
| -rw-r--r-- | Zend/zend_vm_execute.h | 21 | ||||
| -rw-r--r-- | Zend/zend_vm_execute.skl | 1 |
5 files changed, 79 insertions, 4 deletions
diff --git a/Zend/tests/bug33771.phpt b/Zend/tests/bug33771.phpt new file mode 100644 index 0000000000..336aee8e87 --- /dev/null +++ b/Zend/tests/bug33771.phpt @@ -0,0 +1,40 @@ +--TEST-- +bug #33771 (error_reporting falls to 0 when @ was used inside try/catch block) +--FILE-- +<?php + +error_reporting(E_ALL | E_STRICT); + +var_dump(error_reporting()); + +function make_exception() +{ + throw new Exception(); +} + +function make_exception_and_change_err_reporting() +{ + error_reporting(E_ALL); + throw new Exception(); +} + + +try { + @make_exception(); +} catch (Exception $e) {} + +var_dump(error_reporting()); + +try { + @make_exception_and_change_err_reporting(); +} catch (Exception $e) {} + +var_dump(error_reporting()); + +echo "Done\n"; +?> +--EXPECTF-- +int(4095) +int(4095) +int(2047) +Done diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h index c9e1bced91..8a2c3b9cd5 100644 --- a/Zend/zend_compile.h +++ b/Zend/zend_compile.h @@ -294,6 +294,7 @@ struct _zend_execute_data { zend_class_entry *calling_scope; HashTable *symbol_table; struct _zend_execute_data *prev_execute_data; + zval *old_error_reporting; }; #define EX(element) execute_data.element diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 3c16e3e7e5..8374387ca8 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -3449,7 +3449,11 @@ ZEND_VM_HANDLER(57, ZEND_BEGIN_SILENCE, ANY, ANY) EX_T(opline->result.u.var).tmp_var.value.lval = EG(error_reporting); EX_T(opline->result.u.var).tmp_var.type = IS_LONG; /* shouldn't be necessary */ - zend_alter_ini_entry("error_reporting", sizeof("error_reporting"), "0", 1, ZEND_INI_USER, ZEND_INI_STAGE_RUNTIME); + EX(old_error_reporting) = &EX_T(opline->result.u.var).tmp_var; + + if (EG(error_reporting)) { + zend_alter_ini_entry("error_reporting", sizeof("error_reporting"), "0", 1, ZEND_INI_USER, ZEND_INI_STAGE_RUNTIME); + } ZEND_VM_NEXT_OPCODE(); } @@ -3464,13 +3468,14 @@ ZEND_VM_HANDLER(58, ZEND_END_SILENCE, TMP, ANY) zend_op *opline = EX(opline); zval restored_error_reporting; - if (!EG(error_reporting)) { + if (!EG(error_reporting) && EX(old_error_reporting)->value.lval != 0) { restored_error_reporting.type = IS_LONG; restored_error_reporting.value.lval = EX_T(opline->op1.u.var).tmp_var.value.lval; convert_to_string(&restored_error_reporting); zend_alter_ini_entry("error_reporting", sizeof("error_reporting"), Z_STRVAL(restored_error_reporting), Z_STRLEN(restored_error_reporting), ZEND_INI_USER, ZEND_INI_STAGE_RUNTIME); zendi_zval_dtor(restored_error_reporting); } + EX(old_error_reporting) = NULL; ZEND_VM_NEXT_OPCODE(); } @@ -3597,6 +3602,7 @@ ZEND_VM_HANDLER(149, ZEND_HANDLE_EXCEPTION, ANY, ANY) int i; int encapsulating_block=-1; zval **stack_zval_pp; + zval restored_error_reporting; stack_zval_pp = (zval **) EG(argument_stack).top_element - 1; while (*stack_zval_pp != NULL) { @@ -3624,6 +3630,16 @@ ZEND_VM_HANDLER(149, ZEND_HANDLE_EXCEPTION, ANY, ANY) zend_ptr_stack_n_pop(&EG(arg_types_stack), 3, &EX(calling_scope), &EX(object), &EX(fbc)); } + /* restore previous error_reporting value */ + if (!EG(error_reporting) && EX(old_error_reporting) != NULL && EX(old_error_reporting)->value.lval != 0) { + restored_error_reporting.type = IS_LONG; + restored_error_reporting.value.lval = EX(old_error_reporting)->value.lval; + convert_to_string(&restored_error_reporting); + zend_alter_ini_entry("error_reporting", sizeof("error_reporting"), Z_STRVAL(restored_error_reporting), Z_STRLEN(restored_error_reporting), ZEND_INI_USER, ZEND_INI_STAGE_RUNTIME); + zendi_zval_dtor(restored_error_reporting); + } + EX(old_error_reporting) = NULL; + if (encapsulating_block == -1) { ZEND_VM_RETURN_FROM_EXECUTE_LOOP(); } else { diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 6cae5f9998..f940791be9 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -39,6 +39,7 @@ ZEND_API void execute(zend_op_array *op_array TSRMLS_DC) /* Initialize execute_data */ EX(fbc) = NULL; EX(object) = NULL; + EX(old_error_reporting) = NULL; if (op_array->T < TEMP_VAR_STACK_LIMIT) { EX(Ts) = (temp_variable *) do_alloca(sizeof(temp_variable) * op_array->T); } else { @@ -430,7 +431,11 @@ static int ZEND_BEGIN_SILENCE_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS) EX_T(opline->result.u.var).tmp_var.value.lval = EG(error_reporting); EX_T(opline->result.u.var).tmp_var.type = IS_LONG; /* shouldn't be necessary */ - zend_alter_ini_entry("error_reporting", sizeof("error_reporting"), "0", 1, ZEND_INI_USER, ZEND_INI_STAGE_RUNTIME); + EX(old_error_reporting) = &EX_T(opline->result.u.var).tmp_var; + + if (EG(error_reporting)) { + zend_alter_ini_entry("error_reporting", sizeof("error_reporting"), "0", 1, ZEND_INI_USER, ZEND_INI_STAGE_RUNTIME); + } ZEND_VM_NEXT_OPCODE(); } @@ -519,6 +524,7 @@ static int ZEND_HANDLE_EXCEPTION_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS) int i; int encapsulating_block=-1; zval **stack_zval_pp; + zval restored_error_reporting; stack_zval_pp = (zval **) EG(argument_stack).top_element - 1; while (*stack_zval_pp != NULL) { @@ -546,6 +552,16 @@ static int ZEND_HANDLE_EXCEPTION_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_ptr_stack_n_pop(&EG(arg_types_stack), 3, &EX(calling_scope), &EX(object), &EX(fbc)); } + /* restore previous error_reporting value */ + if (!EG(error_reporting) && EX(old_error_reporting) != NULL && EX(old_error_reporting)->value.lval != 0) { + restored_error_reporting.type = IS_LONG; + restored_error_reporting.value.lval = EX(old_error_reporting)->value.lval; + convert_to_string(&restored_error_reporting); + zend_alter_ini_entry("error_reporting", sizeof("error_reporting"), Z_STRVAL(restored_error_reporting), Z_STRLEN(restored_error_reporting), ZEND_INI_USER, ZEND_INI_STAGE_RUNTIME); + zendi_zval_dtor(restored_error_reporting); + } + EX(old_error_reporting) = NULL; + if (encapsulating_block == -1) { ZEND_VM_RETURN_FROM_EXECUTE_LOOP(); } else { @@ -4619,13 +4635,14 @@ static int ZEND_END_SILENCE_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_op *opline = EX(opline); zval restored_error_reporting; - if (!EG(error_reporting)) { + if (!EG(error_reporting) && EX(old_error_reporting)->value.lval != 0) { restored_error_reporting.type = IS_LONG; restored_error_reporting.value.lval = EX_T(opline->op1.u.var).tmp_var.value.lval; convert_to_string(&restored_error_reporting); zend_alter_ini_entry("error_reporting", sizeof("error_reporting"), Z_STRVAL(restored_error_reporting), Z_STRLEN(restored_error_reporting), ZEND_INI_USER, ZEND_INI_STAGE_RUNTIME); zendi_zval_dtor(restored_error_reporting); } + EX(old_error_reporting) = NULL; ZEND_VM_NEXT_OPCODE(); } diff --git a/Zend/zend_vm_execute.skl b/Zend/zend_vm_execute.skl index 414aad994d..6cfd1bbcd3 100644 --- a/Zend/zend_vm_execute.skl +++ b/Zend/zend_vm_execute.skl @@ -10,6 +10,7 @@ ZEND_API void {%EXECUTOR_NAME%}(zend_op_array *op_array TSRMLS_DC) /* Initialize execute_data */ EX(fbc) = NULL; EX(object) = NULL; + EX(old_error_reporting) = NULL; if (op_array->T < TEMP_VAR_STACK_LIMIT) { EX(Ts) = (temp_variable *) do_alloca(sizeof(temp_variable) * op_array->T); } else { |
