[PATCH v9 0/2] MR10579: vbscript: Identifier improvements
Windows limits VBScript identifiers to 255 characters, returning error 1030 (Identifier too long) for longer names. Wine previously accepted identifiers of any length. VBScript allows square brackets to quote identifiers containing spaces, special characters, or reserved words. -- v9: vbscript: Support bracketed identifiers like [my var]. https://gitlab.winehq.org/wine/wine/-/merge_requests/10579
From: Francis De Brabandere <francisdb@gmail.com> Windows limits VBScript identifiers to 255 characters, returning error 1030 (Identifier too long) for longer names. Wine previously accepted identifiers of any length. --- dlls/vbscript/lex.c | 5 +++++ dlls/vbscript/tests/lang.vbs | 5 +++++ dlls/vbscript/tests/run.c | 6 ++++++ dlls/vbscript/vbscript_defs.h | 1 + 4 files changed, 17 insertions(+) diff --git a/dlls/vbscript/lex.c b/dlls/vbscript/lex.c index 12305ab671b..d0f47d495a7 100644 --- a/dlls/vbscript/lex.c +++ b/dlls/vbscript/lex.c @@ -28,6 +28,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(vbscript); +#define MAX_IDENTIFIER_LENGTH 255 + static int lex_error(parser_ctx_t *ctx, HRESULT hres) { ctx->hres = hres; @@ -167,6 +169,9 @@ static int parse_identifier(parser_ctx_t *ctx, const WCHAR **ret) ctx->ptr++; len = ctx->ptr-ptr; + if(len > MAX_IDENTIFIER_LENGTH) + return lex_error(ctx, MAKE_VBSERROR(VBSE_IDENTIFIER_TOO_LONG)); + str = parser_alloc(ctx, (len+1)*sizeof(WCHAR)); if(!str) return 0; diff --git a/dlls/vbscript/tests/lang.vbs b/dlls/vbscript/tests/lang.vbs index cce5b02e9cb..b013e46967f 100644 --- a/dlls/vbscript/tests/lang.vbs +++ b/dlls/vbscript/tests/lang.vbs @@ -273,6 +273,11 @@ x _ x = 3 +' Maximum identifier length (255 chars) +Dim aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa = 42 +Call ok(aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa = 42, "255-char identifier should work") + Class ChainedCallTarget Public Function Ret() Set Ret = Me diff --git a/dlls/vbscript/tests/run.c b/dlls/vbscript/tests/run.c index 70ccd517254..e51bcf29751 100644 --- a/dlls/vbscript/tests/run.c +++ b/dlls/vbscript/tests/run.c @@ -3079,6 +3079,12 @@ static void test_parse_errors(void) L"\x00e9var = 1\n", 0, 0, NULL, S_OK, 1032 + }, + { + /* Identifier too long (256 chars) */ + L"Dim aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n", + 0, 260, + NULL, S_OK, 1030 } }; HRESULT hres; diff --git a/dlls/vbscript/vbscript_defs.h b/dlls/vbscript/vbscript_defs.h index 0dc7b677517..9e7f9aa631b 100644 --- a/dlls/vbscript/vbscript_defs.h +++ b/dlls/vbscript/vbscript_defs.h @@ -288,6 +288,7 @@ #define VBSE_EXPECTED_END_OF_STATEMENT 1025 #define VBSE_EXPECTED_INTEGER_CONSTANT 1026 #define VBSE_EXPECTED_WHILE_UNTIL_EOS 1028 +#define VBSE_IDENTIFIER_TOO_LONG 1030 #define VBSE_INVALID_NUMBER 1031 #define VBSE_INVALID_CHAR 1032 #define VBSE_UNTERMINATED_STRING 1033 -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10579
From: Francis De Brabandere <francisdb@gmail.com> VBScript allows square brackets to quote identifiers containing spaces, special characters, or reserved words. --- dlls/vbscript/lex.c | 30 +++++++++++++++++++++++++ dlls/vbscript/tests/lang.vbs | 41 +++++++++++++++++++++++++++++++++++ dlls/vbscript/tests/run.c | 12 ++++++++++ dlls/vbscript/vbscript_defs.h | 1 + 4 files changed, 84 insertions(+) diff --git a/dlls/vbscript/lex.c b/dlls/vbscript/lex.c index d0f47d495a7..30a260134eb 100644 --- a/dlls/vbscript/lex.c +++ b/dlls/vbscript/lex.c @@ -410,6 +410,34 @@ static int comment_line(parser_ctx_t *ctx) return tNL; } +static int parse_bracket_identifier(parser_ctx_t *ctx, const WCHAR **ret) +{ + const WCHAR *start = ++ctx->ptr; + WCHAR *str; + int len; + + while(ctx->ptr < ctx->end && *ctx->ptr != ']' && *ctx->ptr != '\n' && *ctx->ptr != '\r') + ctx->ptr++; + + if(ctx->ptr >= ctx->end || *ctx->ptr != ']') + return lex_error(ctx, MAKE_VBSERROR(VBSE_UNTERMINATED_IDENTIFIER)); + + len = ctx->ptr - start; + ctx->ptr++; /* skip ']' */ + + if(len > MAX_IDENTIFIER_LENGTH) + return lex_error(ctx, MAKE_VBSERROR(VBSE_IDENTIFIER_TOO_LONG)); + + str = parser_alloc(ctx, (len+1)*sizeof(WCHAR)); + if(!str) + return 0; + + memcpy(str, start, len*sizeof(WCHAR)); + str[len] = 0; + *ret = str; + return tIdentifier; +} + static int parse_next_token(void *lval, unsigned *loc, parser_ctx_t *ctx) { WCHAR c; @@ -499,6 +527,8 @@ static int parse_next_token(void *lval, unsigned *loc, parser_ctx_t *ctx) if(ctx->last_token == tIdentifier || ctx->last_token == ')' || ctx->last_token == tME) return '('; return tEXPRLBRACKET; + case '[': + return parse_bracket_identifier(ctx, lval); case '"': return parse_string_literal(ctx, lval); case '#': diff --git a/dlls/vbscript/tests/lang.vbs b/dlls/vbscript/tests/lang.vbs index b013e46967f..37a92fc53f4 100644 --- a/dlls/vbscript/tests/lang.vbs +++ b/dlls/vbscript/tests/lang.vbs @@ -278,6 +278,47 @@ Dim aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa = 42 Call ok(aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa = 42, "255-char identifier should work") +' Bracketed identifiers +Dim [my var] +[my var] = 42 +Call ok([my var] = 42, "[my var] = " & [my var]) + +Dim [hello world!] +[hello world!] = "works" +Call ok([hello world!] = "works", "[hello world!] = " & [hello world!]) + +Dim [] +[] = "empty" +Call ok([] = "empty", "[] = " & []) + +Dim [ ] +[ ] = "spaces" +Call ok([ ] = "spaces", "[ ] = " & [ ]) + +Dim [dim] +[dim] = 99 +Call ok([dim] = 99, "[dim] = " & [dim]) + +Class BracketTestObj + Public [my property] + Public Sub Class_Initialize + [my property] = "init" + End Sub +End Class + +Dim bracketObj +Set bracketObj = New BracketTestObj +bracketObj.[my property] = "updated" +Call ok(bracketObj.[my property] = "updated", "bracketObj.[my property] = " & bracketObj.[my property]) + +Dim [loop var] +Dim bracketTotal : bracketTotal = 0 +For [loop var] = 1 To 3 + bracketTotal = bracketTotal + [loop var] +Next +Call ok(bracketTotal = 6, "For [loop var] total = " & bracketTotal) + +' Chained call syntax Class ChainedCallTarget Public Function Ret() Set Ret = Me diff --git a/dlls/vbscript/tests/run.c b/dlls/vbscript/tests/run.c index e51bcf29751..730748ee560 100644 --- a/dlls/vbscript/tests/run.c +++ b/dlls/vbscript/tests/run.c @@ -3085,6 +3085,18 @@ static void test_parse_errors(void) L"Dim aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n", 0, 260, NULL, S_OK, 1030 + }, + { + /* Nested square brackets */ + L"Dim [[nested]]\n", + 0, 13, + NULL, S_OK, 1032 + }, + { + /* Unclosed square bracket */ + L"Dim [unclosed\n", + 0, 13, + NULL, S_OK, 1007 } }; HRESULT hres; diff --git a/dlls/vbscript/vbscript_defs.h b/dlls/vbscript/vbscript_defs.h index 9e7f9aa631b..e60eb1604ca 100644 --- a/dlls/vbscript/vbscript_defs.h +++ b/dlls/vbscript/vbscript_defs.h @@ -275,6 +275,7 @@ #define VBSE_UNQUALIFIED_REFERENCE 505 #define VBSE_SYNTAX_ERROR 1002 #define VBSE_EXPECTED_LPAREN 1005 +#define VBSE_UNTERMINATED_IDENTIFIER 1007 #define VBSE_EXPECTED_IDENTIFIER 1010 #define VBSE_EXPECTED_ASSIGN 1011 #define VBSE_EXPECTED_TO 1013 -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10579
participants (2)
-
Francis De Brabandere -
Francis De Brabandere (@francisdb)