vbscript: Fix VT_UNKNOWN handling in set statements.

Signed-off-by: Jacek Caban <jacek@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Jacek Caban 2020-01-27 14:25:39 +01:00 committed by Alexandre Julliard
parent cd1918948f
commit 1c194f3b21
3 changed files with 50 additions and 7 deletions

View File

@ -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)

View File

@ -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))

View File

@ -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);