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