From: jan at kneschke dot de Operating system: PHP version: 5CVS-2003-11-06 (dev) PHP Bug Type: Zend Engine 2 problem Bug description: REPLACE_ZVAL_VALUE works on uninit stack-based zvals
Description: ------------ While the summary is a bit technical it the describes the actual problem very good: all over the code of the Zend Engine there are temporary zval's that find there way to REPLACE_ZVAL_VALUE which 'calls' SEPARATE_ZVAL_IF_NOT_REF and even tries to destrory the temporary zval with zval_dtor(). SEPARATE_ZVAL_IF_NOT_REF expands to ...->is_ref what is an read to an un-init element, the zval_dtor() is an illegal free() call. First occurence: zend_operators.c:494 zval tmp; if (op->value.obj.handlers->cast_object(op, &tmp, IS_STRING, 1 TSRMLS_CC) == SUCCESS) { ... and '&tmp' is passed to zend_std_cast_object() which will result in a REPLACE_ZVAL_VALUE() another path to the same problem: zend.c:266 zend_print_zval_ex() zval expr_copy; zend_make_printable_zval(expr, &expr_copy, &use_copy); My solution for this kind of coding error is to use pzval for this job: diff -u -r1.164 zend_operators.c --- Zend/zend_operators.c 18 Sep 2003 11:50:05 -0000 1.164 +++ Zend/zend_operators.c 7 Nov 2003 00:39:23 -0000 @@ -492,12 +492,17 @@ break; case IS_OBJECT: if (op->value.obj.handlers->cast_object) { - zval tmp; + zval *tmp; TSRMLS_FETCH(); - if (op->value.obj.handlers->cast_object(op, &tmp, IS_STRING, 1 TSRMLS_CC) == SUCCESS) { + + MAKE_STD_ZVAL(tmp); + + if (op->value.obj.handlers->cast_object(op, tmp, IS_STRING, 1 TSRMLS_CC) == SUCCESS) { zval_dtor(op); - *op = tmp; + *op = *tmp; break; + } else { + zval_dtor(tmp); } zend_error(E_NOTICE, "Object of class %s could not be converted to string", Z_OBJCE_P(op)->name); } else { zend_print_zval_ex() has to be fixed accordingly. valgrind helped me to catch this bug. and a last notice: MACROs with such side-effects are evil. Reproduce code: --------------- <?php print new reflection_class('stdclass'); ?> -- Edit bug report at http://bugs.php.net/?id=26156&edit=1 -- Try a CVS snapshot (php4): http://bugs.php.net/fix.php?id=26156&r=trysnapshot4 Try a CVS snapshot (php5): http://bugs.php.net/fix.php?id=26156&r=trysnapshot5 Fixed in CVS: http://bugs.php.net/fix.php?id=26156&r=fixedcvs Fixed in release: http://bugs.php.net/fix.php?id=26156&r=alreadyfixed Need backtrace: http://bugs.php.net/fix.php?id=26156&r=needtrace Try newer version: http://bugs.php.net/fix.php?id=26156&r=oldversion Not developer issue: http://bugs.php.net/fix.php?id=26156&r=support Expected behavior: http://bugs.php.net/fix.php?id=26156&r=notwrong Not enough info: http://bugs.php.net/fix.php?id=26156&r=notenoughinfo Submitted twice: http://bugs.php.net/fix.php?id=26156&r=submittedtwice register_globals: http://bugs.php.net/fix.php?id=26156&r=globals PHP 3 support discontinued: http://bugs.php.net/fix.php?id=26156&r=php3 Daylight Savings: http://bugs.php.net/fix.php?id=26156&r=dst IIS Stability: http://bugs.php.net/fix.php?id=26156&r=isapi Install GNU Sed: http://bugs.php.net/fix.php?id=26156&r=gnused Floating point limitations: http://bugs.php.net/fix.php?id=26156&r=float