From: Nikolay Sivov nsivov@codeweavers.com
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=53888 --- dlls/vbscript/global.c | 40 +++++++++++++++++++++--------- dlls/vbscript/tests/api.vbs | 49 +++++++++++++++++++++++++++++++++++++ 2 files changed, 77 insertions(+), 12 deletions(-)
diff --git a/dlls/vbscript/global.c b/dlls/vbscript/global.c index ccbef9a5974..1abfff9b4fe 100644 --- a/dlls/vbscript/global.c +++ b/dlls/vbscript/global.c @@ -1391,35 +1391,49 @@ static HRESULT Global_RightB(BuiltinDisp *This, VARIANT *arg, unsigned args_cnt, static HRESULT Global_Mid(BuiltinDisp *This, VARIANT *args, unsigned args_cnt, VARIANT *res) { int len = -1, start, str_len; - BSTR str; + BSTR str, conv_str = NULL; HRESULT hres;
TRACE("(%s %s ...)\n", debugstr_variant(args), debugstr_variant(args+1));
assert(args_cnt == 2 || args_cnt == 3);
- if(V_VT(args) != VT_BSTR) { - FIXME("args[0] = %s\n", debugstr_variant(args)); - return E_NOTIMPL; - } + if(V_VT(args) == VT_EMPTY) + return MAKE_VBSERROR(VBSE_ILLEGAL_FUNC_CALL);
- str = V_BSTR(args); + if(V_VT(args+1) == VT_NULL || (args_cnt == 3 && V_VT(args+2) == VT_NULL)) + return MAKE_VBSERROR(VBSE_ILLEGAL_NULL_USE); + + if(V_VT(args+1) == VT_EMPTY) + return MAKE_VBSERROR(VBSE_ILLEGAL_FUNC_CALL);
hres = to_int(args+1, &start); if(FAILED(hres)) return hres;
+ if(start < 0) + return MAKE_VBSERROR(VBSE_ILLEGAL_FUNC_CALL); + if(args_cnt == 3) { + if(V_VT(args+2) == VT_EMPTY) + return MAKE_VBSERROR(VBSE_ILLEGAL_FUNC_CALL); + hres = to_int(args+2, &len); if(FAILED(hres)) return hres;
- if(len < 0) { - FIXME("len = %d\n", len); - return E_FAIL; - } + if(len < 0) + return MAKE_VBSERROR(VBSE_ILLEGAL_FUNC_CALL); }
+ if(V_VT(args) == VT_BSTR) { + str = V_BSTR(args); + }else { + hres = to_string(args, &conv_str); + if(FAILED(hres)) + return hres; + str = conv_str; + }
str_len = SysStringLen(str); start--; @@ -1435,10 +1449,12 @@ static HRESULT Global_Mid(BuiltinDisp *This, VARIANT *args, unsigned args_cnt, V V_VT(res) = VT_BSTR; V_BSTR(res) = SysAllocStringLen(str+start, len); if(!V_BSTR(res)) - return E_OUTOFMEMORY; + hres = E_OUTOFMEMORY; }
- return S_OK; + SysFreeString(conv_str); + + return hres; }
static HRESULT Global_MidB(BuiltinDisp *This, VARIANT *arg, unsigned args_cnt, VARIANT *res) diff --git a/dlls/vbscript/tests/api.vbs b/dlls/vbscript/tests/api.vbs index c9c8610f5fa..5f7f2aac3bf 100644 --- a/dlls/vbscript/tests/api.vbs +++ b/dlls/vbscript/tests/api.vbs @@ -605,10 +605,59 @@ TestMid "test", 1, 2, "te" TestMid "test", 1, 0, "" TestMid "test", 1, 0, "" TestMid "test", 5, 2, "" +TestMid 1234, 1, 2, "12" +TestMid 1234, 5, 2, "" TestMid2 "test", 1, "test" TestMid2 "test", 2, "est" TestMid2 "test", 4, "t" TestMid2 "test", 5, "" +TestMid2 1234, 5, "" + +sub TestMidError() + on error resume next + call Err.clear() + call Mid("test", "a", 1) + call ok(Err.number = 13, "Err.number = " & Err.number) + call Err.clear() + call Mid("test", "a", null) + call ok(Err.number = 94, "Err.number = " & Err.number) + call Err.clear() + call Mid("test", "a", empty) + call ok(Err.number = 13, "Err.number = " & Err.number) + call Mid("test", 0, -1) + call ok(Err.number = 5, "Err.number = " & Err.number) + call Err.clear() + call Mid("test", -1, -1) + call ok(Err.number = 5, "Err.number = " & Err.number) + call Err.clear() + call Mid(null, -1, -1) + call ok(Err.number = 5, "Err.number = " & Err.number) + call Err.clear() + call Mid("test", 0, null) + call ok(Err.number = 94, "Err.number = " & Err.number) + call Err.clear() + call Mid("test", -1, null) + call ok(Err.number = 94, "Err.number = " & Err.number) + call Err.clear() + call Mid("test", null, 2) + call ok(Err.number = 94, "Err.number = " & Err.number) + call Err.clear() + call Mid("test", null, -1) + call ok(Err.number = 94, "Err.number = " & Err.number) + call Err.clear() + call Mid(null, -1, -1) + call ok(Err.number = 5, "Err.number = " & Err.number) + call Err.clear() + call Mid("test", empty, 1) + call ok(Err.number = 5, "Err.number = " & Err.number) + call Err.clear() + call Mid("test", 0, empty) + call ok(Err.number = 5, "Err.number = " & Err.number) + call Err.clear() + call Mid(empty, 0, 0) + call ok(Err.number = 5, "Err.number = " & Err.number) +end sub +call TestMidError()
Sub TestUCase(str, ex) x = UCase(str)