[PATCH 0/1] MR10384: vbscript: Allow hex literals with excess leading zeros.
Windows allows any number of leading zeros in hex literals (e.g. &H000000031 = 49). Wine rejected literals with more than 8 hex digits regardless of value. Fix by skipping leading zeros before counting significant digits, so that only actual 32-bit overflow is rejected. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/10384
From: Francis De Brabandere <francisdb@gmail.com> Windows allows any number of leading zeros in hex literals (e.g. &H000000031 = 49). Wine rejected literals with more than 8 hex digits regardless of value. Fix by skipping leading zeros before counting significant digits, so that only actual 32-bit overflow is rejected. --- dlls/vbscript/lex.c | 12 +++++++++--- dlls/vbscript/tests/lang.vbs | 10 ++++++++++ dlls/vbscript/tests/run.c | 22 ++++++++++++++++++++++ dlls/vbscript/vbscript_defs.h | 1 + 4 files changed, 42 insertions(+), 3 deletions(-) diff --git a/dlls/vbscript/lex.c b/dlls/vbscript/lex.c index 8c5c69ea429..fcde5ff1465 100644 --- a/dlls/vbscript/lex.c +++ b/dlls/vbscript/lex.c @@ -351,14 +351,20 @@ static int hex_to_int(WCHAR c) static int parse_hex_literal(parser_ctx_t *ctx, LONG *ret) { - const WCHAR *begin = ctx->ptr; + const WCHAR *begin; unsigned l = 0, d; + /* Skip leading zeros — Windows allows any number of them. */ + while(ctx->ptr[1] == '0' && hex_to_int(ctx->ptr[2]) != -1) + ctx->ptr++; + + begin = ctx->ptr; + while((d = hex_to_int(*++ctx->ptr)) != -1) l = l*16 + d; - if(begin + 9 /* max digits+1 */ < ctx->ptr) { - FIXME("invalid literal\n"); + if(begin + 9 /* max 8 significant digits + 1 */ < ctx->ptr) { + WARN("overflow in hex literal\n"); return 0; } diff --git a/dlls/vbscript/tests/lang.vbs b/dlls/vbscript/tests/lang.vbs index c364f12c00b..949c5842922 100644 --- a/dlls/vbscript/tests/lang.vbs +++ b/dlls/vbscript/tests/lang.vbs @@ -62,6 +62,16 @@ Call ok(&hfffe& = 65534, "&hfffe& <> -2") Call ok(&hffffffff& = -1, "&hffffffff& <> -1") Call ok((&h01or&h02)=3,"&h01or&h02 <> 3") +' Hex literals with excess leading zeros +Call ok(&H000000031 = 49, "&H000000031 <> 49") +Call ok(&H0000000000000031 = 49, "&H0000000000000031 <> 49") +Call ok(&H00000000000000FF = 255, "&H00000000000000FF <> 255") +Call ok(&H0FFFFFFFF = -1, "&H0FFFFFFFF <> -1") +Call ok(&H007FFFFFFF = 2147483647, "&H007FFFFFFF <> 2147483647") +Call ok(&H000000031& = 49, "&H000000031& <> 49") +Call ok(getVT(&H00000000000000FF) = "VT_I2", "getVT(&H00000000000000FF) is not VT_I2") +Call ok(getVT(&H007FFFFFFF) = "VT_I4", "getVT(&H007FFFFFFF) is not VT_I4") + ' Test concat when no space and var begins with h hi = "y" x = "x" &hi diff --git a/dlls/vbscript/tests/run.c b/dlls/vbscript/tests/run.c index 8aaafbedf54..b873e2bc03b 100644 --- a/dlls/vbscript/tests/run.c +++ b/dlls/vbscript/tests/run.c @@ -29,6 +29,8 @@ #include "wine/test.h" +#define VBSE_SYNTAX_ERROR 1002 + #ifdef _WIN64 #define IActiveScriptParse_QueryInterface IActiveScriptParse64_QueryInterface @@ -1962,6 +1964,7 @@ static HRESULT WINAPI ActiveScriptSite_OnStateChange(IActiveScriptSite *iface, S static IActiveScriptError **store_script_error; static ULONG error_line; static LONG error_char; +static USHORT error_code; static HRESULT WINAPI ActiveScriptSite_OnScriptError(IActiveScriptSite *iface, IActiveScriptError *pscripterror) { @@ -1978,6 +1981,15 @@ static HRESULT WINAPI ActiveScriptSite_OnScriptError(IActiveScriptSite *iface, I trace("Error in line %lu: %x %s\n", error_line + 1, info.wCode, wine_dbgstr_w(info.bstrDescription)); }else { IDispatchEx *dispex; + EXCEPINFO info; + + hres = IActiveScriptError_GetExceptionInfo(pscripterror, &info); + if(SUCCEEDED(hres)) { + error_code = info.wCode; + SysFreeString(info.bstrSource); + SysFreeString(info.bstrDescription); + SysFreeString(info.bstrHelpFile); + } hres = IActiveScriptError_QueryInterface(pscripterror, &IID_IDispatchEx, (void**)&dispex); ok(hres == E_NOINTERFACE, "QI(IDispatchEx) returned: %08lx\n", hres); @@ -2647,6 +2659,7 @@ static void test_parse_errors(void) const WCHAR *src; unsigned error_line; int error_char; + USHORT error_code; } invalid_scripts[] = { @@ -2765,6 +2778,11 @@ static void test_parse_errors(void) " throwInt &h87001234&\n" "end if\n", 2, 1 + }, + { + /* Hex literal overflow */ + L"x = &H100000001\n", + 0, 4, VBSE_SYNTAX_ERROR } }; HRESULT hres; @@ -2774,6 +2792,7 @@ static void test_parse_errors(void) { error_line = ~0; error_char = -1; + error_code = 0; onerror_hres = S_OK; SET_EXPECT(OnScriptError); @@ -2786,6 +2805,9 @@ static void test_parse_errors(void) todo_wine_if(invalid_scripts[i].error_char < 0) ok(error_char == abs(invalid_scripts[i].error_char), "[%u] error char %ld expected %d\n", i, error_char, invalid_scripts[i].error_char); + if(invalid_scripts[i].error_code) + todo_wine ok(error_code == invalid_scripts[i].error_code, "[%u] error code %u expected %u\n", + i, error_code, invalid_scripts[i].error_code); } } diff --git a/dlls/vbscript/vbscript_defs.h b/dlls/vbscript/vbscript_defs.h index 139b71255a0..a1c48ebdb6c 100644 --- a/dlls/vbscript/vbscript_defs.h +++ b/dlls/vbscript/vbscript_defs.h @@ -268,6 +268,7 @@ #define VBSE_INVALID_TYPELIB_VARIABLE 458 #define VBSE_SERVER_NOT_FOUND 462 #define VBSE_UNQUALIFIED_REFERENCE 505 +#define VBSE_SYNTAX_ERROR 1002 #define VBS_COMPILE_ERROR 4096 #define VBS_RUNTIME_ERROR 4097 -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10384
participants (2)
-
Francis De Brabandere -
Francis De Brabandere (@francisdb)