Title: [280181] trunk
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);
     }
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to