Index: runtime/vm/dart_api_message.cc |
diff --git a/runtime/vm/dart_api_message.cc b/runtime/vm/dart_api_message.cc |
index 4cee392ee75564f19ef8bdd909d8116b9ed76e27..5a9b5e12ac0b3ccb8aca17672fcfe608f3bd9d70 100644 |
--- a/runtime/vm/dart_api_message.cc |
+++ b/runtime/vm/dart_api_message.cc |
@@ -389,17 +389,35 @@ Dart_CObject* ApiMessageReader::ReadInternalVMObject(intptr_t class_id, |
uint16_t *utf16 = |
reinterpret_cast<uint16_t*>(::malloc(len * sizeof(uint16_t))); |
intptr_t utf8_len = 0; |
+ // Read all the UTF-16 code units. |
for (intptr_t i = 0; i < len; i++) { |
utf16[i] = Read<uint16_t>(); |
- // TODO(sgjesse): Check for surrogate pairs. |
- utf8_len += Utf8::Length(utf16[i]); |
+ } |
+ // Calculate the UTF-8 length. |
+ for (intptr_t i = 0; i < len; i++) { |
erikcorry
2012/11/23 14:25:47
There is a CodePointIterator in object.h that you
Søren Gjesse
2012/11/26 08:53:00
That is not possible as this is a raw de-serialize
|
+ if (i < len - 1 && |
+ Utf16::IsLeadSurrogate(utf16[i]) && |
+ Utf16::IsTrailSurrogate(utf16[i + 1])) { |
+ uint32_t ch = Utf16::Decode(utf16[i], utf16[i + 1]); |
+ utf8_len += Utf8::Length(ch); |
+ i++; |
+ } else { |
+ utf8_len += Utf8::Length(utf16[i]); |
+ } |
} |
Dart_CObject* object = AllocateDartCObjectString(utf8_len); |
AddBackRef(object_id, object, kIsDeserialized); |
char* p = object->value.as_string; |
for (intptr_t i = 0; i < len; i++) { |
- // TODO(sgjesse): Check for surrogate pairs. |
- p += Utf8::Encode(utf16[i], p); |
+ if (i < len - 1 && |
+ Utf16::IsLeadSurrogate(utf16[i]) && |
+ Utf16::IsTrailSurrogate(utf16[i + 1])) { |
+ uint32_t ch = Utf16::Decode(utf16[i], utf16[i + 1]); |
+ p += Utf8::Encode(ch, p); |
+ i++; |
+ } else { |
+ p += Utf8::Encode(utf16[i], p); |
+ } |
} |
*p = '\0'; |
ASSERT(p == (object->value.as_string + utf8_len)); |
@@ -788,7 +806,7 @@ bool ApiMessageWriter::WriteCObjectInlined(Dart_CObject* object, |
const uint8_t* utf8_str = |
reinterpret_cast<const uint8_t*>(object->value.as_string); |
intptr_t utf8_len = strlen(object->value.as_string); |
- if (!Utf8::IsValid(utf8_str, utf8_len)) { |
+ if (!Utf8::IsValidAllowSurrogates(utf8_str, utf8_len)) { |
return false; |
} |
@@ -807,7 +825,11 @@ bool ApiMessageWriter::WriteCObjectInlined(Dart_CObject* object, |
if (type == Utf8::kLatin1) { |
uint8_t* latin1_str = |
reinterpret_cast<uint8_t*>(::malloc(len * sizeof(uint8_t))); |
- Utf8::DecodeToLatin1(utf8_str, utf8_len, latin1_str, len); |
+ bool success = Utf8::DecodeToLatin1(utf8_str, |
+ utf8_len, |
+ latin1_str, |
+ len); |
+ ASSERT(success); |
for (intptr_t i = 0; i < len; i++) { |
Write<uint8_t>(latin1_str[i]); |
} |
@@ -816,7 +838,11 @@ bool ApiMessageWriter::WriteCObjectInlined(Dart_CObject* object, |
// TODO(sgjesse): Make sure surrogate pairs are handled. |
uint16_t* utf16_str = |
reinterpret_cast<uint16_t*>(::malloc(len * sizeof(uint16_t))); |
- Utf8::DecodeToUTF16(utf8_str, utf8_len, utf16_str, len); |
+ bool success = Utf8::DecodeToUTF16AllowSurrogates(utf8_str, |
+ utf8_len, |
+ utf16_str, |
+ len); |
+ ASSERT(success); |
for (intptr_t i = 0; i < len; i++) { |
Write<uint16_t>(utf16_str[i]); |
} |