[PATCH 0/1] MR10496: vbscript: Return error 1045 for non-literal constant expressions.
When a Const declaration uses a non-literal expression (e.g. "Const x = 1 + \"a\""), Windows parses the full expression and then rejects it with error 1045 ("expected literal constant"). Change ConstDecl to accept Expression instead of ConstExpression, and validate in new_const_decl() that the expression is a literal or negated numeric literal. Remove the now-unused ConstExpression rule. This fixes both the error code (was generic E_FAIL/16389) and the error character position (now points to the end of the expression). -- https://gitlab.winehq.org/wine/wine/-/merge_requests/10496
From: Francis De Brabandere <francisdb@gmail.com> When a Const declaration uses a non-literal expression (e.g. "Const x = 1 + \"a\""), Windows parses the full expression and then rejects it with error 1045 ("expected literal constant"). Change ConstDecl to accept Expression instead of ConstExpression, and validate in new_const_decl() that the expression is a literal or negated numeric literal. Remove the now-unused ConstExpression rule. This fixes both the error code (was generic E_FAIL/16389) and the error character position (now points to the end of the expression). --- dlls/vbscript/parser.y | 35 +++++++++++++++++++++++++++++------ dlls/vbscript/tests/run.c | 4 ++-- 2 files changed, 31 insertions(+), 8 deletions(-) diff --git a/dlls/vbscript/parser.y b/dlls/vbscript/parser.y index c1a5b944268..b332c21ef57 100644 --- a/dlls/vbscript/parser.y +++ b/dlls/vbscript/parser.y @@ -144,7 +144,7 @@ static statement_t *link_statements(statement_t*,statement_t*); %type <expression> Expression LiteralExpression PrimaryExpression EqualityExpression CallExpression ExpressionNl_opt %type <expression> ConcatExpression AdditiveExpression ModExpression IntdivExpression MultiplicativeExpression ExpExpression %type <expression> UnaryExpression AndExpression OrExpression XorExpression EqvExpression SignExpression -%type <expression> ConstExpression NumericLiteralExpression +%type <expression> NumericLiteralExpression %type <member> MemberExpression %type <expression> Arguments ArgumentList ArgumentList_opt Step_opt ExpressionList %type <boolean> DoType Preserve_opt @@ -294,11 +294,7 @@ ConstDeclList | ConstDecl ',' ConstDeclList { $1->next = $3; $$ = $1; } ConstDecl - : Identifier '=' ConstExpression { $$ = new_const_decl(ctx, $1, $3); CHECK_ERROR; } - -ConstExpression - : LiteralExpression { $$ = $1; } - | '-' NumericLiteralExpression { $$ = new_unary_expression(ctx, EXPR_NEG, $2); CHECK_ERROR; } + : Identifier '=' Expression { $$ = new_const_decl(ctx, $1, $3); CHECK_ERROR; } DoType : tWHILE { $$ = TRUE; } @@ -1182,10 +1178,37 @@ static class_decl_t *add_dim_prop(parser_ctx_t *ctx, class_decl_t *class_decl, d return class_decl; } +static BOOL is_const_expression(expression_t *expr) +{ + switch(expr->type) { + case EXPR_INT: + case EXPR_DOUBLE: + case EXPR_STRING: + case EXPR_BOOL: + case EXPR_DATE: + case EXPR_EMPTY: + case EXPR_NULL: + case EXPR_NOTHING: + return TRUE; + case EXPR_NEG: { + unary_expression_t *unary = (unary_expression_t*)expr; + return unary->subexpr->type == EXPR_INT || unary->subexpr->type == EXPR_DOUBLE; + } + default: + return FALSE; + } +} + static const_decl_t *new_const_decl(parser_ctx_t *ctx, const WCHAR *name, expression_t *expr) { const_decl_t *decl; + if(!is_const_expression(expr)) { + ctx->hres = MAKE_VBSERROR(VBSE_EXPECTED_LITERAL_CONSTANT); + ctx->error_loc = ctx->ptr - ctx->code - 1; + return NULL; + } + decl = parser_alloc(ctx, sizeof(*decl)); if(!decl) return NULL; diff --git a/dlls/vbscript/tests/run.c b/dlls/vbscript/tests/run.c index d3aebff098a..d977fb5cd70 100644 --- a/dlls/vbscript/tests/run.c +++ b/dlls/vbscript/tests/run.c @@ -2908,8 +2908,8 @@ static void test_parse_errors(void) { /* Expected literal constant - error 1045 */ L"Const x = 1 + \"a\"\n", - 0, -17, - NULL, S_OK, -1045 + 0, 17, + NULL, S_OK, 1045 }, { /* Expected '(' - error 1005 */ -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10496
participants (2)
-
Francis De Brabandere -
Francis De Brabandere (@francisdb)