From:             peter at lvp-media dot com
Operating system: n/a
PHP version:      5.3CVS-2009-06-25 (snap)
PHP Bug Type:     Scripting Engine problem
Bug description:  Double declaration of __lambda_func when lambda wrongly 
formatted

Description:
------------
When creating a new lambda function using create_function, any code behind
an extra right curly brace (which closes the function) gets executed. This
is known and expected behaviour of eval, so no problem so far. However,
when the function itself does not contain parsing errors, while the code
after it does, the function gets created (and becomes available) while
zend_eval_stringl() returns false. Therefore the function's name,
defaulting to LAMBDA_TEMP_FUNCNAME, will not be changed and any future
calls to create_functions will fail using a fatal error ("Cannot redeclare
__lambda_func()"). Reproduce code is included.

The echo should output "1", however, the fatal error gets thrown instead.
While this absolutely isn't a problem that (should) occur very often,
fixing it seemed fairly easy so I created two patches.

The first patch checks whether any function named LAMBDA_TEMP_FUNCNAME
exists if zend_eval_stringl() fails, and if it does, renames it to
lambda_%d as would be done if the eval succeeded. After all, the function
itself was fine, so the function name can be returned as well.
zend_eval_stringl() outputs the parse error automatically so the
script-owner gets informed of the problem as well. The second patch is
easier, it simply removes any function called LAMBDA_TEMP_FUNCNAME if it
exists.

PATCH 1:

--- zend_builtin_functions.c    2009-06-25 15:23:45.000000000 +0200
+++ zend_builtin_functions_new.c        2009-06-25 15:40:34.000000000
+0200
@@ -1737,8 +1737,8 @@ ZEND_FUNCTION(create_function)
        efree(eval_name);

-       if (retval==SUCCESS) {
+       if (retval==SUCCESS || zend_hash_find(EG(function_table),
LAMBDA_TEMP_FUNCNAME, sizeof(LAMBDA_TEMP_FUNCNAME), (void **)
&func)!=FAILURE) {
                zend_function new_function, *func;

-               if (zend_hash_find(EG(function_table),
LAMBDA_TEMP_FUNCNAME, sizeof(LAMBDA_TEMP_FUNCNAME), (void **)
&func)==FAILURE) {
+               if (retval==SUCCESS && zend_hash_find(EG(function_table),
LAMBDA_TEMP_FUNCNAME, sizeof(LAMBDA_TEMP_FUNCNAME), (void **)
&func)==FAILURE) {
                        zend_error(E_ERROR, "Unexpected inconsistency in
create_function()");
                        RETURN_FALSE;

PATCH 2:

--- zend_builtin_functions.c            2009-06-25 15:23:45.000000000
+0200
+++ zend_builtin_functions_new.c        2009-06-25 15:23:45.000000000
+0200
@@ -1756,4 +1756,7 @@ ZEND_FUNCTION(create_function)
                RETURN_STRINGL(function_name, function_name_length, 0);
        } else {
+                if (zend_hash_find(EG(function_table),
LAMBDA_TEMP_FUNCNAME, sizeof(LAMBDA_TEMP_FUNCNAME), (void **)
&func)!=FAILURE) {
+                       zend_hash_del(EG(function_table),
LAMBDA_TEMP_FUNCNAME, sizeof(LAMBDA_TEMP_FUNCNAME));
+               }
                RETURN_FALSE;
        }

Reproduce code:
---------------
<?php
$borked = create_function ('', 'return 1; } else {}'); // unexpected else
{}
$foo    = create_function ('', 'return 1;');

echo $foo ();
?>

Expected result:
----------------
1

Actual result:
--------------
Fatal error: Cannot redeclare __lambda_func() (previously declared in
/home/peter/test.php(2) : runtime-created function:

-- 
Edit bug report at http://bugs.php.net/?id=48693&edit=1
-- 
Try a CVS snapshot (PHP 5.2):        
http://bugs.php.net/fix.php?id=48693&r=trysnapshot52
Try a CVS snapshot (PHP 5.3):        
http://bugs.php.net/fix.php?id=48693&r=trysnapshot53
Try a CVS snapshot (PHP 6.0):        
http://bugs.php.net/fix.php?id=48693&r=trysnapshot60
Fixed in CVS:                        
http://bugs.php.net/fix.php?id=48693&r=fixedcvs
Fixed in CVS and need be documented: 
http://bugs.php.net/fix.php?id=48693&r=needdocs
Fixed in release:                    
http://bugs.php.net/fix.php?id=48693&r=alreadyfixed
Need backtrace:                      
http://bugs.php.net/fix.php?id=48693&r=needtrace
Need Reproduce Script:               
http://bugs.php.net/fix.php?id=48693&r=needscript
Try newer version:                   
http://bugs.php.net/fix.php?id=48693&r=oldversion
Not developer issue:                 
http://bugs.php.net/fix.php?id=48693&r=support
Expected behavior:                   
http://bugs.php.net/fix.php?id=48693&r=notwrong
Not enough info:                     
http://bugs.php.net/fix.php?id=48693&r=notenoughinfo
Submitted twice:                     
http://bugs.php.net/fix.php?id=48693&r=submittedtwice
register_globals:                    
http://bugs.php.net/fix.php?id=48693&r=globals
PHP 4 support discontinued:          http://bugs.php.net/fix.php?id=48693&r=php4
Daylight Savings:                    http://bugs.php.net/fix.php?id=48693&r=dst
IIS Stability:                       
http://bugs.php.net/fix.php?id=48693&r=isapi
Install GNU Sed:                     
http://bugs.php.net/fix.php?id=48693&r=gnused
Floating point limitations:          
http://bugs.php.net/fix.php?id=48693&r=float
No Zend Extensions:                  
http://bugs.php.net/fix.php?id=48693&r=nozend
MySQL Configuration Error:           
http://bugs.php.net/fix.php?id=48693&r=mysqlcfg

Reply via email to