Module: wine Branch: master Commit: d8a03ae6308e1dacaa382a0bb6404c980ed565d7 URL: https://gitlab.winehq.org/wine/wine/-/commit/d8a03ae6308e1dacaa382a0bb6404c9...
Author: Jacek Caban jacek@codeweavers.com Date: Wed Sep 21 23:17:02 2022 +0200
vbscript: Fix handling missing description in EXCEPINFO.
Based on patch by Kevin Puetz.
---
dlls/vbscript/interp.c | 13 +++-- dlls/vbscript/tests/run.c | 126 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 135 insertions(+), 4 deletions(-)
diff --git a/dlls/vbscript/interp.c b/dlls/vbscript/interp.c index c43b5383dee..1d7482b5013 100644 --- a/dlls/vbscript/interp.c +++ b/dlls/vbscript/interp.c @@ -2490,14 +2490,19 @@ HRESULT exec_script(script_ctx_t *ctx, BOOL extern_caller, function_t *func, vbd if(FAILED(hres)) { if(hres != SCRIPT_E_RECORDED) { clear_ei(&ctx->ei); - - ctx->ei.scode = hres = map_hres(hres); - ctx->ei.bstrSource = get_vbscript_string(VBS_RUNTIME_ERROR); - ctx->ei.bstrDescription = get_vbscript_error_string(hres); + hres = map_hres(hres); + }else if(!ctx->ei.bstrDescription) { + hres = map_hres(ctx->ei.scode); }else { hres = ctx->ei.scode; }
+ ctx->ei.scode = hres; + if(!ctx->ei.bstrSource) + ctx->ei.bstrSource = get_vbscript_string(VBS_RUNTIME_ERROR); + if(!ctx->ei.bstrDescription) + ctx->ei.bstrDescription = get_vbscript_error_string(hres); + if(exec.resume_next) { unsigned stack_off;
diff --git a/dlls/vbscript/tests/run.c b/dlls/vbscript/tests/run.c index 556772e1f37..8d7c15ba70b 100644 --- a/dlls/vbscript/tests/run.c +++ b/dlls/vbscript/tests/run.c @@ -145,6 +145,7 @@ DEFINE_EXPECT(OnLeaveScript); #define DISPID_GLOBAL_THROWWITHDESC 1024 #define DISPID_GLOBAL_PROPARGSET 1025 #define DISPID_GLOBAL_UNKOBJ 1026 +#define DISPID_GLOBAL_THROWEXCEPTION 1027
#define DISPID_TESTOBJ_PROPGET 2000 #define DISPID_TESTOBJ_PROPPUT 2001 @@ -1157,6 +1158,7 @@ static HRESULT WINAPI Global_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD { L"counter", DISPID_GLOBAL_COUNTER }, { L"doubleAsString", DISPID_GLOBAL_DOUBLEASSTRING }, { L"testArray", DISPID_GLOBAL_TESTARRAY }, + { L"throwException", DISPID_GLOBAL_THROWEXCEPTION }, { L"throwInt", DISPID_GLOBAL_THROWINT }, { L"testOptionalArg", DISPID_GLOBAL_TESTOPTIONALARG }, { L"testErrorObject", DISPID_GLOBAL_TESTERROROBJECT }, @@ -1540,6 +1542,54 @@ static HRESULT WINAPI Global_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid,
return hres;
+ case DISPID_GLOBAL_THROWEXCEPTION: { + VARIANT *v = pdp->rgvarg + pdp->cArgs - 1; + + ok((wFlags & ~INVOKE_PROPERTYGET) == INVOKE_FUNC, "wFlags = %x\n", wFlags); + ok(pdp != NULL, "pdp == NULL\n"); + ok(pdp->rgvarg != NULL, "rgvarg == NULL\n"); + ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n"); + ok(pdp->cArgs >= 1, "cArgs = %d\n", pdp->cArgs); + ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs); + ok(pei != NULL, "pei == NULL\n"); + + if(pvarRes) { + ok(V_VT(pvarRes) == VT_EMPTY, "V_VT(pvarRes) = %d\n", V_VT(pvarRes)); + V_VT(pvarRes) = VT_BOOL; + V_BOOL(pvarRes) = VARIANT_FALSE; + } + + if(V_VT(v) == (VT_VARIANT|VT_BYREF)) + v = V_VARIANTREF(v); + + memset(pei, 0, sizeof(*pei)); + switch(V_VT(v)) { + case VT_I2: + pei->scode = V_I2(v); + break; + case VT_I4: + pei->scode = V_I4(v); + break; + default: + ok(0, "unexpected vt %d\n", V_VT(v)); + return E_INVALIDARG; + } + + if(pdp->cArgs >= 2) { + v = pdp->rgvarg + pdp->cArgs - 2; + ok(V_VT(v) == VT_BSTR, "v = %s\n", debugstr_variant(v)); + pei->bstrSource = SysAllocString(V_BSTR(v)); + } + + if(pdp->cArgs >= 3) { + v = pdp->rgvarg + pdp->cArgs - 3; + ok(V_VT(v) == VT_BSTR, "v = %s\n", debugstr_variant(v)); + pei->bstrDescription = SysAllocString(V_BSTR(v)); + } + + return DISP_E_EXCEPTION; + } + case DISPID_GLOBAL_THROWWITHDESC: pei->scode = 0xdeadbeef; pei->bstrDescription = SysAllocString(L"test"); @@ -2351,6 +2401,82 @@ static void test_callbacks(void) IActiveScriptParse_Release(parser); close_script(script); strict_enter_script = FALSE; + + store_script_error = &error1; + SET_EXPECT(OnScriptError); + hres = parse_script_ar("throwException &h80004002&"); + ok(hres == MAKE_VBSERROR(430), "got error: %08lx\n", hres); + CHECK_CALLED(OnScriptError); + + memset(&ei, 0xcc, sizeof(ei)); + hres = IActiveScriptError_GetExceptionInfo(error1, &ei); + ok(hres == S_OK, "GetExceptionInfo returned %08lx\n", hres); + ok(!ei.wCode, "wCode = %x\n", ei.wCode); + ok(!ei.wReserved, "wReserved = %x\n", ei.wReserved); + if(is_english) { + ok(!wcscmp(ei.bstrSource, L"Microsoft VBScript runtime error"), + "bstrSource = %s\n", wine_dbgstr_w(ei.bstrSource)); + ok(!wcscmp(ei.bstrDescription, L"Class doesn't support Automation"), + "bstrDescription = %s\n", wine_dbgstr_w(ei.bstrDescription)); + } + ok(!ei.bstrHelpFile, "bstrHelpFile = %s\n", wine_dbgstr_w(ei.bstrHelpFile)); + ok(!ei.dwHelpContext, "dwHelpContext = %lx\n", ei.dwHelpContext); + ok(!ei.pvReserved, "pvReserved = %p\n", ei.pvReserved); + ok(!ei.pfnDeferredFillIn, "pfnDeferredFillIn = %p\n", ei.pfnDeferredFillIn); + ok(ei.scode == MAKE_VBSERROR(430), "scode = %lx\n", ei.scode); + free_ei(&ei); + + IActiveScriptError_Release(error1); + + store_script_error = &error1; + SET_EXPECT(OnScriptError); + hres = parse_script_ar("throwException &h80004002&, "test src""); + ok(hres == MAKE_VBSERROR(430), "got error: %08lx\n", hres); + CHECK_CALLED(OnScriptError); + + memset(&ei, 0xcc, sizeof(ei)); + hres = IActiveScriptError_GetExceptionInfo(error1, &ei); + ok(hres == S_OK, "GetExceptionInfo returned %08lx\n", hres); + ok(!ei.wCode, "wCode = %x\n", ei.wCode); + ok(!ei.wReserved, "wReserved = %x\n", ei.wReserved); + if(is_english) { + ok(!wcscmp(ei.bstrSource, L"test src"), "bstrSource = %s\n", wine_dbgstr_w(ei.bstrSource)); + ok(!wcscmp(ei.bstrDescription, L"Class doesn't support Automation"), + "bstrDescription = %s\n", wine_dbgstr_w(ei.bstrDescription)); + } + ok(!ei.bstrHelpFile, "bstrHelpFile = %s\n", wine_dbgstr_w(ei.bstrHelpFile)); + ok(!ei.dwHelpContext, "dwHelpContext = %lx\n", ei.dwHelpContext); + ok(!ei.pvReserved, "pvReserved = %p\n", ei.pvReserved); + ok(!ei.pfnDeferredFillIn, "pfnDeferredFillIn = %p\n", ei.pfnDeferredFillIn); + ok(ei.scode == MAKE_VBSERROR(430), "scode = %lx\n", ei.scode); + free_ei(&ei); + + IActiveScriptError_Release(error1); + + store_script_error = &error1; + SET_EXPECT(OnScriptError); + hres = parse_script_ar("throwException &h80004002&, "test src", "test desc""); + ok(hres == E_NOINTERFACE, "got error: %08lx\n", hres); + CHECK_CALLED(OnScriptError); + + memset(&ei, 0xcc, sizeof(ei)); + hres = IActiveScriptError_GetExceptionInfo(error1, &ei); + ok(hres == S_OK, "GetExceptionInfo returned %08lx\n", hres); + ok(!ei.wCode, "wCode = %x\n", ei.wCode); + ok(!ei.wReserved, "wReserved = %x\n", ei.wReserved); + if(is_english) { + ok(!wcscmp(ei.bstrSource, L"test src"), "bstrSource = %s\n", wine_dbgstr_w(ei.bstrSource)); + ok(!wcscmp(ei.bstrDescription, L"test desc"), + "bstrDescription = %s\n", wine_dbgstr_w(ei.bstrDescription)); + } + ok(!ei.bstrHelpFile, "bstrHelpFile = %s\n", wine_dbgstr_w(ei.bstrHelpFile)); + ok(!ei.dwHelpContext, "dwHelpContext = %lx\n", ei.dwHelpContext); + ok(!ei.pvReserved, "pvReserved = %p\n", ei.pvReserved); + ok(!ei.pfnDeferredFillIn, "pfnDeferredFillIn = %p\n", ei.pfnDeferredFillIn); + ok(ei.scode == E_NOINTERFACE, "scode = %lx\n", ei.scode); + free_ei(&ei); + + IActiveScriptError_Release(error1); }
static void test_gc(void)