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