diff --git a/dlls/jscript/jscript_En.rc b/dlls/jscript/jscript_En.rc index 96db21f601a..b47e9517abc 100644 --- a/dlls/jscript/jscript_En.rc +++ b/dlls/jscript/jscript_En.rc @@ -27,6 +27,7 @@ STRINGTABLE DISCARDABLE IDS_NO_PROPERTY "Object doesn't support this property or method" IDS_ARG_NOT_OPT "Argument not optional" IDS_SYNTAX_ERROR "Syntax error" + IDS_SEMICOLON "Expected ';'" IDS_LBRACKET "Expected '('" IDS_RBRACKET "Expected ')'" IDS_NOT_FUNC "Function expected" diff --git a/dlls/jscript/parser.y b/dlls/jscript/parser.y index bcb2c2491db..50092e5c0a6 100644 --- a/dlls/jscript/parser.y +++ b/dlls/jscript/parser.y @@ -26,6 +26,7 @@ static int parser_error(const char*); static void set_error(parser_ctx_t*,UINT); +static BOOL explicit_error(parser_ctx_t*,void*,WCHAR); static BOOL allow_auto_semicolon(parser_ctx_t*); static void program_parsed(parser_ctx_t*,source_elements_t*); static source_elements_t *function_body_parsed(parser_ctx_t*,source_elements_t*); @@ -391,10 +392,18 @@ IterationStatement { $$ = new_while_statement(ctx, TRUE, $5, $2); } | kWHILE left_bracket Expression right_bracket Statement { $$ = new_while_statement(ctx, FALSE, $3, $5); } - | kFOR left_bracket ExpressionNoIn_opt ';' Expression_opt ';' Expression_opt right_bracket Statement - { $$ = new_for_statement(ctx, NULL, $3, $5, $7, $9); } - | kFOR left_bracket kVAR VariableDeclarationListNoIn ';' Expression_opt ';' Expression_opt right_bracket Statement - { $$ = new_for_statement(ctx, $4, NULL, $6, $8, $10); } + | kFOR left_bracket ExpressionNoIn_opt + { if(!explicit_error(ctx, $3, ';')) YYABORT; } + semicolon Expression_opt + { if(!explicit_error(ctx, $6, ';')) YYABORT; } + semicolon Expression_opt right_bracket Statement + { $$ = new_for_statement(ctx, NULL, $3, $6, $9, $11); } + | kFOR left_bracket kVAR VariableDeclarationListNoIn + { if(!explicit_error(ctx, $4, ';')) YYABORT; } + semicolon Expression_opt + { if(!explicit_error(ctx, $7, ';')) YYABORT; } + semicolon Expression_opt right_bracket Statement + { $$ = new_for_statement(ctx, $4, NULL, $7, $10, $12); } | kFOR left_bracket LeftHandSideExpression kIN Expression right_bracket Statement { $$ = new_forin_statement(ctx, NULL, $3, $5, $7); } | kFOR left_bracket kVAR VariableDeclarationNoIn kIN Expression right_bracket Statement @@ -494,7 +503,6 @@ Expression ExpressionNoIn_opt : /* empty */ { $$ = NULL; } | ExpressionNoIn { $$ = $1; } - | error { set_error(ctx, IDS_SYNTAX_ERROR); YYABORT; } /* ECMA-262 3rd Edition 11.14 */ ExpressionNoIn @@ -806,6 +814,10 @@ right_bracket : ')' | error { set_error(ctx, IDS_RBRACKET); YYABORT; } +semicolon + : ';' + | error { set_error(ctx, IDS_SEMICOLON); YYABORT; } + %% static BOOL allow_auto_semicolon(parser_ctx_t *ctx) @@ -1449,6 +1461,14 @@ static void set_error(parser_ctx_t *ctx, UINT error) ctx->hres = JSCRIPT_ERROR|error; } +static BOOL explicit_error(parser_ctx_t *ctx, void *obj, WCHAR next) +{ + if(obj || *(ctx->ptr-1)==next) return TRUE; + + set_error(ctx, IDS_SYNTAX_ERROR); + return FALSE; +} + static expression_t *new_identifier_expression(parser_ctx_t *ctx, const WCHAR *identifier) { diff --git a/dlls/jscript/resource.h b/dlls/jscript/resource.h index 969ea13ac92..05039616176 100644 --- a/dlls/jscript/resource.h +++ b/dlls/jscript/resource.h @@ -23,6 +23,7 @@ #define IDS_NO_PROPERTY 0x01B6 #define IDS_ARG_NOT_OPT 0x01c1 #define IDS_SYNTAX_ERROR 0x03EA +#define IDS_SEMICOLON 0x03EC #define IDS_LBRACKET 0x03ED #define IDS_RBRACKET 0x03EE #define IDS_NOT_FUNC 0x138A diff --git a/dlls/jscript/tests/api.js b/dlls/jscript/tests/api.js index 7e43ffb76a4..720e7c0c5a7 100644 --- a/dlls/jscript/tests/api.js +++ b/dlls/jscript/tests/api.js @@ -1329,5 +1329,7 @@ exception_test(function() {eval("if(false");}, "SyntaxError", -2146827282); exception_test(function() {eval("for(i=0; i<10; i++");}, "SyntaxError", -2146827282); exception_test(function() {eval("while(true");}, "SyntaxError", -2146827282); exception_test(function() {test = function() {}}, "ReferenceError", -2146823280); +exception_test(function() {eval("for(i=0")}, "SyntaxError", -2146827284); +exception_test(function() {eval("for(i=0;i<10")}, "SyntaxError", -2146827284); reportSuccess();