#44182 [Opn->Csd]: extract($a, EXTR_REFS) can fail to split copy-on-write references
| From: | lbarnaud@php.net | Date: | Wed, 26 Nov 2008 01:03:07 +0000 |
| Subject: | #44182 [Opn->Csd]: extract($a, EXTR_REFS) can fail to split copy-on-write references | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-131328@lists.php.net to get a copy of this message | ||
ID: 44182
Updated by: lbarnaud@php.net
Reported By: robin_fernandes at uk dot ibm dot com
-Status: Open
+Status: Closed
Bug Type: Arrays related
Operating System: *
PHP Version: 5CVS, 6CVS (2008-10-27)
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.
Thanks for the patch
Previous Comments:
------------------------------------------------------------------------
[2008-10-27 13:20:20] robin_fernandes at uk dot ibm dot com
Confirmed this bug (and bug 44181) still present on:
PHP 5.2.7RC3-dev (cli) (built: Oct 27 2008 11:40:07)
PHP 5.3.0alpha3-dev (cli) (built: Oct 27 2008 14:06:30)
PHP 6.0.0-dev (cli) (built: Oct 27 2008 12:39:36)
------------------------------------------------------------------------
[2008-10-27 13:01:24] jani@php.net
Does this bug exist in HEAD, PHP_5_3 and PHP_5_2 branches? And in
today's versions of them?
------------------------------------------------------------------------
[2008-10-25 13:52:02] robin_fernandes at uk dot ibm dot com
The patch URL? Seems OK to me, perhaps it was temporarily broken.
In any case, here's another one:
http://soal.org/php/extract.patch.txt
------------------------------------------------------------------------
[2008-10-25 13:25:36] jani@php.net
That url does not work..
------------------------------------------------------------------------
[2008-02-20 09:29:24] robin_fernandes at uk dot ibm dot com
I think the problem is that extract() can set the is_ref flag on zvals
without splitting them (i.e. zvals which have more than 1 copy-on-write
references can get their is_ref flag set).
From array.c:
...
} else {
if (Z_REFCOUNT_P(var_array) > 1 || *entry ==
EG(uninitialized_zval_ptr)) {
SEPARATE_ZVAL_TO_MAKE_IS_REF(entry);
} else {
Z_SET_ISREF_PP(entry); // <-- causes damage if entry has COW
references!
}
...
I believe that the only reliable way to fix this would be to make
extract() take its array argument as PREFER_REF.
This way, we can safely split array elements away from their
copy-on-write references, and still end up with a zval that belongs to
the original array.
I'm attaching a patch which implements this and fixes this bug, as well
as bug http://bugs.php.net/44181.
Disclaimer:
- I am not an internals expert. I might have disregarded some
scenarios. Feedback welcome!
- Patch tested on Windows XP 32bit only.
Patch against php6.0-200802191530 snap (includes test cases):
http://pastebin.ca/910172
------------------------------------------------------------------------
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/44182
--
Edit this bug report at http://bugs.php.net/?id=44182&edit=1