ID: 23619
Updated by: sniper@php.net
Reported By: ldemailly at qualys dot com
Status: Closed
Bug Type: Scripting Engine problem
Operating System: Linux 2.4.20
PHP Version: 4CVS-2003-05-13 (stable)
New Comment:
You should try this package:
http://downloads.php.net/jani/php-4.3.2RC3.tar.gz
And DO NOT run buildconf for it!!
Previous Comments:
------------------------------------------------------------------------
[2003-05-15 18:32:30] sniper@php.net
That patch is also bogus.
And as I said already: It works fine with latest _stable_ CVS. check
what php -v outputs, it's propably not the same version I'm trying this
with.
------------------------------------------------------------------------
[2003-05-15 14:03:28] ldemailly at qualys dot com
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)
------------------------------------------------------------------------
[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;
------------------------------------------------------------------------
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