]> granicus.if.org Git - php/commitdiff
@ Added missing AddRef() calls in the COM extension. This should
authorHarald Radi <phanto@php.net>
Thu, 30 May 2002 23:07:23 +0000 (23:07 +0000)
committerHarald Radi <phanto@php.net>
Thu, 30 May 2002 23:07:23 +0000 (23:07 +0000)
@ fix weird behaviour (in particular with ADODB). (Harald)

# waah, this suxx

ext/com/COM.c
ext/com/VARIANT.c
ext/com/conversion.c
ext/com/dispatch.c
ext/rpc/com/com_wrapper.c
ext/rpc/com/conversion.c
ext/rpc/com/dispatch.c
ext/rpc/com/variant.c

index 288a03ac32aa9bcb60075f9cf8d5c258131bef0a..4354e9bcc22878fa87b7af29d27b71993ddaf4c7 100644 (file)
@@ -281,9 +281,11 @@ PHPAPI HRESULT php_COM_set(comval *obj, IDispatch FAR* FAR* ppDisp, int cleanup
        if (C_HASENUM(obj) = SUCCEEDED(C_DISPATCH_VT(obj)->Invoke(C_DISPATCH(obj), DISPID_NEWENUM, &IID_NULL, LOCALE_SYSTEM_DEFAULT,
                                                                                                                          DISPATCH_METHOD|DISPATCH_PROPERTYGET, &dispparams, var_result, NULL, NULL))) {
                if (V_VT(var_result) == VT_UNKNOWN) {
+                       V_UNKNOWN(var_result)->lpVtbl->AddRef(V_UNKNOWN(var_result));
                        C_HASENUM(obj) = SUCCEEDED(V_UNKNOWN(var_result)->lpVtbl->QueryInterface(V_UNKNOWN(var_result), &IID_IEnumVARIANT,
                                                                                                                                                                         (void**)&C_ENUMVARIANT(obj)));
                } else if (V_VT(var_result) == VT_DISPATCH) {
+                       V_DISPATCH(var_result)->lpVtbl->AddRef(V_DISPATCH(var_result));
                        C_HASENUM(obj) = SUCCEEDED(V_DISPATCH(var_result)->lpVtbl->QueryInterface(V_DISPATCH(var_result), &IID_IEnumVARIANT,
                                                                                                                                                                          (void**)&C_ENUMVARIANT(obj)));
                }
@@ -1584,10 +1586,11 @@ static void do_COM_propput(pval *return_value, comval *obj, pval *arg_property,
                        php_error(E_WARNING,"PropPut() failed: %s", error_message);
                }
                LocalFree(error_message);
-               efree(propname);
 
                FREE_VARIANT(var_result);
-               FREE_VARIANT(new_value);
+
+               efree(new_value);
+               efree(propname);
 
                RETURN_NULL();
        }
@@ -1597,20 +1600,22 @@ 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);
-       } else {
-               *return_value = *value;
-               zval_copy_ctor(return_value);
-       }
+       if (return_value) {
+               if (SUCCEEDED(hr)) {
+                       php_variant_to_pval(var_result, return_value, codepage TSRMLS_CC);
+               } else {
+                       *return_value = *value;
+                       zval_copy_ctor(return_value);
+               }
 
-       if (ErrString) {
-               pefree(ErrString, 1);
+               if (ErrString) {
+                       pefree(ErrString, 1);
+               }
        }
 
        FREE_VARIANT(var_result);
-       FREE_VARIANT(new_value);
 
+       efree(new_value); // FREE_VARIANT does a VariantClear() which is not desired here !
        efree(propname);
 }
 
@@ -1784,6 +1789,7 @@ PHPAPI pval php_COM_get_property_handler(zend_property_reference *property_refer
 
                        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);
 
@@ -1791,7 +1797,6 @@ PHPAPI pval php_COM_get_property_handler(zend_property_reference *property_refer
                        obj_prop = NULL;
                }
 
-               VariantInit(var_result);        // to protect C_DISPATCH(obj) from being freed when var_result is destructed
                pval_destructor(&overloaded_property->element);
        }
 
@@ -1808,7 +1813,6 @@ PHPAPI pval php_COM_get_property_handler(zend_property_reference *property_refer
 
 PHPAPI int php_COM_set_property_handler(zend_property_reference *property_reference, pval *value)
 {
-       pval result;
        zend_overloaded_element *overloaded_property;
        zend_llist_element *element;
        pval **comval_handle;
@@ -1878,7 +1882,7 @@ PHPAPI int php_COM_set_property_handler(zend_property_reference *property_refere
        FREE_VARIANT(var_result);
 
        overloaded_property = (zend_overloaded_element *) element->data;
-       do_COM_propput(&result, obj, &overloaded_property->element, value TSRMLS_CC);
+       do_COM_propput(NULL, obj, &overloaded_property->element, value TSRMLS_CC);
        FREE_COM(obj_prop);
 
        pval_destructor(&overloaded_property->element);
index 2303481cee8d68c40063fdfdcb4e2d2bd32a89a7..e06dd23e9e9571800b085665e49fb4244c9a2139 100644 (file)
@@ -181,6 +181,7 @@ static pval php_VARIANT_get_property_handler(zend_property_reference *property_r
 
                        case OE_IS_OBJECT:
                                if (!strcmp(Z_STRVAL(overloaded_property->element), "value")) {
+                                       // var_arg can't be an idispatch, so we don't care for the implicit AddRef() call here
                                        php_variant_to_pval(var_arg, &result, codepage TSRMLS_CC);
                                } else if (!strcmp(Z_STRVAL(overloaded_property->element), "type")) {
                                        ZVAL_LONG(&result, V_VT(var_arg))
index c9e4f894142e15dab0be4a6e514a5bfcba4f4e92..189a578f5300d43093e1062e41115e0ba68a4841 100644 (file)
@@ -720,9 +720,10 @@ PHPAPI int php_variant_to_pval(VARIANT *var_arg, pval *pval_arg, int codepage TS
                                        ZVAL_NULL(pval_arg);
                                } else {
                                        ALLOC_COM(obj);
-                                       php_COM_set(obj, &V_DISPATCH(var_arg), TRUE TSRMLS_CC);
+                                       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 8d775a86624c8fc9acdd06cff844fabf4f6fd9b2..23c3b0dd9194932f4d162f27a68e870fac694efd 100644 (file)
@@ -280,6 +280,7 @@ static HRESULT STDMETHODCALLTYPE disp_invokeex(
                                        ZVAL_NULL(zarg);
                                }
                        } else {
+                               // arg can't be an idispatch, so we don't care for the implicit AddRef() call here
                                if (FAILURE == php_variant_to_pval(arg, zarg, codepage TSRMLS_CC)) {
                                        trace("failed to convert arg %d to zval\n", i);
                                        ZVAL_NULL(zarg);
index 288a03ac32aa9bcb60075f9cf8d5c258131bef0a..4354e9bcc22878fa87b7af29d27b71993ddaf4c7 100644 (file)
@@ -281,9 +281,11 @@ PHPAPI HRESULT php_COM_set(comval *obj, IDispatch FAR* FAR* ppDisp, int cleanup
        if (C_HASENUM(obj) = SUCCEEDED(C_DISPATCH_VT(obj)->Invoke(C_DISPATCH(obj), DISPID_NEWENUM, &IID_NULL, LOCALE_SYSTEM_DEFAULT,
                                                                                                                          DISPATCH_METHOD|DISPATCH_PROPERTYGET, &dispparams, var_result, NULL, NULL))) {
                if (V_VT(var_result) == VT_UNKNOWN) {
+                       V_UNKNOWN(var_result)->lpVtbl->AddRef(V_UNKNOWN(var_result));
                        C_HASENUM(obj) = SUCCEEDED(V_UNKNOWN(var_result)->lpVtbl->QueryInterface(V_UNKNOWN(var_result), &IID_IEnumVARIANT,
                                                                                                                                                                         (void**)&C_ENUMVARIANT(obj)));
                } else if (V_VT(var_result) == VT_DISPATCH) {
+                       V_DISPATCH(var_result)->lpVtbl->AddRef(V_DISPATCH(var_result));
                        C_HASENUM(obj) = SUCCEEDED(V_DISPATCH(var_result)->lpVtbl->QueryInterface(V_DISPATCH(var_result), &IID_IEnumVARIANT,
                                                                                                                                                                          (void**)&C_ENUMVARIANT(obj)));
                }
@@ -1584,10 +1586,11 @@ static void do_COM_propput(pval *return_value, comval *obj, pval *arg_property,
                        php_error(E_WARNING,"PropPut() failed: %s", error_message);
                }
                LocalFree(error_message);
-               efree(propname);
 
                FREE_VARIANT(var_result);
-               FREE_VARIANT(new_value);
+
+               efree(new_value);
+               efree(propname);
 
                RETURN_NULL();
        }
@@ -1597,20 +1600,22 @@ 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);
-       } else {
-               *return_value = *value;
-               zval_copy_ctor(return_value);
-       }
+       if (return_value) {
+               if (SUCCEEDED(hr)) {
+                       php_variant_to_pval(var_result, return_value, codepage TSRMLS_CC);
+               } else {
+                       *return_value = *value;
+                       zval_copy_ctor(return_value);
+               }
 
-       if (ErrString) {
-               pefree(ErrString, 1);
+               if (ErrString) {
+                       pefree(ErrString, 1);
+               }
        }
 
        FREE_VARIANT(var_result);
-       FREE_VARIANT(new_value);
 
+       efree(new_value); // FREE_VARIANT does a VariantClear() which is not desired here !
        efree(propname);
 }
 
@@ -1784,6 +1789,7 @@ PHPAPI pval php_COM_get_property_handler(zend_property_reference *property_refer
 
                        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);
 
@@ -1791,7 +1797,6 @@ PHPAPI pval php_COM_get_property_handler(zend_property_reference *property_refer
                        obj_prop = NULL;
                }
 
-               VariantInit(var_result);        // to protect C_DISPATCH(obj) from being freed when var_result is destructed
                pval_destructor(&overloaded_property->element);
        }
 
@@ -1808,7 +1813,6 @@ PHPAPI pval php_COM_get_property_handler(zend_property_reference *property_refer
 
 PHPAPI int php_COM_set_property_handler(zend_property_reference *property_reference, pval *value)
 {
-       pval result;
        zend_overloaded_element *overloaded_property;
        zend_llist_element *element;
        pval **comval_handle;
@@ -1878,7 +1882,7 @@ PHPAPI int php_COM_set_property_handler(zend_property_reference *property_refere
        FREE_VARIANT(var_result);
 
        overloaded_property = (zend_overloaded_element *) element->data;
-       do_COM_propput(&result, obj, &overloaded_property->element, value TSRMLS_CC);
+       do_COM_propput(NULL, obj, &overloaded_property->element, value TSRMLS_CC);
        FREE_COM(obj_prop);
 
        pval_destructor(&overloaded_property->element);
index c9e4f894142e15dab0be4a6e514a5bfcba4f4e92..189a578f5300d43093e1062e41115e0ba68a4841 100644 (file)
@@ -720,9 +720,10 @@ PHPAPI int php_variant_to_pval(VARIANT *var_arg, pval *pval_arg, int codepage TS
                                        ZVAL_NULL(pval_arg);
                                } else {
                                        ALLOC_COM(obj);
-                                       php_COM_set(obj, &V_DISPATCH(var_arg), TRUE TSRMLS_CC);
+                                       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 8d775a86624c8fc9acdd06cff844fabf4f6fd9b2..23c3b0dd9194932f4d162f27a68e870fac694efd 100644 (file)
@@ -280,6 +280,7 @@ static HRESULT STDMETHODCALLTYPE disp_invokeex(
                                        ZVAL_NULL(zarg);
                                }
                        } else {
+                               // arg can't be an idispatch, so we don't care for the implicit AddRef() call here
                                if (FAILURE == php_variant_to_pval(arg, zarg, codepage TSRMLS_CC)) {
                                        trace("failed to convert arg %d to zval\n", i);
                                        ZVAL_NULL(zarg);
index 2303481cee8d68c40063fdfdcb4e2d2bd32a89a7..e06dd23e9e9571800b085665e49fb4244c9a2139 100644 (file)
@@ -181,6 +181,7 @@ static pval php_VARIANT_get_property_handler(zend_property_reference *property_r
 
                        case OE_IS_OBJECT:
                                if (!strcmp(Z_STRVAL(overloaded_property->element), "value")) {
+                                       // var_arg can't be an idispatch, so we don't care for the implicit AddRef() call here
                                        php_variant_to_pval(var_arg, &result, codepage TSRMLS_CC);
                                } else if (!strcmp(Z_STRVAL(overloaded_property->element), "type")) {
                                        ZVAL_LONG(&result, V_VT(var_arg))