Gabriel Ivăncescu : mshtml: Ignore named and extra arguments when invoking builtin functions.

Alexandre Julliard julliard at winehq.org
Tue Dec 7 15:58:45 CST 2021


Module: wine
Branch: master
Commit: 0e7d1a601cdff94f13dde8099ba532062fcca725
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=0e7d1a601cdff94f13dde8099ba532062fcca725

Author: Gabriel Ivăncescu <gabrielopcode at gmail.com>
Date:   Tue Dec  7 21:10:02 2021 +0200

mshtml: Ignore named and extra arguments when invoking builtin functions.

Native just ignores the named and extra arguments completely.

Signed-off-by: Gabriel Ivăncescu <gabrielopcode at gmail.com>
Signed-off-by: Jacek Caban <jacek at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/mshtml/dispex.c              |  14 ++--
 dlls/mshtml/tests/documentmode.js |   2 +-
 dlls/mshtml/tests/script.c        | 136 ++++++++++++++++++++++++++++++++++++++
 3 files changed, 144 insertions(+), 8 deletions(-)

diff --git a/dlls/mshtml/dispex.c b/dlls/mshtml/dispex.c
index 9f56a561e0d..b7bc75104ad 100644
--- a/dlls/mshtml/dispex.c
+++ b/dlls/mshtml/dispex.c
@@ -738,12 +738,17 @@ static HRESULT dispex_value(DispatchEx *This, LCID lcid, WORD flags, DISPPARAMS
 static HRESULT typeinfo_invoke(DispatchEx *This, func_info_t *func, WORD flags, DISPPARAMS *dp, VARIANT *res,
         EXCEPINFO *ei)
 {
-    DISPPARAMS params = {dp->rgvarg+dp->cNamedArgs, NULL, dp->cArgs-dp->cNamedArgs, 0};
+    DISPPARAMS params = {dp->rgvarg, NULL, dp->cArgs, 0};
     ITypeInfo *ti;
     IUnknown *unk;
     UINT argerr=0;
     HRESULT hres;
 
+    if(params.cArgs > func->argc) {
+        params.rgvarg += params.cArgs - func->argc;
+        params.cArgs = func->argc;
+    }
+
     hres = get_typeinfo(func->tid, &ti);
     if(FAILED(hres)) {
         ERR("Could not get type info: %08x\n", hres);
@@ -1170,12 +1175,7 @@ static HRESULT invoke_builtin_function(DispatchEx *This, func_info_t *func, DISP
     IUnknown *iface;
     HRESULT hres;
 
-    if(dp->cNamedArgs) {
-        FIXME("Named arguments not supported\n");
-        return E_NOTIMPL;
-    }
-
-    if(dp->cArgs > func->argc || dp->cArgs + func->default_value_cnt < func->argc) {
+    if(dp->cArgs + func->default_value_cnt < func->argc) {
         FIXME("Invalid argument count (expected %u, got %u)\n", func->argc, dp->cArgs);
         return E_INVALIDARG;
     }
diff --git a/dlls/mshtml/tests/documentmode.js b/dlls/mshtml/tests/documentmode.js
index 6555e8ba489..af057f2cb3d 100644
--- a/dlls/mshtml/tests/documentmode.js
+++ b/dlls/mshtml/tests/documentmode.js
@@ -1113,7 +1113,7 @@ sync_test("elem_attr", function() {
     r = elem.getAttribute("htmlFor");
     ok(r === "for3", "htmlFor attr = " + r);
 
-    elem.setAttribute("testattr", "test");
+    elem.setAttribute("testattr", "test", 0, "extra arg", 0xdeadbeef);
     test_exposed("class", v < 8);
     test_exposed("className", true);
     test_exposed("for", v < 9);
diff --git a/dlls/mshtml/tests/script.c b/dlls/mshtml/tests/script.c
index a57468afc65..e95cea4307c 100644
--- a/dlls/mshtml/tests/script.c
+++ b/dlls/mshtml/tests/script.c
@@ -2170,6 +2170,141 @@ static void test_default_arg_conv(IHTMLWindow2 *window)
     IDispatchEx_Release(dispex);
 }
 
+static void test_named_args(IHTMLWindow2 *window)
+{
+    DISPID named_args[] = { 0, 2, 1, 1337, 0xdeadbeef, DISPID_THIS };
+    IHTMLDocument2 *doc;
+    IDispatchEx *dispex;
+    IHTMLElement *elem;
+    VARIANT args[4];
+    DISPPARAMS dp;
+    HRESULT hres;
+    VARIANT var;
+    DISPID id;
+    BSTR bstr;
+
+    hres = IHTMLWindow2_get_document(window, &doc);
+    ok(hres == S_OK, "get_document failed: %08x\n", hres);
+
+    bstr = SysAllocString(L"div");
+    hres = IHTMLDocument2_createElement(doc, bstr, &elem);
+    IHTMLDocument2_Release(doc);
+    SysFreeString(bstr);
+    ok(hres == S_OK, "createElement failed: %08x\n", hres);
+
+    hres = IHTMLElement_QueryInterface(elem, &IID_IDispatchEx, (void**)&dispex);
+    ok(hres == S_OK, "Could not get IDispatchEx iface: %08x\n", hres);
+
+    bstr = SysAllocString(L"setAttribute");
+    hres = IDispatchEx_GetDispID(dispex, bstr, fdexNameCaseSensitive, &id);
+    SysFreeString(bstr);
+
+    dp.cArgs = 2;
+    dp.cNamedArgs = 3;
+    dp.rgvarg = args;
+    dp.rgdispidNamedArgs = named_args;
+    V_VT(&args[0]) = VT_BSTR;
+    V_BSTR(&args[0]) = SysAllocString(L"testattr");
+    V_VT(&args[1]) = VT_I4;
+    V_I4(&args[1]) = 0;
+    hres = IDispatchEx_InvokeEx(dispex, id, LOCALE_NEUTRAL, DISPATCH_METHOD, &dp, NULL, NULL, NULL);
+    ok(hres == S_OK, "InvokeEx returned: %08x\n", hres);
+
+    hres = IHTMLElement_getAttribute(elem, V_BSTR(&args[0]), 0, &var);
+    ok(hres == S_OK, "getAttribute failed: %08x\n", hres);
+    ok(V_VT(&var) == VT_NULL, "V_VT(var)=%d\n", V_VT(&var));
+
+    bstr = SysAllocString(L"0");
+    hres = IHTMLElement_getAttribute(elem, bstr, 0, &var);
+    SysFreeString(bstr);
+    ok(hres == S_OK, "getAttribute failed: %08x\n", hres);
+    ok(V_VT(&var) == VT_BSTR, "V_VT(var)=%d\n", V_VT(&var));
+    ok(!lstrcmpW(V_BSTR(&var), L"testattr"), "V_BSTR(&var) = %s\n", debugstr_w(V_BSTR(&var)));
+    VariantClear(&var);
+
+    dp.cArgs = 3;
+    V_VT(&args[2]) = VT_BSTR;
+    V_BSTR(&args[2]) = SysAllocString(L"testval");
+    hres = IDispatchEx_InvokeEx(dispex, id, LOCALE_NEUTRAL, DISPATCH_METHOD, &dp, NULL, NULL, NULL);
+    VariantClear(&args[2]);
+    ok(hres == DISP_E_TYPEMISMATCH, "InvokeEx returned: %08x\n", hres);
+
+    V_VT(&args[2]) = VT_I4;
+    V_I4(&args[2]) = 0;
+    hres = IDispatchEx_InvokeEx(dispex, id, LOCALE_NEUTRAL, DISPATCH_METHOD, &dp, NULL, NULL, NULL);
+    ok(hres == DISP_E_TYPEMISMATCH, "InvokeEx returned: %08x\n", hres);
+
+    args[2] = args[0];
+    V_VT(&args[1]) = VT_BSTR;
+    V_BSTR(&args[1]) = SysAllocString(L"testval");
+    V_VT(&args[0]) = VT_I4;
+    V_I4(&args[0]) = 0;
+    hres = IDispatchEx_InvokeEx(dispex, id, LOCALE_NEUTRAL, DISPATCH_METHOD, &dp, NULL, NULL, NULL);
+    ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
+    VariantClear(&args[1]);
+
+    hres = IHTMLElement_getAttribute(elem, V_BSTR(&args[2]), 0, &var);
+    ok(hres == S_OK, "getAttribute failed: %08x\n", hres);
+    ok(V_VT(&var) == VT_BSTR, "V_VT(var)=%d\n", V_VT(&var));
+    ok(!lstrcmpW(V_BSTR(&var), L"testval"), "V_BSTR(&var) = %s\n", debugstr_w(V_BSTR(&var)));
+    VariantClear(&var);
+
+    dp.cArgs = 2;
+    dp.cNamedArgs = 1;
+    args[1] = args[2];
+    V_VT(&args[0]) = VT_BSTR;
+    V_BSTR(&args[0]) = SysAllocString(L"newValue");
+    hres = IDispatchEx_InvokeEx(dispex, id, LOCALE_NEUTRAL, DISPATCH_METHOD, &dp, NULL, NULL, NULL);
+    ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
+    VariantClear(&args[0]);
+
+    hres = IHTMLElement_getAttribute(elem, V_BSTR(&args[1]), 0, &var);
+    ok(hres == S_OK, "getAttribute failed: %08x\n", hres);
+    ok(V_VT(&var) == VT_BSTR, "V_VT(var)=%d\n", V_VT(&var));
+    ok(!lstrcmpW(V_BSTR(&var), L"newValue"), "V_BSTR(&var) = %s\n", debugstr_w(V_BSTR(&var)));
+    VariantClear(&var);
+
+    dp.cArgs = 4;
+    dp.cNamedArgs = ARRAY_SIZE(named_args);
+    args[3] = args[1];
+    V_VT(&args[2]) = VT_BSTR;
+    V_BSTR(&args[2]) = SysAllocString(L"foobar");
+    V_VT(&args[1]) = VT_I4;
+    V_I4(&args[1]) = 1;
+    V_VT(&args[0]) = VT_BSTR;
+    V_BSTR(&args[0]) = SysAllocString(L"extra");
+    hres = IDispatchEx_InvokeEx(dispex, id, LOCALE_NEUTRAL, DISPATCH_METHOD, &dp, NULL, NULL, NULL);
+    ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
+    VariantClear(&args[2]);
+    VariantClear(&args[0]);
+
+    hres = IHTMLElement_getAttribute(elem, V_BSTR(&args[3]), 0, &var);
+    ok(hres == S_OK, "getAttribute failed: %08x\n", hres);
+    ok(V_VT(&var) == VT_BSTR, "V_VT(var)=%d\n", V_VT(&var));
+    ok(!lstrcmpW(V_BSTR(&var), L"foobar"), "V_BSTR(&var) = %s\n", debugstr_w(V_BSTR(&var)));
+    VariantClear(&var);
+
+    dp.cNamedArgs = 1;
+    named_args[0] = DISPID_THIS;
+    V_VT(&args[0]) = VT_DISPATCH;
+    V_DISPATCH(&args[0]) = (IDispatch*)&funcDisp;
+    V_VT(&args[2]) = VT_BSTR;
+    V_BSTR(&args[2]) = SysAllocString(L"withThis");
+    hres = IDispatchEx_InvokeEx(dispex, id, LOCALE_NEUTRAL, DISPATCH_METHOD, &dp, NULL, NULL, NULL);
+    ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
+    VariantClear(&args[2]);
+
+    hres = IHTMLElement_getAttribute(elem, V_BSTR(&args[3]), 0, &var);
+    ok(hres == S_OK, "getAttribute failed: %08x\n", hres);
+    ok(V_VT(&var) == VT_BSTR, "V_VT(var)=%d\n", V_VT(&var));
+    ok(!lstrcmpW(V_BSTR(&var), L"withThis"), "V_BSTR(&var) = %s\n", debugstr_w(V_BSTR(&var)));
+    VariantClear(&args[3]);
+    VariantClear(&var);
+
+    IHTMLElement_Release(elem);
+    IDispatchEx_Release(dispex);
+}
+
 static void test_ui(void)
 {
     IActiveScriptSiteUIControl *ui_control;
@@ -2381,6 +2516,7 @@ static void test_script_run(void)
 
     test_arg_conv(window);
     test_default_arg_conv(window);
+    test_named_args(window);
     IHTMLWindow2_Release(window);
 
     tmp = SysAllocString(L"test");




More information about the wine-cvs mailing list