]> granicus.if.org Git - php/commitdiff
MFH: 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:18 +0000 (19:03 +0000)
committerAntony Dovgal <tony2001@php.net>
Thu, 22 Sep 2005 19:03:18 +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 c9e1bced9167a1531ca64c57c863792afd674250..8a2c3b9cd59e524474ee01a95226520780772f9e 100644 (file)
@@ -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
index 3c16e3e7e5fc875cf53a1c374d60634bd658540a..8374387ca8d0f1f280e8c16d6c453e355557b0e7 100644 (file)
@@ -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 {
index 6cae5f99985400a487826c3936953a4e4b6b9967..f940791be9d22aedfe791bb0c5f44d4bb282ed8d 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 {
@@ -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();
 }
 
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 {