php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #23078 overload, switch, array square bracket construct, foreach
Submitted: 2003-04-07 01:01 UTC Modified: 2003-10-08 08:07 UTC
Votes:7
Avg. Score:3.6 ± 1.3
Reproduced:7 of 7 (100.0%)
Same Version:3 (42.9%)
Same OS:4 (57.1%)
From: bugs dot php dot net at wizzard dot org Assigned: zeev (profile)
Status: Wont fix Package: Scripting Engine problem
PHP Version: 4.3.3 OS: *
Private report: No CVE-ID: None
Have you experienced this issue?
Rate the importance of this bug to you:

 [2003-04-07 01:01 UTC] bugs dot php dot net at wizzard dot org
It seems that in a class with overloading enabled, inside a method, if you switch based on a declared attribute, PHP segfaults. Another FreeBSD user in #PHP on freenode was able to confirm the problem, using the following test code.

I've worked out the test case using the CGI binary, but I've also confirmed that it happens through the APXS2 SAPI. In that case, the errors from apache are:

[notice] child pid 72051 exit signal Segmentation fault (11)
- and/or - 
httpd in free(): warning: chunk is already free

The __get and __set methods are defined here as dummies just so overloading will truly be enabled. I'm assuming they would not be called because $var is pre-defined.

Test Code:
<?php
class demo {
   var $var;

   function demo() {
      $this->var = FALSE;
      return TRUE;
   }

   function problem_function() {
      switch( $this->var ) {
         case 'foo':

            break;
      }
      return TRUE;
   }

   function __get($name, &$value) {
      return TRUE;
   }    

   function __set($name, $value) {
      return TRUE;
   }
}

overload('demo');

$obj = new demo();
$obj->problem_function();
?>


Backtrace:
(gdb) bt
#0  overload_get_property (property_reference=0xbfbfdfe0)
    at /usr/ports/www/mod_php4/work/php-4.3.1/ext/overload/overload.c:363
#1  0x8144e07 in get_overloaded_property (T=0xbfbfdfd4)
    at /usr/ports/www/mod_php4/work/php-4.3.1/Zend/zend_execute.c:929
#2  0x814e2a3 in execute (op_array=0x8301ea4)
    at /usr/ports/www/mod_php4/work/php-4.3.1/Zend/zend_execute.c:92
#3  0x814adab in execute (op_array=0x8301424)
    at /usr/ports/www/mod_php4/work/php-4.3.1/Zend/zend_execute.c:1640
#4  0x81365f8 in zend_execute_scripts (type=8, retval=0x0, file_count=3)
    at /usr/ports/www/mod_php4/work/php-4.3.1/Zend/zend.c:864
#5  0x810aaea in php_execute_script (primary_file=0xbfbffd0c)
    at /usr/ports/www/mod_php4/work/php-4.3.1/main/main.c:1573
#6  0x81532b6 in main (argc=3, argv=0xbfbffd70)
    at /usr/ports/www/mod_php4/work/php-4.3.1/sapi/cli/php_cli.c:746
#7  0x80637ca in _start ()


More:
(gdb) f 0
#0  overload_get_property (property_reference=0xbfbfdfe0)
    at /usr/ports/www/mod_php4/work/php-4.3.1/ext/overload/overload.c:363
363                if (Z_TYPE_P(overloaded_property) == OE_IS_OBJECT) {
(gdb) p overloaded_property 
$1 = (zend_overloaded_element *) 0x5a5a5a62
(gdb) p *overloaded_property
Error accessing memory address 0x5a5a5a62: Bad address.


PHP Config Args:
'./configure' '--with-apxs2=/usr/local/sbin/apxs' '--with-tsrm-pth' '--with-config-file-path=/usr/local/etc' '--enable-versioning' '--with-regex=system' '--without-gd' '--without-mysql' '--with-gd=/usr/local' '--enable-gd-native-ttf' '--with-freetype-dir=/usr/local' '--with-jpeg-dir=/usr/local' '--with-png-dir=/usr/local' '--with-zlib' '--with-bz2=/usr' '--with-mcrypt=/usr/local' '--with-mhash=/usr/local' '--with-imap=/usr/local' '--with-mysql=/usr/local' '--with-expat-dir=/usr/local' '--with-gettext=/usr/local' '--enable-debug' '--prefix=/usr/local' 'i386-portbld-freebsd4.8'

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2003-04-07 04:41 UTC] sniper@php.net
Assigning to Andrei who wrote this thing, he can decide if it's worth to fix this.

 [2003-04-07 04:59 UTC] bugs dot php dot net at wizzard dot org
It appears that the same kind of problem occurs when using the square bracket construct on class attributes. To demonstrate the problem, replace the "problem_function" in the first code sample with the one below.

function problem_function() {
   $this->var[] = 'foo';

   return TRUE;
}

Backtrace:
(gdb) run testcase4.php
Starting program: /usr/local/bin/php testcase4.php

Program received signal SIGSEGV, Segmentation fault.
fetch_overloaded_element (result=0x830e0a0, op1=0x830e0b0, op2=0x830e0c0, Ts=0xbfbfdbe8, type=1, retval=0xbfbfdc20, 
    overloaded_element_type=1) at /usr/ports/www/mod_php4/work/php-4.3.1/Zend/zend_execute.c:701
701             overloaded_element.element = *get_zval_ptr(op2, Ts, &EG(free_op2), type);
(gdb) bt
#0  fetch_overloaded_element (result=0x830e0a0, op1=0x830e0b0, op2=0x830e0c0, Ts=0xbfbfdbe8, type=1, retval=0xbfbfdc20, 
    overloaded_element_type=1) at /usr/ports/www/mod_php4/work/php-4.3.1/Zend/zend_execute.c:701
#1  0x8142a4b in zend_fetch_dimension_address (result=0x830e0a0, op1=0x830e0b0, op2=0x830e0c0, Ts=0xbfbfdbe8, type=1)
    at /usr/ports/www/mod_php4/work/php-4.3.1/Zend/zend_execute.c:724
#2  0x8146f19 in execute (op_array=0x8305924) at /usr/ports/www/mod_php4/work/php-4.3.1/Zend/zend_execute.c:1267
#3  0x814adab in execute (op_array=0x8305024) at /usr/ports/www/mod_php4/work/php-4.3.1/Zend/zend_execute.c:1640
#4  0x81365f8 in zend_execute_scripts (type=8, retval=0x0, file_count=3)
    at /usr/ports/www/mod_php4/work/php-4.3.1/Zend/zend.c:864
#5  0x810aaea in php_execute_script (primary_file=0xbfbff8fc) at /usr/ports/www/mod_php4/work/php-4.3.1/main/main.c:1573
#6  0x81532b6 in main (argc=2, argv=0xbfbff968) at /usr/ports/www/mod_php4/work/php-4.3.1/sapi/cli/php_cli.c:746
#7  0x80637ca in _start ()
 [2003-04-07 09:57 UTC] andrei@php.net
The problems is not in ext/overload, it is in the engine. The code for handling ZEND_CASE obtains the value with no problem. However, when zend_switch_free() is executed, it passes an invalid overloaded property reference to the handler.
 [2003-04-08 10:33 UTC] bugs dot php dot net at wizzard dot org
Foreach is also affected by this problem.
E.G. foreach( $this->array_attr as $something )

I don't know if you need/want it, but here is some test code  you may want to use while debugging this problem. It contains an example of each part of this bug found so far.

<?php

class overload_tests {
   var $array;
   var $someattr;
   var $bucket;

   function overload_tests() {
      $this->array = array();
      $this->someattr = 'foo';
   }

   function append_attr_array() {
      $this->array[] = 'bar';
   }

   function access_attr_array() {
      foreach( $this->array as $elem ) {
         echo "AA: $elem\n";
      }
   }

   function switch_on_attr() {
      switch( $this->someattr ) {
         case 'baz':
            echo "Shouldn't get here\n";
            break;
         default:
            echo "Switched {$this->someattr}\n";
      }
   }

   function __get($name, &$value) {
      if ( isset($this->bucket[$name]) ) {
         $value = $this->bucket[$name];
         return TRUE;
      }
      return FALSE;
   }    

   function __set($name, $value) {
      $this->bucket[$name] = $value;
      return TRUE;
   }

}

overload('overload_tests');

echo "<plaintext>\n";

$obj = new overload_tests();
$obj->append_attr_array();
$obj->access_attr_array();
$obj->switch_on_attr();
$obj->baz = "What's after baz?";

print_r($obj);

?>
 [2003-10-08 08:07 UTC] zeev@php.net
I don't expect to see this resolved in PHP 4.  We're doing overloading differently in Zend Engine 2 / PHP 5 - stay tuned...
 
PHP Copyright © 2001-2022 The PHP Group
All rights reserved.
Last updated: Mon Jul 04 03:03:50 2022 UTC