From 0fb086d5736508b1dca3c6433fa67a6df482b8a1 Mon Sep 17 00:00:00 2001 From: Jacek Caban Date: Thu, 23 Jan 2020 13:52:15 +0100 Subject: [PATCH] jscript: Use parser location to calculate function body string. Signed-off-by: Jacek Caban Signed-off-by: Alexandre Julliard --- dlls/jscript/compile.c | 10 +++++++++- dlls/jscript/lex.c | 16 ++++++++-------- dlls/jscript/parser.h | 2 +- dlls/jscript/parser.y | 30 +++++++++++++----------------- 4 files changed, 31 insertions(+), 27 deletions(-) diff --git a/dlls/jscript/compile.c b/dlls/jscript/compile.c index a530e87d8e1..d8eb3de7149 100644 --- a/dlls/jscript/compile.c +++ b/dlls/jscript/compile.c @@ -2245,6 +2245,11 @@ void release_bytecode(bytecode_t *code) static HRESULT init_code(compiler_ctx_t *compiler, const WCHAR *source) { + size_t len = source ? lstrlenW(source) : 0; + + if(len > INT32_MAX) + return E_OUTOFMEMORY; + compiler->code = heap_alloc_zero(sizeof(bytecode_t)); if(!compiler->code) return E_OUTOFMEMORY; @@ -2252,11 +2257,14 @@ static HRESULT init_code(compiler_ctx_t *compiler, const WCHAR *source) compiler->code->ref = 1; heap_pool_init(&compiler->code->heap); - compiler->code->source = heap_strdupW(source); + compiler->code->source = heap_alloc((len + 1) * sizeof(WCHAR)); if(!compiler->code->source) { release_bytecode(compiler->code); return E_OUTOFMEMORY; } + if(len) + memcpy(compiler->code->source, source, len * sizeof(WCHAR)); + compiler->code->source[len] = 0; compiler->code->instrs = heap_alloc(64 * sizeof(instr_t)); if(!compiler->code->instrs) { diff --git a/dlls/jscript/lex.c b/dlls/jscript/lex.c index 1b34a14a792..de8549eeaf5 100644 --- a/dlls/jscript/lex.c +++ b/dlls/jscript/lex.c @@ -543,12 +543,15 @@ static BOOL parse_numeric_literal(parser_ctx_t *ctx, double *ret) return TRUE; } -static int next_token(parser_ctx_t *ctx, void *lval) +static int next_token(parser_ctx_t *ctx, unsigned *loc, void *lval) { do { - if(!skip_spaces(ctx)) + if(!skip_spaces(ctx)) { + *loc = ctx->ptr - ctx->begin; return tEOF; + } }while(skip_comment(ctx) || skip_html_comment(ctx)); + *loc = ctx->ptr - ctx->begin; if(ctx->implicit_nl_semicolon) { if(ctx->nl) @@ -576,6 +579,7 @@ static int next_token(parser_ctx_t *ctx, void *lval) switch(*ctx->ptr) { case '{': + case '}': case '(': case ')': case '[': @@ -586,10 +590,6 @@ static int next_token(parser_ctx_t *ctx, void *lval) case '?': return *ctx->ptr++; - case '}': - *(const WCHAR**)lval = ctx->ptr++; - return '}'; - case '.': if(ctx->ptr+1 < ctx->end && is_digit(ctx->ptr[1])) { double n; @@ -1099,14 +1099,14 @@ static int cc_token(parser_ctx_t *ctx, void *lval) return tBooleanLiteral; } -int parser_lex(void *lval, parser_ctx_t *ctx) +int parser_lex(void *lval, unsigned *loc, parser_ctx_t *ctx) { int ret; ctx->nl = ctx->ptr == ctx->begin; do { - ret = next_token(ctx, lval); + ret = next_token(ctx, loc, lval); } while(ret == '@' && !(ret = cc_token(ctx, lval))); return ret; diff --git a/dlls/jscript/parser.h b/dlls/jscript/parser.h index bceb5569b4a..d180c0551a1 100644 --- a/dlls/jscript/parser.h +++ b/dlls/jscript/parser.h @@ -51,7 +51,7 @@ typedef struct _parser_ctx_t { HRESULT script_parse(script_ctx_t*,struct _compiler_ctx_t*,const WCHAR*,const WCHAR*,BOOL,parser_ctx_t**) DECLSPEC_HIDDEN; void parser_release(parser_ctx_t*) DECLSPEC_HIDDEN; -int parser_lex(void*,parser_ctx_t*) DECLSPEC_HIDDEN; +int parser_lex(void*,unsigned*,parser_ctx_t*) DECLSPEC_HIDDEN; static inline void *parser_alloc(parser_ctx_t *ctx, DWORD size) { diff --git a/dlls/jscript/parser.y b/dlls/jscript/parser.y index ca83b6fd15b..aa5e27d7c77 100644 --- a/dlls/jscript/parser.y +++ b/dlls/jscript/parser.y @@ -26,7 +26,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(jscript); -static int parser_error(parser_ctx_t*,const char*); +static int parser_error(unsigned*,parser_ctx_t*,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*); @@ -137,6 +137,9 @@ static expression_t *new_prop_and_value_expression(parser_ctx_t*,property_list_t static source_elements_t *new_source_elements(parser_ctx_t*); static source_elements_t *source_elements_add_statement(source_elements_t*,statement_t*); +#define YYLTYPE unsigned +#define YYLLOC_DEFAULT(Cur, Rhs, N) Cur = YYRHSLOC((Rhs), (N) ? 1 : 0) + %} %lex-param { parser_ctx_t *ctx } @@ -146,7 +149,6 @@ static source_elements_t *source_elements_add_statement(source_elements_t*,state %union { int ival; - const WCHAR *srcptr; jsstr_t *str; literal_t *literal; struct _argument_list_t *argument_list; @@ -171,8 +173,6 @@ static source_elements_t *source_elements_add_statement(source_elements_t*,state %token kINSTANCEOF kNEW kNULL kRETURN kSWITCH kTHIS kTHROW kTRUE kFALSE kTRY kTYPEOF kVAR kVOID kWHILE kWITH %token tANDAND tOROR tINC tDEC tHTMLCOMMENT kDIVEQ kDCOL -%token '}' - /* tokens */ %token tIdentifier %token tAssignOper tEqOper tShiftOper tRelOper @@ -244,7 +244,6 @@ static source_elements_t *source_elements_add_statement(source_elements_t*,state %type PropertyDefinition %type PropertyName %type BooleanLiteral -%type KFunction left_bracket %type AssignOper %type IdentifierName ReservedAsIdentifier @@ -270,15 +269,12 @@ SourceElements /* ECMA-262 3rd Edition 13 */ FunctionExpression - : KFunction left_bracket FormalParameterList_opt right_bracket '{' FunctionBody '}' - { $$ = new_function_expression(ctx, NULL, $3, $6, NULL, $1, $7-$1+1); } - | KFunction tIdentifier left_bracket FormalParameterList_opt right_bracket '{' FunctionBody '}' - { $$ = new_function_expression(ctx, $2, $4, $7, NULL, $1, $8-$1+1); } - | KFunction tIdentifier kDCOL tIdentifier left_bracket FormalParameterList_opt right_bracket '{' FunctionBody '}' - { $$ = new_function_expression(ctx, $4, $6, $9, $2, $1, $10-$1+1); } - -KFunction - : kFUNCTION { $$ = ctx->ptr - 8; } + : kFUNCTION left_bracket FormalParameterList_opt right_bracket '{' FunctionBody '}' + { $$ = new_function_expression(ctx, NULL, $3, $6, NULL, ctx->begin + @1, @7 - @1 + 1); } + | kFUNCTION tIdentifier left_bracket FormalParameterList_opt right_bracket '{' FunctionBody '}' + { $$ = new_function_expression(ctx, $2, $4, $7, NULL, ctx->begin + @1, @8 - @1 + 1); } + | kFUNCTION tIdentifier kDCOL tIdentifier left_bracket FormalParameterList_opt right_bracket '{' FunctionBody '}' + { $$ = new_function_expression(ctx, $4, $6, $9, $2, ctx->begin + @1, @10 - @1 + 1); } /* ECMA-262 3rd Edition 13 */ FunctionBody @@ -809,7 +805,7 @@ PropertyDefinition GetterSetterMethod : left_bracket FormalParameterList_opt right_bracket '{' FunctionBody '}' - { $$ = new_function_expression(ctx, NULL, $2, $5, NULL, $1, $6-$1); } + { $$ = new_function_expression(ctx, NULL, $2, $5, NULL, ctx->begin + @1, @6 - @1 + 1); } /* Ecma-262 3rd Edition 11.1.5 */ PropertyName @@ -889,7 +885,7 @@ semicolon_opt | error { if(!allow_auto_semicolon(ctx)) {YYABORT;} } left_bracket - : '(' { $$ = ctx->ptr; } + : '(' | error { set_error(ctx, JS_E_MISSING_LBRACKET); YYABORT; } right_bracket @@ -1461,7 +1457,7 @@ static expression_t *new_call_expression(parser_ctx_t *ctx, expression_t *expres return &ret->expr; } -static int parser_error(parser_ctx_t *ctx, const char *str) +static int parser_error(unsigned *loc, parser_ctx_t *ctx, const char *str) { return 0; }