Module: wine Branch: master Commit: 1c194f3b21967024b10de5b2f6b72947d687731b URL: https://source.winehq.org/git/wine.git/?a=commit;h=1c194f3b21967024b10de5b2f...
Author: Jacek Caban jacek@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@codeweavers.com Signed-off-by: Alexandre Julliard julliard@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);