]> granicus.if.org Git - php/commitdiff
fix #33771 (error_reporting falls to 0 when @ was used inside try/catch block)
authorAntony Dovgal <tony2001@php.net>
Thu, 22 Sep 2005 19:03:04 +0000 (19:03 +0000)
committerAntony Dovgal <tony2001@php.net>
Thu, 22 Sep 2005 19:03:04 +0000 (19:03 +0000)
Zend/tests/bug33771.phpt [new file with mode: 0644]
Zend/zend_compile.h
Zend/zend_vm_def.h
Zend/zend_vm_execute.h
Zend/zend_vm_execute.skl

diff --git a/Zend/tests/bug33771.phpt b/Zend/tests/bug33771.phpt
new file mode 100644 (file)
index 0000000..336aee8
--- /dev/null
@@ -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
index c0ae3181b3a93150329119a19d205a86b4a24d86..ba7f18627a26a7e0d17271f4c67f090826bb53b0 100644 (file)
@@ -299,6 +299,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
index 57e8594fa59b40a6439f8b882eaedf7b588d6604..eaaf5f4f543847e463906d6783167d07e3b87cd8 100644 (file)
@@ -3589,7 +3589,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();
 }
 
@@ -3604,13 +3608,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();
 }
 
@@ -3737,6 +3742,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) {
@@ -3764,6 +3770,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 {
index 91980a2ad374c60d4cc9dcf8e07e90fdf1c0cc96..91abdc3978f6f7598e978aa5897878f825471b51 100644 (file)
@@ -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 {
@@ -439,7 +440,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();
 }
 
@@ -528,6 +533,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) {
@@ -555,6 +561,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 {
@@ -4770,13 +4786,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();
 }
 
index 414aad994df5010c90f70b0ab4cd7e83bdc3ea72..6cfd1bbcd3057f3782efa2b64e42618a91d75bcc 100644 (file)
@@ -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 {