From: Christoph M. Becker Date: Mon, 6 Apr 2020 08:51:10 +0000 (+0200) Subject: Clean up constructor handling in com_dotnet X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=9cb32640afb23626920f3e31439310cb83e68550;p=php Clean up constructor handling in com_dotnet We substitute the construction magic with standard constructors, move the ZPP checks to the beginning of the ctors, and also let the function entries be generated from the stubs. --- diff --git a/ext/com_dotnet/com_com.c b/ext/com_dotnet/com_com.c index 58c7f7b963..768e3a1169 100644 --- a/ext/com_dotnet/com_com.c +++ b/ext/com_dotnet/com_com.c @@ -26,7 +26,7 @@ #include "Zend/zend_exceptions.h" /* {{{ com_create_instance - ctor for COM class */ -PHP_FUNCTION(com_create_instance) +PHP_METHOD(com, __construct) { zval *object = getThis(); zval *server_params = NULL; @@ -51,9 +51,6 @@ PHP_FUNCTION(com_create_instance) zend_long cp = GetACP(); const struct php_win32_cp *cp_it; - php_com_initialize(); - obj = CDNO_FETCH(object); - if (FAILURE == zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS(), "s|s!ls", &module_name, &module_name_len, &server_name, &server_name_len, @@ -65,6 +62,9 @@ PHP_FUNCTION(com_create_instance) RETURN_THROWS(); } + php_com_initialize(); + obj = CDNO_FETCH(object); + cp_it = php_win32_cp_get_by_id((DWORD)cp); if (!cp_it) { php_com_throw_exception(E_INVALIDARG, "Could not create COM object - invalid codepage!"); diff --git a/ext/com_dotnet/com_dotnet.c b/ext/com_dotnet/com_dotnet.c index bee7116fc3..6bd492ef1d 100644 --- a/ext/com_dotnet/com_dotnet.c +++ b/ext/com_dotnet/com_dotnet.c @@ -179,7 +179,7 @@ out: } /* {{{ com_dotnet_create_instance - ctor for DOTNET class */ -PHP_FUNCTION(com_dotnet_create_instance) +PHP_METHOD(dotnet, __construct) { zval *object = getThis(); php_com_dotnet_object *obj; @@ -195,6 +195,13 @@ PHP_FUNCTION(com_dotnet_create_instance) zend_long cp = GetACP(); const struct php_win32_cp *cp_it; + if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS(), "ss|l", + &assembly_name, &assembly_name_len, + &datatype_name, &datatype_name_len, + &cp)) { + RETURN_THROWS(); + } + php_com_initialize(); stuff = (struct dotnet_runtime_stuff*)COMG(dotnet_runtime_stuff); if (stuff == NULL) { @@ -237,13 +244,6 @@ PHP_FUNCTION(com_dotnet_create_instance) obj = CDNO_FETCH(object); - if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS(), "ss|l", - &assembly_name, &assembly_name_len, - &datatype_name, &datatype_name_len, - &cp)) { - RETURN_THROWS(); - } - cp_it = php_win32_cp_get_by_id((DWORD)cp); if (!cp_it) { php_com_throw_exception(E_INVALIDARG, "Could not create .Net object - invalid codepage!"); diff --git a/ext/com_dotnet/com_extension.c b/ext/com_dotnet/com_extension.c index 1353f48cb4..b37e4b8ffe 100644 --- a/ext/com_dotnet/com_extension.c +++ b/ext/com_dotnet/com_extension.c @@ -37,40 +37,18 @@ zend_class_entry *php_com_exception_class_entry, *php_com_saproxy_class_entry; -static const zend_function_entry com_dotnet_functions[] = { - PHP_FE(variant_set, arginfo_variant_set) - PHP_FE(variant_add, arginfo_variant_add) - PHP_FE(variant_cat, arginfo_variant_add) - PHP_FE(variant_sub, arginfo_variant_add) - PHP_FE(variant_mul, arginfo_variant_add) - PHP_FE(variant_and, arginfo_variant_add) - PHP_FE(variant_div, arginfo_variant_add) - PHP_FE(variant_eqv, arginfo_variant_add) - PHP_FE(variant_idiv, arginfo_variant_add) - PHP_FE(variant_imp, arginfo_variant_add) - PHP_FE(variant_mod, arginfo_variant_add) - PHP_FE(variant_or, arginfo_variant_add) - PHP_FE(variant_pow, arginfo_variant_add) - PHP_FE(variant_xor, arginfo_variant_add) - PHP_FE(variant_abs, arginfo_variant_abs) - PHP_FE(variant_fix, arginfo_variant_fix) - PHP_FE(variant_int, arginfo_variant_int) - PHP_FE(variant_neg, arginfo_variant_neg) - PHP_FE(variant_not, arginfo_variant_not) - PHP_FE(variant_round, arginfo_variant_round) - PHP_FE(variant_cmp, arginfo_variant_cmp) - PHP_FE(variant_date_to_timestamp, arginfo_variant_date_to_timestamp) - PHP_FE(variant_date_from_timestamp, arginfo_variant_date_from_timestamp) - PHP_FE(variant_get_type, arginfo_variant_get_type) - PHP_FE(variant_set_type, arginfo_variant_set_type) - PHP_FE(variant_cast, arginfo_variant_cast) - /* com_com.c */ - PHP_FE(com_create_guid, arginfo_com_create_guid) - PHP_FE(com_event_sink, arginfo_com_event_sink) - PHP_FE(com_print_typeinfo, arginfo_com_print_typeinfo) - PHP_FE(com_message_pump, arginfo_com_message_pump) - PHP_FE(com_load_typelib, arginfo_com_load_typelib) - PHP_FE(com_get_active_object, arginfo_com_get_active_object) +static const zend_function_entry com_variant_funcs[] = { + PHP_ME(variant, __construct, arginfo_class_variant___construct, ZEND_ACC_PUBLIC) + PHP_FE_END +}; + +static const zend_function_entry com_com_funcs[] = { + PHP_ME(com, __construct, arginfo_class_com___construct, ZEND_ACC_PUBLIC) + PHP_FE_END +}; + +static const zend_function_entry com_dotnet_funcs[] = { + PHP_ME(dotnet, __construct, arginfo_class_dotnet___construct, ZEND_ACC_PUBLIC) PHP_FE_END }; @@ -79,7 +57,7 @@ static const zend_function_entry com_dotnet_functions[] = { zend_module_entry com_dotnet_module_entry = { STANDARD_MODULE_HEADER, "com_dotnet", - com_dotnet_functions, + ext_functions, PHP_MINIT(com_dotnet), PHP_MSHUTDOWN(com_dotnet), PHP_RINIT(com_dotnet), @@ -218,14 +196,14 @@ PHP_MINIT_FUNCTION(com_dotnet) /* php_com_saproxy_class_entry->constructor->common.fn_flags |= ZEND_ACC_PROTECTED; */ php_com_saproxy_class_entry->get_iterator = php_com_saproxy_iter_get; - INIT_CLASS_ENTRY(ce, "variant", NULL); + INIT_CLASS_ENTRY(ce, "variant", com_variant_funcs); ce.create_object = php_com_object_new; php_com_variant_class_entry = zend_register_internal_class(&ce); php_com_variant_class_entry->get_iterator = php_com_iter_get; php_com_variant_class_entry->serialize = zend_class_serialize_deny; php_com_variant_class_entry->unserialize = zend_class_unserialize_deny; - INIT_CLASS_ENTRY(ce, "com", NULL); + INIT_CLASS_ENTRY(ce, "com", com_com_funcs); ce.create_object = php_com_object_new; tmp = zend_register_internal_class_ex(&ce, php_com_variant_class_entry); tmp->get_iterator = php_com_iter_get; @@ -233,7 +211,7 @@ PHP_MINIT_FUNCTION(com_dotnet) tmp->unserialize = zend_class_unserialize_deny; #if HAVE_MSCOREE_H - INIT_CLASS_ENTRY(ce, "dotnet", NULL); + INIT_CLASS_ENTRY(ce, "dotnet", com_dotnet_funcs); ce.create_object = php_com_object_new; tmp = zend_register_internal_class_ex(&ce, php_com_variant_class_entry); tmp->get_iterator = php_com_iter_get; diff --git a/ext/com_dotnet/com_extension.stub.php b/ext/com_dotnet/com_extension.stub.php index 8e065fb2ba..fe35e17c42 100644 --- a/ext/com_dotnet/com_extension.stub.php +++ b/ext/com_dotnet/com_extension.stub.php @@ -1,5 +1,7 @@ ce->name; \ - f.scope = obj->ce; \ - f.arg_info = NULL; \ - f.num_args = 0; \ - f.fn_flags = 0; \ - f.handler = ZEND_FN(fn); \ - return (zend_function*)&f; - - switch (obj->ce->name->val[0]) { -#if HAVE_MSCOREE_H - case 'd': - POPULATE_CTOR(d, com_dotnet_create_instance); -#endif - - case 'c': - POPULATE_CTOR(c, com_create_instance); - - case 'v': - POPULATE_CTOR(v, com_variant_create_instance); - - default: - return NULL; - } -} - static zend_string* com_class_name_get(const zend_object *object) { php_com_dotnet_object *obj = (php_com_dotnet_object *)object; @@ -553,7 +521,7 @@ zend_object_handlers php_com_object_handlers = { com_dimension_delete, com_properties_get, com_method_get, - com_constructor_get, + zend_std_get_constructor, com_class_name_get, com_object_cast, com_object_count, diff --git a/ext/com_dotnet/com_variant.c b/ext/com_dotnet/com_variant.c index bc4c7950e0..72cf16b9e3 100644 --- a/ext/com_dotnet/com_variant.c +++ b/ext/com_dotnet/com_variant.c @@ -425,14 +425,14 @@ PHP_COM_DOTNET_API int php_com_copy_variant(VARIANT *dstvar, VARIANT *srcvar) return php_com_copy_variant(V_VARIANTREF(dstvar), srcvar); default: - php_error_docref(NULL, E_WARNING, "variant->variant: failed to copy from 0x%x to 0x%x", V_VT(dstvar), V_VT(srcvar)); + php_error_docref(NULL, E_WARNING, "variant->__construct: failed to copy from 0x%x to 0x%x", V_VT(dstvar), V_VT(srcvar)); ret = FAILURE; } return ret; } /* {{{ com_variant_create_instance - ctor for new VARIANT() */ -PHP_FUNCTION(com_variant_create_instance) +PHP_METHOD(variant, __construct) { /* VARTYPE == unsigned short */ zend_long vt = VT_EMPTY; zend_long codepage = CP_ACP; @@ -446,14 +446,14 @@ PHP_FUNCTION(com_variant_create_instance) return; } - obj = CDNO_FETCH(object); - if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS(), "z!|ll", &zvalue, &vt, &codepage)) { RETURN_THROWS(); } php_com_initialize(); + obj = CDNO_FETCH(object); + if (ZEND_NUM_ARGS() == 3) { obj->code_page = (int)codepage; } diff --git a/ext/com_dotnet/php_com_dotnet_internal.h b/ext/com_dotnet/php_com_dotnet_internal.h index 3ee7ec4eba..8521277083 100644 --- a/ext/com_dotnet/php_com_dotnet_internal.h +++ b/ext/com_dotnet/php_com_dotnet_internal.h @@ -87,13 +87,7 @@ PHP_COM_DOTNET_API OLECHAR *php_com_string_to_olestring(char *string, /* com_com.c */ -PHP_FUNCTION(com_create_instance); -PHP_FUNCTION(com_event_sink); -PHP_FUNCTION(com_create_guid); -PHP_FUNCTION(com_print_typeinfo); -PHP_FUNCTION(com_message_pump); -PHP_FUNCTION(com_load_typelib); -PHP_FUNCTION(com_get_active_object); +PHP_METHOD(com, __construct); HRESULT php_com_invoke_helper(php_com_dotnet_object *obj, DISPID id_member, WORD flags, DISPPARAMS *disp_params, VARIANT *v, int silent, int allow_noarg); @@ -115,33 +109,7 @@ PHP_COM_DOTNET_API IDispatch *php_com_wrapper_export(zval *val); int php_com_persist_minit(INIT_FUNC_ARGS); /* com_variant.c */ -PHP_FUNCTION(com_variant_create_instance); -PHP_FUNCTION(variant_set); -PHP_FUNCTION(variant_add); -PHP_FUNCTION(variant_cat); -PHP_FUNCTION(variant_sub); -PHP_FUNCTION(variant_mul); -PHP_FUNCTION(variant_and); -PHP_FUNCTION(variant_div); -PHP_FUNCTION(variant_eqv); -PHP_FUNCTION(variant_idiv); -PHP_FUNCTION(variant_imp); -PHP_FUNCTION(variant_mod); -PHP_FUNCTION(variant_or); -PHP_FUNCTION(variant_pow); -PHP_FUNCTION(variant_xor); -PHP_FUNCTION(variant_abs); -PHP_FUNCTION(variant_fix); -PHP_FUNCTION(variant_int); -PHP_FUNCTION(variant_neg); -PHP_FUNCTION(variant_not); -PHP_FUNCTION(variant_round); -PHP_FUNCTION(variant_cmp); -PHP_FUNCTION(variant_date_to_timestamp); -PHP_FUNCTION(variant_date_from_timestamp); -PHP_FUNCTION(variant_get_type); -PHP_FUNCTION(variant_set_type); -PHP_FUNCTION(variant_cast); +PHP_METHOD(variant, __construct); PHP_COM_DOTNET_API void php_com_variant_from_zval_with_type(VARIANT *v, zval *z, VARTYPE type, int codepage); PHP_COM_DOTNET_API void php_com_variant_from_zval(VARIANT *v, zval *z, int codepage); @@ -149,7 +117,7 @@ PHP_COM_DOTNET_API int php_com_zval_from_variant(zval *z, VARIANT *v, int codepa PHP_COM_DOTNET_API int php_com_copy_variant(VARIANT *dst, VARIANT *src); /* com_dotnet.c */ -PHP_FUNCTION(com_dotnet_create_instance); +PHP_METHOD(dotnet, __construct); void php_com_dotnet_rshutdown(void); void php_com_dotnet_mshutdown(void); diff --git a/ext/com_dotnet/tests/bug73679.phpt b/ext/com_dotnet/tests/bug73679.phpt index 47de9b10c7..235fd3e33e 100644 --- a/ext/com_dotnet/tests/bug73679.phpt +++ b/ext/com_dotnet/tests/bug73679.phpt @@ -17,6 +17,6 @@ echo $stack->Pop() . $stack->Pop(); --EXPECTF-- Fatal error: Uncaught com_exception: Could not create .Net object - invalid codepage! in %sbug73679.php:%d Stack trace: -#0 %sbug73679.php(%d): dotnet->dotnet('mscorlib', 'System.Collecti...', -2200000000) +#0 %sbug73679.php(%d): dotnet->__construct('mscorlib', 'System.Collecti...', -2200000000) #1 {main} thrown in %sbug73679.php on line %d