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