Improve expected identifier checks. (#3064)
Checks for "of" or "from" does not accept quoted strings. JerryScript-DCO-1.0-Signed-off-by: Zoltan Herczeg zherczeg.u-szeged@partner.samsung.com
This commit is contained in:
committed by
Robert Fancsik
parent
086c4ebf13
commit
96edec1a62
@@ -47,6 +47,7 @@
|
|||||||
*/
|
*/
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
|
/* The LEXER_IS_IDENT_OR_STRING macro must be updated if the order is changed. */
|
||||||
LEXER_IDENT_LITERAL = 0, /**< identifier literal */
|
LEXER_IDENT_LITERAL = 0, /**< identifier literal */
|
||||||
LEXER_STRING_LITERAL = 1, /**< string literal */
|
LEXER_STRING_LITERAL = 1, /**< string literal */
|
||||||
LEXER_NUMBER_LITERAL = 2, /**< number literal */
|
LEXER_NUMBER_LITERAL = 2, /**< number literal */
|
||||||
@@ -56,6 +57,11 @@ typedef enum
|
|||||||
used by the byte code generator. */
|
used by the byte code generator. */
|
||||||
} lexer_literal_type_t;
|
} lexer_literal_type_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks whether the literal type is identifier or string.
|
||||||
|
*/
|
||||||
|
#define LEXER_IS_IDENT_OR_STRING(literal_type) ((literal_type) <= LEXER_STRING_LITERAL)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Flag bits for status_flags member of lexer_literal_t.
|
* Flag bits for status_flags member of lexer_literal_t.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -2331,12 +2331,12 @@ lexer_expect_object_literal_id (parser_context_t *context_p, /**< context */
|
|||||||
if (context_p->source_p < context_p->source_end_p
|
if (context_p->source_p < context_p->source_end_p
|
||||||
&& context_p->source_p[0] != LIT_CHAR_COLON)
|
&& context_p->source_p[0] != LIT_CHAR_COLON)
|
||||||
{
|
{
|
||||||
if (lexer_compare_raw_identifier_to_current (context_p, "get", 3))
|
if (lexer_compare_literal_to_string (context_p, "get", 3))
|
||||||
{
|
{
|
||||||
context_p->token.type = LEXER_PROPERTY_GETTER;
|
context_p->token.type = LEXER_PROPERTY_GETTER;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (lexer_compare_raw_identifier_to_current (context_p, "set", 3))
|
else if (lexer_compare_literal_to_string (context_p, "set", 3))
|
||||||
{
|
{
|
||||||
context_p->token.type = LEXER_PROPERTY_SETTER;
|
context_p->token.type = LEXER_PROPERTY_SETTER;
|
||||||
return;
|
return;
|
||||||
@@ -2345,8 +2345,7 @@ lexer_expect_object_literal_id (parser_context_t *context_p, /**< context */
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if ENABLED (JERRY_ES2015_CLASS)
|
#if ENABLED (JERRY_ES2015_CLASS)
|
||||||
if (is_class_method
|
if (is_class_method && lexer_compare_literal_to_string (context_p, "static", 6))
|
||||||
&& lexer_compare_raw_identifier_to_current (context_p, "static", 6))
|
|
||||||
{
|
{
|
||||||
context_p->token.type = LEXER_KEYW_STATIC;
|
context_p->token.type = LEXER_KEYW_STATIC;
|
||||||
return;
|
return;
|
||||||
@@ -2406,8 +2405,7 @@ lexer_expect_object_literal_id (parser_context_t *context_p, /**< context */
|
|||||||
if (create_literal_object)
|
if (create_literal_object)
|
||||||
{
|
{
|
||||||
#if ENABLED (JERRY_ES2015_CLASS)
|
#if ENABLED (JERRY_ES2015_CLASS)
|
||||||
if (is_class_method
|
if (is_class_method && lexer_compare_literal_to_string (context_p, "constructor", 11))
|
||||||
&& lexer_compare_raw_identifier_to_current (context_p, "constructor", 11))
|
|
||||||
{
|
{
|
||||||
context_p->token.type = LEXER_CLASS_CONSTRUCTOR;
|
context_p->token.type = LEXER_CLASS_CONSTRUCTOR;
|
||||||
return;
|
return;
|
||||||
@@ -2447,11 +2445,11 @@ lexer_scan_identifier (parser_context_t *context_p, /**< context */
|
|||||||
if (context_p->source_p < context_p->source_end_p
|
if (context_p->source_p < context_p->source_end_p
|
||||||
&& context_p->source_p[0] != LIT_CHAR_COLON)
|
&& context_p->source_p[0] != LIT_CHAR_COLON)
|
||||||
{
|
{
|
||||||
if (lexer_compare_raw_identifier_to_current (context_p, "get", 3))
|
if (lexer_compare_literal_to_string (context_p, "get", 3))
|
||||||
{
|
{
|
||||||
context_p->token.type = LEXER_PROPERTY_GETTER;
|
context_p->token.type = LEXER_PROPERTY_GETTER;
|
||||||
}
|
}
|
||||||
else if (lexer_compare_raw_identifier_to_current (context_p, "set", 3))
|
else if (lexer_compare_literal_to_string (context_p, "set", 3))
|
||||||
{
|
{
|
||||||
context_p->token.type = LEXER_PROPERTY_SETTER;
|
context_p->token.type = LEXER_PROPERTY_SETTER;
|
||||||
}
|
}
|
||||||
@@ -2573,27 +2571,46 @@ lexer_compare_identifier_to_current (parser_context_t *context_p, /**< context *
|
|||||||
} /* lexer_compare_identifier_to_current */
|
} /* lexer_compare_identifier_to_current */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compares the current identifier in the context to the parameter identifier
|
* Compares the current identifier to an expected identifier.
|
||||||
*
|
*
|
||||||
* Note:
|
* Note:
|
||||||
* Escape sequences are not allowed.
|
* Escape sequences are not allowed.
|
||||||
*
|
*
|
||||||
* @return true if the input identifiers are the same
|
* @return true if they are the same, false otherwise
|
||||||
*/
|
*/
|
||||||
bool
|
inline bool JERRY_ATTR_ALWAYS_INLINE
|
||||||
lexer_compare_raw_identifier_to_current (parser_context_t *context_p, /**< context */
|
lexer_compare_literal_to_identifier (parser_context_t *context_p, /**< context */
|
||||||
const char *right_ident_p, /**< identifier */
|
const char *identifier_p, /**< identifier */
|
||||||
size_t right_ident_length) /**< identifier length */
|
size_t identifier_length) /**< identifier length */
|
||||||
{
|
{
|
||||||
lexer_lit_location_t *left_ident_p = &context_p->token.lit_location;
|
/* Checking has_escape is unnecessary because memcmp will fail if escape sequences are present. */
|
||||||
|
return (context_p->token.type == LEXER_LITERAL
|
||||||
|
&& context_p->token.lit_location.type == LEXER_IDENT_LITERAL
|
||||||
|
&& context_p->token.lit_location.length == identifier_length
|
||||||
|
&& memcmp (context_p->token.lit_location.char_p, identifier_p, identifier_length) == 0);
|
||||||
|
} /* lexer_compare_literal_to_identifier */
|
||||||
|
|
||||||
if (left_ident_p->length != right_ident_length || left_ident_p->has_escape)
|
/**
|
||||||
{
|
* Compares the current identifier or string to an expected string.
|
||||||
return 0;
|
*
|
||||||
}
|
* Note:
|
||||||
|
* Escape sequences are not allowed.
|
||||||
|
*
|
||||||
|
* @return true if they are the same, false otherwise
|
||||||
|
*/
|
||||||
|
inline bool JERRY_ATTR_ALWAYS_INLINE
|
||||||
|
lexer_compare_literal_to_string (parser_context_t *context_p, /**< context */
|
||||||
|
const char *string_p, /**< string */
|
||||||
|
size_t string_length) /**< string length */
|
||||||
|
{
|
||||||
|
JERRY_ASSERT (context_p->token.type == LEXER_LITERAL
|
||||||
|
&& (context_p->token.lit_location.type == LEXER_IDENT_LITERAL
|
||||||
|
|| context_p->token.lit_location.type == LEXER_STRING_LITERAL));
|
||||||
|
|
||||||
return memcmp (left_ident_p->char_p, right_ident_p, right_ident_length) == 0;
|
/* Checking has_escape is unnecessary because memcmp will fail if escape sequences are present. */
|
||||||
} /* lexer_compare_raw_identifier_to_current */
|
return (context_p->token.lit_location.length == string_length
|
||||||
|
&& memcmp (context_p->token.lit_location.char_p, string_p, string_length) == 0);
|
||||||
|
} /* lexer_compare_literal_to_string */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert binary lvalue token to binary token
|
* Convert binary lvalue token to binary token
|
||||||
|
|||||||
@@ -442,7 +442,8 @@ parser_parse_class_literal (parser_context_t *context_p) /**< context */
|
|||||||
is_computed = true;
|
is_computed = true;
|
||||||
}
|
}
|
||||||
else if (!(status_flags & PARSER_CLASS_STATIC_FUNCTION)
|
else if (!(status_flags & PARSER_CLASS_STATIC_FUNCTION)
|
||||||
&& lexer_compare_raw_identifier_to_current (context_p, "constructor", 11))
|
&& LEXER_IS_IDENT_OR_STRING (context_p->token.lit_location.type)
|
||||||
|
&& lexer_compare_literal_to_string (context_p, "constructor", 11))
|
||||||
{
|
{
|
||||||
parser_raise_error (context_p, PARSER_ERR_CLASS_CONSTRUCTOR_AS_ACCESSOR);
|
parser_raise_error (context_p, PARSER_ERR_CLASS_CONSTRUCTOR_AS_ACCESSOR);
|
||||||
}
|
}
|
||||||
@@ -538,7 +539,8 @@ parser_parse_class_literal (parser_context_t *context_p) /**< context */
|
|||||||
is_computed = true;
|
is_computed = true;
|
||||||
}
|
}
|
||||||
else if ((status_flags & PARSER_CLASS_STATIC_FUNCTION)
|
else if ((status_flags & PARSER_CLASS_STATIC_FUNCTION)
|
||||||
&& lexer_compare_raw_identifier_to_current (context_p, "prototype", 9))
|
&& LEXER_IS_IDENT_OR_STRING (context_p->token.lit_location.type)
|
||||||
|
&& lexer_compare_literal_to_string (context_p, "prototype", 9))
|
||||||
{
|
{
|
||||||
parser_raise_error (context_p, PARSER_ERR_CLASS_STATIC_PROTOTYPE);
|
parser_raise_error (context_p, PARSER_ERR_CLASS_STATIC_PROTOTYPE);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -521,8 +521,9 @@ void lexer_convert_push_number_to_push_literal (parser_context_t *context_p);
|
|||||||
uint16_t lexer_construct_function_object (parser_context_t *context_p, uint32_t extra_status_flags);
|
uint16_t lexer_construct_function_object (parser_context_t *context_p, uint32_t extra_status_flags);
|
||||||
void lexer_construct_regexp_object (parser_context_t *context_p, bool parse_only);
|
void lexer_construct_regexp_object (parser_context_t *context_p, bool parse_only);
|
||||||
bool lexer_compare_identifier_to_current (parser_context_t *context_p, const lexer_lit_location_t *right_ident_p);
|
bool lexer_compare_identifier_to_current (parser_context_t *context_p, const lexer_lit_location_t *right_ident_p);
|
||||||
bool lexer_compare_raw_identifier_to_current (parser_context_t *context_p, const char *right_ident_p,
|
bool lexer_compare_literal_to_identifier (parser_context_t *context_p, const char *identifier_p,
|
||||||
size_t right_ident_length);
|
size_t identifier_length);
|
||||||
|
bool lexer_compare_literal_to_string (parser_context_t *context_p, const char *string_p, size_t string_length);
|
||||||
uint8_t lexer_convert_binary_lvalue_token_to_binary (uint8_t token);
|
uint8_t lexer_convert_binary_lvalue_token_to_binary (uint8_t token);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -362,8 +362,7 @@ parser_module_parse_export_clause (parser_context_t *context_p) /**< parser cont
|
|||||||
uint16_t export_name_index = PARSER_MAXIMUM_NUMBER_OF_LITERALS;
|
uint16_t export_name_index = PARSER_MAXIMUM_NUMBER_OF_LITERALS;
|
||||||
|
|
||||||
lexer_next_token (context_p);
|
lexer_next_token (context_p);
|
||||||
if (context_p->token.type == LEXER_LITERAL
|
if (lexer_compare_literal_to_identifier (context_p, "as", 2))
|
||||||
&& lexer_compare_raw_identifier_to_current (context_p, "as", 2))
|
|
||||||
{
|
{
|
||||||
lexer_next_token (context_p);
|
lexer_next_token (context_p);
|
||||||
|
|
||||||
@@ -415,8 +414,7 @@ parser_module_parse_export_clause (parser_context_t *context_p) /**< parser cont
|
|||||||
lexer_next_token (context_p);
|
lexer_next_token (context_p);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (context_p->token.type == LEXER_LITERAL
|
if (lexer_compare_literal_to_identifier (context_p, "from", 4))
|
||||||
&& lexer_compare_raw_identifier_to_current (context_p, "from", 4))
|
|
||||||
{
|
{
|
||||||
parser_raise_error (context_p, PARSER_ERR_RIGHT_BRACE_EXPECTED);
|
parser_raise_error (context_p, PARSER_ERR_RIGHT_BRACE_EXPECTED);
|
||||||
}
|
}
|
||||||
@@ -455,8 +453,7 @@ parser_module_parse_import_clause (parser_context_t *context_p) /**< parser cont
|
|||||||
uint16_t local_name_index = PARSER_MAXIMUM_NUMBER_OF_LITERALS;
|
uint16_t local_name_index = PARSER_MAXIMUM_NUMBER_OF_LITERALS;
|
||||||
|
|
||||||
lexer_next_token (context_p);
|
lexer_next_token (context_p);
|
||||||
if (context_p->token.type == LEXER_LITERAL
|
if (lexer_compare_literal_to_identifier (context_p, "as", 2))
|
||||||
&& lexer_compare_raw_identifier_to_current (context_p, "as", 2))
|
|
||||||
{
|
{
|
||||||
lexer_next_token (context_p);
|
lexer_next_token (context_p);
|
||||||
|
|
||||||
@@ -508,8 +505,7 @@ parser_module_parse_import_clause (parser_context_t *context_p) /**< parser cont
|
|||||||
lexer_next_token (context_p);
|
lexer_next_token (context_p);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (context_p->token.type == LEXER_LITERAL
|
if (lexer_compare_literal_to_identifier (context_p, "from", 4))
|
||||||
&& lexer_compare_raw_identifier_to_current (context_p, "from", 4))
|
|
||||||
{
|
{
|
||||||
parser_raise_error (context_p, PARSER_ERR_RIGHT_BRACE_EXPECTED);
|
parser_raise_error (context_p, PARSER_ERR_RIGHT_BRACE_EXPECTED);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -720,7 +720,7 @@ parser_scan_until (parser_context_t *context_p, /**< context */
|
|||||||
context_p->token.type = LEXER_KEYW_IN;
|
context_p->token.type = LEXER_KEYW_IN;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (type == LEXER_LITERAL && lexer_compare_raw_identifier_to_current (context_p, "of", 2))
|
else if (lexer_compare_literal_to_identifier (context_p, "of", 2))
|
||||||
{
|
{
|
||||||
parser_stack_pop_uint8 (context_p);
|
parser_stack_pop_uint8 (context_p);
|
||||||
context_p->token.type = LEXER_LITERAL_OF;
|
context_p->token.type = LEXER_LITERAL_OF;
|
||||||
@@ -788,13 +788,13 @@ parser_scan_until (parser_context_t *context_p, /**< context */
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lexer_compare_raw_identifier_to_current (context_p, "static", 6))
|
if (lexer_compare_literal_to_identifier (context_p, "static", 6))
|
||||||
{
|
{
|
||||||
lexer_next_token (context_p);
|
lexer_next_token (context_p);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lexer_compare_raw_identifier_to_current (context_p, "get", 3)
|
if (lexer_compare_literal_to_identifier (context_p, "get", 3)
|
||||||
|| lexer_compare_raw_identifier_to_current (context_p, "set", 3))
|
|| lexer_compare_literal_to_identifier (context_p, "set", 3))
|
||||||
{
|
{
|
||||||
lexer_next_token (context_p);
|
lexer_next_token (context_p);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1884,12 +1884,6 @@ parser_parse_import_statement (parser_context_t *context_p) /**< parser context
|
|||||||
|
|
||||||
lexer_next_token (context_p);
|
lexer_next_token (context_p);
|
||||||
|
|
||||||
if (context_p->token.type != LEXER_COMMA
|
|
||||||
&& !lexer_compare_raw_identifier_to_current (context_p, "from", 4))
|
|
||||||
{
|
|
||||||
parser_raise_error (context_p, PARSER_ERR_FROM_COMMA_EXPECTED);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (context_p->token.type == LEXER_COMMA)
|
if (context_p->token.type == LEXER_COMMA)
|
||||||
{
|
{
|
||||||
lexer_next_token (context_p);
|
lexer_next_token (context_p);
|
||||||
@@ -1899,14 +1893,17 @@ parser_parse_import_statement (parser_context_t *context_p) /**< parser context
|
|||||||
parser_raise_error (context_p, PARSER_ERR_LEFT_BRACE_MULTIPLY_EXPECTED);
|
parser_raise_error (context_p, PARSER_ERR_LEFT_BRACE_MULTIPLY_EXPECTED);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (!lexer_compare_literal_to_identifier (context_p, "from", 4))
|
||||||
|
{
|
||||||
|
parser_raise_error (context_p, PARSER_ERR_FROM_COMMA_EXPECTED);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (context_p->token.type == LEXER_MULTIPLY)
|
if (context_p->token.type == LEXER_MULTIPLY)
|
||||||
{
|
{
|
||||||
/* NameSpaceImport*/
|
/* NameSpaceImport*/
|
||||||
lexer_next_token (context_p);
|
lexer_next_token (context_p);
|
||||||
if (context_p->token.type != LEXER_LITERAL
|
if (!lexer_compare_literal_to_identifier (context_p, "as", 2))
|
||||||
|| !lexer_compare_raw_identifier_to_current (context_p, "as", 2))
|
|
||||||
{
|
{
|
||||||
parser_raise_error (context_p, PARSER_ERR_AS_EXPECTED);
|
parser_raise_error (context_p, PARSER_ERR_AS_EXPECTED);
|
||||||
}
|
}
|
||||||
@@ -1942,7 +1939,7 @@ parser_parse_import_statement (parser_context_t *context_p) /**< parser context
|
|||||||
parser_module_parse_import_clause (context_p);
|
parser_module_parse_import_clause (context_p);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (context_p->token.type != LEXER_LITERAL || !lexer_compare_raw_identifier_to_current (context_p, "from", 4))
|
if (!lexer_compare_literal_to_identifier (context_p, "from", 4))
|
||||||
{
|
{
|
||||||
parser_raise_error (context_p, PARSER_ERR_FROM_EXPECTED);
|
parser_raise_error (context_p, PARSER_ERR_FROM_EXPECTED);
|
||||||
}
|
}
|
||||||
@@ -2035,8 +2032,7 @@ parser_parse_export_statement (parser_context_t *context_p) /**< context */
|
|||||||
case LEXER_MULTIPLY:
|
case LEXER_MULTIPLY:
|
||||||
{
|
{
|
||||||
lexer_next_token (context_p);
|
lexer_next_token (context_p);
|
||||||
if (!(context_p->token.type == LEXER_LITERAL
|
if (!lexer_compare_literal_to_identifier (context_p, "from", 4))
|
||||||
&& lexer_compare_raw_identifier_to_current (context_p, "from", 4)))
|
|
||||||
{
|
{
|
||||||
parser_raise_error (context_p, PARSER_ERR_FROM_EXPECTED);
|
parser_raise_error (context_p, PARSER_ERR_FROM_EXPECTED);
|
||||||
}
|
}
|
||||||
@@ -2106,8 +2102,7 @@ parser_parse_export_statement (parser_context_t *context_p) /**< context */
|
|||||||
{
|
{
|
||||||
parser_module_parse_export_clause (context_p);
|
parser_module_parse_export_clause (context_p);
|
||||||
|
|
||||||
if (context_p->token.type == LEXER_LITERAL
|
if (lexer_compare_literal_to_identifier (context_p, "from", 4))
|
||||||
&& lexer_compare_raw_identifier_to_current (context_p, "from", 4))
|
|
||||||
{
|
{
|
||||||
lexer_next_token (context_p);
|
lexer_next_token (context_p);
|
||||||
parser_module_handle_module_specifier (context_p);
|
parser_module_handle_module_specifier (context_p);
|
||||||
|
|||||||
@@ -52,6 +52,10 @@ var forOf =
|
|||||||
" obj[prop] += 4;"
|
" obj[prop] += 4;"
|
||||||
parse (forOf)
|
parse (forOf)
|
||||||
|
|
||||||
|
var forOf =
|
||||||
|
"for (var a \"of\" []) {}"
|
||||||
|
parse (forOf)
|
||||||
|
|
||||||
checkError(5)
|
checkError(5)
|
||||||
|
|
||||||
var obj = {}
|
var obj = {}
|
||||||
|
|||||||
Reference in New Issue
Block a user