helly           Sun Jun 19 23:02:52 2005 EDT

  Added files:                 
    /php-src/ext/spl/tests      bug33136.phpt 

  Modified files:              
    /php-src/ext/spl    spl_array.c 
  Log:
  - Fixed #33136:
  - Allow ArrayObject::offsetSet(NULL, $value) as replacement for [] = $value
  - Fix memleaks with overloading ArrayObject
  
  
http://cvs.php.net/diff.php/php-src/ext/spl/spl_array.c?r1=1.69&r2=1.70&ty=u
Index: php-src/ext/spl/spl_array.c
diff -u php-src/ext/spl/spl_array.c:1.69 php-src/ext/spl/spl_array.c:1.70
--- php-src/ext/spl/spl_array.c:1.69    Sun Jun 19 20:19:18 2005
+++ php-src/ext/spl/spl_array.c Sun Jun 19 23:02:52 2005
@@ -16,7 +16,7 @@
    +----------------------------------------------------------------------+
  */
 
-/* $Id: spl_array.c,v 1.69 2005/06/20 00:19:18 helly Exp $ */
+/* $Id: spl_array.c,v 1.70 2005/06/20 03:02:52 helly Exp $ */
 
 #ifdef HAVE_CONFIG_H
 # include "config.h"
@@ -152,6 +152,7 @@
 typedef struct _spl_array_object {
        zend_object       std;
        zval              *array;
+       zval              *retval;
        HashPosition      pos;
        int               ar_flags;
        int               is_self;
@@ -202,6 +203,7 @@
        FREE_HASHTABLE(intern->std.properties);
 
        zval_ptr_dtor(&intern->array);
+       zval_ptr_dtor(&intern->retval);
 
        efree(object);
 }
@@ -220,6 +222,7 @@
        memset(intern, 0, sizeof(spl_array_object));
        intern->std.ce = class_type;
        *obj = intern;
+       ALLOC_INIT_ZVAL(intern->retval);
 
        ALLOC_HASHTABLE(intern->std.properties);
        zend_hash_init(intern->std.properties, 0, NULL, ZVAL_PTR_DTOR, 0);
@@ -351,7 +354,11 @@
                spl_array_object *intern = 
(spl_array_object*)zend_object_store_get_object(object TSRMLS_CC);
                if (intern->fptr_offset_get) {
                        zval *rv;
-                       return zend_call_method_with_1_params(&object, 
Z_OBJCE_P(object), &intern->fptr_offset_get, "offsetGet", &rv, offset);  
+                       zend_call_method_with_1_params(&object, 
Z_OBJCE_P(object), &intern->fptr_offset_get, "offsetGet", &rv, offset); 
+                       zval_ptr_dtor(&intern->retval);
+                       MAKE_STD_ZVAL(intern->retval);
+                       ZVAL_ZVAL(intern->retval, rv, 1, 1);
+                       return intern->retval;
                }
        }
        return *spl_array_get_dimension_ptr_ptr(check_inherited, object, 
offset, type TSRMLS_CC);
@@ -366,10 +373,19 @@
 {
        spl_array_object *intern = 
(spl_array_object*)zend_object_store_get_object(object TSRMLS_CC);
        long index;
-       zval *rv;
+       int free_offset;
 
        if (check_inherited && intern->fptr_offset_set) {
-               zend_call_method_with_2_params(&object, Z_OBJCE_P(object), 
&intern->fptr_offset_set, "offsetSet", &rv, offset, value);
+               if (!offset) {
+                       ALLOC_INIT_ZVAL(offset);
+                       free_offset = 1;
+               } else {
+                       free_offset = 0;
+               }
+               zend_call_method_with_2_params(&object, Z_OBJCE_P(object), 
&intern->fptr_offset_set, "offsetSet", NULL, offset, value);
+               if (free_offset) {
+                       zval_ptr_dtor(&offset);
+               }
                return;
        }
        
@@ -395,6 +411,10 @@
                value->refcount++;
                zend_hash_index_update(spl_array_get_hash_table(intern, 0 
TSRMLS_CC), index, (void**)&value, sizeof(void*), NULL);
                return;
+       case IS_NULL:
+               value->refcount++;
+               zend_hash_next_index_insert(spl_array_get_hash_table(intern, 0 
TSRMLS_CC), (void**)&value, sizeof(void*), NULL);
+               return;
        default:
                zend_error(E_WARNING, "Illegal offset type");
                return;
@@ -410,10 +430,9 @@
 {
        spl_array_object *intern = 
(spl_array_object*)zend_object_store_get_object(object TSRMLS_CC);
        long index;
-       zval *rv;
 
        if (check_inherited && intern->fptr_offset_del) {
-               zend_call_method_with_1_params(&object, Z_OBJCE_P(object), 
&intern->fptr_offset_del, "offsetUnset", &rv, offset);
+               zend_call_method_with_1_params(&object, Z_OBJCE_P(object), 
&intern->fptr_offset_del, "offsetUnset", NULL, offset);
                return;
        }
 

http://cvs.php.net/co.php/php-src/ext/spl/tests/bug33136.phpt?r=1.1&p=1
Index: php-src/ext/spl/tests/bug33136.phpt
+++ php-src/ext/spl/tests/bug33136.phpt
--TEST--
Bug #33136 method offsetSet in class extended from ArrayObject crash PHP 
--FILE--
<?php

class Collection extends ArrayObject
{
        private $data;
        
        function __construct()
        {
                $this->data = array();
                parent::__construct($this->data);
        }
        
        function offsetGet($index)
        {
                echo __METHOD__ . "($index)\n";
                return parent::offsetGet($index);
        }
        
        function offsetSet($index, $value)
        {
                echo __METHOD__ . "(" . (is_null($index) ? "NULL" : $index) . 
",$value)\n";
                parent::offsetSet($index, $value);
        }
}

echo "\n\nInitiate Obj\n";
$arrayObj = new Collection();

echo "Assign values\n";

$arrayObj[] = "foo";
var_dump($arrayObj[0]);

$arrayObj[] = "bar";
var_dump($arrayObj[0]);
var_dump($arrayObj[1]);

$arrayObj["foo"] = "baz";
var_dump($arrayObj["foo"]);

print_r($arrayObj);

var_dump(count($arrayObj));

?>
===DONE===
<?php //exit(0); ?>
--EXPECT--
Initiate Obj
Assign values
Collection::offsetSet(NULL,foo)
Collection::offsetGet(0)
string(3) "foo"
Collection::offsetSet(NULL,bar)
Collection::offsetGet(0)
string(3) "foo"
Collection::offsetGet(1)
string(3) "bar"
Collection::offsetSet(foo,baz)
Collection::offsetGet(foo)
string(3) "baz"
Collection Object
(
    [0] => foo
    [1] => bar
    [foo] => baz
)
int(3)
===DONE===

-- 
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to