[PATCH v2 2/2] vbscript: Don't create script dispatches for items with the SCRIPTITEM_GLOBALMEMBERS flag.

Gabriel Ivăncescu gabrielopcode at gmail.com
Wed Feb 26 06:38:02 CST 2020


Signed-off-by: Gabriel Ivăncescu <gabrielopcode at gmail.com>
---

This may seem weird, but it's needed to pass all of the tests. First, the
items with this flag must not be linked to the vbscode at all. Because of
that, items with GLOBALMEMBERS do *not* follow the CODEONLY rules where
the script dispatch is picked if the flag is set; instead, they always pick
the host_global, unless it's not available, then the ctx->script_obj. The
current code does take care of this as long as the vbscode has no item,
so it doesn't need any changes.

This also neatly solves the issue when restarting the script.

 dlls/vbscript/compile.c        |  1 +
 dlls/vbscript/tests/vbscript.c | 97 ++++++++++++++++++++++++++++++++--
 dlls/vbscript/vbscript.c       |  7 +--
 3 files changed, 98 insertions(+), 7 deletions(-)

diff --git a/dlls/vbscript/compile.c b/dlls/vbscript/compile.c
index 8ce4692..cc78daa 100644
--- a/dlls/vbscript/compile.c
+++ b/dlls/vbscript/compile.c
@@ -1947,6 +1947,7 @@ HRESULT compile_script(script_ctx_t *script, const WCHAR *src, const WCHAR *item
             WARN("Unknown context %s\n", debugstr_w(item_name));
             return E_INVALIDARG;
         }
+        if(!item->script_obj) item = NULL;
     }
 
     memset(&ctx, 0, sizeof(ctx));
diff --git a/dlls/vbscript/tests/vbscript.c b/dlls/vbscript/tests/vbscript.c
index 8536ee1..8653463 100644
--- a/dlls/vbscript/tests/vbscript.c
+++ b/dlls/vbscript/tests/vbscript.c
@@ -98,6 +98,7 @@ DEFINE_EXPECT(OnLeaveScript);
 DEFINE_EXPECT(OnScriptError);
 DEFINE_EXPECT(GetIDsOfNames);
 DEFINE_EXPECT(GetItemInfo_global);
+DEFINE_EXPECT(GetItemInfo_global_code);
 DEFINE_EXPECT(GetItemInfo_visible);
 DEFINE_EXPECT(GetItemInfo_visible_code);
 DEFINE_EXPECT(testCall);
@@ -140,6 +141,16 @@ static HRESULT WINAPI Dispatch_QueryInterface(IDispatch *iface, REFIID riid, voi
     return E_NOINTERFACE;
 }
 
+static ULONG WINAPI Dispatch_AddRef(IDispatch *iface)
+{
+    return 2;
+}
+
+static ULONG WINAPI Dispatch_Release(IDispatch *iface)
+{
+    return 1;
+}
+
 static ULONG global_named_item_ref, visible_named_item_ref, visible_code_named_item_ref;
 
 static ULONG WINAPI global_AddRef(IDispatch *iface)
@@ -207,6 +218,18 @@ static HRESULT WINAPI Dispatch_Invoke(IDispatch *iface, DISPID id, REFIID riid,
     return S_OK;
 }
 
+static const IDispatchVtbl dispatch_vtbl = {
+    Dispatch_QueryInterface,
+    Dispatch_AddRef,
+    Dispatch_Release,
+    Dispatch_GetTypeInfoCount,
+    Dispatch_GetTypeInfo,
+    Dispatch_GetIDsOfNames,
+    Dispatch_Invoke
+};
+
+static IDispatch dispatch_object = { &dispatch_vtbl };
+
 static const IDispatchVtbl global_named_item_vtbl = {
     Dispatch_QueryInterface,
     global_AddRef,
@@ -284,6 +307,12 @@ static HRESULT WINAPI ActiveScriptSite_GetItemInfo(IActiveScriptSite *iface, LPC
         *item_unk = (IUnknown*)&global_named_item;
         return S_OK;
     }
+    if(!wcscmp(name, L"globalCodeItem")) {
+        CHECK_EXPECT(GetItemInfo_global_code);
+        IDispatch_AddRef(&dispatch_object);
+        *item_unk = (IUnknown*)&dispatch_object;
+        return S_OK;
+    }
     if(!wcscmp(name, L"visibleItem")) {
         CHECK_EXPECT(GetItemInfo_visible);
         IDispatch_AddRef(&visible_named_item);
@@ -1739,6 +1768,8 @@ static void test_named_items(void)
 {
     static const WCHAR *global_idents[] =
     {
+        L"global_me",
+        L"globalCode_me",
         L"testSub_global",
         L"testExplicitVar_global",
         L"testVar_global"
@@ -1812,7 +1843,18 @@ static void test_named_items(void)
     hres = IActiveScript_GetScriptDispatch(script, L"noContext", &disp);
     ok(hres == E_INVALIDARG, "GetScriptDispatch returned: %08x\n", hres);
 
+    SET_EXPECT(GetItemInfo_global_code);
+    hres = IActiveScript_AddNamedItem(script, L"globalCodeItem", SCRIPTITEM_GLOBALMEMBERS | SCRIPTITEM_CODEONLY);
+    ok(hres == S_OK, "AddNamedItem failed: %08x\n", hres);
+    CHECK_CALLED(GetItemInfo_global_code);
+
     script_disp = get_script_dispatch(script, NULL);
+    script_disp2 = get_script_dispatch(script, L"globalItem");
+    ok(script_disp == script_disp2, "get_script_dispatch returned different dispatch objects.\n");
+    IDispatchEx_Release(script_disp2);
+    script_disp2 = get_script_dispatch(script, L"globalCodeItem");
+    ok(script_disp == script_disp2, "get_script_dispatch returned different dispatch objects.\n");
+    IDispatchEx_Release(script_disp2);
     script_disp2 = get_script_dispatch(script, L"codeONLYitem");
     ok(script_disp != script_disp2, "get_script_dispatch returned same dispatch objects.\n");
 
@@ -1889,6 +1931,8 @@ static void test_named_items(void)
     SET_EXPECT(GetIDsOfNames);
     SET_EXPECT(OnLeaveScript);
     hres = IActiveScriptParse_ParseScriptText(parse, L""
+        "dim global_me\nglobal_me = 0\n"
+        "dim globalCode_me\nglobalCode_me = 0\n"
         "sub testSub_global\nend sub\n"
         "dim testExplicitVar_global\ntestExplicitVar_global = 10\n"
         "testVar_global = 10\n"
@@ -1919,6 +1963,18 @@ static void test_named_items(void)
     CHECK_CALLED(OnEnterScript);
     CHECK_CALLED(GetIDsOfNames);
     CHECK_CALLED(OnLeaveScript);
+    SET_EXPECT(OnEnterScript);
+    SET_EXPECT(OnLeaveScript);
+    hres = IActiveScriptParse_ParseScriptText(parse, L"set global_me = me\n", L"globalItem", NULL, NULL, 0, 0, SCRIPTTEXT_ISPERSISTENT, NULL, NULL);
+    ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres);
+    CHECK_CALLED(OnEnterScript);
+    CHECK_CALLED(OnLeaveScript);
+    SET_EXPECT(OnEnterScript);
+    SET_EXPECT(OnLeaveScript);
+    hres = IActiveScriptParse_ParseScriptText(parse, L"set globalCode_me = me\n", L"globalCodeItem", NULL, NULL, 0, 0, SCRIPTTEXT_ISPERSISTENT, NULL, NULL);
+    ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres);
+    CHECK_CALLED(OnEnterScript);
+    CHECK_CALLED(OnLeaveScript);
 
     for (i = 0; i < ARRAY_SIZE(global_idents); i++)
     {
@@ -2018,6 +2074,15 @@ static void test_named_items(void)
     VariantClear(&var);
     CHECK_CALLED(OnEnterScript);
     CHECK_CALLED(OnLeaveScript);
+    SET_EXPECT(OnEnterScript);
+    SET_EXPECT(OnLeaveScript);
+    hres = IActiveScriptParse_ParseScriptText(parse, L"globalCode_me", NULL, NULL, NULL, 0, 0, SCRIPTTEXT_ISEXPRESSION, &var, NULL);
+    ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres);
+    ok(V_VT(&var) == VT_DISPATCH && V_DISPATCH(&var) == &global_named_item,
+        "Unexpected 'me': V_VT = %d, V_DISPATCH = %p\n", V_VT(&var), V_DISPATCH(&var));
+    VariantClear(&var);
+    CHECK_CALLED(OnEnterScript);
+    CHECK_CALLED(OnLeaveScript);
 
     IDispatchEx_Release(script_disp2);
     IDispatchEx_Release(script_disp);
@@ -2050,13 +2115,13 @@ static void test_named_items(void)
     ok(hres == S_OK, "AddNamedItem failed: %08x\n", hres);
 
     SET_EXPECT(OnStateChange_CONNECTED);
-    SET_EXPECT_MULTI(OnEnterScript, 2);
-    SET_EXPECT_MULTI(OnLeaveScript, 2);
+    SET_EXPECT_MULTI(OnEnterScript, 4);
+    SET_EXPECT_MULTI(OnLeaveScript, 4);
     hres = IActiveScript_SetScriptState(script, SCRIPTSTATE_CONNECTED);
     ok(hres == S_OK, "SetScriptState(SCRIPTSTATE_CONNECTED) failed: %08x\n", hres);
     CHECK_CALLED(OnStateChange_CONNECTED);
-    CHECK_CALLED_MULTI(OnEnterScript, 2);
-    CHECK_CALLED_MULTI(OnLeaveScript, 2);
+    CHECK_CALLED_MULTI(OnEnterScript, 4);
+    CHECK_CALLED_MULTI(OnLeaveScript, 4);
     test_state(script, SCRIPTSTATE_CONNECTED);
 
     script_disp = get_script_dispatch(script, NULL);
@@ -2078,6 +2143,30 @@ static void test_named_items(void)
         ok(id == -1, "[%s] id = %d, expected -1\n", wine_dbgstr_w(context_idents[i]), id);
         SysFreeString(bstr);
     }
+    SET_EXPECT(OnEnterScript);
+    SET_EXPECT(OnLeaveScript);
+    hres = IActiveScriptParse_ParseScriptText(parse, L"global_me", NULL, NULL, NULL, 0, 0, SCRIPTTEXT_ISEXPRESSION, &var, NULL);
+    ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres);
+    ok(V_VT(&var) == VT_DISPATCH && V_DISPATCH(&var) == (IDispatch*)script_disp,
+        "Unexpected 'me': V_VT = %d, V_DISPATCH = %p\n", V_VT(&var), V_DISPATCH(&var));
+    VariantClear(&var);
+    CHECK_CALLED(OnEnterScript);
+    CHECK_CALLED(OnLeaveScript);
+    SET_EXPECT(OnEnterScript);
+    SET_EXPECT(OnLeaveScript);
+    hres = IActiveScriptParse_ParseScriptText(parse, L"globalCode_me", NULL, NULL, NULL, 0, 0, SCRIPTTEXT_ISEXPRESSION, &var, NULL);
+    ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres);
+    ok(V_VT(&var) == VT_DISPATCH && V_DISPATCH(&var) == (IDispatch*)script_disp,
+        "Unexpected 'me': V_VT = %d, V_DISPATCH = %p\n", V_VT(&var), V_DISPATCH(&var));
+    VariantClear(&var);
+    CHECK_CALLED(OnEnterScript);
+    CHECK_CALLED(OnLeaveScript);
+    SET_EXPECT(OnEnterScript);
+    SET_EXPECT(OnLeaveScript);
+    hres = IActiveScriptParse_ParseScriptText(parse, L"global_me = 0\nglobalCode_me = 0\n", NULL, NULL, NULL, 0, 0, 0, NULL, NULL);
+    ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres);
+    CHECK_CALLED(OnEnterScript);
+    CHECK_CALLED(OnLeaveScript);
     IDispatchEx_Release(script_disp);
 
     script_disp = get_script_dispatch(script, L"codeOnlyItem");
diff --git a/dlls/vbscript/vbscript.c b/dlls/vbscript/vbscript.c
index 1df6a29..d70ca1a 100644
--- a/dlls/vbscript/vbscript.c
+++ b/dlls/vbscript/vbscript.c
@@ -206,6 +206,8 @@ named_item_t *lookup_named_item(script_ctx_t *ctx, const WCHAR *name, unsigned f
     LIST_FOR_EACH_ENTRY(item, &ctx->named_items, named_item_t, entry) {
         if((item->flags & flags) == flags && !wcsicmp(item->name, name)) {
             if(!item->script_obj) {
+                if(item->flags & SCRIPTITEM_GLOBALMEMBERS)
+                    return item;
                 hres = create_script_disp(ctx, &item->script_obj);
                 if(FAILED(hres)) return NULL;
             }
@@ -728,13 +730,12 @@ static HRESULT WINAPI VBScript_GetScriptDispatch(IActiveScript *iface, LPCOLESTR
         return E_UNEXPECTED;
     }
 
+    script_obj = This->ctx->script_obj;
     if(pstrItemName) {
         named_item_t *item = lookup_named_item(This->ctx, pstrItemName, 0);
         if(!item) return E_INVALIDARG;
-        script_obj = item->script_obj;
+        if(item->script_obj) script_obj = item->script_obj;
     }
-    else
-        script_obj = This->ctx->script_obj;
 
     *ppdisp = (IDispatch*)&script_obj->IDispatchEx_iface;
     IDispatch_AddRef(*ppdisp);
-- 
2.21.0




More information about the wine-devel mailing list