]> granicus.if.org Git - php/commitdiff
Implemented FR #60738 (Allow 'set_error_handler' to handle NULL)
authorXinchen Hui <laruence@gmail.com>
Sat, 24 Mar 2012 07:13:10 +0000 (15:13 +0800)
committerXinchen Hui <laruence@gmail.com>
Sat, 24 Mar 2012 07:13:10 +0000 (15:13 +0800)
NEWS
Zend/tests/bug60738.phpt [new file with mode: 0644]
Zend/zend_builtin_functions.c

diff --git a/NEWS b/NEWS
index fa36358231cc9a4cb15bba0775c43a507784821b..2e1dd7c438d795d681f5d513138253086091d672 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -23,6 +23,8 @@ PHP                                                                        NEWS
   . Fixed bug #60825 (Segfault when running symfony 2 tests).
     (Dmitry, Laruence)
   . Fixed bug #60801 (strpbrk() mishandles NUL byte). (Adam)
+  . Implemented FR #60738 (Allow 'set_error_handler' to handle NULL).
+    (Laruence, Nikita Popov)
   . Fixed bug #60569 (Nullbyte truncates Exception $message). (Ilia)
   . Fixed bug #60227 (header() cannot detect the multi-line header with CR).
     (rui, Gustavo)
diff --git a/Zend/tests/bug60738.phpt b/Zend/tests/bug60738.phpt
new file mode 100644 (file)
index 0000000..e0c9793
--- /dev/null
@@ -0,0 +1,17 @@
+--TEST--
+Bug #60738 Allow 'set_error_handler' to handle NULL
+--FILE--
+<?php
+
+set_error_handler(function() { echo 'Intercepted error!', "\n"; });
+
+trigger_error('Error!');
+
+set_error_handler(null);
+
+trigger_error('Error!');
+?>
+--EXPECTF--
+Intercepted error!
+
+Notice: Error! in %s on line %d
index 57a9e3a7bccf0ba8d7f169ed7171a6c974c910e0..c4a10fde3759ee5f158b6a03acb1336fdf6f39e1 100644 (file)
@@ -1413,7 +1413,6 @@ ZEND_FUNCTION(trigger_error)
 ZEND_FUNCTION(set_error_handler)
 {
        zval *error_handler;
-       zend_bool had_orig_error_handler=0;
        char *error_handler_name = NULL;
        long error_type = E_ALL | E_STRICT;
 
@@ -1421,37 +1420,40 @@ ZEND_FUNCTION(set_error_handler)
                return;
        }
 
-       if (!zend_is_callable(error_handler, 0, &error_handler_name TSRMLS_CC)) {
-               zend_error(E_WARNING, "%s() expects the argument (%s) to be a valid callback",
-                                  get_active_function_name(TSRMLS_C), error_handler_name?error_handler_name:"unknown");
+       if (IS_NULL != Z_TYPE_P(error_handler)) {
+           zend_bool had_orig_error_handler = 0;
+               if (!zend_is_callable(error_handler, 0, &error_handler_name TSRMLS_CC)) {
+                       zend_error(E_WARNING, "%s() expects the argument (%s) to be a valid callback",
+                                       get_active_function_name(TSRMLS_C), error_handler_name?error_handler_name:"unknown");
+                       efree(error_handler_name);
+                       return;
+               }
                efree(error_handler_name);
-               return;
-       }
-       efree(error_handler_name);
 
-       if (EG(user_error_handler)) {
-               had_orig_error_handler = 1;
-               *return_value = *EG(user_error_handler);
-               zval_copy_ctor(return_value);
-               INIT_PZVAL(return_value);
-               zend_stack_push(&EG(user_error_handlers_error_reporting), &EG(user_error_handler_error_reporting), sizeof(EG(user_error_handler_error_reporting)));
-               zend_ptr_stack_push(&EG(user_error_handlers), EG(user_error_handler));
-       }
-       ALLOC_ZVAL(EG(user_error_handler));
+               if (EG(user_error_handler)) {
+                       had_orig_error_handler = 1;
+                       *return_value = *EG(user_error_handler);
+                       zval_copy_ctor(return_value);
+                       INIT_PZVAL(return_value);
+                       zend_stack_push(&EG(user_error_handlers_error_reporting), &EG(user_error_handler_error_reporting), sizeof(EG(user_error_handler_error_reporting)));
+                       zend_ptr_stack_push(&EG(user_error_handlers), EG(user_error_handler));
+               }
 
-       if (!zend_is_true(error_handler)) { /* unset user-defined handler */
-               FREE_ZVAL(EG(user_error_handler));
-               EG(user_error_handler) = NULL;
-               RETURN_TRUE;
-       }
+               ALLOC_ZVAL(EG(user_error_handler));
+               EG(user_error_handler_error_reporting) = (int)error_type;
+               MAKE_COPY_ZVAL(&error_handler, EG(user_error_handler));
 
-       EG(user_error_handler_error_reporting) = (int)error_type;
-       *EG(user_error_handler) = *error_handler;
-       zval_copy_ctor(EG(user_error_handler));
-       INIT_PZVAL(EG(user_error_handler));
+               if (!had_orig_error_handler) {
+                       RETURN_NULL();
+               }
+       } else { /* unset user-defined handler */
+               if (EG(user_error_handler)) {
+                       zend_stack_push(&EG(user_error_handlers_error_reporting), &EG(user_error_handler_error_reporting), sizeof(EG(user_error_handler_error_reporting)));
+                       zend_ptr_stack_push(&EG(user_error_handlers), EG(user_error_handler));
+               }
 
-       if (!had_orig_error_handler) {
-               RETURN_NULL();
+               EG(user_error_handler) = NULL;
+               RETURN_TRUE;
        }
 }
 /* }}} */