]> granicus.if.org Git - php/commitdiff
Clean up constructor handling in com_dotnet
authorChristoph M. Becker <cmbecker69@gmx.de>
Mon, 6 Apr 2020 08:51:10 +0000 (10:51 +0200)
committerChristoph M. Becker <cmbecker69@gmx.de>
Mon, 6 Apr 2020 08:53:45 +0000 (10:53 +0200)
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.

ext/com_dotnet/com_com.c
ext/com_dotnet/com_dotnet.c
ext/com_dotnet/com_extension.c
ext/com_dotnet/com_extension.stub.php
ext/com_dotnet/com_extension_arginfo.h
ext/com_dotnet/com_handlers.c
ext/com_dotnet/com_variant.c
ext/com_dotnet/php_com_dotnet_internal.h
ext/com_dotnet/tests/bug73679.phpt

index 58c7f7b96347cbf0d9bec02d59689f4e769b8207..768e3a11692c083f246e488474d4c80a1948710a 100644 (file)
@@ -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!");
index bee7116fc3d1d76cbdf829c6d791337762ee4e78..6bd492ef1d9b924ba4049e117d41bddf1631c849 100644 (file)
@@ -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!");
index 1353f48cb4e7277e8682cbfbcc9e7f4dfcf439f6..b37e4b8ffe12ff926dac8bec681fa37caa602ff4 100644 (file)
@@ -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;
index 8e065fb2bafd258cba610e6c3f3db99eead9b88c..fe35e17c42c270ff9b9590e3aaa91443e107347b 100644 (file)
@@ -1,5 +1,7 @@
 <?php
 
+/** @generate-function-entries */
+
 function variant_set(variant $variant, $value): void {}
 
 function variant_add($left, $right): variant {}
@@ -64,3 +66,21 @@ function com_print_typeinfo($comobject, ?string $dispinterface = null, bool $wan
 function com_message_pump(int $timeoutms = 0): bool {}
 
 function com_load_typelib(string $typelib_name, bool $case_insensitive = true): bool {}
+
+class variant
+{
+    public function __construct($value = null, int $type = VT_EMPTY, int $codepage = CP_ACP) {}
+}
+
+class com
+{
+    /** @param string|array|null $server_name */
+    public function __construct(string $module_name, $server_name = UNKOWN, int $codepage = CP_ACP, string $typelib = "") {}
+}
+
+#if HAVE_MSCOREE_H
+class dotnet
+{
+    public function __construct(string $assembly_name, string $datatype_name, int $codepage = CP_ACP) {}
+}
+#endif
index b5eac32332392bba33491ed29fad170a844c66bd..4553db9283bc34a49d65ad4eb621e07784275f79 100644 (file)
@@ -108,3 +108,95 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_com_load_typelib, 0, 1, _IS_BOOL
        ZEND_ARG_TYPE_INFO(0, typelib_name, IS_STRING, 0)
        ZEND_ARG_TYPE_INFO(0, case_insensitive, _IS_BOOL, 0)
 ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_class_variant___construct, 0, 0, 0)
+       ZEND_ARG_INFO(0, value)
+       ZEND_ARG_TYPE_INFO(0, type, IS_LONG, 0)
+       ZEND_ARG_TYPE_INFO(0, codepage, IS_LONG, 0)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_class_com___construct, 0, 0, 1)
+       ZEND_ARG_TYPE_INFO(0, module_name, IS_STRING, 0)
+       ZEND_ARG_INFO(0, server_name)
+       ZEND_ARG_TYPE_INFO(0, codepage, IS_LONG, 0)
+       ZEND_ARG_TYPE_INFO(0, typelib, IS_STRING, 0)
+ZEND_END_ARG_INFO()
+
+#if HAVE_MSCOREE_H
+ZEND_BEGIN_ARG_INFO_EX(arginfo_class_dotnet___construct, 0, 0, 2)
+       ZEND_ARG_TYPE_INFO(0, assembly_name, IS_STRING, 0)
+       ZEND_ARG_TYPE_INFO(0, datatype_name, IS_STRING, 0)
+       ZEND_ARG_TYPE_INFO(0, codepage, IS_LONG, 0)
+ZEND_END_ARG_INFO()
+#endif
+
+
+ZEND_FUNCTION(variant_set);
+ZEND_FUNCTION(variant_add);
+ZEND_FUNCTION(variant_cat);
+ZEND_FUNCTION(variant_sub);
+ZEND_FUNCTION(variant_mul);
+ZEND_FUNCTION(variant_and);
+ZEND_FUNCTION(variant_div);
+ZEND_FUNCTION(variant_eqv);
+ZEND_FUNCTION(variant_idiv);
+ZEND_FUNCTION(variant_imp);
+ZEND_FUNCTION(variant_mod);
+ZEND_FUNCTION(variant_or);
+ZEND_FUNCTION(variant_pow);
+ZEND_FUNCTION(variant_xor);
+ZEND_FUNCTION(variant_abs);
+ZEND_FUNCTION(variant_fix);
+ZEND_FUNCTION(variant_int);
+ZEND_FUNCTION(variant_neg);
+ZEND_FUNCTION(variant_not);
+ZEND_FUNCTION(variant_round);
+ZEND_FUNCTION(variant_cmp);
+ZEND_FUNCTION(variant_date_to_timestamp);
+ZEND_FUNCTION(variant_date_from_timestamp);
+ZEND_FUNCTION(variant_get_type);
+ZEND_FUNCTION(variant_set_type);
+ZEND_FUNCTION(variant_cast);
+ZEND_FUNCTION(com_get_active_object);
+ZEND_FUNCTION(com_create_guid);
+ZEND_FUNCTION(com_event_sink);
+ZEND_FUNCTION(com_print_typeinfo);
+ZEND_FUNCTION(com_message_pump);
+ZEND_FUNCTION(com_load_typelib);
+
+
+static const zend_function_entry ext_functions[] = {
+       ZEND_FE(variant_set, arginfo_variant_set)
+       ZEND_FE(variant_add, arginfo_variant_add)
+       ZEND_FE(variant_cat, arginfo_variant_cat)
+       ZEND_FE(variant_sub, arginfo_variant_sub)
+       ZEND_FE(variant_mul, arginfo_variant_mul)
+       ZEND_FE(variant_and, arginfo_variant_and)
+       ZEND_FE(variant_div, arginfo_variant_div)
+       ZEND_FE(variant_eqv, arginfo_variant_eqv)
+       ZEND_FE(variant_idiv, arginfo_variant_idiv)
+       ZEND_FE(variant_imp, arginfo_variant_imp)
+       ZEND_FE(variant_mod, arginfo_variant_mod)
+       ZEND_FE(variant_or, arginfo_variant_or)
+       ZEND_FE(variant_pow, arginfo_variant_pow)
+       ZEND_FE(variant_xor, arginfo_variant_xor)
+       ZEND_FE(variant_abs, arginfo_variant_abs)
+       ZEND_FE(variant_fix, arginfo_variant_fix)
+       ZEND_FE(variant_int, arginfo_variant_int)
+       ZEND_FE(variant_neg, arginfo_variant_neg)
+       ZEND_FE(variant_not, arginfo_variant_not)
+       ZEND_FE(variant_round, arginfo_variant_round)
+       ZEND_FE(variant_cmp, arginfo_variant_cmp)
+       ZEND_FE(variant_date_to_timestamp, arginfo_variant_date_to_timestamp)
+       ZEND_FE(variant_date_from_timestamp, arginfo_variant_date_from_timestamp)
+       ZEND_FE(variant_get_type, arginfo_variant_get_type)
+       ZEND_FE(variant_set_type, arginfo_variant_set_type)
+       ZEND_FE(variant_cast, arginfo_variant_cast)
+       ZEND_FE(com_get_active_object, arginfo_com_get_active_object)
+       ZEND_FE(com_create_guid, arginfo_com_create_guid)
+       ZEND_FE(com_event_sink, arginfo_com_event_sink)
+       ZEND_FE(com_print_typeinfo, arginfo_com_print_typeinfo)
+       ZEND_FE(com_message_pump, arginfo_com_message_pump)
+       ZEND_FE(com_load_typelib, arginfo_com_load_typelib)
+       ZEND_FE_END
+};
index 31e01061e3f7003930f76a4958543c9232101cb5..cd1f59f5550057e179e99450582c89037f1d2773 100644 (file)
@@ -387,38 +387,6 @@ static zend_function *com_method_get(zend_object **object_ptr, zend_string *name
        return NULL;
 }
 
-static zend_function *com_constructor_get(zend_object *object)
-{
-       php_com_dotnet_object *obj = (php_com_dotnet_object *) object;
-       static zend_internal_function c, d, v;
-
-#define POPULATE_CTOR(f, fn)   \
-       f.type = ZEND_INTERNAL_FUNCTION; \
-       f.function_name = obj->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,
index bc4c7950e04a0aee6e835697c1d8c0cb29ef7b50..72cf16b9e3b5d620dbc827fd6ccec80e7362f04f 100644 (file)
@@ -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;
        }
index 3ee7ec4eba0225832c3947fc050731e28f626fc7..8521277083f944441e1497c090bf3a5aab19de43 100644 (file)
@@ -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);
 
index 47de9b10c7f361c9f239b0dc650824b3cc304589..235fd3e33e16b8f4ab64689ac6d020896aa3bd13 100644 (file)
@@ -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