From: Shuai Meng Subject: [PATCH] vbscript: Implemented String(try 2) Message-Id: <544B5AFF.7010309@gmail.com> Date: Sat, 25 Oct 2014 16:10:39 +0800 testbot: https://newtestbot.winehq.org/JobDetails.pl?Key=9749 Change log: made str a WCHAR rather than an array of type BSTR; handled the situation when the second number is greater than 256; fixed the range of len; added more tests. --- dlls/vbscript/global.c | 65 +++++++++++++++++++++++++++++++++++++++++++-- dlls/vbscript/tests/api.vbs | 55 ++++++++++++++++++++++++++++++++++++++ dlls/vbscript/vbscript.h | 1 + 3 files changed, 119 insertions(+), 2 deletions(-) diff --git a/dlls/vbscript/global.c b/dlls/vbscript/global.c index bbbe22c..363fe77 100644 --- a/dlls/vbscript/global.c +++ b/dlls/vbscript/global.c @@ -156,6 +156,20 @@ static inline HRESULT return_date(VARIANT *res, double date) return S_OK; } +HRESULT to_short(VARIANT *v, short *ret) +{ + VARIANT r; + HRESULT hres; + + V_VT(&r) = VT_EMPTY; + hres = VariantChangeType(&r, v, 0, VT_I2); + if(FAILED(hres)) + return hres; + + *ret = V_I2(&r); + return S_OK; +} + HRESULT to_int(VARIANT *v, int *ret) { VARIANT r; @@ -1176,8 +1190,55 @@ static HRESULT Global_Space(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VAR static HRESULT Global_String(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res) { - FIXME("\n"); - return E_NOTIMPL; + HRESULT hres; + int i, len; + short tmp; + BSTR newstr; + WCHAR str; + + TRACE("%s\n", debugstr_variant(arg)); + assert(args_cnt == 2); + + if(V_VT(arg) == VT_NULL) + return MAKE_VBSERROR(VBSE_ILLEGAL_NULL_USE); + + switch(V_VT(arg + 1)) { + case VT_NULL: + return MAKE_VBSERROR(VBSE_ILLEGAL_NULL_USE); + case VT_BSTR: + str = *V_BSTR(arg + 1); + break; + case VT_ARRAY|VT_BYREF|VT_VARIANT: + return DISP_E_TYPEMISMATCH; + default: + hres = to_short(arg + 1, &tmp); + if(FAILED(hres)) + return hres; + + if(tmp < 256) + str = tmp; + else + str = tmp / 256; + break; + } + + hres = to_int(arg, &len); + if(FAILED(hres)) + return hres; + + if(len < 0 || len > 0x3fffffff) + return MAKE_VBSERROR(VBSE_ILLEGAL_FUNC_CALL); + else if(len > 755826669) + return MAKE_VBSERROR(VBSE_OUT_OF_STRING_SPACE); + else if(len == 0) + newstr = '\0'; + + newstr = SysAllocStringLen(NULL, len); + if(!newstr) + return E_OUTOFMEMORY; + for(i = 0; i < len; i++) + newstr[i] = str; + return return_bstr(res, newstr); } static HRESULT Global_InStr(vbdisp_t *This, VARIANT *args, unsigned args_cnt, VARIANT *res) diff --git a/dlls/vbscript/tests/api.vbs b/dlls/vbscript/tests/api.vbs index 1b68d2e..1c28a05 100644 --- a/dlls/vbscript/tests/api.vbs +++ b/dlls/vbscript/tests/api.vbs @@ -1266,4 +1266,59 @@ Call testRGBError(&h4d&, -2, &h2f&, 5) Call ok(getVT(Timer) = "VT_R4", "getVT(Timer) = " & getVT(Timer)) +Sub testStringError(arg1, arg2, error_num) + on error resume next + Dim x + + Call Err.clear() + x = String(arg1, arg2) + Call ok(Err.number = error_num, arg1 & ", " & arg2 & ": Err.number = " & Err.number) +End Sub + +Call ok(String(3, "abcd") = "aaa", "String(3, ""abcd"") = " & String(3, "abcd")) +Call ok(getVT(String(3, "abcd")) = "VT_BSTR", "getVT(String(3, ""abcd"")) = " & getVT(String(3, "abcd"))) +Call ok(String(0, "abcd") = "", "String(0, ""abcd"") = " & String(0, "abcd")) +Call ok(getVT(String(0, "abcd")) = "VT_BSTR", "getVT(String(0, ""abcd"")) = " & getVT(String(0, "abcd"))) +Call ok(String(1, 65) = "A", "String(1, 65) = " & String(1, 65)) +Call ok(getVT(String(1, 65)) = "VT_BSTR", "getVT(String(1, 65)) = " & getVT(String(1, 65))) +Call ok(String(1, CLng(65)) = "A", "String(1, CLng(65)) = " & String(1, CLng(65))) +Call ok(getVT(String(1, CLng(65))) = "VT_BSTR", "getVT(String(1, CLng(65))) = " & getVT(String(1, CLng(65)))) +Call ok(String(1, CByte(65)) = "A", "String(1, CByte(65)) = " & String(1, CByte(65))) +Call ok(getVT(String(1, CByte(65))) = "VT_BSTR", "getVT(String(1, CByte(65))) = " & getVT(String(1, CByte(65)))) +Call ok(String(1, 65.49) = "A", "String(1, 65.49) = " & String(1, 65.49)) +Call ok(getVT(String(1, 65.49)) = "VT_BSTR", "getVT(String(1, 65.49)) = " & getVT(String(1, 65.49))) +Call ok(String(1, 65.5) = "B", "String(1, 65.5) = " & String(1, 65.5)) +Call ok(getVT(String(1, 65.5)) = "VT_BSTR", "getVT(String(1, 65.5)) = " & getVT(String(1, 65.5))) +Call ok(String(1, 66.5) = "B", "String(1, 66.5) = " & String(1, 66.5)) +Call ok(getVT(String(1, 66.5)) = "VT_BSTR", "getVT(String(1, 66.5)) = " & getVT(String(1, 66.5))) +Call ok(String(1, 564) = String(1, Int(564 / 256)), "String(1, 564) = " & String(1, 564)) +Call ok(getVT(String(1, 564)) = "VT_BSTR", "getVT(String(1, 564)) = " & getVT(String(1, 564))) +Call ok(String(1, Empty) = String(1, 0), "String(1, Empty) = " & String(1, Empty)) +Call ok(getVT(String(1, Empty)) = "VT_BSTR", "getVT(String(1, Empty)) = " & getVT(String(1, Empty))) +Call ok(String(1, 16895.49) = "A", "String(1, 16895.49) = " & String(1, 16895.49)) +Call ok(getVT(String(1, 16895.49)) = "VT_BSTR", "getVT(String(1, 16895.49)) = " & getVT(String(1, 16895.49))) +Call ok(String(1, CSng(16895.5)) = "B", "String(1, CSng(16895.5)) = " & String(1, CSng(16895.5))) +Call ok(getVT(String(1, CSng(16895.5))) = "VT_BSTR", "getVT(String(1, CSng(16895.5))) = " & getVT(String(1, CSng(16895.5)))) +Call ok(String(1, True) = String(1, -1), "String(1, True) = " & String(1, True)) +Call ok(getVT(String(1, True)) = "VT_BSTR", "getVT(String(1, True)) = " & getVT(String(1, True))) +Call ok(String(1, False) = String(1, 0), "String(1, False) = " & String(1, False)) +Call ok(getVT(String(1, False)) = "VT_BSTR", "getVT(String(1, False)) = " & getVT(String(1, False))) +Dim testObject +Set testObject = New EmptyClass +Call testStringError(2, testObject, 438) +MyObject.myval = 122 +Call ok(String(1, MyObject) = "z", "String(1, MyObject) = " & String(1, MyObject)) +Call ok(getVT(String(1, MyObject)) = "VT_BSTR", "getVT(String(1, MyObject)) = " & getVT(String(1, MyObject))) +Dim iarray(2,3) +Call testStringError(2, iarray, 13) +Call testStringError(-1, "w", 5) +Call testStringError(2147483648, "w", 6) +Call testStringError(2147483647, "w", 5) +Call testStringError(1073741824, "w", 5) +Call testStringError(1073741823, "w", 14) +Call testStringError(755826670, "w", 14) +Call testStringError(755826669, "w", 0) +Call testStringError(2, Null, 94) +Call testStringError(Null, "f", 94) + Call reportSuccess() diff --git a/dlls/vbscript/vbscript.h b/dlls/vbscript/vbscript.h index d21e80a..651d34d 100644 --- a/dlls/vbscript/vbscript.h +++ b/dlls/vbscript/vbscript.h @@ -398,6 +398,7 @@ HRESULT map_hres(HRESULT) DECLSPEC_HIDDEN; #define VBSE_OUT_OF_BOUNDS 9 #define VBSE_ARRAY_LOCKED 10 #define VBSE_TYPE_MISMATCH 13 +#define VBSE_OUT_OF_STRING_SPACE 14 #define VBSE_FILE_NOT_FOUND 53 #define VBSE_IO_ERROR 57 #define VBSE_FILE_ALREADY_EXISTS 58