Edit report at http://bugs.php.net/bug.php?id=52001&edit=1
ID: 52001 Comment by: boldin dot pavel at gmail dot com Reported by: lisio at bk dot ru Summary: Memory allocation problems after using variable variables Status: Open Type: Bug Package: Scripting Engine problem Operating System: Linux PHP Version: 5.3.2 New Comment: I have attached patch. It must be reviewed by professional PHP developer. For me it is clearly that call of SEPARATE_ZVAL_TO_MAKE_IS_REF must be predicated with such a check (and it is done in all other cases). Previous Comments: ------------------------------------------------------------------------ [2010-06-06 18:38:05] boldin dot pavel at gmail dot com Finally: bug is at if (opline->extended_value & ZEND_FETCH_MAKE_REF) { SEPARATE_ZVAL_TO_MAKE_IS_REF(retval); } SEPARATE_ZVAL_TO_MAKE_IS_REF seems to ruine *retval (which is executor_globals.uninitialized_ptr). Then this leads to incorrectly working zend_send_by_var_helper and incorrect referencing count in zend_assign_to_variable. Trying to patch now. ------------------------------------------------------------------------ [2010-06-06 18:08:56] boldin dot pavel at gmail dot com Version without bug: (gdb) zend_send_by_var_helper_SPEC_VAR (execute_data=0x88a28d0) at /home/davinchi/php-5.3.2/Zend/zend_vm_execute.h:8257 8257 varptr = _get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC); (gdb) 8259 if (varptr == &EG(uninitialized_zval)) { (gdb) p varptr $24 = (zval *) 0x877fd04 (gdb) p &executor_globals.uninitialized_zval $25 = (zval *) 0x877fd04 (gdb) p executor_globals.uninitialized_zval_ptr $26 = (zval *) 0x877fd04 And version with bug: zend_send_by_var_helper_SPEC_VAR (execute_data=0x88a28d0) at /home/davinchi/php-5.3.2/Zend/zend_vm_execute.h:8254 8254 zend_op *opline = EX(opline); (gdb) 8257 varptr = _get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC); (gdb) n 8259 if (varptr == &EG(uninitialized_zval)) { (gdb) p varptr $27 = (zval *) 0x8876d8c (gdb) p &executor_globals.uninitialized_zval $28 = (zval *) 0x877fd04 (gdb) p executor_globals.uninitialized_zval_ptr $29 = (zval *) 0x8876d8c See that uninitialized_zval_ptr dont pointers to the uninitialized_zval at all! ------------------------------------------------------------------------ [2010-06-06 11:23:47] boldin dot pavel at gmail dot com Here is the problem: Zend/zend_execution.c line 703 (version 5.3.2): incorrect reference count (== 1) in case of bug. Should be == 3 and copy data in 'else' branch. ------------------------------------------------------------------------ [2010-06-06 10:36:36] boldin dot pavel at gmail dot com More detailed: when you pass off the function, _get_zval_cv_lookup no longer able to find your CVs, and they are missed. _get_zval_cv_lookup then returns pointer EG(uninitialized_zval_ptr), which is shared among a set of values. So two values are stored in same place. It is essential that this happens only if you call it with ZEND_FCALL_BY_NAME (i.e. declare after using) and only if dereferenced value is not first. ------------------------------------------------------------------------ [2010-06-06 10:30:54] boldin dot pavel at gmail dot com Even more: f($$var, 0) will also work. If you declare function before calling it will work too. Seems like bug in zend_do_pass_params or so on, causing to corruption of buffer. These CVs are just missing from the scope (active_symbol_table) after calling function. Seems like they are removed in middle of code execution. ------------------------------------------------------------------------ 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/bug.php?id=52001 -- Edit this bug report at http://bugs.php.net/bug.php?id=52001&edit=1