colder          Thu Mar 19 02:44:04 2009 UTC

  Modified files:              
    /php-src/ext/spl    spl_observer.c 
  Log:
  Fix #47671 (cloning SplObjectStorage instances)
  
http://cvs.php.net/viewvc.cgi/php-src/ext/spl/spl_observer.c?r1=1.33&r2=1.34&diff_format=u
Index: php-src/ext/spl/spl_observer.c
diff -u php-src/ext/spl/spl_observer.c:1.33 php-src/ext/spl/spl_observer.c:1.34
--- php-src/ext/spl/spl_observer.c:1.33 Tue Mar 10 23:39:38 2009
+++ php-src/ext/spl/spl_observer.c      Thu Mar 19 02:44:04 2009
@@ -17,7 +17,7 @@
    +----------------------------------------------------------------------+
  */
 
-/* $Id: spl_observer.c,v 1.33 2009/03/10 23:39:38 helly Exp $ */
+/* $Id: spl_observer.c,v 1.34 2009/03/19 02:44:04 colder Exp $ */
 
 #ifdef HAVE_CONFIG_H
 # include "config.h"
@@ -106,6 +106,85 @@
        zval_ptr_dtor(&element->inf);
 } /* }}} */
 
+spl_SplObjectStorageElement* spl_object_storage_get(spl_SplObjectStorage 
*intern, zval *obj TSRMLS_DC) /* {{{ */
+{
+       spl_SplObjectStorageElement *element;
+       zend_object_value *pzvalue;     
+#if HAVE_PACKED_OBJECT_VALUE
+       pzvalue = &Z_OBJVAL_P(obj);
+#else
+       zend_object_value zvalue;
+       memset(&zvalue, 0, sizeof(zend_object_value));
+       zvalue.handle = Z_OBJ_HANDLE_P(obj);
+       zvalue.handlers = Z_OBJ_HT_P(obj);
+       pzvalue = &zvalue;
+#endif
+       if (zend_hash_find(&intern->storage, (char*)pzvalue, 
sizeof(zend_object_value), (void**)&element) == SUCCESS) {
+               return element;
+       } else {
+               return NULL;
+       }
+} /* }}} */
+
+void spl_object_storage_attach(spl_SplObjectStorage *intern, zval *obj, zval 
*inf TSRMLS_DC) /* {{{ */
+{
+       spl_SplObjectStorageElement *pelement, element;
+       pelement = spl_object_storage_get(intern, obj TSRMLS_CC);
+       if (inf) {
+               Z_ADDREF_P(inf);
+       } else {
+               ALLOC_INIT_ZVAL(inf);
+       }
+       if (pelement) {
+               zval_ptr_dtor(&pelement->inf);
+               pelement->inf = inf;
+               return;
+       }
+       Z_ADDREF_P(obj);
+       element.obj = obj;
+       element.inf = inf;
+#if HAVE_PACKED_OBJECT_VALUE
+       zend_hash_update(&intern->storage, (char*)&Z_OBJVAL_P(obj), 
sizeof(zend_object_value), &element, sizeof(spl_SplObjectStorageElement), 
NULL);    
+#else
+       {
+               zend_object_value zvalue;
+               memset(&zvalue, 0, sizeof(zend_object_value));
+               zvalue.handle = Z_OBJ_HANDLE_P(obj);
+               zvalue.handlers = Z_OBJ_HT_P(obj);
+               zend_hash_update(&intern->storage, (char*)&zvalue, 
sizeof(zend_object_value), &element, sizeof(spl_SplObjectStorageElement), NULL);
+       }
+#endif
+} /* }}} */
+
+void spl_object_storage_detach(spl_SplObjectStorage *intern, zval *obj 
TSRMLS_DC) /* {{{ */
+{
+#if HAVE_PACKED_OBJECT_VALUE
+       zend_hash_del(&intern->storage, (char*)&Z_OBJVAL_P(obj), 
sizeof(zend_object_value));
+#else
+       {
+               zend_object_value zvalue;
+               memset(&zvalue, 0, sizeof(zend_object_value));
+               zvalue.handle = Z_OBJ_HANDLE_P(obj);
+               zvalue.handlers = Z_OBJ_HT_P(obj);
+               zend_hash_del(&intern->storage, (char*)&zvalue, 
sizeof(zend_object_value));
+       }
+#endif
+} /* }}}*/
+
+void spl_object_storage_addall(spl_SplObjectStorage *intern, 
spl_SplObjectStorage *other TSRMLS_DC) { /* {{{ */
+       spl_SplObjectStorageElement *element;
+       HashPosition pos;
+
+       zend_hash_internal_pointer_reset_ex(&other->storage, &pos);
+       while (zend_hash_get_current_data_ex(&other->storage, (void 
**)&element, &pos) == SUCCESS) {
+               spl_object_storage_attach(intern, element->obj, element->inf 
TSRMLS_CC);
+               zend_hash_move_forward_ex(&other->storage, &pos);
+       }
+
+       zend_hash_internal_pointer_reset_ex(&intern->storage, &intern->pos);
+       intern->index = 0;
+} /* }}} */
+
 static zend_object_value spl_object_storage_new_ex(zend_class_entry 
*class_type, spl_SplObjectStorage **obj, zval *orig TSRMLS_DC) /* {{{ */
 {
        zend_object_value retval;
@@ -123,10 +202,36 @@
 
        retval.handle = zend_objects_store_put(intern, 
(zend_objects_store_dtor_t)zend_objects_destroy_object, 
(zend_objects_free_object_storage_t) spl_SplOjectStorage_free_storage, NULL 
TSRMLS_CC);
        retval.handlers = &spl_handler_SplObjectStorage;
+
+       if (orig) {
+               spl_SplObjectStorage *other = 
(spl_SplObjectStorage*)zend_object_store_get_object(orig TSRMLS_CC);
+               spl_object_storage_addall(intern, other TSRMLS_CC);
+       }
+
        return retval;
 }
 /* }}} */
 
+/* {{{ spl_object_storage_clone */
+static zend_object_value spl_object_storage_clone(zval *zobject TSRMLS_DC)
+{
+       zend_object_value new_obj_val;
+       zend_object *old_object;
+       zend_object *new_object;
+       zend_object_handle handle = Z_OBJ_HANDLE_P(zobject);
+       spl_SplObjectStorage *intern;
+
+       old_object = zend_objects_get_address(zobject TSRMLS_CC);
+       new_obj_val = spl_object_storage_new_ex(old_object->ce, &intern, 
zobject TSRMLS_CC);
+       new_object = &intern->std;
+
+       zend_objects_clone_members(new_object, new_obj_val, old_object, handle 
TSRMLS_CC);
+
+       return new_obj_val;
+}
+/* }}} */
+
+
 static HashTable* spl_object_storage_debug_info(zval *obj, int *is_temp 
TSRMLS_DC) /* {{{ */
 {
        spl_SplObjectStorage *intern = 
(spl_SplObjectStorage*)zend_object_store_get_object(obj TSRMLS_CC);
@@ -218,72 +323,6 @@
 #endif
 } /* }}} */
 
-spl_SplObjectStorageElement* spl_object_storage_get(spl_SplObjectStorage 
*intern, zval *obj TSRMLS_DC) /* {{{ */
-{
-       spl_SplObjectStorageElement *element;
-       zend_object_value *pzvalue;     
-#if HAVE_PACKED_OBJECT_VALUE
-       pzvalue = &Z_OBJVAL_P(obj);
-#else
-       zend_object_value zvalue;
-       memset(&zvalue, 0, sizeof(zend_object_value));
-       zvalue.handle = Z_OBJ_HANDLE_P(obj);
-       zvalue.handlers = Z_OBJ_HT_P(obj);
-       pzvalue = &zvalue;
-#endif
-       if (zend_hash_find(&intern->storage, (char*)pzvalue, 
sizeof(zend_object_value), (void**)&element) == SUCCESS) {
-               return element;
-       } else {
-               return NULL;
-       }
-} /* }}} */
-
-
-void spl_object_storage_attach(spl_SplObjectStorage *intern, zval *obj, zval 
*inf TSRMLS_DC) /* {{{ */
-{
-       spl_SplObjectStorageElement *pelement, element;
-       pelement = spl_object_storage_get(intern, obj TSRMLS_CC);
-       if (inf) {
-               Z_ADDREF_P(inf);
-       } else {
-               ALLOC_INIT_ZVAL(inf);
-       }
-       if (pelement) {
-               zval_ptr_dtor(&pelement->inf);
-               pelement->inf = inf;
-               return;
-       }
-       Z_ADDREF_P(obj);
-       element.obj = obj;
-       element.inf = inf;
-#if HAVE_PACKED_OBJECT_VALUE
-       zend_hash_update(&intern->storage, (char*)&Z_OBJVAL_P(obj), 
sizeof(zend_object_value), &element, sizeof(spl_SplObjectStorageElement), 
NULL);    
-#else
-       {
-               zend_object_value zvalue;
-               memset(&zvalue, 0, sizeof(zend_object_value));
-               zvalue.handle = Z_OBJ_HANDLE_P(obj);
-               zvalue.handlers = Z_OBJ_HT_P(obj);
-               zend_hash_update(&intern->storage, (char*)&zvalue, 
sizeof(zend_object_value), &element, sizeof(spl_SplObjectStorageElement), NULL);
-       }
-#endif
-} /* }}} */
-
-void spl_object_storage_detach(spl_SplObjectStorage *intern, zval *obj 
TSRMLS_DC) /* {{{ */
-{
-#if HAVE_PACKED_OBJECT_VALUE
-       zend_hash_del(&intern->storage, (char*)&Z_OBJVAL_P(obj), 
sizeof(zend_object_value));
-#else
-       {
-               zend_object_value zvalue;
-               memset(&zvalue, 0, sizeof(zend_object_value));
-               zvalue.handle = Z_OBJ_HANDLE_P(obj);
-               zvalue.handlers = Z_OBJ_HT_P(obj);
-               zend_hash_del(&intern->storage, (char*)&zvalue, 
sizeof(zend_object_value));
-       }
-#endif
-} /* }}}*/
-
 /* {{{ proto void SplObjectStorage::attach($obj, $inf = NULL) U
  Attaches an object to the storage if not yet contained */
 SPL_METHOD(SplObjectStorage, attach)
@@ -340,8 +379,6 @@
        zval *obj;
        spl_SplObjectStorage *intern = (spl_SplObjectStorage 
*)zend_object_store_get_object(getThis() TSRMLS_CC);
        spl_SplObjectStorage *other;
-       spl_SplObjectStorageElement *element;
-       HashPosition pos;
 
        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O", &obj, 
spl_ce_SplObjectStorage) == FAILURE) {
                return;
@@ -349,14 +386,7 @@
 
        other = (spl_SplObjectStorage *)zend_object_store_get_object(obj 
TSRMLS_CC);
 
-       zend_hash_internal_pointer_reset_ex(&other->storage, &pos);
-       while (zend_hash_get_current_data_ex(&other->storage, (void 
**)&element, &pos) == SUCCESS) {
-               spl_object_storage_attach(intern, element->obj, element->inf 
TSRMLS_CC);
-               zend_hash_move_forward_ex(&other->storage, &pos);
-       }
-
-       zend_hash_internal_pointer_reset_ex(&intern->storage, &intern->pos);
-       intern->index = 0;
+       spl_object_storage_addall(intern, other TSRMLS_CC);
 
        RETURN_LONG(zend_hash_num_elements(&intern->storage));
 } /* }}} */
@@ -998,6 +1028,7 @@
 
        spl_handler_SplObjectStorage.get_debug_info  = 
spl_object_storage_debug_info;
        spl_handler_SplObjectStorage.compare_objects = 
spl_object_storage_compare_objects;
+       spl_handler_SplObjectStorage.clone_obj       = spl_object_storage_clone;
 
        REGISTER_SPL_IMPLEMENTS(SplObjectStorage, Countable);
        REGISTER_SPL_IMPLEMENTS(SplObjectStorage, Iterator);

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

Reply via email to