[PATCH v2 0/1] MR10312: vbscript: fix dot member access after line continuation
fixes https://bugs.winehq.org/show_bug.cgi?id=56480 The lexer distinguishes '.' (member access) from tDOT (with-statement expression) by checking the character before the dot. After a line continuation (_), ptr[-1] is a newline or whitespace instead of the actual preceding token, causing the dot to be incorrectly treated as a with-expression. Track when a line continuation was just consumed and use last_token to resolve the ambiguity in that case. -- v2: vbscript: fix dot member access after line continuation https://gitlab.winehq.org/wine/wine/-/merge_requests/10312
From: Francis De Brabandere <francisdb@gmail.com> --- dlls/vbscript/lex.c | 10 ++++++++++ dlls/vbscript/parse.h | 1 + dlls/vbscript/tests/lang.vbs | 15 +++++++++++++++ 3 files changed, 26 insertions(+) diff --git a/dlls/vbscript/lex.c b/dlls/vbscript/lex.c index 8c5c69ea429..37a368ce3eb 100644 --- a/dlls/vbscript/lex.c +++ b/dlls/vbscript/lex.c @@ -440,6 +440,14 @@ static int parse_next_token(void *lval, unsigned *loc, parser_ctx_t *ctx) ctx->ptr++; return '.'; } + /* After line continuation, ptr[-1] is a newline or space, but the dot + * is logically on the same line as the previous token. */ + if(ctx->after_continuation + && (ctx->last_token == tIdentifier || ctx->last_token == ')' + || ctx->last_token == tEMPTYBRACKETS)) { + ctx->ptr++; + return '.'; + } c = ctx->ptr[1]; if('0' <= c && c <= '9') return parse_numeric_literal(ctx, lval); @@ -538,6 +546,7 @@ int parser_lex(void *lval, unsigned *loc, parser_ctx_t *ctx) ctx->ptr++; if(*ctx->ptr == '\n') ctx->ptr++; + ctx->after_continuation = TRUE; continue; } if(ret != tNL || ctx->last_token != tNL) @@ -546,5 +555,6 @@ int parser_lex(void *lval, unsigned *loc, parser_ctx_t *ctx) ctx->last_nl = ctx->ptr-ctx->code; } + ctx->after_continuation = FALSE; return (ctx->last_token = ret); } diff --git a/dlls/vbscript/parse.h b/dlls/vbscript/parse.h index 64c3dee2a69..71fc713ea9c 100644 --- a/dlls/vbscript/parse.h +++ b/dlls/vbscript/parse.h @@ -302,6 +302,7 @@ typedef struct { int last_token; unsigned last_nl; + BOOL after_continuation; statement_t *stats; statement_t *stats_tail; diff --git a/dlls/vbscript/tests/lang.vbs b/dlls/vbscript/tests/lang.vbs index 0025bfeddcf..de91cc21947 100644 --- a/dlls/vbscript/tests/lang.vbs +++ b/dlls/vbscript/tests/lang.vbs @@ -247,6 +247,21 @@ x _ x = 3 +Class ChainedCallTarget + Public Function Ret() + Set Ret = Me + End Function +End Class + +Dim chainObj +Set chainObj = New ChainedCallTarget +chainObj.Ret().Ret() +chainObj.Ret() _ +.Ret() +chainObj _ +.Ret() _ +.Ret() + if true then y = true : x = y ok x, "x is false" -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10312
participants (2)
-
Francis De Brabandere -
Francis De Brabandere (@francisdb)