]> granicus.if.org Git - php/commitdiff
modify get_iterator calls for engine change
authorRob Richards <rrichards@php.net>
Tue, 7 Feb 2006 11:52:45 +0000 (11:52 +0000)
committerRob Richards <rrichards@php.net>
Tue, 7 Feb 2006 11:52:45 +0000 (11:52 +0000)
fix mem leak with iterators
fix object casting for edge case

ext/com_dotnet/com_handlers.c
ext/com_dotnet/com_iterator.c
ext/com_dotnet/com_saproxy.c
ext/com_dotnet/php_com_dotnet_internal.h

index d535affc5de8ca269d1d133764e93a07787354ad..06ca1f120bf2088bcc8d7f74743f44d0bbc980d6 100644 (file)
@@ -499,7 +499,7 @@ static int com_object_cast(zval *readobj, zval *writeobj, int type TSRMLS_DC)
        VariantInit(&v);
 
        if (V_VT(&obj->v) == VT_DISPATCH) {
-               if (FAILURE == php_com_do_invoke_by_id(obj, DISPID_VALUE,
+               if (SUCCESS != php_com_do_invoke_by_id(obj, DISPID_VALUE,
                                DISPATCH_METHOD|DISPATCH_PROPERTYGET, &v, 0, NULL, 1 TSRMLS_CC)) {
                        VariantCopy(&v, &obj->v);
                }
index 454d5a2f55d11789b7404a453bf4b6e5cbcc06da..2527dacea2e896eebb605716d8e72fdbf53d3f88 100644 (file)
@@ -38,6 +38,7 @@ struct php_com_iterator {
        VARIANT safe_array;
        VARTYPE sa_type;
        LONG sa_max;
+       zval *zdata;
 };
 
 static void com_iter_dtor(zend_object_iterator *iter TSRMLS_DC)
@@ -49,6 +50,9 @@ static void com_iter_dtor(zend_object_iterator *iter TSRMLS_DC)
        }
        VariantClear(&I->v);
        VariantClear(&I->safe_array);
+       if (I->zdata) {
+               zval_ptr_dtor((zval**)&I->zdata);
+       }
        efree(I);
 }
 
@@ -56,32 +60,18 @@ static int com_iter_valid(zend_object_iterator *iter TSRMLS_DC)
 {
        struct php_com_iterator *I = (struct php_com_iterator*)iter->data;
 
-       if (I->key == (ulong)-1) {
-               return FAILURE;
+       if (I->zdata) {
+               return SUCCESS;
        }
-       return SUCCESS;
+
+       return FAILURE;
 }
 
 static void com_iter_get_data(zend_object_iterator *iter, zval ***data TSRMLS_DC)
 {
        struct php_com_iterator *I = (struct php_com_iterator*)iter->data;
-       zval **ptr_ptr;
-       zval *ptr;
-
-       /* sanity */
-       if (I->key == (ulong)-1) {
-               *data = NULL;
-               return;
-       }
-
-       MAKE_STD_ZVAL(ptr);
-       php_com_zval_from_variant(ptr, &I->v, I->code_page TSRMLS_CC);
-       /* php_com_wrap_variant(ptr, &I->v, I->code_page TSRMLS_CC); */
-       ptr_ptr = emalloc(sizeof(*ptr_ptr));
-       *ptr_ptr = ptr;
-       *data = ptr_ptr;
 
-       return;
+       *data = &I->zdata;
 }
 
 static int com_iter_get_key(zend_object_iterator *iter, char **str_key, uint *str_key_len,
@@ -100,15 +90,20 @@ static int com_iter_move_forwards(zend_object_iterator *iter TSRMLS_DC)
 {
        struct php_com_iterator *I = (struct php_com_iterator*)iter->data;
        unsigned long n_fetched;
+       zval *ptr;
 
        /* release current cached element */
        VariantClear(&I->v);
 
+       if (I->zdata) {
+               zval_ptr_dtor((zval**)&I->zdata);
+               I->zdata = NULL;
+       }
+
        if (I->ev) {
                /* Get the next element */
                if (SUCCEEDED(IEnumVARIANT_Next(I->ev, 1, &I->v, &n_fetched)) && n_fetched > 0) {
                        I->key++;
-                       return SUCCESS;
                } else {
                        /* indicate that there are no more items */
                        I->key = (ulong)-1;
@@ -121,13 +116,17 @@ static int com_iter_move_forwards(zend_object_iterator *iter TSRMLS_DC)
                        return FAILURE;
                }
                I->key++;
-               if (php_com_safearray_get_elem(&I->safe_array, &I->v, (LONG)I->key TSRMLS_CC)) {
-                       return SUCCESS;
-               } else {
+               if (php_com_safearray_get_elem(&I->safe_array, &I->v, (LONG)I->key TSRMLS_CC) == 0) {
                        I->key = (ulong)-1;
                        return FAILURE;
                }
        }
+
+       MAKE_STD_ZVAL(ptr);
+       php_com_zval_from_variant(ptr, &I->v, I->code_page TSRMLS_CC);
+       /* php_com_wrap_variant(ptr, &I->v, I->code_page TSRMLS_CC); */
+       I->zdata = ptr;
+       return SUCCESS;
 }
 
 
@@ -140,7 +139,7 @@ static zend_object_iterator_funcs com_iter_funcs = {
        NULL
 };
 
-zend_object_iterator *php_com_iter_get(zend_class_entry *ce, zval *object TSRMLS_DC)
+zend_object_iterator *php_com_iter_get(zend_class_entry *ce, zval *object, int by_ref TSRMLS_DC)
 {
        php_com_dotnet_object *obj;
        struct php_com_iterator *I;
@@ -148,6 +147,11 @@ zend_object_iterator *php_com_iter_get(zend_class_entry *ce, zval *object TSRMLS
        DISPPARAMS dp;
        VARIANT v;
        unsigned long n_fetched;
+       zval *ptr;
+
+       if (by_ref) {
+               zend_error(E_ERROR, "An iterator cannot be used with foreach by reference");
+       }
 
        obj = CDNO_FETCH(object);
 
@@ -163,6 +167,7 @@ zend_object_iterator *php_com_iter_get(zend_class_entry *ce, zval *object TSRMLS
        I->iter.funcs = &com_iter_funcs;
        I->iter.data = I;
        I->code_page = obj->code_page;
+       I->zdata = NULL;
        VariantInit(&I->safe_array);
        VariantInit(&I->v);
 
@@ -189,6 +194,9 @@ zend_object_iterator *php_com_iter_get(zend_class_entry *ce, zval *object TSRMLS
                /* pre-fetch the element */
                if (php_com_safearray_get_elem(&I->safe_array, &I->v, bound TSRMLS_CC)) {
                        I->key = bound;
+                       MAKE_STD_ZVAL(ptr);
+                       php_com_zval_from_variant(ptr, &I->v, I->code_page TSRMLS_CC);
+                       I->zdata = ptr;
                } else {
                        I->key = (ulong)-1;
                }
@@ -220,6 +228,9 @@ zend_object_iterator *php_com_iter_get(zend_class_entry *ce, zval *object TSRMLS
                if (SUCCEEDED(IEnumVARIANT_Next(I->ev, 1, &I->v, &n_fetched)) && n_fetched > 0) {
                        /* indicate that we have element 0 */
                        I->key = 0;
+                       MAKE_STD_ZVAL(ptr);
+                       php_com_zval_from_variant(ptr, &I->v, I->code_page TSRMLS_CC);
+                       I->zdata = ptr;
                } else {
                        /* indicate that there are no more items */
                        I->key = (ulong)-1;
index f9ae38ca95d5e360d36efc63abca98d15b75c773..8cc0c5e64b66dd2abed60768a9eea94ace3ff227 100644 (file)
@@ -554,12 +554,16 @@ static zend_object_iterator_funcs saproxy_iter_funcs = {
 };
 
 
-zend_object_iterator *php_com_saproxy_iter_get(zend_class_entry *ce, zval *object TSRMLS_DC)
+zend_object_iterator *php_com_saproxy_iter_get(zend_class_entry *ce, zval *object, int by_ref TSRMLS_DC)
 {
        php_com_saproxy *proxy = SA_FETCH(object);
        php_com_saproxy_iter *I;
        int i;
 
+       if (by_ref) {
+               zend_error(E_ERROR, "An iterator cannot be used with foreach by reference");
+       }
+
        I = ecalloc(1, sizeof(*I));
        I->iter.funcs = &saproxy_iter_funcs;
        I->iter.data = I;
index 4c442389f6fde10383a9bffd18a109535bf89e4e..2cd0c2b960cabd602809c119e98c30356a766eff 100644 (file)
@@ -82,7 +82,7 @@ zend_object_handlers php_com_object_handlers;
 void php_com_object_enable_event_sink(php_com_dotnet_object *obj, int enable TSRMLS_DC);
 
 /* com_saproxy.c */
-zend_object_iterator *php_com_saproxy_iter_get(zend_class_entry *ce, zval *object TSRMLS_DC);
+zend_object_iterator *php_com_saproxy_iter_get(zend_class_entry *ce, zval *object, int by_ref TSRMLS_DC);
 int php_com_saproxy_create(zval *com_object, zval *proxy_out, zval *index TSRMLS_DC);
 
 /* com_olechar.c */
@@ -177,7 +177,7 @@ ITypeInfo *php_com_locate_typeinfo(char *typelibname, php_com_dotnet_object *obj
 int php_com_process_typeinfo(ITypeInfo *typeinfo, HashTable *id_to_name, int printdef, GUID *guid, int codepage TSRMLS_DC);
 
 /* com_iterator.c */
-zend_object_iterator *php_com_iter_get(zend_class_entry *ce, zval *object TSRMLS_DC);
+zend_object_iterator *php_com_iter_get(zend_class_entry *ce, zval *object, int by_ref TSRMLS_DC);
 
 
 #endif