ID: 29493 Updated by: [EMAIL PROTECTED] Reported By: msm at manley dot org -Status: Verified +Status: Closed Bug Type: Unknown/Other Function Operating System: Linux, FreeBSD PHP Version: 5.0.0 Assigned To: moriyoshi New Comment:
This bug has been fixed in CVS. Snapshots of the sources are packaged every three hours; this change will be in the next snapshot. You can grab the snapshot at http://snaps.php.net/. Thank you for the report, and for helping us make PHP better. Previous Comments: ------------------------------------------------------------------------ [2004-08-09 00:37:29] [EMAIL PROTECTED] Seems a side-effect of the fix I did for bug #25708. ------------------------------------------------------------------------ [2004-08-06 16:35:22] msm at manley dot org Sent patch to [EMAIL PROTECTED] that passes all of the PHP distribution testcases for bug 25708 and all of the testcases above. ------------------------------------------------------------------------ [2004-08-05 00:44:03] msm at manley dot org That patch is no good. It causes the testcase for bug 25708 to fail. ------------------------------------------------------------------------ [2004-08-04 23:46:02] msm at manley dot org The problem lies in extract()'s use of the SEPARATE_ZVAL macro in ext/standard/array.c. That macro actually makes a full copy of a ZVAL if the ZVAL's refcount is > 1. I assume that's used when doing lazy copies, normally. The existing extract() function uses SEPARATE_ZVAL_TO_MAKE_IS_REF to set is_ref = 1 in the ZVAL. When the refcount on the extract()ed array is 1, no copy is made and the extracted variables are refs to the array member. When the refcount is > 1, a copy of the array entry gets made by SEPARATE_ZVAL and the extracted variable end up as refs to the copy. Here is a patch that I believe fixes the problem. So far a modified version of PHP 5.0.0 has passed all the testcases with this patch in place. --- array.c Wed Aug 4 15:54:40 2004 +++ array.c.msm Wed Aug 4 16:42:01 2004 @@ -1372,7 +1372,7 @@ if (extract_refs) { zval **orig_var; - SEPARATE_ZVAL_TO_MAKE_IS_REF(entry); + (*(entry))->is_ref = 1; zval_add_ref(entry); if (zend_hash_find(EG(active_symbol_table), final_name.c, final_name.len+1, (void **) &orig_var) == SUCCESS) { ------------------------------------------------------------------------ [2004-08-03 22:59:58] msm at manley dot org Realizing I'm mostly conversing with myself here: I'm not completely certain, but I think the issue is on line 1375 of ext/standard/array.c SEPARATE_ZVAL_TO_MAKE_IS_REF(entry); If I follow the logic back through the twisty little maze of zend.h macros, it would appear that when that macro is called and the refcount on the original entry is > 1, SEPARATE_ZVAL ends up copying the entry entirely. But that would mean the individual entries in a array/hash have the same refcount as the array in general. Perhaps that's true? At this point I am in way deeper than I can figure, having never even looked at the PHP source before today. ------------------------------------------------------------------------ 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/29493 -- Edit this bug report at http://bugs.php.net/?id=29493&edit=1
