| Index: frog/leg/scanner/scanner.dart
|
| diff --git a/frog/leg/scanner/scanner.dart b/frog/leg/scanner/scanner.dart
|
| index bfce2342cb9597ab318b32124ef838c973f29a26..873fc0e76567129b90d084cc213b521d57c70517 100644
|
| --- a/frog/leg/scanner/scanner.dart
|
| +++ b/frog/leg/scanner/scanner.dart
|
| @@ -629,16 +629,70 @@ class AbstractScanner<T> implements Scanner {
|
| }
|
| }
|
|
|
| + static bool isHexDigit(int character) {
|
| + if ($0 <= character && character <= $9) return true;
|
| + character |= 0x20;
|
| + return ($a <= character && character <= $f);
|
| + }
|
| +
|
| int tokenizeSingleLineString(int next, int q1, int start) {
|
| - while (next !== $EOF) {
|
| + loop: while (next !== $EOF) {
|
| if (next === q1) {
|
| appendByteStringToken(STRING_INFO, utf8String(start, 0));
|
| return advance();
|
| } else if (next === $BACKSLASH) {
|
| next = advance();
|
| - if (next === $EOF) {
|
| + if (next === $EOF || next === $LF || next === $CR) {
|
| throw new MalformedInputException(charOffset);
|
| }
|
| + switch (next) {
|
| + case $u:
|
| + next = advance();
|
| + bool isBracketed = false;
|
| + int maxLength = 4;
|
| + if (next === $OPEN_CURLY_BRACKET) {
|
| + isBracketed = true;
|
| + maxLength = 7;
|
| + next = advance();
|
| + }
|
| + int startOffset = charOffset;
|
| + int unicodePoint = 0;
|
| + int length = 0;
|
| + while (length < maxLength && isHexDigit(next)) {
|
| + int digit = next <= $9 ? next - 0x30 : (next | 0x20) - ($a - 10);
|
| + unicodePoint = unicodePoint * 16 + digit;
|
| + length += 1;
|
| + next = advance();
|
| + }
|
| + if (isBracketed) {
|
| + if (length === 0) {
|
| + throw new MalformedInputException(startOffset);
|
| + }
|
| + if (next !== $CLOSE_CURLY_BRACKET) {
|
| + throw new MalformedInputException(charOffset);
|
| + }
|
| + next = advance();
|
| + } else if (length != 4) {
|
| + throw new MalformedInputException(startOffset + length);
|
| + }
|
| + if ((0xD800 <= unicodePoint && unicodePoint <= 0xDFFF) ||
|
| + unicodePoint > 0x10ffff) {
|
| + // Don't allow invalid code points in strings.
|
| + throw new MalformedInputException(startOffset);
|
| + }
|
| + // TODO(lrn): This should be just "continue", but the VM is bugged.
|
| + continue loop;
|
| + case $x:
|
| + for (int i = 0; i < 2; i++) {
|
| + next = advance();
|
| + if (!isHexDigit(next)) {
|
| + throw new MalformedInputException(charOffset);
|
| + }
|
| + }
|
| + break;
|
| + default:
|
| + // All other escapes are trivially valid.
|
| + }
|
| } else if (next === $$) {
|
| beginToken();
|
| next = advance();
|
|
|