From 2de18383f4e3cec85486259eb93b7652f60c6391 Mon Sep 17 00:00:00 2001 From: Robert Fancsik Date: Mon, 25 May 2020 16:08:55 +0200 Subject: [PATCH] Fix error handling in scanner when in case of OOM This patch fixes #3786 and fixes #3788. JerryScript-DCO-1.0-Signed-off-by: Robert Fancsik frobert@inf.u-szeged.hu --- jerry-core/parser/js/js-scanner-internal.h | 1 + jerry-core/parser/js/js-scanner-util.c | 17 ++++++++++++ jerry-core/parser/js/js-scanner.c | 30 ++++++++++------------ 3 files changed, 32 insertions(+), 16 deletions(-) diff --git a/jerry-core/parser/js/js-scanner-internal.h b/jerry-core/parser/js/js-scanner-internal.h index 3dbaf97a86..6214135cec 100644 --- a/jerry-core/parser/js/js-scanner-internal.h +++ b/jerry-core/parser/js/js-scanner-internal.h @@ -358,6 +358,7 @@ scanner_info_t *scanner_insert_info_before (parser_context_t *context_p, const u scanner_info_t *start_info_p, size_t size); scanner_literal_pool_t *scanner_push_literal_pool (parser_context_t *context_p, scanner_context_t *scanner_context_p, uint16_t status_flags); +void scanner_release_all_literal_pools (scanner_context_t *scanner_context_p); void scanner_pop_literal_pool (parser_context_t *context_p, scanner_context_t *scanner_context_p); #if ENABLED (JERRY_ES2015) void scanner_construct_global_block (parser_context_t *context_p, scanner_context_t *scanner_context_p); diff --git a/jerry-core/parser/js/js-scanner-util.c b/jerry-core/parser/js/js-scanner-util.c index f2d6235638..9386da922c 100644 --- a/jerry-core/parser/js/js-scanner-util.c +++ b/jerry-core/parser/js/js-scanner-util.c @@ -463,6 +463,23 @@ scanner_literal_is_arguments (lexer_lit_location_t *literal_p) /**< literal */ return lexer_compare_identifier_to_string (literal_p, (const uint8_t *) "arguments", 9); } /* scanner_literal_is_arguments */ +/** + * Release all literal pools + */ +void +scanner_release_all_literal_pools (scanner_context_t *scanner_context_p) /**< scanner context */ +{ + while (scanner_context_p->active_literal_pool_p != NULL) + { + scanner_literal_pool_t *literal_pool_p = scanner_context_p->active_literal_pool_p; + + scanner_context_p->active_literal_pool_p = literal_pool_p->prev_p; + + parser_list_free (&literal_pool_p->literal_pool); + scanner_free (literal_pool_p, sizeof (scanner_literal_pool_t)); + } +} /* scanner_release_all_literal_pools */ + /** * Pop the last literal pool from the end. */ diff --git a/jerry-core/parser/js/js-scanner.c b/jerry-core/parser/js/js-scanner.c index 45f643423b..ccb2a4fdcf 100644 --- a/jerry-core/parser/js/js-scanner.c +++ b/jerry-core/parser/js/js-scanner.c @@ -3159,12 +3159,6 @@ scanner_scan_all (parser_context_t *context_p, /**< context */ } PARSER_CATCH { - /* Ignore the errors thrown by the lexer. */ - if (context_p->error != PARSER_ERR_OUT_OF_MEMORY) - { - context_p->error = PARSER_ERR_NO_ERROR; - } - #if ENABLED (JERRY_ES2015) while (scanner_context.active_binding_list_p != NULL) { @@ -3172,6 +3166,16 @@ scanner_scan_all (parser_context_t *context_p, /**< context */ } #endif /* ENABLED (JERRY_ES2015) */ + if (JERRY_UNLIKELY (context_p->error == PARSER_ERR_OUT_OF_MEMORY)) + { + scanner_release_all_literal_pools (&scanner_context); + parser_stack_free (context_p); + return; + } + + /* Ignore the errors thrown by the lexer. */ + context_p->error = PARSER_ERR_NO_ERROR; + /* The following code may allocate memory, so it is enclosed in a try/catch. */ PARSER_TRY (context_p->try_buffer) { @@ -3193,17 +3197,11 @@ scanner_scan_all (parser_context_t *context_p, /**< context */ } PARSER_CATCH { - JERRY_ASSERT (context_p->error == PARSER_ERR_NO_ERROR); + JERRY_ASSERT (context_p->error == PARSER_ERR_OUT_OF_MEMORY); - while (scanner_context.active_literal_pool_p != NULL) - { - scanner_literal_pool_t *literal_pool_p = scanner_context.active_literal_pool_p; - - scanner_context.active_literal_pool_p = literal_pool_p->prev_p; - - parser_list_free (&literal_pool_p->literal_pool); - scanner_free (literal_pool_p, sizeof (scanner_literal_pool_t)); - } + scanner_release_all_literal_pools (&scanner_context); + parser_stack_free (context_p); + return; } PARSER_TRY_END