php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #36567 $obj->arr[] with __set/__get cause data corrupted without any warning
Submitted: 2006-03-01 12:13 UTC Modified: 2006-08-01 22:53 UTC
From: xuefer at gmail dot com Assigned: dmitry (profile)
Status: Closed Package: Scripting Engine problem
PHP Version: 5CVS-2006-03-01 (CVS) OS: gentoo
Private report: No CVE-ID: None
 [2006-03-01 12:13 UTC] xuefer at gmail dot com
Description:
------------
yeah, i know using "$obj->arr[]" with __set/__get, the result is undefined. but shouldn't it be denied? because it's causing really bad side effect now... and hard to debug if there's no warning.
it's hard to know the instance $obj will be used as $obj->arr[] = ''; else where, if the project is big enough, while u implement __set/__get for classes happily

relatived bug:
http://bugs.php.net/bug.php?id=33941

Reproduce code:
---------------
<?php
class test {
    private $vars;

    public function __construct($vars) {
        $this->vars = $vars;
    }

    public function __get($key)
    {
        echo "get $key\n";
        return $this->vars[$key];
    }

    public function __set($key, $value)
    {
        echo "set $key to $value \n";
        $this->vars[$key] = $value;
    }
}
$vars = array('test' => array(0 => ""));
$obj = new test($vars);
$obj->test[0] = 'modified';
var_dump($vars);
?>

to reproduce the leak in http://bugs.php.net/bug.php?id=33941
<?php
class test {
    private $vars;

    public function __construct($vars) {
        $this->vars = $vars;
    }

    public function __get($key)
    {
        return $this->vars[$key];
    }
}
$vars = array('test' => array(0 => ""));
$obj = new test($vars); 
$obj->undefined[0] = 'modified';
?>

Notice: Undefined index:  undefined in /tmp/test.php on line 12
[Wed Mar  1 19:08:25 2006]  Script:  './/test.php'
/usr/src/php5/Zend/zend_variables.h(45) :  Freeing 0x08765E2C (9 bytes), script=.//test.php
/usr/src/php5/Zend/zend_variables.c(120) : Actual location (location was relayed)
[Wed Mar  1 19:08:25 2006]  Script:  './/test.php'
/usr/src/php5/Zend/zend_execute.c(1020) :  Freeing 0x0877BACC (35 bytes), script=.//test.php
/usr/src/php5/Zend/zend_hash.c(383) : Actual location (location was relayed)
[Wed Mar  1 19:08:25 2006]  Script:  './/test.php'
/usr/src/php5/Zend/zend_execute.c(1076) :  Freeing 0x0877BA7C (32 bytes), script=.//test.php
/usr/src/php5/Zend/zend_hash.c(169) : Actual location (location was relayed)
Last leak repeated 1 time
[Wed Mar  1 19:08:25 2006]  Script:  './/test.php'
/usr/src/php5/Zend/zend_execute.c(842) :  Freeing 0x0877B9DC (16 bytes), script=.//test.php
[Wed Mar  1 19:08:25 2006]  Script:  './/test.php'
/usr/src/php5/Zend/zend_execute.c(1072) :  Freeing 0x0877B88C (16 bytes), script=.//test.php

Expected result:
----------------
output
array(1) {
  ["test"]=>
  array(1) {
    [0]=>
    string(0) ""
  }
}
and just don't call __get/__set, raising a warning


Actual result:
--------------
get test
array(1) {
  ["test"]=>
  array(1) {
    [0]=>
    string(8) "modified"
  }
}

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2006-03-02 15:43 UTC] tony2001@php.net
Dmitry, could you please look into this?
 [2006-08-01 22:53 UTC] tony2001@php.net
Not reproducible with 5.2-CVS.
 
PHP Copyright © 2001-2020 The PHP Group
All rights reserved.
Last updated: Mon Sep 28 10:01:24 2020 UTC