#23619 [Csd->Opn]: set_error_handler registered hdler not called for object instances

From: Date: Thu, 15 May 2003 19:03:28 +0000
Subject: #23619 [Csd->Opn]: set_error_handler registered hdler not called for object instances
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-39731@lists.php.net to get a copy of this message
 ID:               23619
 User updated by:  ldemailly at qualys dot com
 Reported By:      ldemailly at qualys dot com
-Status:           Closed
+Status:           Open
 Bug Type:         Scripting Engine problem
 Operating System: Linux 2.4.20
 PHP Version:      4CVS-2003-05-13 (stable)
 New Comment:

sniper, what did you try exactly ?
I tried again with the latest from cvs and

./configure  --with-oci8=$ORACLE_HOME \
             --with-apache=../../apache_1.3.27 --with-mcrypt=/usr/local
\
             --enable-sysvsem --enable-sysvshm --enable-trackvars \
             --with-gd --with-png-dir=/usr \
             --with-jpeg-dir=/usr --with-zlib-dir=/usr \
             --with-mysql=/usr

and from the command line :
[dl@dl-pc php4]$ sapi/cli/php ~/foo.php
set_error_handler done retcode=1
 
Notice: Undefined variable:  foo in /home/dl/foo.php on line 12

This is another patch, as that unset thing seems
to leave stuff corrupt and looks like dead code
anyway (is_callable would theoritically fail for
an empty string anyway)

*** zend_builtin_functions.c.~1.124.2.4.~	2002-12-31 08:22:58.000000000
-0800
--- zend_builtin_functions.c	2003-05-15 12:01:48.000000000 -0700
***************
*** 891,902 ****
  	}
  	ALLOC_ZVAL(EG(user_error_handler));
  
- 	if (Z_STRLEN_PP(error_handler)==0) { /* unset user-defined handler
*/
- 		FREE_ZVAL(EG(user_error_handler));
- 		EG(user_error_handler) = NULL;
- 		RETURN_TRUE;
- 	}
- 
  	*EG(user_error_handler) = **error_handler;
  	zval_copy_ctor(EG(user_error_handler));
  
--- 891,896 ----

with the patch :
[dl@dl-pc php4]$ sapi/cli/php ~/foo.php
set_error_handler done retcode=
ERROR HANDLER CALLED (EXPECTED)


Previous Comments:
------------------------------------------------------------------------

[2003-05-15 13:18:39] wboring at qualys dot com

I tested this with php 4.3.1 and found that the code assumes that what
is passed in to set_error_handler() is a string, which you can clearly
see by the line
...
if (Z_STRLEN_PP(error_handler)==0) { /* unset user-defined
...

This is wrong and does not work when you pass an array into
set_error_handler( array(&$this, "myhandler") );

error_handler is an array zval, and therefore the test for Z_STRLEN_PP
always returns 0.  This case falls through and sets the
user_error_handler = NULL;
which prevents the user defined handler from working at all.  I am able
to reproduce this 100% of the time.  Please fix this, as it is totally
broken in its current state.  The patch provided works.  

  Also, if you assume that the variable passed in is a string, and
happens to be empty, then why do we RETURN_TRUE; in that block, when in
fact the user_error_handler is NOT set, and is set to NULL.  This is
also wrong.  This is an error case which should return FALSE.

------------------------------------------------------------------------

[2003-05-15 12:06:20] sniper@php.net

Seems to work fine with current stable CVS.
(without the patch, which is bogus anyway.)


------------------------------------------------------------------------

[2003-05-14 16:18:14] ldemailly at qualys dot com

A collegue of mine (Thanks Walter!) here actually found 
a fix (patch below);
looking at the code it is puzzling that it would
ever work, there seems to be some other bug/corruption
in the zend engine that would explain why it works/
behave differently sometimes. Also that test for empty
string should probably be before the test for callable... ?

php-4.3.1-walt/Zend/zend_builtin_functions.c 
--- php-4.3.1/Zend/zend_builtin_functions.c     2002-11-27
12:11:10.000000000 -0800 
+++ php-4.3.1-walt/Zend/zend_builtin_functions.c        2003-05-14
13:15:39.000000000 -0700 
@@ -891,7 +891,8 @@ 
       } 
       ALLOC_ZVAL(EG(user_error_handler)); 

-       if (Z_STRLEN_PP(error_handler)==0) { /* unset user-defined
handler */ 
+    /* Make sure we test for an empty string on a non-array value
here
*/ 
+       if (Z_TYPE_PP(error_handler) == IS_STRING &&
Z_STRLEN_PP(error_handler)==0) { /* unset user-defined handler */ 
               FREE_ZVAL(EG(user_error_handler)); 
               EG(user_error_handler) = NULL; 
               RETURN_TRUE;

------------------------------------------------------------------------

[2003-05-14 14:01:07] ldemailly at qualys dot com

Aha, I managed to reduce the repro script dramatically :

<?php
ini_set("error_reporting" , E_ALL);

class TestErrorHdl {
    // Will not be called !!
    function errorHandler($errno, $errstr, $errfile, $errline) {
        echo("ERROR HANDLER CALLED (EXPECTED)\n");
    }
    function runTest() {
        $res = set_error_handler(array(&$this, "errorHandler"));
	echo("set_error_handler done retcode=" . $res . "\n");
        $bar = $foo;
    }
}

$t = new TestErrorHdl();
$t->runTest();

?>

--- output (buggy, with current 4.3 php cli versions): ----
$ php ErrorBug.php
set_error_handler done retcode=1
 
Notice: Undefined variable:  foo in /home/dl/test_err_tiny/ErrorBug.php
on line
12
--- output (expected) : ----
set_error_handler done retcode=1
ERROR HANDLER CALLED (EXPECTED)


[note that with a longer script it does *most of the time*
work as expected, so it's not like the feature of
having an instance method for a error handler is not
supported at all...]

------------------------------------------------------------------------

[2003-05-14 10:42:42] sniper@php.net

You're propably doing something wrong. As long as you can't provide a
_SHORT_ example script which clearly shows the problem, we'll assume
that.


------------------------------------------------------------------------

The remainder of the comments for this report are too long. To view
the rest of the comments, please view the bug report online at
    http://bugs.php.net/23619

-- 
Edit this bug report at http://bugs.php.net/?id=23619&edit=1



Thread (15 messages)

« previous php.bugs (#39731) next »