Chromium Code Reviews| Index: src/scanner.cc |
| diff --git a/src/scanner.cc b/src/scanner.cc |
| index ddcd937584d50fc45fa921a25e2a5d21fcf5697e..7289c7a7d08b233a9669fa4c729123b1a1a2fe58 100644 |
| --- a/src/scanner.cc |
| +++ b/src/scanner.cc |
| @@ -71,6 +71,22 @@ uc32 Scanner::ScanHexNumber(int expected_length) { |
| } |
| +uc32 Scanner::ScanUnlimitedLengthHexNumber(int max_value) { |
| + uc32 x = 0; |
| + int d = HexValue(c0_); |
| + if (d < 0) { |
| + return -1; |
| + } |
| + while (d >= 0) { |
| + x = x * 16 + d; |
| + if (x > max_value) return -1; |
| + Advance(); |
| + d = HexValue(c0_); |
| + } |
| + return x; |
| +} |
| + |
| + |
| // Ensure that tokens can be stored in a byte. |
| STATIC_ASSERT(Token::NUM_TOKENS <= 0x100); |
| @@ -673,6 +689,7 @@ void Scanner::SeekForward(int pos) { |
| bool Scanner::ScanEscape() { |
| uc32 c = c0_; |
| + uc32 c2 = -1; |
| Advance(); |
| // Skip escaped newlines. |
| @@ -694,7 +711,7 @@ bool Scanner::ScanEscape() { |
| case 'r' : c = '\r'; break; |
| case 't' : c = '\t'; break; |
| case 'u' : { |
| - c = ScanHexNumber(4); |
| + c = ScanUnicodeEscape(); |
| if (c < 0) return false; |
| break; |
| } |
| @@ -718,6 +735,9 @@ bool Scanner::ScanEscape() { |
| // above cases should be illegal, but they are commonly handled as |
| // non-escaped characters by JS VMs. |
| AddLiteralChar(c); |
| + if (c2 >= 0) { |
| + AddLiteralChar(c2); |
| + } |
| return true; |
| } |
| @@ -885,8 +905,27 @@ Token::Value Scanner::ScanNumber(bool seen_period) { |
| uc32 Scanner::ScanIdentifierUnicodeEscape() { |
| Advance(); |
| - if (c0_ != 'u') return -1; |
| + if (c0_ != 'u') return false; |
|
caitp (gmail)
2014/11/13 03:21:42
Will cause `var \x` to look like `var \u{0}x`, if
marja
2014/11/13 10:06:23
Oh, yes, this was a pure editing error.
|
| Advance(); |
| + return ScanUnicodeEscape(); |
| +} |
| + |
| + |
| +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_ == '{') { |
| + Advance(); |
| + uc32 cp = ScanUnlimitedLengthHexNumber(0x10ffff); |
| + if (cp < 0) { |
| + return -1; |
| + } |
| + if (c0_ != '}') { |
| + return -1; |
| + } |
| + Advance(); |
| + return cp; |
| + } |
| return ScanHexNumber(4); |
| } |