php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #30074 apparent symbol table error with extract($blah, EXTR_REFS)
Submitted: 2004-09-13 15:47 UTC Modified: 2006-12-19 08:20 UTC
Votes:4
Avg. Score:5.0 ± 0.0
Reproduced:4 of 4 (100.0%)
Same Version:1 (25.0%)
Same OS:1 (25.0%)
From: owen dot beresford at murphx dot com Assigned:
Status: Closed Package: Scripting Engine problem
PHP Version: 5.0.1 OS: linux
Private report: No CVE-ID:
 [2004-09-13 15:47 UTC] owen dot beresford at murphx dot com
Description:
------------
PHP 5.0.1 (cli) (built: Aug 16 2004 23:07:06),
linux, rh7.3, kernel2.4, libc-2.2.5
The extract function seems incomplete/ broken.

I have a code base which uses arguments arrays, like perl.
Inorder to alter varaibles inside the parameter array in a convient fashion, I extract the variables at the top of the methods.  

Some of the boundary cases don't perform correctly.   I have NOT experienced this under other releases of php, so assume the problem is induced by the new zend engine.

I am assuming that php 5.0.1 includes prevous fixes for errors reported against php 4.3.8 and php 5.0.0 (there are closed cases with similar problems). 

This is a small simple case, there are other failures, but this would exceed the twenty line limit.  will post an URL with full senario
The described output ommited some of the english statements for brevity.
I have not tested this under other operating systems, but this is not a platform dependant function (well it shouldn't be), and I don't have any to hand.

in the interests of thoroughness:
Configure Command =>  './configure' '--prefix=/usr' '--with-config-file-path=/etc' '--enable-cli' '--disable-cgi' '--without-pear' '--enable-force-cgi-redirect' '--with-exec-dir=/usr/bin' '--with-mysql' '--with-curl=/usr/local/lib' '--with-zlib' '--enable-sockets' '--with-openssl' '--enable-pcntl' '--enable-libxml' '--enable-shared'


Reproduce code:
---------------
function x($args) {
	$count	=extract($args, EXTR_REFS);
	echo("inside function x()\n$count items\n");
	$count+=10;
	echo("altered count to $count\n");
	var_dump(array($a, $b));
}

echo("before function x() (second is a null)\n");
$a=array('a'=>1, 'b'=>NULL);
var_dump($a);
x($a);

echo("before function x() (second is undefined variable)\n");
$d=array('a'=>1, 'b'=>NULL);
$e=array('a'=>1, 'b'=>$d['d']);
var_dump($e);
x($e);


Expected result:
----------------
array(2) {
  ["a"]=>
  int(1)
  ["b"]=>
  NULL
}

array(2) {
  ["a"]=>
  int(1)
  ["b"]=>
  NULL
}


Actual result:
--------------
array(2) {
  [0]=>
  int(1)
  [1]=>
  NULL
}

array(2) {
  [0]=>
  int(1)
  [1]=>
  int(12)
}


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2004-09-14 11:10 UTC] owen dot beresford at murphx dot com
I have noticed my code output has the wrong indexes.
the expected out put should read index 0 and index 1 not index 'a', index 'b'

bug still present
 [2004-11-28 16:34 UTC] tony2001@php.net
Reduced reproduce code looks like this:
<?php
$result = extract(array('a'=>1, 'b'=>$foo), EXTR_REFS); 
//extract(array('a'=>1, 'b'=>$foo), EXTR_REFS); // they are not the same
var_dump(array($b));
?>

 [2004-12-20 22:07 UTC] mikael at SPAMMENOTchl dot chalmers dot se
I belive this bug was introduced in PHP 4.3.10, it would seem that when doing EXTR_REFS $a in the example below isn't  SEPARATE_ZVAL_TO_MAKE_IS_REF or something when being extracted from the array. 

Reproduce code:
------------
$a = 1; $b = 1;
$arr = array('acopy' => $a, 'bref' => &$b);

extract($arr, EXTR_REFS);

$acopy++;
$bref++;

debug_zval_dump($a, $b, $arr, $acopy, $bref);


Expected result (As seen on PHP < 4.3.10):
------------
$a: long(1) refcount(2)
$b: long(2) refcount(1)
$arr: array(2) refcount(2){
  ["acopy"]=>
  &long(2) refcount(2)
  ["bref"]=>
  &long(2) refcount(3)
}
$acopy: long(2) refcount(1)
$bref: long(2) refcount(1)


Actual result:
--------------
$a: long(2) refcount(1)
$b: long(2) refcount(1)
$arr: array(2) refcount(2){
  ["acopy"]=>
  &long(2) refcount(3)
  ["bref"]=>
  &long(2) refcount(3)
}
$acopy: long(2) refcount(1)
$bref: long(2) refcount(1)
 [2004-12-20 22:09 UTC] mikael at SPAMMENOTchl dot chalmers dot se
That should read "I belive this bug was backported into PHP 4.3.10", it seems to be present in the newly released 4.3.10 but not in 4.3.9
 [2004-12-20 22:29 UTC] mikael at SPAMMENOTchl dot chalmers dot se
My bad, seems it was actually introduced in 4.3.9 by the fix for bug #29493. Then the question is; if it is a feature or a bug, it certainly breaks a lot of old unit tests/code for me.
 [2005-01-19 22:10 UTC] sniper@php.net
See also bug #31217
 [2005-01-29 21:36 UTC] t3 at rohms dot com
I believe my problem may be related; I also filed a <a href="http://bugs.php.net/?id=31753">report</a> but not every isntance of extract() was causing problems. I was running 4.3.6 with no problems; upgraded to 4.3.10 and code didn't work; updated to latest version of zend; didn't work; downgraded back to 4.3.6, didn't work; downgraded to 4.3.6 and switched back to previous version of zend: worked.  It seems that the new version of zend may be invovled in the problem.  I wonder if turning down the optimization level would help?
 [2005-03-07 21:42 UTC] sniper@php.net
Please try using this CVS snapshot:

  http://snaps.php.net/php5-latest.tar.gz
 
For Windows:
 
  http://snaps.php.net/win32/php5-win32-latest.zip


 [2005-03-15 01:00 UTC] php-bugs at lists dot php dot net
No feedback was provided for this bug for over a week, so it is
being suspended automatically. If you are able to provide the
information that was originally requested, please do so and change
the status of the bug back to "Open".
 [2005-06-15 23:06 UTC] t3 at rohms dot com
Has this bug been fixed in a release yet?  I'd like to see comments added to these to indicate so and with what versions.
 [2006-12-10 00:54 UTC] shire at facebook dot com
I'm able to reproduce this using current CVS.  The problem appears to be when a CV value is passed into extract() either as the array or an array value.  Looks like in this case the IS_CV value is assigned to EG(uninitialized_zval_ptr).  The following patch will correct the problem for this case (and still pass a php 'make test').  However I'm not familiar enough with CV to know if there's a better way to correct to this problem:

diff --git a/ext/standard/array.c b/ext/standard/array.c
index fad4bf2..fdc9a88 100644
--- a/ext/standard/array.c
+++ b/ext/standard/array.c
@@ -1438,7 +1438,7 @@ PHP_FUNCTION(extract)
 
                                                *orig_var = *entry;
                                        } else {
-                                               if ((*var_array)->refcount > 1) {
+                                               if ((*var_array)->refcount > 1 || *entry == EG(uninitialized_zval_ptr)) {
                                                        SEPARATE_ZVAL_TO_MAKE_IS_REF(entry);
                                                } else {
                                                        (*entry)->is_ref = 1;
 [2006-12-10 00:55 UTC] shire at facebook dot com
I forgot to specify that in this case extract is setting the EG(uninitialized_zval_ptr)->is_ref = 1, causing further problems later in the code.
 [2006-12-19 08:20 UTC] shire@php.net
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.


 
PHP Copyright © 2001-2014 The PHP Group
All rights reserved.
Last updated: Thu Apr 17 18:02:13 2014 UTC