#29493 [Ver->Csd]: extract(array, EXTR_REFS) fails if array has more than one referring symbol
| From: | moriyoshi@php.net | Date: | Tue, 10 Aug 2004 06:06:07 +0000 |
| Subject: | #29493 [Ver->Csd]: extract(array, EXTR_REFS) fails if array has more than one referring symbol | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-64343@lists.php.net to get a copy of this message | ||
ID: 29493
Updated by: moriyoshi@php.net
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] moriyoshi@php.net
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 moriyoshi@php.net 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