diff --git a/jerry-core/parser/js/js-lexer.c b/jerry-core/parser/js/js-lexer.c index 6c5ff1d1d..03dd85625 100644 --- a/jerry-core/parser/js/js-lexer.c +++ b/jerry-core/parser/js/js-lexer.c @@ -917,6 +917,28 @@ lexer_parse_string (parser_context_t *context_p) /**< context */ context_p->column = (parser_line_counter_t) (column + 1); } /* lexer_parse_string */ +/** + * Parse octal number. + */ +static inline void +lexer_parse_octal_number (parser_context_t *context_p, /** context */ + const uint8_t **source_p) /**< current source position */ +{ + do + { + (*source_p)++; + } + while (*source_p < context_p->source_end_p + && *source_p[0] >= LIT_CHAR_0 + && *source_p[0] <= LIT_CHAR_7); + + if (*source_p < context_p->source_end_p + && (*source_p[0] == LIT_CHAR_8 || *source_p[0] == LIT_CHAR_9)) + { + parser_raise_error (context_p, PARSER_ERR_INVALID_OCTAL_DIGIT); + } +} /* lexer_parse_octal_number */ + /** * Parse number. */ @@ -956,6 +978,23 @@ lexer_parse_number (parser_context_t *context_p) /**< context */ while (source_p < source_end_p && lit_char_is_hex_digit (source_p[0])); } +#if ENABLED (JERRY_ES2015) + else if (LEXER_TO_ASCII_LOWERCASE (source_p[1]) == LIT_CHAR_LOWERCASE_O) + { + context_p->token.extra_value = LEXER_NUMBER_OCTAL; + context_p->token.lit_location.char_p++; + context_p->source_p++; + source_p += 2; + + if (source_p >= source_end_p + || !lit_char_is_octal_digit (source_p[0])) + { + parser_raise_error (context_p, PARSER_ERR_INVALID_OCTAL_DIGIT); + } + + lexer_parse_octal_number (context_p, &source_p); + } +#endif /* ENABLED (JERRY_ES2015) */ else if (source_p[1] >= LIT_CHAR_0 && source_p[1] <= LIT_CHAR_7) { @@ -966,20 +1005,7 @@ lexer_parse_number (parser_context_t *context_p) /**< context */ parser_raise_error (context_p, PARSER_ERR_OCTAL_NUMBER_NOT_ALLOWED); } - do - { - source_p++; - } - while (source_p < source_end_p - && source_p[0] >= LIT_CHAR_0 - && source_p[0] <= LIT_CHAR_7); - - if (source_p < source_end_p - && source_p[0] >= LIT_CHAR_8 - && source_p[0] <= LIT_CHAR_9) - { - parser_raise_error (context_p, PARSER_ERR_INVALID_NUMBER); - } + lexer_parse_octal_number (context_p, &source_p); } else if (source_p[1] >= LIT_CHAR_8 && source_p[1] <= LIT_CHAR_9) diff --git a/jerry-core/parser/js/js-parser-util.c b/jerry-core/parser/js/js-parser-util.c index 7f7536c23..d8ea887d3 100644 --- a/jerry-core/parser/js/js-parser-util.c +++ b/jerry-core/parser/js/js-parser-util.c @@ -828,6 +828,10 @@ parser_error_to_string (parser_error_t error) /**< error code */ { return "Invalid (unexpected) character."; } + case PARSER_ERR_INVALID_OCTAL_DIGIT: + { + return "Invalid octal digit."; + } case PARSER_ERR_INVALID_HEX_DIGIT: { return "Invalid hexadecimal digit."; diff --git a/jerry-core/parser/js/js-parser.h b/jerry-core/parser/js/js-parser.h index fb4dab118..8ad734609 100644 --- a/jerry-core/parser/js/js-parser.h +++ b/jerry-core/parser/js/js-parser.h @@ -42,6 +42,7 @@ typedef enum PARSER_ERR_STACK_LIMIT_REACHED, /**< maximum function stack size reached */ PARSER_ERR_INVALID_CHARACTER, /**< unexpected character */ + PARSER_ERR_INVALID_OCTAL_DIGIT, /**< invalid octal digit */ PARSER_ERR_INVALID_HEX_DIGIT, /**< invalid hexadecimal digit */ PARSER_ERR_INVALID_ESCAPE_SEQUENCE, /**< invalid escape sequence */ PARSER_ERR_INVALID_UNICODE_ESCAPE_SEQUENCE, /**< invalid unicode escape sequence */ diff --git a/tests/jerry/es2015/octal-literal.js b/tests/jerry/es2015/octal-literal.js new file mode 100644 index 000000000..da9e0bed5 --- /dev/null +++ b/tests/jerry/es2015/octal-literal.js @@ -0,0 +1,46 @@ +/* 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. + */ + +function checkSyntaxError (str) { + try { + eval (str); + assert (false); + } catch (e) { + assert (e instanceof SyntaxError); + } +} + +checkSyntaxError ("0p"); +checkSyntaxError ("0o"); +checkSyntaxError ("0o0123456789"); +checkSyntaxError ("0o9"); + +checkSyntaxError ("0p"); +checkSyntaxError ("0O"); +checkSyntaxError ("0O9"); + +// Check strict mode +checkSyntaxError ("'use strict'; 0777"); +assert (eval ("'use strict'; 0o777") === 511); + +assert (0o123 === 83); +assert (0o77777777 === 16777215); +assert (0o767 === parseInt ("767", 8)); +assert (0767 === 0o767); + +assert (0O123 === 83); +assert (0O77777777 === 16777215); +assert (0O767 === parseInt ("767", 8)); +assert (0767 === 0O767);