| Index: sdk/lib/_internal/compiler/implementation/string_validator.dart
|
| diff --git a/sdk/lib/_internal/compiler/implementation/string_validator.dart b/sdk/lib/_internal/compiler/implementation/string_validator.dart
|
| index a5f15e218067e6b85a39ba45c28ced379726c840..c48611dc9f52ac1afd00b9a1556bff96d05aebea 100644
|
| --- a/sdk/lib/_internal/compiler/implementation/string_validator.dart
|
| +++ b/sdk/lib/_internal/compiler/implementation/string_validator.dart
|
| @@ -96,6 +96,8 @@ class StringValidator {
|
| int length = 0;
|
| int index = startOffset;
|
| bool containsEscape = false;
|
| + bool previousWasLeadSurrogate = false;
|
| + bool invalidUtf16 = false;
|
| for(Iterator<int> iter = string.iterator(); iter.hasNext; length++) {
|
| index++;
|
| int code = iter.next();
|
| @@ -168,15 +170,27 @@ class StringValidator {
|
| code = value;
|
| }
|
| }
|
| + if (code >= 0x10000) length++;
|
| + assert(code <= 0x10ffff);
|
| // This handles both unescaped characters and the value of unicode
|
| // escapes.
|
| - if (!isUnicodeScalarValue(code)) {
|
| - stringParseError(
|
| - "Invalid Unicode scalar value U+${code.toRadixString(16)}",
|
| - token, index);
|
| - return null;
|
| + if (previousWasLeadSurrogate) {
|
| + if (!isUtf16TrailSurrogate(code)) {
|
| + invalidUtf16 = true;
|
| + break;
|
| + }
|
| + previousWasLeadSurrogate = false;
|
| + } else if (isUtf16LeadSurrogate(code)) {
|
| + previousWasLeadSurrogate = true;
|
| + } else if (!isUnicodeScalarValue(code)) {
|
| + invalidUtf16 = true;
|
| + break;
|
| }
|
| }
|
| + if (previousWasLeadSurrogate || invalidUtf16) {
|
| + stringParseError("Invalid Utf16 surrogate", token, index);
|
| + return null;
|
| + }
|
| // String literal successfully validated.
|
| if (quoting.raw || !containsEscape) {
|
| // A string without escapes could just as well have been raw.
|
|
|