Commit b102540e authored by bakkot's avatar bakkot Committed by Commit Bot

[parser] Forbid \08 in strict strings and in untagged templates

This was never legal; the spec only allows '\0' in strict-mode strings or templates
when not followed by a decimal digit. Previously we were only enforcing that it
not be followed by an _octal_ digit.

This was already fixed for numeric literals, but not for escape sequences in strings.

BUG=v8:6504

Review-Url: https://codereview.chromium.org/2950633002
Cr-Commit-Position: refs/heads/master@{#46046}
parent c0f1ff24
...@@ -1045,7 +1045,7 @@ uc32 Scanner::ScanOctalEscape(uc32 c, int length) { ...@@ -1045,7 +1045,7 @@ uc32 Scanner::ScanOctalEscape(uc32 c, int length) {
// can be reported later (in strict mode). // can be reported later (in strict mode).
// We don't report the error immediately, because the octal escape can // We don't report the error immediately, because the octal escape can
// occur before the "use strict" directive. // occur before the "use strict" directive.
if (c != '0' || i > 0) { if (c != '0' || i > 0 || c0_ == '8' || c0_ == '9') {
octal_pos_ = Location(source_pos() - i - 1, source_pos() - 1); octal_pos_ = Location(source_pos() - i - 1, source_pos() - 1);
octal_message_ = MessageTemplate::kStrictOctalEscape; octal_message_ = MessageTemplate::kStrictOctalEscape;
} }
......
...@@ -5901,6 +5901,33 @@ TEST(UnicodeEscapes) { ...@@ -5901,6 +5901,33 @@ TEST(UnicodeEscapes) {
RunParserSyncTest(context_data, data, kSuccess); RunParserSyncTest(context_data, data, kSuccess);
} }
TEST(OctalEscapes) {
const char* sloppy_context_data[][2] = {{"", ""}, // as a directive
{"0;", ""}, // as a string literal
{NULL, NULL}};
const char* strict_context_data[][2] = {
{"'use strict';", ""}, // as a directive before 'use strict'
{"", ";'use strict';"}, // as a directive after 'use strict'
{"'use strict'; 0;", ""}, // as a string literal
{NULL, NULL}};
// clang-format off
const char* data[] = {
"'\\1'",
"'\\01'",
"'\\001'",
"'\\08'",
"'\\09'",
NULL};
// clang-format on
// Permitted in sloppy mode
RunParserSyncTest(sloppy_context_data, data, kSuccess);
// Error in strict mode
RunParserSyncTest(strict_context_data, data, kError);
}
TEST(ScanTemplateLiterals) { TEST(ScanTemplateLiterals) {
const char* context_data[][2] = {{"'use strict';", ""}, const char* context_data[][2] = {{"'use strict';", ""},
...@@ -7112,6 +7139,7 @@ TEST(TemplateEscapesPositiveTests) { ...@@ -7112,6 +7139,7 @@ TEST(TemplateEscapesPositiveTests) {
// clang-format off // clang-format off
const char* data[] = { const char* data[] = {
"tag`\\08`",
"tag`\\01`", "tag`\\01`",
"tag`\\01${0}right`", "tag`\\01${0}right`",
"tag`left${0}\\01`", "tag`left${0}\\01`",
...@@ -7195,6 +7223,7 @@ TEST(TemplateEscapesNegativeTests) { ...@@ -7195,6 +7223,7 @@ TEST(TemplateEscapesNegativeTests) {
// clang-format off // clang-format off
const char* data[] = { const char* data[] = {
"`\\08`",
"`\\01`", "`\\01`",
"`\\01${0}right`", "`\\01${0}right`",
"`left${0}\\01`", "`left${0}\\01`",
......
...@@ -476,7 +476,7 @@ var obj = { ...@@ -476,7 +476,7 @@ var obj = {
(function testLegacyOctal() { (function testLegacyOctal() {
assertEquals('\u0000', `\0`); assertEquals('\u0000', `\0`);
assertEquals('\u0000a', `\0a`); assertEquals('\u0000a', `\0a`);
for (var i = 0; i < 8; i++) { for (var i = 0; i < 10; i++) {
var code = "`\\0" + i + "`"; var code = "`\\0" + i + "`";
assertThrows(code, SyntaxError); assertThrows(code, SyntaxError);
code = "(function(){})" + code; code = "(function(){})" + code;
...@@ -502,8 +502,6 @@ var obj = { ...@@ -502,8 +502,6 @@ var obj = {
(function testValidNumericEscapes() { (function testValidNumericEscapes() {
assertEquals("8", `\8`); assertEquals("8", `\8`);
assertEquals("9", `\9`); assertEquals("9", `\9`);
assertEquals("\u00008", `\08`);
assertEquals("\u00009", `\09`);
})(); })();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment