phanto          Tue Jan 28 19:10:01 2003 EDT

  Modified files:              (Branch: PHP_4_3)
    /php4/ext/com       COM.c com.h conversion.c variant.h 
  Log:
  fix for bug  #20282 (and propably some of the
  other com bugs)
  
  #credits also go to tzm.de for sponsoring me
  
Index: php4/ext/com/COM.c
diff -u php4/ext/com/COM.c:1.90.2.1 php4/ext/com/COM.c:1.90.2.2
--- php4/ext/com/COM.c:1.90.2.1 Tue Dec 31 11:34:12 2002
+++ php4/ext/com/COM.c  Tue Jan 28 19:10:00 2003
@@ -15,10 +15,10 @@
    | Author: Zeev Suraski <[EMAIL PROTECTED]>                                 |
    |         Harald Radi  <[EMAIL PROTECTED]>                                 |
    |         Alan Brown   <[EMAIL PROTECTED]>                              |
-   |         Wez Furlong <[EMAIL PROTECTED]>                           |
+   |         Wez Furlong  <[EMAIL PROTECTED]>                          |
    +----------------------------------------------------------------------+
  */
-/* $Id: COM.c,v 1.90.2.1 2002/12/31 16:34:12 sebastian Exp $ */
+/* $Id: COM.c,v 1.90.2.2 2003/01/29 00:10:00 phanto Exp $ */
 /*
  * This module implements support for COM components that support the IDispatch
  * interface.  Both local (COM) and remote (DCOM) components can be accessed.
@@ -726,7 +726,7 @@
                }
        }
 
-       RETURN_RESOURCE(zend_list_insert(obj, IS_COM));
+       RETVAL_COM(obj);
 }
 /* }}} */
 
@@ -744,7 +744,7 @@
        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 @@
        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 @@
        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 @@
        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 @@
        }
 
        /* 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 @@
        }
 
        /* 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 @@
                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 @@
                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 @@
                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 @@
                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 @@
        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 @@
        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 @@
 {
        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 @@
        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 @@
                                        FREE_VARIANT(var_result);
                                        FREE_COM(obj_prop);
 
-                                       return return_value;
+                                       return retval;
                                }
                                break;
 
@@ -1882,7 +1830,7 @@
                                        FREE_VARIANT(var_result);
                                        FREE_COM(obj_prop);
 
-                                       return return_value;
+                                       return retval;
                                }
                                break;
 
@@ -1892,13 +1840,13 @@
                                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 @@
                                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 @@
 
        FREE_VARIANT(var_result);              
 
-       return return_value;
+       return retval;
 }
 
 
@@ -2041,20 +1989,10 @@
        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 @@
                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 @@
        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: php4/ext/com/com.h
diff -u php4/ext/com/com.h:1.13 php4/ext/com/com.h:1.13.4.1
--- php4/ext/com/com.h:1.13     Tue May 21 14:58:10 2002
+++ php4/ext/com/com.h  Tue Jan 28 19:10:00 2003
@@ -42,12 +42,12 @@
                        }                                                              
                                                                                 \
                        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;
 
@@ -55,6 +55,20 @@
                                                C_REFCOUNT(z) = 0;
 
 #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()
 
Index: php4/ext/com/conversion.c
diff -u php4/ext/com/conversion.c:1.50.2.1 php4/ext/com/conversion.c:1.50.2.2
--- php4/ext/com/conversion.c:1.50.2.1  Tue Dec 31 11:34:12 2002
+++ php4/ext/com/conversion.c   Tue Jan 28 19:10:00 2003
@@ -729,7 +729,6 @@
                                        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: php4/ext/com/variant.h
diff -u php4/ext/com/variant.h:1.4 php4/ext/com/variant.h:1.4.4.1
--- php4/ext/com/variant.h:1.4  Tue May 21 14:58:10 2002
+++ php4/ext/com/variant.h      Tue Jan 28 19:10:01 2003
@@ -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);                                                                       
 \

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

Reply via email to