Index: third_party/WebKit/Source/wtf/text/TextCodecICU.cpp |
diff --git a/third_party/WebKit/Source/wtf/text/TextCodecICU.cpp b/third_party/WebKit/Source/wtf/text/TextCodecICU.cpp |
index b3423597e2e6eee88bcadb6a3b195ea1a56c6b05..b157bf9084e44ddc8a3fe93d2dc316b41d63c3b7 100644 |
--- a/third_party/WebKit/Source/wtf/text/TextCodecICU.cpp |
+++ b/third_party/WebKit/Source/wtf/text/TextCodecICU.cpp |
@@ -409,22 +409,37 @@ static UChar fallbackForGBK(UChar32 character) |
} |
#endif |
-// Invalid character handler when writing escaped entities for unrepresentable |
-// characters. See the declaration of TextCodec::encode for more. |
-static void urlEscapedEntityCallback(const void* context, UConverterFromUnicodeArgs* fromUArgs, const UChar* codeUnits, int32_t length, |
- UChar32 codePoint, UConverterCallbackReason reason, UErrorCode* err) |
+// Generic helper for writing escaped entities using the specfied UnencodableHandling. |
+static void formatEscapedEntityCallback(const void* context, UConverterFromUnicodeArgs* fromUArgs, const UChar* codeUnits, int32_t length, |
+ UChar32 codePoint, UConverterCallbackReason reason, UErrorCode* err, UnencodableHandling handling) |
{ |
if (reason == UCNV_UNASSIGNED) { |
*err = U_ZERO_ERROR; |
UnencodableReplacementArray entity; |
- int entityLen = TextCodec::getUnencodableReplacement(codePoint, URLEncodedEntitiesForUnencodables, entity); |
+ int entityLen = TextCodec::getUnencodableReplacement(codePoint, handling, entity); |
ucnv_cbFromUWriteBytes(fromUArgs, entity, entityLen, 0, err); |
} else { |
UCNV_FROM_U_CALLBACK_ESCAPE(context, fromUArgs, codeUnits, length, codePoint, reason, err); |
} |
} |
+// Invalid character handler when writing escaped entities in CSS encoding for |
+// unrepresentable characters. See the declaration of TextCodec::encode for more. |
+static void cssEscapedEntityCallback(const void* context, UConverterFromUnicodeArgs* fromUArgs, const UChar* codeUnits, int32_t length, |
+ UChar32 codePoint, UConverterCallbackReason reason, UErrorCode* err) |
+{ |
+ formatEscapedEntityCallback(context, fromUArgs, codeUnits, length, codePoint, reason, err, CSSEncodedEntitiesForUnencodables); |
+} |
+ |
+// Invalid character handler when writing escaped entities in HTML/XML encoding for |
+// unrepresentable characters. See the declaration of TextCodec::encode for more. |
+static void urlEscapedEntityCallback(const void* context, UConverterFromUnicodeArgs* fromUArgs, const UChar* codeUnits, int32_t length, |
+ UChar32 codePoint, UConverterCallbackReason reason, UErrorCode* err) |
+{ |
+ formatEscapedEntityCallback(context, fromUArgs, codeUnits, length, codePoint, reason, err, URLEncodedEntitiesForUnencodables); |
+} |
+ |
#if defined(USING_SYSTEM_ICU) |
// Substitutes special GBK characters, escaping all other unassigned entities. |
static void gbkCallbackEscape(const void* context, UConverterFromUnicodeArgs* fromUArgs, const UChar* codeUnits, int32_t length, |
@@ -440,6 +455,23 @@ static void gbkCallbackEscape(const void* context, UConverterFromUnicodeArgs* fr |
UCNV_FROM_U_CALLBACK_ESCAPE(context, fromUArgs, codeUnits, length, codePoint, reason, err); |
} |
+// Combines both gbkCssEscapedEntityCallback and GBK character substitution. |
+static void gbkCssEscapedEntityCallack(const void* context, UConverterFromUnicodeArgs* fromUArgs, const UChar* codeUnits, int32_t length, |
+ UChar32 codePoint, UConverterCallbackReason reason, UErrorCode* err) |
+{ |
+ if (reason == UCNV_UNASSIGNED) { |
+ if (UChar outChar = fallbackForGBK(codePoint)) { |
+ const UChar* source = &outChar; |
+ *err = U_ZERO_ERROR; |
+ ucnv_cbFromUWriteUChars(fromUArgs, &source, source + 1, 0, err); |
+ return; |
+ } |
+ cssEscapedEntityCallback(context, fromUArgs, codeUnits, length, codePoint, reason, err); |
+ return; |
+ } |
+ UCNV_FROM_U_CALLBACK_ESCAPE(context, fromUArgs, codeUnits, length, codePoint, reason, err); |
+} |
+ |
// Combines both gbkUrlEscapedEntityCallback and GBK character substitution. |
static void gbkUrlEscapedEntityCallack(const void* context, UConverterFromUnicodeArgs* fromUArgs, const UChar* codeUnits, int32_t length, |
UChar32 codePoint, UConverterCallbackReason reason, UErrorCode* err) |
@@ -527,6 +559,13 @@ CString TextCodecICU::encodeInternal(const TextCodecInput& input, UnencodableHan |
ucnv_setFromUCallBack(m_converterICU, m_needsGBKFallbacks ? gbkUrlEscapedEntityCallack : urlEscapedEntityCallback, 0, 0, 0, &err); |
#endif |
break; |
+ case CSSEncodedEntitiesForUnencodables: |
+#if !defined(USING_SYSTEM_ICU) |
+ ucnv_setFromUCallBack(m_converterICU, cssEscapedEntityCallback, 0, 0, 0, &err); |
+#else |
+ ucnv_setFromUCallBack(m_converterICU, m_needsGBKFallbacks ? gbkCssEscapedEntityCallack : cssEscapedEntityCallback, 0, 0, 0, &err); |
+#endif |
+ break; |
} |
ASSERT(U_SUCCESS(err)); |