[PATCH v4 0/2] MR10579: Draft: 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. -- v4: 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 1f9c4c3b18c..57817d21a15 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; @@ -159,6 +161,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 ed483602176..36db21afad8 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 da6f31ff4df..90b256a926c 100644 --- a/dlls/vbscript/tests/run.c +++ b/dlls/vbscript/tests/run.c @@ -3049,6 +3049,12 @@ static void test_parse_errors(void) L"x = 1 _x\n", 0, 7, 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 4654798b8a1..6e647918e34 100644 --- a/dlls/vbscript/vbscript_defs.h +++ b/dlls/vbscript/vbscript_defs.h @@ -287,6 +287,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 | 33 +++++++++++++++++++++++++++++++++ dlls/vbscript/tests/lang.vbs | 32 ++++++++++++++++++++++++++++++++ dlls/vbscript/tests/run.c | 12 ++++++++++++ dlls/vbscript/vbscript_defs.h | 1 + 4 files changed, 78 insertions(+) diff --git a/dlls/vbscript/lex.c b/dlls/vbscript/lex.c index 57817d21a15..6513fac10e5 100644 --- a/dlls/vbscript/lex.c +++ b/dlls/vbscript/lex.c @@ -402,6 +402,37 @@ 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') { + if(*ctx->ptr == '[') + return lex_error(ctx, MAKE_VBSERROR(VBSE_INVALID_CHAR)); + 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; @@ -491,6 +522,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 36db21afad8..8ece960c1e8 100644 --- a/dlls/vbscript/tests/lang.vbs +++ b/dlls/vbscript/tests/lang.vbs @@ -278,6 +278,38 @@ 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 [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) + Class ChainedCallTarget Public Function Ret() Set Ret = Me diff --git a/dlls/vbscript/tests/run.c b/dlls/vbscript/tests/run.c index 90b256a926c..61708cfcfff 100644 --- a/dlls/vbscript/tests/run.c +++ b/dlls/vbscript/tests/run.c @@ -3055,6 +3055,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, 5, + 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 6e647918e34..04038682f51 100644 --- a/dlls/vbscript/vbscript_defs.h +++ b/dlls/vbscript/vbscript_defs.h @@ -274,6 +274,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)