From f32c18313738c3b42574ba0916295c3fb7207ea0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A1szl=C3=B3=20Lang=C3=B3?= Date: Mon, 11 Jun 2018 09:25:53 +0200 Subject: [PATCH] Fixed assertion in 're_insert_into_group'. (#2388) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Assertion 'qmin <= qmax' failed in 're_insert_into_group', but it should throw a SyntaxError. Fixes #2384. JerryScript-DCO-1.0-Signed-off-by: László Langó llango.u-szeged@partner.samsung.com --- jerry-core/parser/regexp/re-compiler.c | 48 +++++++++++++++-------- tests/jerry/regression-test-issue-2384.js | 20 ++++++++++ 2 files changed, 52 insertions(+), 16 deletions(-) create mode 100644 tests/jerry/regression-test-issue-2384.js diff --git a/jerry-core/parser/regexp/re-compiler.c b/jerry-core/parser/regexp/re-compiler.c index 9046fa46e..89df5829a 100644 --- a/jerry-core/parser/regexp/re-compiler.c +++ b/jerry-core/parser/regexp/re-compiler.c @@ -75,7 +75,8 @@ re_insert_simple_iterator (re_compiler_ctx_t *re_ctx_p, /**< RegExp compiler con } else if (qmin > qmax) { - return ecma_raise_syntax_error (ECMA_ERR_MSG ("RegExp quantifier error: qmin > qmax.")); + /* ECMA-262 v5.1 15.10.2.5 */ + return ecma_raise_syntax_error (ECMA_ERR_MSG ("RegExp quantifier error: min > max.")); } /* TODO: optimize bytecode length. Store 0 rather than INF */ @@ -166,23 +167,31 @@ re_get_end_opcode_type (re_compiler_ctx_t *re_ctx_p, /**< RegExp compiler contex /** * Enclose the given bytecode to a group + * + * @return empty ecma value - if inserted successfully + * error ecma value - otherwise + * + * Returned value must be freed with ecma_free_value */ -static void +static ecma_value_t re_insert_into_group (re_compiler_ctx_t *re_ctx_p, /**< RegExp compiler context */ uint32_t group_start_offset, /**< offset of group start */ uint32_t idx, /**< index of group */ bool is_capturable) /**< is capturable group */ { - uint32_t qmin, qmax; + uint32_t qmin = re_ctx_p->current_token.qmin; + uint32_t qmax = re_ctx_p->current_token.qmax; + + if (qmin > qmax) + { + /* ECMA-262 v5.1 15.10.2.5 */ + return ecma_raise_syntax_error (ECMA_ERR_MSG ("RegExp quantifier error: min > max.")); + } + re_opcode_t start_opcode = re_get_start_opcode_type (re_ctx_p, is_capturable); re_opcode_t end_opcode = re_get_end_opcode_type (re_ctx_p, is_capturable); - uint32_t start_head_offset_len; - qmin = re_ctx_p->current_token.qmin; - qmax = re_ctx_p->current_token.qmax; - JERRY_ASSERT (qmin <= qmax); - - start_head_offset_len = re_get_bytecode_length (re_ctx_p->bytecode_ctx_p); + uint32_t start_head_offset_len = re_get_bytecode_length (re_ctx_p->bytecode_ctx_p); re_insert_u32 (re_ctx_p->bytecode_ctx_p, group_start_offset, idx); re_insert_opcode (re_ctx_p->bytecode_ctx_p, group_start_offset, start_opcode); start_head_offset_len = re_get_bytecode_length (re_ctx_p->bytecode_ctx_p) - start_head_offset_len; @@ -201,12 +210,19 @@ re_insert_into_group (re_compiler_ctx_t *re_ctx_p, /**< RegExp compiler context group_start_offset, re_get_bytecode_length (re_ctx_p->bytecode_ctx_p) - group_start_offset); } + + return ECMA_VALUE_EMPTY; } /* re_insert_into_group */ /** * Enclose the given bytecode to a group and inster jump value + * + * @return empty ecma value - if inserted successfully + * error ecma value - otherwise + * + * Returned value must be freed with ecma_free_value */ -static void +static ecma_value_t re_insert_into_group_with_jump (re_compiler_ctx_t *re_ctx_p, /**< RegExp compiler context */ uint32_t group_start_offset, /**< offset of group start */ uint32_t idx, /**< index of group */ @@ -215,7 +231,7 @@ re_insert_into_group_with_jump (re_compiler_ctx_t *re_ctx_p, /**< RegExp compile re_insert_u32 (re_ctx_p->bytecode_ctx_p, group_start_offset, re_get_bytecode_length (re_ctx_p->bytecode_ctx_p) - group_start_offset); - re_insert_into_group (re_ctx_p, group_start_offset, idx, is_capturable); + return re_insert_into_group (re_ctx_p, group_start_offset, idx, is_capturable); } /* re_insert_into_group_with_jump */ /** @@ -261,7 +277,7 @@ re_parse_alternative (re_compiler_ctx_t *re_ctx_p, /**< RegExp compiler context if (ecma_is_value_empty (ret_value)) { - re_insert_into_group (re_ctx_p, new_atom_start_offset, idx, true); + ret_value = re_insert_into_group (re_ctx_p, new_atom_start_offset, idx, true); } break; @@ -275,7 +291,7 @@ re_parse_alternative (re_compiler_ctx_t *re_ctx_p, /**< RegExp compiler context if (ecma_is_value_empty (ret_value)) { - re_insert_into_group (re_ctx_p, new_atom_start_offset, idx, false); + ret_value = re_insert_into_group (re_ctx_p, new_atom_start_offset, idx, false); } break; @@ -345,7 +361,7 @@ re_parse_alternative (re_compiler_ctx_t *re_ctx_p, /**< RegExp compiler context { re_append_opcode (bc_ctx_p, RE_OP_MATCH); - re_insert_into_group_with_jump (re_ctx_p, new_atom_start_offset, idx, false); + ret_value = re_insert_into_group_with_jump (re_ctx_p, new_atom_start_offset, idx, false); } break; @@ -362,7 +378,7 @@ re_parse_alternative (re_compiler_ctx_t *re_ctx_p, /**< RegExp compiler context { re_append_opcode (bc_ctx_p, RE_OP_MATCH); - re_insert_into_group_with_jump (re_ctx_p, new_atom_start_offset, idx, false); + ret_value = re_insert_into_group_with_jump (re_ctx_p, new_atom_start_offset, idx, false); } break; @@ -381,7 +397,7 @@ re_parse_alternative (re_compiler_ctx_t *re_ctx_p, /**< RegExp compiler context re_append_opcode (bc_ctx_p, RE_OP_BACKREFERENCE); re_append_u32 (bc_ctx_p, backref); - re_insert_into_group_with_jump (re_ctx_p, new_atom_start_offset, idx, false); + ret_value = re_insert_into_group_with_jump (re_ctx_p, new_atom_start_offset, idx, false); break; } case RE_TOK_DIGIT: diff --git a/tests/jerry/regression-test-issue-2384.js b/tests/jerry/regression-test-issue-2384.js new file mode 100644 index 000000000..fc2c41050 --- /dev/null +++ b/tests/jerry/regression-test-issue-2384.js @@ -0,0 +1,20 @@ +// Copyright JS Foundation and other contributors, http://js.foundation +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +try { + "[]{83}".match("(?=){12,8}"); + assert (false); +} catch (e) { + assert (e instanceof SyntaxError); +}