Chromium Code Reviews| Index: src/scanner.cc |
| diff --git a/src/scanner.cc b/src/scanner.cc |
| index 96459f3c6699ec07f5b3a73db6defd5665dc791e..6e2e67d328d81d90150ee1659710c2d79ae0e866 100644 |
| --- a/src/scanner.cc |
| +++ b/src/scanner.cc |
| @@ -697,13 +697,13 @@ void Scanner::SeekForward(int pos) { |
| } |
| -template <bool capture_raw> |
| +template <bool capture_raw, bool in_template_literal> |
| bool Scanner::ScanEscape() { |
| uc32 c = c0_; |
| Advance<capture_raw>(); |
| // Skip escaped newlines. |
| - if (c0_ >= 0 && unicode_cache_->IsLineTerminator(c)) { |
| + if (!in_template_literal && c0_ >= 0 && unicode_cache_->IsLineTerminator(c)) { |
| // Allow CR+LF newlines in multiline string literals. |
| if (IsCarriageReturn(c) && IsLineFeed(c0_)) Advance<capture_raw>(); |
| // Allow LF+CR newlines in multiline string literals. |
| @@ -731,7 +731,21 @@ bool Scanner::ScanEscape() { |
| if (c < 0) return false; |
| break; |
| } |
| - case '0' : // fall through |
| + case '0': |
| + if (in_template_literal) { |
| + // \ 0 DecimalDigit is never allowed in templates. |
| + if (IsDecimalDigit(c0_)) { |
| + Advance<capture_raw>(); |
| + return false; |
|
caitp (gmail)
2014/12/17 19:35:56
I feel like we should just let ScanOctalEscape do
|
| + } |
| + |
| + // The TV of TemplateCharacter :: \ EscapeSequence is the CV of |
| + // EscapeSequence. |
| + // The CV of EscapeSequence :: 0 is the code unit value 0. |
| + c = 0; |
| + break; |
| + } |
| + // Fall through. |
| case '1' : // fall through |
| case '2' : // fall through |
| case '3' : // fall through |
| @@ -739,7 +753,9 @@ bool Scanner::ScanEscape() { |
| case '5' : // fall through |
| case '6' : // fall through |
| case '7': |
| - c = ScanOctalEscape<capture_raw>(c, 2); |
| + if (!in_template_literal) { |
| + c = ScanOctalEscape<capture_raw>(c, 2); |
| + } |
| break; |
| } |
| @@ -787,7 +803,7 @@ Token::Value Scanner::ScanString() { |
| uc32 c = c0_; |
| Advance(); |
| if (c == '\\') { |
| - if (c0_ < 0 || !ScanEscape<false>()) return Token::ILLEGAL; |
| + if (c0_ < 0 || !ScanEscape<false, false>()) return Token::ILLEGAL; |
| } else { |
| AddLiteralChar(c); |
| } |
| @@ -818,6 +834,7 @@ Token::Value Scanner::ScanTemplateSpan() { |
| LiteralScope literal(this); |
| StartRawLiteral(); |
| const bool capture_raw = true; |
| + const bool in_template_literal = true; |
| while (true) { |
| uc32 c = c0_; |
| @@ -844,11 +861,8 @@ Token::Value Scanner::ScanTemplateSpan() { |
| AddRawLiteralChar('\n'); |
| } |
| } |
| - } else if (c0_ == '0') { |
| - Advance<capture_raw>(); |
| - AddLiteralChar('0'); |
| - } else { |
| - ScanEscape<true>(); |
| + } else if (!ScanEscape<capture_raw, in_template_literal>()) { |
| + return Token::ILLEGAL; |
| } |
| } else if (c < 0) { |
| // Unterminated template literal |