Jacek Caban : vbscript: Fix VT_UNKNOWN handling in set statements.

Alexandre Julliard julliard at winehq.org
Mon Jan 27 15:00:23 CST 2020


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

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Mon Jan 27 14:25:39 2020 +0100

vbscript: Fix VT_UNKNOWN handling in set statements.

Signed-off-by: Jacek Caban <jacek at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/vbscript/interp.c       | 12 ++++++------
 dlls/vbscript/tests/lang.vbs |  6 ++++++
 dlls/vbscript/tests/run.c    | 39 ++++++++++++++++++++++++++++++++++++++-
 3 files changed, 50 insertions(+), 7 deletions(-)

diff --git a/dlls/vbscript/interp.c b/dlls/vbscript/interp.c
index 9c07535517..333fe0f6bd 100644
--- a/dlls/vbscript/interp.c
+++ b/dlls/vbscript/interp.c
@@ -458,22 +458,22 @@ static HRESULT stack_assume_disp(exec_ctx_t *ctx, unsigned n, IDispatch **disp)
 {
     VARIANT *v = stack_top(ctx, n), *ref;
 
-    if(V_VT(v) != VT_DISPATCH) {
+    if(V_VT(v) != VT_DISPATCH && (disp || V_VT(v) != VT_UNKNOWN)) {
         if(V_VT(v) != (VT_VARIANT|VT_BYREF)) {
             FIXME("not supported type: %s\n", debugstr_variant(v));
             return E_FAIL;
         }
 
         ref = V_VARIANTREF(v);
-        if(V_VT(ref) != VT_DISPATCH) {
+        if(V_VT(ref) != VT_DISPATCH && (disp || V_VT(ref) != VT_UNKNOWN)) {
             FIXME("not disp %s\n", debugstr_variant(ref));
             return E_FAIL;
         }
 
-        V_VT(v) = VT_DISPATCH;
-        V_DISPATCH(v) = V_DISPATCH(ref);
-        if(V_DISPATCH(v))
-            IDispatch_AddRef(V_DISPATCH(v));
+        V_VT(v) = V_VT(ref);
+        V_UNKNOWN(v) = V_UNKNOWN(ref);
+        if(V_UNKNOWN(v))
+            IUnknown_AddRef(V_UNKNOWN(v));
     }
 
     if(disp)
diff --git a/dlls/vbscript/tests/lang.vbs b/dlls/vbscript/tests/lang.vbs
index 8007823394..f527b3411b 100644
--- a/dlls/vbscript/tests/lang.vbs
+++ b/dlls/vbscript/tests/lang.vbs
@@ -1197,6 +1197,12 @@ Call ok(obj.Test1 = 6, "obj.Test1 is not 6")
 obj.AddToTest1(5)
 Call ok(obj.Test1 = 11, "obj.Test1 is not 11")
 
+set obj = unkObj
+set x = obj
+call ok(getVT(obj) = "VT_UNKNOWN*", "getVT(obj) = " & getVT(obj))
+call ok(getVT(x) = "VT_UNKNOWN*", "getVT(x) = " & getVT(x))
+call ok(getVT(unkObj) = "VT_UNKNOWN", "getVT(unkObj) = " & getVT(unkObj))
+
 ' Array tests
 
 Call ok(getVT(arr) = "VT_EMPTY*", "getVT(arr) = " & getVT(arr))
diff --git a/dlls/vbscript/tests/run.c b/dlls/vbscript/tests/run.c
index 015f2b816a..8acf220f9f 100644
--- a/dlls/vbscript/tests/run.c
+++ b/dlls/vbscript/tests/run.c
@@ -144,6 +144,7 @@ DEFINE_EXPECT(OnLeaveScript);
 #define DISPID_GLOBAL_TESTERROROBJECT 1023
 #define DISPID_GLOBAL_THROWWITHDESC   1024
 #define DISPID_GLOBAL_PROPARGSET      1025
+#define DISPID_GLOBAL_UNKOBJ          1026
 
 #define DISPID_TESTOBJ_PROPGET      2000
 #define DISPID_TESTOBJ_PROPPUT      2001
@@ -214,6 +215,8 @@ static const char *vt2a(VARIANT *v)
         return "VT_BSTR";
     case VT_DISPATCH:
         return "VT_DISPATCH";
+    case VT_UNKNOWN:
+        return "VT_UNKNOWN";
     case VT_BOOL:
         return "VT_BOOL";
     case VT_ARRAY|VT_VARIANT:
@@ -595,6 +598,35 @@ static void _test_grfdex(unsigned line, DWORD grfdex, DWORD expect)
 
 static IDispatchEx enumDisp;
 
+static HRESULT WINAPI unkObj_QueryInterface(IUnknown *iface, REFIID riid, void **ppv)
+{
+    if(IsEqualGUID(riid, &IID_IUnknown)) {
+        *ppv = iface;
+        return S_OK;
+    }
+
+    *ppv = NULL;
+    return E_NOINTERFACE;
+}
+
+static ULONG WINAPI unkObj_AddRef(IUnknown *iface)
+{
+    return 2;
+}
+
+static ULONG WINAPI unkObj_Release(IUnknown *iface)
+{
+    return 1;
+}
+
+static const IUnknownVtbl unkObjVtbl = {
+    unkObj_QueryInterface,
+    unkObj_AddRef,
+    unkObj_Release
+};
+
+static IUnknown unkObj = { &unkObjVtbl };
+
 static HRESULT WINAPI EnumVARIANT_QueryInterface(IEnumVARIANT *iface, REFIID riid, void **ppv)
 {
     if(IsEqualGUID(riid, &IID_IUnknown) || IsEqualGUID(riid, &IID_IEnumVARIANT)) {
@@ -1138,7 +1170,8 @@ static HRESULT WINAPI Global_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD
         { L"throwInt",        DISPID_GLOBAL_THROWINT },
         { L"testOptionalArg", DISPID_GLOBAL_TESTOPTIONALARG },
         { L"testErrorObject", DISPID_GLOBAL_TESTERROROBJECT },
-        { L"throwWithDesc",   DISPID_GLOBAL_THROWWITHDESC }
+        { L"throwWithDesc",   DISPID_GLOBAL_THROWWITHDESC },
+        { L"unkObj",          DISPID_GLOBAL_UNKOBJ }
     };
 
     test_grfdex(grfdex, fdexNameCaseInsensitive);
@@ -1657,6 +1690,10 @@ static HRESULT WINAPI Global_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid,
         ok(hres == S_OK, "Invoke failed: %08x\n", hres);
         return S_OK;
     }
+    case DISPID_GLOBAL_UNKOBJ:
+        V_VT(pvarRes) = VT_UNKNOWN;
+        V_UNKNOWN(pvarRes) = &unkObj;
+        return S_OK;
     }
 
     ok(0, "unexpected call %d\n", id);




More information about the wine-cvs mailing list