Chromium Code Reviews| Index: src/parsing/scanner.cc |
| diff --git a/src/parsing/scanner.cc b/src/parsing/scanner.cc |
| index a197829b35b69a6ecbe7d9b7521554eeb8c8c8c1..507e1ad1d8500ed5515bc0e16c84248a71d3ea27 100644 |
| --- a/src/parsing/scanner.cc |
| +++ b/src/parsing/scanner.cc |
| @@ -62,15 +62,19 @@ void Scanner::Initialize(Utf16CharacterStream* source) { |
| Scan(); |
| } |
| - |
| -template <bool capture_raw> |
| +template <bool capture_raw, bool unicode> |
| uc32 Scanner::ScanHexNumber(int expected_length) { |
| DCHECK(expected_length <= 4); // prevent overflow |
| + int begin = source_pos() - 2; |
| uc32 x = 0; |
| for (int i = 0; i < expected_length; i++) { |
| int d = HexValue(c0_); |
| if (d < 0) { |
| + ReportScannerError(Location(begin, begin + expected_length + 2), |
| + unicode |
| + ? MessageTemplate::kInvalidUnicodeEscapeSequence |
| + : MessageTemplate::kInvalidHexEscapeSequence); |
| return -1; |
| } |
| x = x * 16 + d; |
| @@ -80,20 +84,27 @@ uc32 Scanner::ScanHexNumber(int expected_length) { |
| return x; |
| } |
| - |
| template <bool capture_raw> |
| uc32 Scanner::ScanUnlimitedLengthHexNumber(int max_value) { |
| uc32 x = 0; |
| int d = HexValue(c0_); |
| - if (d < 0) { |
| - return -1; |
| - } |
| + int nof_digits = 0; |
| while (d >= 0) { |
| x = x * 16 + d; |
| - if (x > max_value) return -1; |
| + if (x > max_value) { |
| + return -1; |
|
adamk
2016/03/21 19:13:56
Seems like this is the right place to report the g
caitp (gmail)
2016/03/21 19:40:05
Done.
|
| + } |
| Advance<capture_raw>(); |
| d = HexValue(c0_); |
| + nof_digits++; |
| + } |
| + |
| + if (!nof_digits || (c0_ != '}')) { |
|
adamk
2016/03/21 19:13:56
I'd leave the closing brace check in the caller, s
caitp (gmail)
2016/03/21 19:40:05
Done.
|
| + ReportScannerError(source_pos(), |
| + MessageTemplate::kInvalidUnicodeEscapeSequence); |
| + return -1; |
| } |
| + |
| return x; |
| } |
| @@ -856,7 +867,9 @@ Token::Value Scanner::ScanString() { |
| uc32 c = c0_; |
| Advance(); |
| if (c == '\\') { |
| - if (c0_ < 0 || !ScanEscape<false, false>()) return Token::ILLEGAL; |
| + if (c0_ < 0 || !ScanEscape<false, false>()) { |
| + return Token::ILLEGAL; |
| + } |
| } else { |
| AddLiteralChar(c); |
| } |
| @@ -888,7 +901,6 @@ Token::Value Scanner::ScanTemplateSpan() { |
| StartRawLiteral(); |
| const bool capture_raw = true; |
| const bool in_template_literal = true; |
| - |
| while (true) { |
| uc32 c = c0_; |
| Advance<capture_raw>(); |
| @@ -1108,18 +1120,19 @@ uc32 Scanner::ScanUnicodeEscape() { |
| // Accept both \uxxxx and \u{xxxxxx}. In the latter case, the number of |
| // hex digits between { } is arbitrary. \ and u have already been read. |
| if (c0_ == '{') { |
| + int begin = source_pos() - 2; |
| Advance<capture_raw>(); |
| uc32 cp = ScanUnlimitedLengthHexNumber<capture_raw>(0x10ffff); |
| if (cp < 0) { |
| - return -1; |
| - } |
| - if (c0_ != '}') { |
| + ReportScannerError(Location(begin, source_pos() + 1), |
| + MessageTemplate::kUndefinedUnicodeCodePoint); |
| return -1; |
| } |
| Advance<capture_raw>(); |
| return cp; |
| } |
| - return ScanHexNumber<capture_raw>(4); |
| + const bool unicode = true; |
| + return ScanHexNumber<capture_raw, unicode>(4); |
| } |