]> granicus.if.org Git - php/commitdiff
fix for bug #20282 (and propably some of the
authorHarald Radi <phanto@php.net>
Wed, 29 Jan 2003 00:10:01 +0000 (00:10 +0000)
committerHarald Radi <phanto@php.net>
Wed, 29 Jan 2003 00:10:01 +0000 (00:10 +0000)
other com bugs)

#credits also go to tzm.de for sponsoring me

ext/com/COM.c
ext/com/com.h
ext/com/conversion.c
ext/com/variant.h

index 9c344023001b668dd867a7264eb48daecf75a08e..dd8b8ecd4a2a2e96a0ecb6b4c0fb0fca846600ae 100644 (file)
@@ -15,7 +15,7 @@
    | Author: Zeev Suraski <zeev@zend.com>                                 |
    |         Harald Radi  <h.radi@nme.at>                                 |
    |         Alan Brown   <abrown@pobox.com>                              |
-   |         Wez Furlong <wez@thebrainroom.com>                           |
+   |         Wez Furlong  <wez@thebrainroom.com>                          |
    +----------------------------------------------------------------------+
  */
 /* $Id$ */
@@ -726,7 +726,7 @@ PHP_FUNCTION(com_load)
                }
        }
 
-       RETURN_RESOURCE(zend_list_insert(obj, IS_COM));
+       RETVAL_COM(obj);
 }
 /* }}} */
 
@@ -744,7 +744,7 @@ static int do_COM_invoke(comval *obj, WORD dispflags, pval *function_name, VARIA
        int current_arg, current_variant;
        unsigned long count;
 
-       if (C_HASENUM(obj) && strstr(Z_STRVAL_P(function_name), "next")) {
+       if (C_HASENUM(obj) && strstr(Z_STRVAL_P(function_name), "next")) {
                /* Grab one argument off the stack, allocate enough
                 * VARIANTs
                 * Get the IEnumVariant interface and call ->Next();
@@ -918,6 +918,7 @@ static int do_COM_invoke(comval *obj, WORD dispflags, pval *function_name, VARIA
        return SUCCESS;
 }
 
+
 /* {{{ proto mixed com_invoke_ex(int module, int invokeflags, string handler_name [, mixed arg [, mixed ...]])
    Invokes a COM module */
 PHP_FUNCTION(com_invoke_ex)
@@ -947,17 +948,7 @@ PHP_FUNCTION(com_invoke_ex)
        dispflags = (WORD)Z_LVAL_P(invokeflags);
 
        /* obtain IDispatch interface */
-       if (Z_TYPE_P(object) == IS_OBJECT && (Z_OBJCE_P(object) == &COM_class_entry || !strcmp(Z_OBJCE_P(object)->name, "COM"))) {
-               zval **tmp;
-               zend_hash_index_find(Z_OBJPROP_P(object), 0, (void**)&tmp);
-               ZEND_FETCH_RESOURCE(obj, comval*, tmp, -1, "comval", IS_COM);
-       } else if (Z_TYPE_P(object) == IS_RESOURCE) {
-               ZEND_FETCH_RESOURCE(obj, comval*, &object, -1, "comval", IS_COM);
-       }
-       if (obj == NULL) {
-               php_error(E_WARNING, "%d is not a COM object handler", Z_LVAL_P(object));
-               RETURN_NULL();
-       }
+       FETCH_COM_SAFE(object, obj);
 
        ALLOC_VARIANT(var_result);
 
@@ -998,12 +989,7 @@ PHP_FUNCTION(com_invoke)
        function_name = arguments[1];
 
        /* obtain IDispatch interface */
-       convert_to_long(object);
-       obj = (comval *)zend_list_find(Z_LVAL_P(object), &type);
-       if (!obj || (type != IS_COM)) {
-               php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s is not a COM object handler", Z_STRVAL_P(function_name));
-               RETURN_NULL();
-       }
+       FETCH_COM_SAFE(object, obj);
 
        /* obtain property/method handler */
        convert_to_string_ex(&function_name);
@@ -1042,12 +1028,7 @@ PHP_FUNCTION(com_release)
        }
 
        /* obtain IDispatch interface */
-       convert_to_long_ex(&object);
-       obj = (comval *)zend_list_find(Z_LVAL_P(object), &type);
-       if (!obj || (type != IS_COM)) {
-               php_error(E_WARNING, "%s(): %d is not a COM object handler", get_active_function_name(TSRMLS_C));
-               RETURN_FALSE;
-       }
+       FETCH_COM_SAFE(object, obj);
 
        RETURN_LONG(php_COM_release(obj TSRMLS_CC))
 }
@@ -1072,13 +1053,7 @@ PHP_FUNCTION(com_addref)
        }
 
        /* obtain IDispatch interface */
-       convert_to_long_ex(&object);
-       obj = (comval *)zend_list_find(Z_LVAL_P(object), &type);
-       if (!obj || (type != IS_COM))
-       {
-               php_error(E_WARNING, "%s(): %d is not a COM object handler", get_active_function_name(TSRMLS_C));
-               RETURN_FALSE;
-       }
+       FETCH_COM_SAFE(object, obj);
 
        RETURN_LONG(php_COM_addref(obj TSRMLS_CC));
 }
@@ -1453,12 +1428,8 @@ PHP_FUNCTION(com_print_typeinfo)
                RETURN_FALSE;
        }
 
-       if (Z_TYPE_P(arg1) == IS_OBJECT && (Z_OBJCE_P(arg1) == &COM_class_entry || !strcmp(Z_OBJCE_P(arg1)->name, "COM"))) {
-               zval **tmp;
-               zend_hash_index_find(Z_OBJPROP_P(arg1), 0, (void**)&tmp);
-               ZEND_FETCH_RESOURCE(obj, comval*, tmp, -1, "comval", IS_COM);
-       } else if (Z_TYPE_P(arg1) == IS_RESOURCE) {
-               ZEND_FETCH_RESOURCE(obj, comval*, &arg1, -1, "comval", IS_COM);
+       if (Z_TYPE_P(arg1) == IS_OBJECT) {
+               FETCH_COM_SAFE(arg1, obj);
        } else {
                convert_to_string(arg1);
                typelibname = Z_STRVAL_P(arg1);
@@ -1492,14 +1463,8 @@ PHP_FUNCTION(com_event_sink)
                RETURN_FALSE;
        }
 
-       if (Z_TYPE_P(object) == IS_OBJECT && (Z_OBJCE_P(object) == &COM_class_entry || !strcmp(Z_OBJCE_P(object)->name, "COM"))) {
-               zval **tmp;
-               zend_hash_index_find(Z_OBJPROP_P(object), 0, (void**)&tmp);
-               ZEND_FETCH_RESOURCE(obj, comval*, tmp, -1, "comval", IS_COM);
-       } else {
-               ZEND_FETCH_RESOURCE(obj, comval*, &object, -1, "comval", IS_COM);
-       }
-
+       FETCH_COM_SAFE(object, obj);
+       
        if (sink && Z_TYPE_P(sink) == IS_ARRAY) {
                /* 0 => typelibname, 1 => dispname */
                zval **tmp;
@@ -1682,8 +1647,10 @@ static void do_COM_propput(pval *return_value, comval *obj, pval *arg_property,
                hr = php_COM_invoke(obj, dispid, DISPATCH_PROPERTYGET, &dispparams, var_result, &ErrString TSRMLS_CC);
 
                if (SUCCEEDED(hr)) {
-                       php_variant_to_pval(var_result, return_value, codepage TSRMLS_CC);
+                       RETVAL_VARIANT(var_result);
                } else {
+                       FREE_VARIANT(var_result);
+
                        *return_value = *value;
                        zval_copy_ctor(return_value);
                }
@@ -1691,10 +1658,10 @@ static void do_COM_propput(pval *return_value, comval *obj, pval *arg_property,
                if (ErrString) {
                        pefree(ErrString, 1);
                }
+       } else {
+               FREE_VARIANT(var_result);
        }
 
-       FREE_VARIANT(var_result);
-
        efree(new_value); // FREE_VARIANT does a VariantClear() which is not desired here !
        efree(propname);
 }
@@ -1721,18 +1688,8 @@ PHP_FUNCTION(com_propget)
        object = arguments[0];
        function_name = arguments[1];
 
-       if (Z_TYPE_P(object) == IS_OBJECT && (Z_OBJCE_P(object) == &COM_class_entry || !strcmp(Z_OBJCE_P(object)->name, "COM"))) {
-               zval **tmp;
-               zend_hash_index_find(Z_OBJPROP_P(object), 0, (void**)&tmp);
-               ZEND_FETCH_RESOURCE(obj, comval*, tmp, -1, "comval", IS_COM);
-       } else if (Z_TYPE_P(object) == IS_RESOURCE) {
-               ZEND_FETCH_RESOURCE(obj, comval*, &object, -1, "comval", IS_COM);
-       }
-       if (obj == NULL) {
-               php_error_docref(NULL TSRMLS_CC, E_WARNING, "parameter 1 is not a COM object handler");
-               RETURN_NULL();
-       }
-
+       FETCH_COM_SAFE(object, obj);
+       
        /* obtain property/method handler */
        convert_to_string_ex(&function_name);
 
@@ -1773,18 +1730,8 @@ PHP_FUNCTION(com_propput)
        object = arguments[0];
        function_name = arguments[1];
 
-       if (Z_TYPE_P(object) == IS_OBJECT && (Z_OBJCE_P(object) == &COM_class_entry || !strcmp(Z_OBJCE_P(object)->name, "COM"))) {
-               zval **tmp;
-               zend_hash_index_find(Z_OBJPROP_P(object), 0, (void**)&tmp);
-               ZEND_FETCH_RESOURCE(obj, comval*, tmp, -1, "comval", IS_COM);
-       } else if (Z_TYPE_P(object) == IS_RESOURCE) {
-               ZEND_FETCH_RESOURCE(obj, comval*, &object, -1, "comval", IS_COM);
-       }
-       if (obj == NULL) {
-               php_error_docref(NULL TSRMLS_CC, E_WARNING, "parameter 1 is not a COM object handler");
-               RETURN_NULL();
-       }
-
+       FETCH_COM_SAFE(object, obj);
+       
        /* obtain property/method handler */
        convert_to_string_ex(&function_name);
 
@@ -1844,7 +1791,8 @@ PHPAPI pval php_COM_get_property_handler(zend_property_reference *property_refer
 {
        zend_overloaded_element *overloaded_property;
        zend_llist_element *element;
-       pval return_value;
+       pval retval;
+       pval *return_value = &retval;
        pval **comval_handle;
        pval *object = property_reference->object;
        int type;
@@ -1852,14 +1800,14 @@ PHPAPI pval php_COM_get_property_handler(zend_property_reference *property_refer
        VARIANT *var_result;
        TSRMLS_FETCH();
 
-       INIT_ZVAL(return_value);    
-       ZVAL_NULL(&return_value);
+       INIT_ZVAL(retval);    
+       ZVAL_NULL(&retval);
 
        /* fetch the IDispatch interface */
        zend_hash_index_find(Z_OBJPROP_P(object), 0, (void **) &comval_handle);
        obj = (comval *) zend_list_find(Z_LVAL_P(*comval_handle), &type);
        if (!obj || (type != IS_COM)) {
-               return return_value;
+               return retval;
        }
 
        ALLOC_COM(obj_prop);
@@ -1873,7 +1821,7 @@ PHPAPI pval php_COM_get_property_handler(zend_property_reference *property_refer
                                        FREE_VARIANT(var_result);
                                        FREE_COM(obj_prop);
 
-                                       return return_value;
+                                       return retval;
                                }
                                break;
 
@@ -1882,7 +1830,7 @@ PHPAPI pval php_COM_get_property_handler(zend_property_reference *property_refer
                                        FREE_VARIANT(var_result);
                                        FREE_COM(obj_prop);
 
-                                       return return_value;
+                                       return retval;
                                }
                                break;
 
@@ -1892,13 +1840,13 @@ PHPAPI pval php_COM_get_property_handler(zend_property_reference *property_refer
                                if (obj != obj_prop) {
                                        FREE_COM(obj_prop);
 
-                                       return_value = *object;
-                                       ZVAL_ADDREF(&return_value);
+                                       retval = *object;
+                                       ZVAL_ADDREF(return_value);
                                } else {
                                        RETVAL_COM(obj);
                                }
 
-                               return return_value;
+                               return retval;
                }
 
                if (obj == obj_prop) {
@@ -1911,14 +1859,14 @@ PHPAPI pval php_COM_get_property_handler(zend_property_reference *property_refer
                                FREE_VARIANT(var_result);
                                FREE_COM(obj_prop);
 
-                               return return_value;
+                               return retval;
                        }
 
                        obj = obj_prop;
                        php_COM_set(obj, &V_DISPATCH(var_result), TRUE TSRMLS_CC);
                        VariantInit(var_result);        // to protect C_DISPATCH(obj) from being freed when var_result is destructed
                } else {
-                       php_variant_to_pval(var_result, &return_value, codepage TSRMLS_CC);
+                       php_variant_to_pval(var_result, return_value, codepage TSRMLS_CC);
 
                        FREE_COM(obj_prop);
                        obj_prop = NULL;
@@ -1932,7 +1880,7 @@ PHPAPI pval php_COM_get_property_handler(zend_property_reference *property_refer
 
        FREE_VARIANT(var_result);              
 
-       return return_value;
+       return retval;
 }
 
 
@@ -2041,20 +1989,10 @@ PHPAPI void php_COM_call_function_handler(INTERNAL_FUNCTION_PARAMETERS, zend_pro
        if (zend_llist_count(property_reference->elements_list)==1
                && !strcmp(Z_STRVAL(function_name->element), "com")) {
                /* constructor */
-               pval *object_handle;
-
                PHP_FN(com_load)(INTERNAL_FUNCTION_PARAM_PASSTHRU);
-               if (zend_is_true(return_value)) {
-                       ALLOC_ZVAL(object_handle);
-                       *object_handle = *return_value;
-                       pval_copy_constructor(object_handle);
-                       INIT_PZVAL(object_handle);
-                       zend_hash_index_update(Z_OBJPROP_P(object), 0, &object_handle, sizeof(pval *), NULL);
-                       pval_destructor(&function_name->element);
-               } else {
-                       ZVAL_NULL(object);
-               }
-
+               *object = *return_value;
+               pval_copy_constructor(object);
+               pval_destructor(&function_name->element);
                return;
        }
 
@@ -2096,10 +2034,11 @@ PHPAPI void php_COM_call_function_handler(INTERNAL_FUNCTION_PARAMETERS, zend_pro
                zend_get_parameters_array(ht, arg_count, arguments);
 
                if (do_COM_invoke(obj , DISPATCH_METHOD|DISPATCH_PROPERTYGET, &function_name->element, var_result, arguments, arg_count TSRMLS_CC) == SUCCESS) {
-                       php_variant_to_pval(var_result, return_value, codepage TSRMLS_CC);
+                       RETVAL_VARIANT(var_result);
+               } else {
+                       FREE_VARIANT(var_result);
                }
-
-               FREE_VARIANT(var_result);
+               
                efree(arguments);
        }
 
@@ -2381,12 +2320,7 @@ PHP_FUNCTION(com_isenum)
        zend_get_parameters(ht, 1, &object);
 
        /* obtain IDispatch interface */
-       zend_hash_index_find(Z_OBJPROP_P(object), 0, (void **) &comval_handle);
-       obj = (comval *) zend_list_find(Z_LVAL_PP(comval_handle), &type);
-       if (!obj || (type != IS_COM)) {
-               php_error(E_WARNING,"%s(): %s is not a COM object handler", get_active_function_name(TSRMLS_C), "");
-               RETURN_FALSE;
-       }
+       FETCH_COM_SAFE(object, obj);
 
        RETURN_BOOL(C_HASENUM(obj));
 }
index 5ec791dd43d19e297070e051323fa21c9d959b82..70efb790db41bd6cfca7516a11dcab5362aa0154 100644 (file)
@@ -42,12 +42,12 @@ END_EXTERN_C()
                        }                                                                                                                                               \
                        ZVAL_RESOURCE(handle, zend_list_insert((o), IS_COM));                                           \
                                                                                                                                                                        \
-                       zval_copy_ctor(handle);                                                                                                 \
                        zend_hash_index_update(properties, 0, &handle, sizeof(zval *), NULL);   \
                        object_and_properties_init(z, &COM_class_entry, properties);                    \
+                       (z)->is_ref=1;                                                                                                                  \
                }
 
-#define RETVAL_COM(o)  ZVAL_COM(&return_value, o);
+#define RETVAL_COM(o)  ZVAL_COM(return_value, o);
 #define RETURN_COM(o)  RETVAL_COM(o)                                                                                           \
                                                return;
 
@@ -56,6 +56,20 @@ END_EXTERN_C()
 
 #define FREE_COM(z)            php_COM_destruct(z TSRMLS_CC);
 
+#define FETCH_COM(z, obj) {                                                                                                                    \
+               zval **tmp;                                                                                                                                     \
+               zend_hash_index_find(Z_OBJPROP_P(z), 0, (void**)&tmp);                                          \
+               ZEND_FETCH_RESOURCE(obj, comval*, tmp, -1, "comval", IS_COM);                           \
+       }                                                                                                                                                               \
+       if (obj == NULL) {                                                                                                                              \
+               php_error(E_WARNING, "%d is not a COM object handler", Z_LVAL_P(z));            \
+               RETURN_NULL();                                                                                                                          \
+       }
+
+#define FETCH_COM_SAFE(z, obj)                                                                                                         \
+       if ((Z_TYPE_P(z) == IS_OBJECT) && (Z_OBJCE_P(z) == &COM_class_entry))                   \
+       FETCH_COM(z, obj)
+
 #define IS_COM                 php_COM_get_le_comval()
 
 #define C_HASTLIB(x)   ((x)->typelib)
index 5f04709f91468567343e058f685f378e96771c05..2c050f49ae2dc4afa80c894da927fd8048a75e70 100644 (file)
@@ -729,7 +729,6 @@ PHPAPI int php_variant_to_pval(VARIANT *var_arg, pval *pval_arg, int codepage TS
                                        php_COM_set(obj, &V_DISPATCH(var_arg), FALSE TSRMLS_CC);
                                        
                                        ZVAL_COM(pval_arg, obj);
-                                       VariantInit(var_arg);   // to protect C_DISPATCH(obj) from being freed when var_result is destructed
                                }
                        }
                        break;
index 31ea342d66bb3fd78802eb8c1b3602a784c6ccf9..66b4605613858ffe500c9f1e1916748279aeada0 100644 (file)
@@ -16,7 +16,8 @@
                                                                        comval *obj;                                                                            \
                                                                        ALLOC_COM(obj);                                                                         \
                                                                        php_COM_set(obj, &V_DISPATCH(v), TRUE TSRMLS_CC);       \
-                                                                       ZVAL_RESOURCE((z), zend_list_insert(obj, IS_COM));              \
+                                                                       ZVAL_COM((z), obj);                                                                     \
+                                                                       efree(v);                                                                                       \
                                                                } else {                                                                                                \
                                                                        php_variant_to_pval((v), (z), codepage TSRMLS_CC);      \
                                                                        FREE_VARIANT(v);                                                                        \