- Revision
- 280181
- Author
- [email protected]
- Date
- 2021-07-22 10:44:34 -0700 (Thu, 22 Jul 2021)
Log Message
XHR.send(Document) should replace mismatched surrogates with replacement character before sending
https://bugs.webkit.org/show_bug.cgi?id=228170
Patch by Alex Christensen <[email protected]> on 2021-07-22
Reviewed by Chris Dumez.
LayoutTests/imported/w3c:
* web-platform-tests/xhr/send-entity-body-document-bogus-expected.txt:
Source/WebCore:
This matches the behavior of Chrome and Firefox.
Covered by a newly passing WPT test.
* bindings/js/JSDOMConvertStrings.cpp:
(WebCore::identifierToUSVString):
(WebCore::valueToUSVString):
(WebCore::stringToUSVString): Deleted.
* bindings/js/JSDOMConvertStrings.h:
* css/parser/CSSTokenizer.cpp:
(WebCore::preprocessString):
* xml/XMLHttpRequest.cpp:
(WebCore::XMLHttpRequest::send):
Source/WTF:
* wtf/text/WTFString.cpp:
(WTF::replaceUnpairedSurrogatesWithReplacementCharacter):
* wtf/text/WTFString.h:
Move from WebCore, rename as suggested, update spec link to one that works.
Modified Paths
Diff
Modified: trunk/LayoutTests/imported/w3c/ChangeLog (280180 => 280181)
--- trunk/LayoutTests/imported/w3c/ChangeLog 2021-07-22 17:28:57 UTC (rev 280180)
+++ trunk/LayoutTests/imported/w3c/ChangeLog 2021-07-22 17:44:34 UTC (rev 280181)
@@ -1,3 +1,12 @@
+2021-07-22 Alex Christensen <[email protected]>
+
+ XHR.send(Document) should replace mismatched surrogates with replacement character before sending
+ https://bugs.webkit.org/show_bug.cgi?id=228170
+
+ Reviewed by Chris Dumez.
+
+ * web-platform-tests/xhr/send-entity-body-document-bogus-expected.txt:
+
2021-07-22 Sihui Liu <[email protected]>
[macOS Debug] Layout Test imported/w3c/web-platform-tests/IndexedDB/open-request-queue.html is a flaky timeout.
Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/xhr/send-entity-body-document-bogus-expected.txt (280180 => 280181)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/xhr/send-entity-body-document-bogus-expected.txt 2021-07-22 17:28:57 UTC (rev 280180)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/xhr/send-entity-body-document-bogus-expected.txt 2021-07-22 17:44:34 UTC (rev 280181)
@@ -2,5 +2,5 @@
PASS Serializing documents through XMLHttpRequest: ''
PASS Serializing documents through XMLHttpRequest: '<test:test/>'
PASS Serializing documents through XMLHttpRequest: '<test:test test:test="gee"/>'
-FAIL Serializing documents through XMLHttpRequest: '<test:test test:test="gee" x="�"/>' assert_equals: expected "<test:test test:test=\"gee\" x=\"\ufffd\"/>" but got "<test:test test:test=\"gee\" x=\"\ufffd\ufffd\ufffd\"/>"
+PASS Serializing documents through XMLHttpRequest: '<test:test test:test="gee" x="�"/>'
Modified: trunk/Source/WTF/ChangeLog (280180 => 280181)
--- trunk/Source/WTF/ChangeLog 2021-07-22 17:28:57 UTC (rev 280180)
+++ trunk/Source/WTF/ChangeLog 2021-07-22 17:44:34 UTC (rev 280181)
@@ -1,3 +1,15 @@
+2021-07-22 Alex Christensen <[email protected]>
+
+ XHR.send(Document) should replace mismatched surrogates with replacement character before sending
+ https://bugs.webkit.org/show_bug.cgi?id=228170
+
+ Reviewed by Chris Dumez.
+
+ * wtf/text/WTFString.cpp:
+ (WTF::replaceUnpairedSurrogatesWithReplacementCharacter):
+ * wtf/text/WTFString.h:
+ Move from WebCore, rename as suggested, update spec link to one that works.
+
2021-07-22 Zan Dobersek <[email protected]>
Add CPU(RISCV64)
Modified: trunk/Source/WTF/wtf/text/WTFString.cpp (280180 => 280181)
--- trunk/Source/WTF/wtf/text/WTFString.cpp 2021-07-22 17:28:57 UTC (rev 280180)
+++ trunk/Source/WTF/wtf/text/WTFString.cpp 2021-07-22 17:44:34 UTC (rev 280181)
@@ -863,6 +863,26 @@
return nullString;
}
+String replaceUnpairedSurrogatesWithReplacementCharacter(String&& string)
+{
+ // Fast path for the case where there are no unpaired surrogates.
+ if (!hasUnpairedSurrogate(string))
+ return WTFMove(string);
+
+ // Slow path: https://infra.spec.whatwg.org/#_javascript_-string-convert
+ // Replaces unpaired surrogates with the replacement character.
+ StringBuilder result;
+ result.reserveCapacity(string.length());
+ StringView view { string };
+ for (auto codePoint : view.codePoints()) {
+ if (U_IS_SURROGATE(codePoint))
+ result.append(replacementCharacter);
+ else
+ result.appendCharacter(codePoint);
+ }
+ return result.toString();
+}
+
} // namespace WTF
#ifndef NDEBUG
Modified: trunk/Source/WTF/wtf/text/WTFString.h (280180 => 280181)
--- trunk/Source/WTF/wtf/text/WTFString.h 2021-07-22 17:28:57 UTC (rev 280180)
+++ trunk/Source/WTF/wtf/text/WTFString.h 2021-07-22 17:44:34 UTC (rev 280181)
@@ -426,6 +426,8 @@
#endif
+WTF_EXPORT_PRIVATE String replaceUnpairedSurrogatesWithReplacementCharacter(String&&);
+
// Definitions of string operations
inline String::String(StringImpl& string)
Modified: trunk/Source/WebCore/ChangeLog (280180 => 280181)
--- trunk/Source/WebCore/ChangeLog 2021-07-22 17:28:57 UTC (rev 280180)
+++ trunk/Source/WebCore/ChangeLog 2021-07-22 17:44:34 UTC (rev 280181)
@@ -1,3 +1,23 @@
+2021-07-22 Alex Christensen <[email protected]>
+
+ XHR.send(Document) should replace mismatched surrogates with replacement character before sending
+ https://bugs.webkit.org/show_bug.cgi?id=228170
+
+ Reviewed by Chris Dumez.
+
+ This matches the behavior of Chrome and Firefox.
+ Covered by a newly passing WPT test.
+
+ * bindings/js/JSDOMConvertStrings.cpp:
+ (WebCore::identifierToUSVString):
+ (WebCore::valueToUSVString):
+ (WebCore::stringToUSVString): Deleted.
+ * bindings/js/JSDOMConvertStrings.h:
+ * css/parser/CSSTokenizer.cpp:
+ (WebCore::preprocessString):
+ * xml/XMLHttpRequest.cpp:
+ (WebCore::XMLHttpRequest::send):
+
2021-07-22 Víctor Manuel Jáquez Leal <[email protected]>
Compilation error with gcc version 9.3.0 (Buildroot 2020.08-14-ge5a2a90)
Modified: trunk/Source/WebCore/bindings/js/JSDOMConvertStrings.cpp (280180 => 280181)
--- trunk/Source/WebCore/bindings/js/JSDOMConvertStrings.cpp 2021-07-22 17:28:57 UTC (rev 280180)
+++ trunk/Source/WebCore/bindings/js/JSDOMConvertStrings.cpp 2021-07-22 17:44:34 UTC (rev 280181)
@@ -74,29 +74,9 @@
return stringToByteString(lexicalGlobalObject, scope, WTFMove(string));
}
-String stringToUSVString(String&& string)
-{
- // Fast path for the case where there are no unpaired surrogates.
- if (!hasUnpairedSurrogate(string))
- return WTFMove(string);
-
- // Slow path: http://heycam.github.io/webidl/#dfn-obtain-unicode
- // Replaces unpaired surrogates with the replacement character.
- StringBuilder result;
- result.reserveCapacity(string.length());
- StringView view { string };
- for (auto codePoint : view.codePoints()) {
- if (U_IS_SURROGATE(codePoint))
- result.append(replacementCharacter);
- else
- result.appendCharacter(codePoint);
- }
- return result.toString();
-}
-
String identifierToUSVString(JSGlobalObject& lexicalGlobalObject, const Identifier& identifier)
{
- return stringToUSVString(identifierToString(lexicalGlobalObject, identifier));
+ return replaceUnpairedSurrogatesWithReplacementCharacter(identifierToString(lexicalGlobalObject, identifier));
}
String valueToUSVString(JSGlobalObject& lexicalGlobalObject, JSValue value)
@@ -107,7 +87,7 @@
auto string = value.toWTFString(&lexicalGlobalObject);
RETURN_IF_EXCEPTION(scope, { });
- return stringToUSVString(WTFMove(string));
+ return replaceUnpairedSurrogatesWithReplacementCharacter(WTFMove(string));
}
} // namespace WebCore
Modified: trunk/Source/WebCore/bindings/js/JSDOMConvertStrings.h (280180 => 280181)
--- trunk/Source/WebCore/bindings/js/JSDOMConvertStrings.h 2021-07-22 17:28:57 UTC (rev 280180)
+++ trunk/Source/WebCore/bindings/js/JSDOMConvertStrings.h 2021-07-22 17:44:34 UTC (rev 280181)
@@ -37,9 +37,6 @@
WEBCORE_EXPORT String identifierToUSVString(JSC::JSGlobalObject&, const JSC::Identifier&);
WEBCORE_EXPORT String valueToUSVString(JSC::JSGlobalObject&, JSC::JSValue);
-// FIXME: Consider renaming this to replaceUnpairedSurrogatesWithReplacementCharacter and moving to WTF.
-String stringToUSVString(String&&);
-
inline String propertyNameToString(JSC::PropertyName propertyName)
{
ASSERT(!propertyName.isSymbol());
Modified: trunk/Source/WebCore/css/parser/CSSTokenizer.cpp (280180 => 280181)
--- trunk/Source/WebCore/css/parser/CSSTokenizer.cpp 2021-07-22 17:28:57 UTC (rev 280180)
+++ trunk/Source/WebCore/css/parser/CSSTokenizer.cpp 2021-07-22 17:44:34 UTC (rev 280181)
@@ -48,7 +48,7 @@
// We don't replace '\r' and '\f' with '\n' as the specification suggests, instead
// we treat them all the same in the isNewLine function below.
string.replace('\0', replacementCharacter);
- return stringToUSVString(WTFMove(string));
+ return replaceUnpairedSurrogatesWithReplacementCharacter(WTFMove(string));
}
std::unique_ptr<CSSTokenizer> CSSTokenizer::tryCreate(const String& string)
Modified: trunk/Source/WebCore/xml/XMLHttpRequest.cpp (280180 => 280181)
--- trunk/Source/WebCore/xml/XMLHttpRequest.cpp 2021-07-22 17:28:57 UTC (rev 280180)
+++ trunk/Source/WebCore/xml/XMLHttpRequest.cpp 2021-07-22 17:44:34 UTC (rev 280181)
@@ -480,7 +480,12 @@
// FIXME: According to XMLHttpRequest Level 2, this should use the Document.innerHTML algorithm
// from the HTML5 specification to serialize the document.
- m_requestEntityBody = FormData::create(UTF8Encoding().encode(serializeFragment(document, SerializedNodes::SubtreeIncludingNode), UnencodableHandling::Entities));
+
+ // https://xhr.spec.whatwg.org/#dom-xmlhttprequest-send Step 4.2.
+ auto serialized = serializeFragment(document, SerializedNodes::SubtreeIncludingNode);
+ auto converted = replaceUnpairedSurrogatesWithReplacementCharacter(WTFMove(serialized));
+ auto encoded = UTF8Encoding().encode(WTFMove(converted), UnencodableHandling::Entities);
+ m_requestEntityBody = FormData::create(WTFMove(encoded));
if (m_upload)
m_requestEntityBody->setAlwaysStream(true);
}