Commit d2c2c0c4 authored by Nikolay Sivov's avatar Nikolay Sivov Committed by Alexandre Julliard

vbscript: Improve argument type handling in Mid().

parent 47ecca25
......@@ -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)
......
......@@ -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)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment