Chromium Code Reviews| Index: src/scanner.cc |
| diff --git a/src/scanner.cc b/src/scanner.cc |
| index 96459f3c6699ec07f5b3a73db6defd5665dc791e..7cd0895cb3ddb47169b88ed8c1ddf83c3ed4c2a5 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. |
| @@ -725,22 +725,44 @@ bool Scanner::ScanEscape() { |
| if (c < 0) return false; |
| break; |
| } |
| - case 'v' : c = '\v'; break; |
| - case 'x' : { |
| + case 'v': |
| + c = '\v'; |
| + break; |
|
caitp (gmail)
2014/12/17 20:32:14
Was this added changed by accident? not a big deal
arv (Not doing code reviews)
2014/12/17 20:57:13
git cl format complained...
|
| + case 'x': { |
| c = ScanHexNumber<capture_raw>(2); |
| if (c < 0) return false; |
| break; |
| } |
| - case '0' : // fall through |
| - case '1' : // fall through |
| - case '2' : // fall through |
| - case '3' : // fall through |
| - case '4' : // fall through |
| - case '5' : // fall through |
| - case '6' : // fall through |
| + case '0': |
| + if (in_template_literal) { |
| + // \ 0 DecimalDigit is never allowed in templates. |
|
caitp (gmail)
2014/12/17 20:32:14
It's not really restricted to templates, this appl
arv (Not doing code reviews)
2014/12/17 20:57:13
We talked about legacy octal numbers at a recent T
|
| + if (IsDecimalDigit(c0_)) { |
| + Advance<capture_raw>(); // Advance to include the problematic char. |
| + return false; |
| + } |
| + |
| + // 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 |
| + case '4': // fall through |
| + case '5': // fall through |
| + case '6': // fall through |
| case '7': |
| - c = ScanOctalEscape<capture_raw>(c, 2); |
| - break; |
| + if (!in_template_literal) { |
| + c = ScanOctalEscape<capture_raw>(c, 2); |
| + break; |
| + } |
| + // Fall through |
| + case '8': |
| + case '9': |
| + if (in_template_literal) return false; |
| } |
| // According to ECMA-262, section 7.8.4, characters not covered by the |
| @@ -787,7 +809,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 +840,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 +867,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 |