HTML fragment serialization should not strip whitespace from URL attribute values
authorcdumez@apple.com <cdumez@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 3 Apr 2019 20:08:34 +0000 (20:08 +0000)
committercdumez@apple.com <cdumez@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 3 Apr 2019 20:08:34 +0000 (20:08 +0000)
https://bugs.webkit.org/show_bug.cgi?id=196551

Reviewed by Ryosuke Niwa.

LayoutTests/imported/w3c:

Rebaseline WPT test now that all checks are passing. This test was already passing
in Gecko and Blink.

* web-platform-tests/domparsing/innerhtml-mxss.sub-expected.txt:

Source/WebCore:

HTML fragment serialization should not strip whitespace from URL attribute values as per:
- https://html.spec.whatwg.org/multipage/parsing.html#html-fragment-serialisation-algorithm

WebKit was stripping such whitespace, Gecko and Blink are not. Align WebKit with other
browser engines and the specification.

No new tests, rebaselined existing test.

* editing/MarkupAccumulator.cpp:
(WebCore::MarkupAccumulator::appendQuotedURLAttributeValue):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@243821 268f45cc-cd09-0410-ab3c-d52691b4dbfc

LayoutTests/imported/w3c/ChangeLog
LayoutTests/imported/w3c/web-platform-tests/domparsing/innerhtml-mxss.sub-expected.txt
Source/WebCore/ChangeLog
Source/WebCore/editing/MarkupAccumulator.cpp

index ab49bb9..1266bfd 100644 (file)
@@ -1,5 +1,17 @@
 2019-04-03  Chris Dumez  <cdumez@apple.com>
 
+        HTML fragment serialization should not strip whitespace from URL attribute values
+        https://bugs.webkit.org/show_bug.cgi?id=196551
+
+        Reviewed by Ryosuke Niwa.
+
+        Rebaseline WPT test now that all checks are passing. This test was already passing
+        in Gecko and Blink.
+
+        * web-platform-tests/domparsing/innerhtml-mxss.sub-expected.txt:
+
+2019-04-03  Chris Dumez  <cdumez@apple.com>
+
         [XML Parser] Insert the error message block when stopping parsing and an error occurred
         https://bugs.webkit.org/show_bug.cgi?id=196546
 
index f6d046b..51609bf 100644 (file)
@@ -1,63 +1,63 @@
 Linkfoo
 
-FAIL innerHTML before setter: 1680 assert_equals: expected "<a href=\" javascript:alert(1)\">Link</a>" but got "<a href=\"javascript:alert(1)\">Link</a>"
+PASS innerHTML before setter: 1680 
 PASS href before setter: 1680 
-FAIL innerHTML after setter: 1680 assert_equals: expected "<a href=\" javascript:alert(1)\">Link</a>foo" but got "<a href=\"javascript:alert(1)\">Link</a>foo"
-FAIL href after setter: 1680 assert_equals: expected "http://localhost:8800/domparsing/%E1%9A%80javascript:alert(1)" but got "javascript:alert(1)"
-FAIL innerHTML before setter: 2000 assert_equals: expected "<a href=\" javascript:alert(1)\">Link</a>" but got "<a href=\"javascript:alert(1)\">Link</a>"
+PASS innerHTML after setter: 1680 
+PASS href after setter: 1680 
+PASS innerHTML before setter: 2000 
 PASS href before setter: 2000 
-FAIL innerHTML after setter: 2000 assert_equals: expected "<a href=\" javascript:alert(1)\">Link</a>foo" but got "<a href=\"javascript:alert(1)\">Link</a>foo"
-FAIL href after setter: 2000 assert_equals: expected "http://localhost:8800/domparsing/%E2%80%80javascript:alert(1)" but got "javascript:alert(1)"
-FAIL innerHTML before setter: 2001 assert_equals: expected "<a href=\" javascript:alert(1)\">Link</a>" but got "<a href=\"javascript:alert(1)\">Link</a>"
+PASS innerHTML after setter: 2000 
+PASS href after setter: 2000 
+PASS innerHTML before setter: 2001 
 PASS href before setter: 2001 
-FAIL innerHTML after setter: 2001 assert_equals: expected "<a href=\" javascript:alert(1)\">Link</a>foo" but got "<a href=\"javascript:alert(1)\">Link</a>foo"
-FAIL href after setter: 2001 assert_equals: expected "http://localhost:8800/domparsing/%E2%80%81javascript:alert(1)" but got "javascript:alert(1)"
-FAIL innerHTML before setter: 2002 assert_equals: expected "<a href=\" javascript:alert(1)\">Link</a>" but got "<a href=\"javascript:alert(1)\">Link</a>"
+PASS innerHTML after setter: 2001 
+PASS href after setter: 2001 
+PASS innerHTML before setter: 2002 
 PASS href before setter: 2002 
-FAIL innerHTML after setter: 2002 assert_equals: expected "<a href=\" javascript:alert(1)\">Link</a>foo" but got "<a href=\"javascript:alert(1)\">Link</a>foo"
-FAIL href after setter: 2002 assert_equals: expected "http://localhost:8800/domparsing/%E2%80%82javascript:alert(1)" but got "javascript:alert(1)"
-FAIL innerHTML before setter: 2003 assert_equals: expected "<a href=\" javascript:alert(1)\">Link</a>" but got "<a href=\"javascript:alert(1)\">Link</a>"
+PASS innerHTML after setter: 2002 
+PASS href after setter: 2002 
+PASS innerHTML before setter: 2003 
 PASS href before setter: 2003 
-FAIL innerHTML after setter: 2003 assert_equals: expected "<a href=\" javascript:alert(1)\">Link</a>foo" but got "<a href=\"javascript:alert(1)\">Link</a>foo"
-FAIL href after setter: 2003 assert_equals: expected "http://localhost:8800/domparsing/%E2%80%83javascript:alert(1)" but got "javascript:alert(1)"
-FAIL innerHTML before setter: 2004 assert_equals: expected "<a href=\" javascript:alert(1)\">Link</a>" but got "<a href=\"javascript:alert(1)\">Link</a>"
+PASS innerHTML after setter: 2003 
+PASS href after setter: 2003 
+PASS innerHTML before setter: 2004 
 PASS href before setter: 2004 
-FAIL innerHTML after setter: 2004 assert_equals: expected "<a href=\" javascript:alert(1)\">Link</a>foo" but got "<a href=\"javascript:alert(1)\">Link</a>foo"
-FAIL href after setter: 2004 assert_equals: expected "http://localhost:8800/domparsing/%E2%80%84javascript:alert(1)" but got "javascript:alert(1)"
-FAIL innerHTML before setter: 2005 assert_equals: expected "<a href=\" javascript:alert(1)\">Link</a>" but got "<a href=\"javascript:alert(1)\">Link</a>"
+PASS innerHTML after setter: 2004 
+PASS href after setter: 2004 
+PASS innerHTML before setter: 2005 
 PASS href before setter: 2005 
-FAIL innerHTML after setter: 2005 assert_equals: expected "<a href=\" javascript:alert(1)\">Link</a>foo" but got "<a href=\"javascript:alert(1)\">Link</a>foo"
-FAIL href after setter: 2005 assert_equals: expected "http://localhost:8800/domparsing/%E2%80%85javascript:alert(1)" but got "javascript:alert(1)"
-FAIL innerHTML before setter: 2006 assert_equals: expected "<a href=\" javascript:alert(1)\">Link</a>" but got "<a href=\"javascript:alert(1)\">Link</a>"
+PASS innerHTML after setter: 2005 
+PASS href after setter: 2005 
+PASS innerHTML before setter: 2006 
 PASS href before setter: 2006 
-FAIL innerHTML after setter: 2006 assert_equals: expected "<a href=\" javascript:alert(1)\">Link</a>foo" but got "<a href=\"javascript:alert(1)\">Link</a>foo"
-FAIL href after setter: 2006 assert_equals: expected "http://localhost:8800/domparsing/%E2%80%86javascript:alert(1)" but got "javascript:alert(1)"
-FAIL innerHTML before setter: 2007 assert_equals: expected "<a href=\" javascript:alert(1)\">Link</a>" but got "<a href=\"javascript:alert(1)\">Link</a>"
+PASS innerHTML after setter: 2006 
+PASS href after setter: 2006 
+PASS innerHTML before setter: 2007 
 PASS href before setter: 2007 
-FAIL innerHTML after setter: 2007 assert_equals: expected "<a href=\" javascript:alert(1)\">Link</a>foo" but got "<a href=\"javascript:alert(1)\">Link</a>foo"
-FAIL href after setter: 2007 assert_equals: expected "http://localhost:8800/domparsing/%E2%80%87javascript:alert(1)" but got "javascript:alert(1)"
-FAIL innerHTML before setter: 2008 assert_equals: expected "<a href=\" javascript:alert(1)\">Link</a>" but got "<a href=\"javascript:alert(1)\">Link</a>"
+PASS innerHTML after setter: 2007 
+PASS href after setter: 2007 
+PASS innerHTML before setter: 2008 
 PASS href before setter: 2008 
-FAIL innerHTML after setter: 2008 assert_equals: expected "<a href=\" javascript:alert(1)\">Link</a>foo" but got "<a href=\"javascript:alert(1)\">Link</a>foo"
-FAIL href after setter: 2008 assert_equals: expected "http://localhost:8800/domparsing/%E2%80%88javascript:alert(1)" but got "javascript:alert(1)"
-FAIL innerHTML before setter: 2009 assert_equals: expected "<a href=\" javascript:alert(1)\">Link</a>" but got "<a href=\"javascript:alert(1)\">Link</a>"
+PASS innerHTML after setter: 2008 
+PASS href after setter: 2008 
+PASS innerHTML before setter: 2009 
 PASS href before setter: 2009 
-FAIL innerHTML after setter: 2009 assert_equals: expected "<a href=\" javascript:alert(1)\">Link</a>foo" but got "<a href=\"javascript:alert(1)\">Link</a>foo"
-FAIL href after setter: 2009 assert_equals: expected "http://localhost:8800/domparsing/%E2%80%89javascript:alert(1)" but got "javascript:alert(1)"
-FAIL innerHTML before setter: 200a assert_equals: expected "<a href=\" javascript:alert(1)\">Link</a>" but got "<a href=\"javascript:alert(1)\">Link</a>"
+PASS innerHTML after setter: 2009 
+PASS href after setter: 2009 
+PASS innerHTML before setter: 200a 
 PASS href before setter: 200a 
-FAIL innerHTML after setter: 200a assert_equals: expected "<a href=\" javascript:alert(1)\">Link</a>foo" but got "<a href=\"javascript:alert(1)\">Link</a>foo"
-FAIL href after setter: 200a assert_equals: expected "http://localhost:8800/domparsing/%E2%80%8Ajavascript:alert(1)" but got "javascript:alert(1)"
-FAIL innerHTML before setter: 2028 assert_equals: expected "<a href=\"
javascript:alert(1)\">Link</a>" but got "<a href=\"javascript:alert(1)\">Link</a>"
+PASS innerHTML after setter: 200a 
+PASS href after setter: 200a 
+PASS innerHTML before setter: 2028 
 PASS href before setter: 2028 
-FAIL innerHTML after setter: 2028 assert_equals: expected "<a href=\"
javascript:alert(1)\">Link</a>foo" but got "<a href=\"javascript:alert(1)\">Link</a>foo"
-FAIL href after setter: 2028 assert_equals: expected "http://localhost:8800/domparsing/%E2%80%A8javascript:alert(1)" but got "javascript:alert(1)"
-FAIL innerHTML before setter: 205f assert_equals: expected "<a href=\" javascript:alert(1)\">Link</a>" but got "<a href=\"javascript:alert(1)\">Link</a>"
+PASS innerHTML after setter: 2028 
+PASS href after setter: 2028 
+PASS innerHTML before setter: 205f 
 PASS href before setter: 205f 
-FAIL innerHTML after setter: 205f assert_equals: expected "<a href=\" javascript:alert(1)\">Link</a>foo" but got "<a href=\"javascript:alert(1)\">Link</a>foo"
-FAIL href after setter: 205f assert_equals: expected "http://localhost:8800/domparsing/%E2%81%9Fjavascript:alert(1)" but got "javascript:alert(1)"
-FAIL innerHTML before setter: 3000 assert_equals: expected "<a href=\" javascript:alert(1)\">Link</a>" but got "<a href=\"javascript:alert(1)\">Link</a>"
+PASS innerHTML after setter: 205f 
+PASS href after setter: 205f 
+PASS innerHTML before setter: 3000 
 PASS href before setter: 3000 
-FAIL innerHTML after setter: 3000 assert_equals: expected "<a href=\" javascript:alert(1)\">Link</a>foo" but got "<a href=\"javascript:alert(1)\">Link</a>foo"
-FAIL href after setter: 3000 assert_equals: expected "http://localhost:8800/domparsing/%E3%80%80javascript:alert(1)" but got "javascript:alert(1)"
+PASS innerHTML after setter: 3000 
+PASS href after setter: 3000 
 
index cec56c1..92bfafb 100644 (file)
@@ -1,3 +1,21 @@
+2019-04-03  Chris Dumez  <cdumez@apple.com>
+
+        HTML fragment serialization should not strip whitespace from URL attribute values
+        https://bugs.webkit.org/show_bug.cgi?id=196551
+
+        Reviewed by Ryosuke Niwa.
+
+        HTML fragment serialization should not strip whitespace from URL attribute values as per:
+        - https://html.spec.whatwg.org/multipage/parsing.html#html-fragment-serialisation-algorithm
+
+        WebKit was stripping such whitespace, Gecko and Blink are not. Align WebKit with other
+        browser engines and the specification.
+
+        No new tests, rebaselined existing test.
+
+        * editing/MarkupAccumulator.cpp:
+        (WebCore::MarkupAccumulator::appendQuotedURLAttributeValue):
+
 2019-04-02  Ryosuke Niwa  <rniwa@webkit.org>
 
         Crash in HTMLCanvasElement::createContext2d after the element got adopted to a new document
index 23f6e5d..5250063 100644 (file)
@@ -292,19 +292,18 @@ void MarkupAccumulator::appendCustomAttributes(StringBuilder&, const Element&, N
 void MarkupAccumulator::appendQuotedURLAttributeValue(StringBuilder& result, const Element& element, const Attribute& attribute)
 {
     ASSERT(element.isURLAttribute(attribute));
-    const String resolvedURLString = resolveURLIfNeeded(element, attribute.value());
+    String resolvedURLString = resolveURLIfNeeded(element, attribute.value());
     UChar quoteChar = '"';
-    String strippedURLString = resolvedURLString.stripWhiteSpace();
-    if (WTF::protocolIsJavaScript(strippedURLString)) {
+    if (WTF::protocolIsJavaScript(resolvedURLString)) {
         // minimal escaping for javascript urls
-        if (strippedURLString.contains('"')) {
-            if (strippedURLString.contains('\''))
-                strippedURLString.replaceWithLiteral('"', "&quot;");
+        if (resolvedURLString.contains('"')) {
+            if (resolvedURLString.contains('\''))
+                resolvedURLString.replaceWithLiteral('"', "&quot;");
             else
                 quoteChar = '\'';
         }
         result.append(quoteChar);
-        result.append(strippedURLString);
+        result.append(resolvedURLString);
         result.append(quoteChar);
         return;
     }