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. |