Gabriel Ivăncescu : vbscript: Don't create script dispatches for items with the SCRIPTITEM_GLOBALMEMBERS flag.

Alexandre Julliard julliard at winehq.org
Fri Feb 28 13:54:41 CST 2020


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

Author: Gabriel Ivăncescu <gabrielopcode at gmail.com>
Date:   Fri Feb 28 17:26:33 2020 +0100

vbscript: Don't create script dispatches for items with the SCRIPTITEM_GLOBALMEMBERS flag.

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/vbscript/compile.c        |  1 +
 dlls/vbscript/tests/vbscript.c | 97 ++++++++++++++++++++++++++++++++++++++++--
 dlls/vbscript/vbscript.c       |  7 ++-
 3 files changed, 97 insertions(+), 8 deletions(-)

diff --git a/dlls/vbscript/compile.c b/dlls/vbscript/compile.c
index 8ce469265e..cc78daab1a 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 8536ee1776..86534632f0 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 ea80911f10..86902d84ea 100644
--- a/dlls/vbscript/vbscript.c
+++ b/dlls/vbscript/vbscript.c
@@ -205,7 +205,7 @@ 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->script_obj && !(item->flags & SCRIPTITEM_GLOBALMEMBERS)) {
                 hres = create_script_disp(ctx, &item->script_obj);
                 if(FAILED(hres)) return NULL;
             }
@@ -718,13 +718,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);




More information about the wine-cvs mailing list