Fix: parsing regex and div operator correctly
JerryScript-DCO-1.0-Signed-off-by: Hanjoung Lee hanjoung.lee@samsung.com
This commit is contained in:
@@ -1262,10 +1262,15 @@ lexer_parse_comment (void)
|
|||||||
* Currently, lexer token doesn't fully correspond to Token, defined in ECMA-262, v5, 7.5.
|
* Currently, lexer token doesn't fully correspond to Token, defined in ECMA-262, v5, 7.5.
|
||||||
* For example, there is no new-line token type in the token definition of ECMA-262 v5.
|
* For example, there is no new-line token type in the token definition of ECMA-262 v5.
|
||||||
*
|
*
|
||||||
|
* Note:
|
||||||
|
* For Lexer alone, it is hard to find out a token is whether a regexp or a division.
|
||||||
|
* Parser must set maybe_regexp to true if a regexp is expected.
|
||||||
|
* Otherwise, a division is expected.
|
||||||
|
*
|
||||||
* @return constructed token
|
* @return constructed token
|
||||||
*/
|
*/
|
||||||
static token
|
static token
|
||||||
lexer_parse_token (void)
|
lexer_parse_token (bool maybe_regexp) /**< read '/' as regexp? */
|
||||||
{
|
{
|
||||||
ecma_char_t c = LA (0);
|
ecma_char_t c = LA (0);
|
||||||
|
|
||||||
@@ -1335,21 +1340,11 @@ lexer_parse_token (void)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return lexer_parse_token ();
|
return lexer_parse_token (maybe_regexp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (c == LIT_CHAR_SLASH
|
if (c == LIT_CHAR_SLASH && maybe_regexp)
|
||||||
&& !(prev_non_lf_token.type == TOK_NAME
|
|
||||||
|| prev_non_lf_token.type == TOK_NULL
|
|
||||||
|| prev_non_lf_token.type == TOK_BOOL
|
|
||||||
|| prev_non_lf_token.type == TOK_CLOSE_BRACE
|
|
||||||
|| prev_non_lf_token.type == TOK_CLOSE_SQUARE
|
|
||||||
|| prev_non_lf_token.type == TOK_CLOSE_PAREN
|
|
||||||
|| prev_non_lf_token.type == TOK_SMALL_INT
|
|
||||||
|| prev_non_lf_token.type == TOK_NUMBER
|
|
||||||
|| prev_non_lf_token.type == TOK_STRING
|
|
||||||
|| prev_non_lf_token.type == TOK_REGEXP))
|
|
||||||
{
|
{
|
||||||
return lexer_parse_regexp ();
|
return lexer_parse_regexp ();
|
||||||
}
|
}
|
||||||
@@ -1517,7 +1512,7 @@ lexer_parse_token (void)
|
|||||||
} /* lexer_parse_token */
|
} /* lexer_parse_token */
|
||||||
|
|
||||||
token
|
token
|
||||||
lexer_next_token (void)
|
lexer_next_token (bool maybe_regexp) /**< read '/' as regexp? */
|
||||||
{
|
{
|
||||||
lit_utf8_iterator_pos_t src_pos = lit_utf8_iterator_get_pos (&src_iter);
|
lit_utf8_iterator_pos_t src_pos = lit_utf8_iterator_get_pos (&src_iter);
|
||||||
if (src_pos.offset == 0 && !src_pos.is_non_bmp_middle)
|
if (src_pos.offset == 0 && !src_pos.is_non_bmp_middle)
|
||||||
@@ -1546,7 +1541,7 @@ lexer_next_token (void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
prev_token = sent_token;
|
prev_token = sent_token;
|
||||||
sent_token = lexer_parse_token ();
|
sent_token = lexer_parse_token (maybe_regexp);
|
||||||
|
|
||||||
if (sent_token.type == TOK_NEWLINE)
|
if (sent_token.type == TOK_NEWLINE)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -171,7 +171,7 @@ typedef struct
|
|||||||
|
|
||||||
void lexer_init (const jerry_api_char_t *, size_t, bool);
|
void lexer_init (const jerry_api_char_t *, size_t, bool);
|
||||||
|
|
||||||
token lexer_next_token (void);
|
token lexer_next_token (bool);
|
||||||
void lexer_save_token (token);
|
void lexer_save_token (token);
|
||||||
token lexer_prev_token (void);
|
token lexer_prev_token (void);
|
||||||
|
|
||||||
|
|||||||
@@ -95,9 +95,19 @@ token_data_as_lit_cp (void)
|
|||||||
static void
|
static void
|
||||||
skip_token (void)
|
skip_token (void)
|
||||||
{
|
{
|
||||||
tok = lexer_next_token ();
|
tok = lexer_next_token (false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* In case a regexp token is scanned as a division operator, rescan it
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
rescan_regexp_token (void)
|
||||||
|
{
|
||||||
|
lexer_seek (tok.loc);
|
||||||
|
tok = lexer_next_token (true);
|
||||||
|
} /* rescan_regexp_token */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
assert_keyword (keyword kw)
|
assert_keyword (keyword kw)
|
||||||
{
|
{
|
||||||
@@ -252,7 +262,7 @@ jsp_find_next_token_before_the_locus (token_type token_to_find, /**< token to se
|
|||||||
if (lit_utf8_iterator_pos_cmp (tok.loc, end_loc) >= 0)
|
if (lit_utf8_iterator_pos_cmp (tok.loc, end_loc) >= 0)
|
||||||
{
|
{
|
||||||
lexer_seek (end_loc);
|
lexer_seek (end_loc);
|
||||||
tok = lexer_next_token ();
|
tok = lexer_next_token (false);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -830,6 +840,13 @@ parse_primary_expression (void)
|
|||||||
|
|
||||||
switch (tok.type)
|
switch (tok.type)
|
||||||
{
|
{
|
||||||
|
case TOK_DIV:
|
||||||
|
case TOK_DIV_EQ:
|
||||||
|
{
|
||||||
|
// must be a regexp literal so rescan the token
|
||||||
|
rescan_regexp_token ();
|
||||||
|
/* FALLTHRU */
|
||||||
|
}
|
||||||
case TOK_NULL:
|
case TOK_NULL:
|
||||||
case TOK_BOOL:
|
case TOK_BOOL:
|
||||||
case TOK_SMALL_INT:
|
case TOK_SMALL_INT:
|
||||||
@@ -2129,7 +2146,7 @@ jsp_parse_for_in_statement (jsp_label_t *outermost_stmt_label_p, /**< outermost
|
|||||||
|
|
||||||
// Dump assignment VariableDeclarationNoIn / LeftHandSideExpression <- VM_REG_SPECIAL_FOR_IN_PROPERTY_NAME
|
// Dump assignment VariableDeclarationNoIn / LeftHandSideExpression <- VM_REG_SPECIAL_FOR_IN_PROPERTY_NAME
|
||||||
lexer_seek (iterator_loc);
|
lexer_seek (iterator_loc);
|
||||||
tok = lexer_next_token ();
|
tok = lexer_next_token (false);
|
||||||
|
|
||||||
jsp_operand_t iterator_base, iterator_identifier, for_in_special_reg;
|
jsp_operand_t iterator_base, iterator_identifier, for_in_special_reg;
|
||||||
for_in_special_reg = jsp_create_operand_for_in_special_reg ();
|
for_in_special_reg = jsp_create_operand_for_in_special_reg ();
|
||||||
@@ -2146,7 +2163,7 @@ jsp_parse_for_in_statement (jsp_label_t *outermost_stmt_label_p, /**< outermost
|
|||||||
|
|
||||||
// Body
|
// Body
|
||||||
lexer_seek (for_body_statement_loc);
|
lexer_seek (for_body_statement_loc);
|
||||||
tok = lexer_next_token ();
|
tok = lexer_next_token (false);
|
||||||
|
|
||||||
parse_statement (NULL);
|
parse_statement (NULL);
|
||||||
|
|
||||||
@@ -2164,7 +2181,7 @@ jsp_parse_for_in_statement (jsp_label_t *outermost_stmt_label_p, /**< outermost
|
|||||||
dump_for_in_end ();
|
dump_for_in_end ();
|
||||||
|
|
||||||
lexer_seek (loop_end_loc);
|
lexer_seek (loop_end_loc);
|
||||||
tok = lexer_next_token ();
|
tok = lexer_next_token (false);
|
||||||
if (tok.type != TOK_CLOSE_BRACE)
|
if (tok.type != TOK_CLOSE_BRACE)
|
||||||
{
|
{
|
||||||
lexer_save_token (tok);
|
lexer_save_token (tok);
|
||||||
@@ -2201,13 +2218,13 @@ jsp_parse_for_or_for_in_statement (jsp_label_t *outermost_stmt_label_p) /**< out
|
|||||||
for_body_statement_loc = tok.loc;
|
for_body_statement_loc = tok.loc;
|
||||||
|
|
||||||
lexer_seek (for_open_paren_loc);
|
lexer_seek (for_open_paren_loc);
|
||||||
tok = lexer_next_token ();
|
tok = lexer_next_token (false);
|
||||||
|
|
||||||
bool is_plain_for = jsp_find_next_token_before_the_locus (TOK_SEMICOLON,
|
bool is_plain_for = jsp_find_next_token_before_the_locus (TOK_SEMICOLON,
|
||||||
for_body_statement_loc,
|
for_body_statement_loc,
|
||||||
true);
|
true);
|
||||||
lexer_seek (for_open_paren_loc);
|
lexer_seek (for_open_paren_loc);
|
||||||
tok = lexer_next_token ();
|
tok = lexer_next_token (false);
|
||||||
|
|
||||||
if (is_plain_for)
|
if (is_plain_for)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -65,3 +65,21 @@ try {
|
|||||||
} catch (e) {
|
} catch (e) {
|
||||||
assert(e instanceof SyntaxError);
|
assert(e instanceof SyntaxError);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
eval("var x = /aaa/");
|
||||||
|
} catch (e) {
|
||||||
|
assert (false);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
eval("{}/a/g");
|
||||||
|
} catch (e) {
|
||||||
|
assert (false);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
eval("var a, g; +{}/a/g");
|
||||||
|
} catch (e) {
|
||||||
|
assert (false);
|
||||||
|
}
|
||||||
|
|||||||
@@ -0,0 +1,32 @@
|
|||||||
|
// Copyright 2015 Samsung Electronics Co., Ltd.
|
||||||
|
// Copyright 2015 University of Szeged.
|
||||||
|
//
|
||||||
|
// 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 {
|
||||||
|
eval('if (true) /abc/.exec("abc");');
|
||||||
|
} catch (e) {
|
||||||
|
assert (false);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
eval('if (true) {} /abc/.exec("abc");');
|
||||||
|
} catch (e) {
|
||||||
|
assert (false);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
eval('var a\n/abc/.exec("abc");');
|
||||||
|
} catch (e) {
|
||||||
|
assert (false);
|
||||||
|
}
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
// Copyright 2015 Samsung Electronics Co., Ltd.
|
||||||
|
// Copyright 2015 University of Szeged.
|
||||||
|
//
|
||||||
|
// 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 {
|
||||||
|
eval("this / 10");
|
||||||
|
} catch (e) {
|
||||||
|
assert (false);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
eval("var v_0 = 10;\nv_0++ / 1");
|
||||||
|
} catch (e) {
|
||||||
|
assert (false);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
eval("var v_0 = 10;\nif (v_0++ / 1) {\n}");
|
||||||
|
} catch (e) {
|
||||||
|
assert (false);
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
// Copyright 2015 Samsung Electronics Co., Ltd.
|
||||||
|
// Copyright 2015 University of Szeged.
|
||||||
|
//
|
||||||
|
// 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 {
|
||||||
|
eval("if (true) {}\n/a/;");
|
||||||
|
} catch (e) {
|
||||||
|
assert (false);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user