From: Francis De Brabandere <francisdb@gmail.com> Native VBScript treats '&' followed by octal digits as octal even without an explicit 'o'/'O' prefix, so &10000000 is octal (2097152). Wine only accepted the &O form and raised a syntax error otherwise. A decimal digit (8 or 9) terminating the octal run is an invalid octal digit and raises a syntax error (1002), matching native (&19, &18). --- dlls/vbscript/lex.c | 9 +++++++++ dlls/vbscript/tests/lang.vbs | 9 +++++++++ 2 files changed, 18 insertions(+) diff --git a/dlls/vbscript/lex.c b/dlls/vbscript/lex.c index ef20604c8db..5273a88bdbb 100644 --- a/dlls/vbscript/lex.c +++ b/dlls/vbscript/lex.c @@ -434,6 +434,10 @@ static int parse_oct_literal(parser_ctx_t *ctx, LONG *ret) } } + /* A decimal digit (8 or 9) ends the octal run: it is an invalid octal digit. */ + if(*ctx->ptr == '8' || *ctx->ptr == '9') + return lex_error(ctx, MAKE_VBSERROR(VBSE_SYNTAX_ERROR)); + if(*ctx->ptr == '&') { ctx->ptr++; *ret = (LONG)l; @@ -590,6 +594,11 @@ static int parse_next_token(void *lval, unsigned *loc, parser_ctx_t *ctx) return parse_hex_literal(ctx, lval); if((*ctx->ptr == 'o' || *ctx->ptr == 'O') && oct_to_int(ctx->ptr[1]) != -1) return parse_oct_literal(ctx, lval); + if(oct_to_int(*ctx->ptr) != -1) { + /* A bare '&' followed by octal digits (no 'o'/'O') is also octal. */ + ctx->ptr--; + return parse_oct_literal(ctx, lval); + } return '&'; case '=': switch(*++ctx->ptr) { diff --git a/dlls/vbscript/tests/lang.vbs b/dlls/vbscript/tests/lang.vbs index 6c9628d7e69..1cf7c0ddab4 100644 --- a/dlls/vbscript/tests/lang.vbs +++ b/dlls/vbscript/tests/lang.vbs @@ -103,10 +103,19 @@ Call ok(getVT(&O77) = "VT_I2", "getVT(&O77) is not VT_I2") Call ok(getVT(&O200000) = "VT_I4", "getVT(&O200000) is not VT_I4") Call ok(getVT(&O177777&) = "VT_I4", "getVT(&O177777&) is not VT_I4") +' Bare '&' followed by octal digits (no 'o'/'O') is octal too +Call ok(&100 = 64, "&100 <> 64") +Call ok(&777 = 511, "&777 <> 511") +Call ok(&10000000 = 2097152, "&10000000 <> 2097152") +Call ok(&010 = 8, "&010 <> 8") +Call ok(&32 = 26, "&32 <> 26") +Call ok(&17& = 15, "&17& <> 15") + sub testOctalLiteralErrors() Dim oct on error resume next Err.Clear : oct = Eval("&O8") : call ok(Err.number = 1002, "&O8 should be syntax error, got err=" & Err.number) + Err.Clear : oct = Eval("&19") : call ok(Err.number = 1002, "&19 should be syntax error, got err=" & Err.number) end sub call testOctalLiteralErrors() -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/11229