|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
[2004-09-02 04:48 UTC] norxh at binnews dot com
Description:
------------
Crashes when run in cli or apache2 with no external modules.
Reproduce code:
---------------
<?PHP
$a = 1;
$b = "1";
switch ($a) {
case 1:
function foo($bar) {
if (preg_match('/\d/', $bar)) return true;
return false;
}
echo foo($b);
}
?>
Expected result:
----------------
1
Actual result:
--------------
crash
PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
|
|||||||||||||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Fri Oct 24 02:00:01 2025 UTC |
Although I see no point in doing this at all (it should not necessarily work), it shouldn't crash either. valgrind: ==2720== Conditional jump or move depends on uninitialised value(s) ==2720== at 0x83062CB: zend_switch_free (zend_execute.c:200) ==2720== by 0x8302A8D: zend_switch_free_handler (zend_execute.c:3222) ==2720== by 0x82FDC88: execute (zend_execute.c:1391) ==2720== by 0x830140F: zend_do_fcall_common_helper (zend_execute.c:2728) ==2720== by 0x8301890: zend_do_fcall_by_name_handler (zend_execute.c:2810) ==2720== ==2720== Use of uninitialised value of size 4 ==2720== at 0x8305E29: zend_pzval_unlock_func (zend_execute.c:65) ==2720== by 0x83062E6: zend_switch_free (zend_execute.c:205) ==2720== by 0x8302A8D: zend_switch_free_handler (zend_execute.c:3222) ==2720== by 0x82FDC88: execute (zend_execute.c:1391) ==2720== by 0x830140F: zend_do_fcall_common_helper (zend_execute.c:2728) ==2720== ==2720== Invalid read of size 4 ==2720== at 0x8305E29: zend_pzval_unlock_func (zend_execute.c:65) ==2720== by 0x83062E6: zend_switch_free (zend_execute.c:205) ==2720== by 0x8302A8D: zend_switch_free_handler (zend_execute.c:3222) ==2720== by 0x82FDC88: execute (zend_execute.c:1391) ==2720== by 0x830140F: zend_do_fcall_common_helper (zend_execute.c:2728) ==2720== Address 0x8 is not stack'd, malloc'd or (recently) free'd ==2720== ==2720== Process terminating with default action of signal 11 (SIGSEGV) ==2720== Access not within mapped region at address 0x8 ==2720== at 0x8305E29: zend_pzval_unlock_func (zend_execute.c:65) ==2720== by 0x83062E6: zend_switch_free (zend_execute.c:205) ==2720== by 0x8302A8D: zend_switch_free_handler (zend_execute.c:3222) ==2720== by 0x82FDC88: execute (zend_execute.c:1391) ==2720== by 0x830140F: zend_do_fcall_common_helper (zend_execute.c:2728) ==2720== GDB: 0x08305e29 in zend_pzval_unlock_func (z=0x0) at /dat/dev/php/php-5.0dev/Zend/zend_execute.c:65 65 z->refcount--; (gdb) bt #0 0x08305e29 in zend_pzval_unlock_func (z=0x0) at /dat/dev/php/php-5.0dev/Zend/zend_execute.c:65 #1 0x083062e7 in zend_switch_free (opline=0x85bd95c, Ts=0x85bdfbc) at /dat/dev/php/php-5.0dev/Zend/zend_execute.c:205 #2 0x08302a8e in zend_switch_free_handler (execute_data=0xbfffd400, opline=0x85bd95c, op_array=0x85bded8) at /dat/dev/php/php-5.0dev/Zend/zend_execute.c:3222 #3 0x082fdc89 in execute (op_array=0x85bded8) at /dat/dev/php/php-5.0dev/Zend/zend_execute.c:1391 #4 0x08301410 in zend_do_fcall_common_helper (execute_data=0xbfffd4f0, opline=0x85bc4cc, op_array=0x85b7f5c) at /dat/dev/php/php-5.0dev/Zend/zend_execute.c:2728 #5 0x08301891 in zend_do_fcall_by_name_handler (execute_data=0xbfffd4f0, opline=0x85bc4cc, op_array=0x85b7f5c) at /dat/dev/php/php-5.0dev/Zend/zend_execute.c:2810 #6 0x082fdc89 in execute (op_array=0x85b7f5c) at /dat/dev/php/php-5.0dev/Zend/zend_execute.c:1391 #7 0x082da17f in zend_execute_scripts (type=8, retval=0x0, file_count=3) at /dat/dev/php/php-5.0dev/Zend/zend.c:1061 #8 0x08293dc7 in php_execute_script (primary_file=0xbffff930) at /dat/dev/php/php-5.0dev/main/main.c:1629 #9 0x0830a856 in main (argc=1, argv=0xbffffa04) at /dat/dev/php/php-5.0dev/sapi/cli/php_cli.c:943 Assinging to Andi.<? switch ($_GET["test"]) { default: function testfunc() { } } testfunc(); ?> This code crashes PHP 5.1.0-DEV Windows Version.Problem is in CG(switch_cond_stack) that is shared by two op_arrays(One which has original switch and another one being the function declararion inside a case). Case 1 ---------------- <?php function foo() { echo "hi"; } ?> op_array of foo ZEND_ECHO ZEND_FETCH_CONSTANT ZEND_RETURN ZEND_HANDLE_EXCEPTION Case 2(Segfault case) ---------------- <?php $a=1; switch($a) { case 1: function foo() { echo "hi"; } } ?> op_array of foo ZEND_ECHO ZEND_FETCH_CONSTANT ZEND_SWITCH_FREE ZEND_RETURN ZEND_HANDLE_EXCEPTION In Case 2 ZEND_SWITCH_FREE opcode is getting included in the function foo's op_array. This is done by zend_do_return in zend_compile.c with the following code zend_stack_apply(&CG(switch_cond_stack), ZEND_STACK_APPLY_TOPDOWN, (int (*)(void *element)) generate_free_switch_expr); In zend_do_return of foo of Case 2, While executing zend_stack_apply, CG(switch_cond_stack) has 2 entries as follows, foo's seperator dummy switch_cond(at top) main op_array's switch case(at bottom) "main op_array's switch case(at bottom)" is generating ZEND_SWITCH_FREE opcode. I feel the switch_cond_stack to be op_array specific rather than keeping it at compiler_globals as it is now.I have a reduced test case for this bug. <?php $foo = 'bar'; switch ($foo) { case 'bar': function foobar() { $variable = 1; } foobar(); break; } ?> Things necessary for Apache to segfault: * The function must be defined inside a case statement that is executed. * A variable must be set to a value within the function. * The function must be called. I'm running PHP 5.0.3 (built from source, but I doubt that matters) on Apache 2. Bug is reproducible through Apache and through CLI.I have just tried this with the latest CVS (after spending 4 hours bug finding!). This bug is still in CVS. Exactly the same as is shown here, the following will crash apache: <?php $do = 1; switch ($do) { default: function test_function() { return 'Hello World'; } echo test_function(); } ?> This crashes both apache 1 and apache 2 on windows xp, macosx and linux based systems. I was testing on the CVS from 23/04/05.