Title: [211645] trunk
Revision
211645
Author
cdu...@apple.com
Date
2017-02-03 12:49:39 -0800 (Fri, 03 Feb 2017)

Log Message

Fix bad assertion under HTMLTreeBuilder::processStartTagForInBody()
https://bugs.webkit.org/show_bug.cgi?id=167799
<rdar://problem/30237241>

Reviewed by Brent Fulgham.

Source/WebCore:

Fix bad assertion under HTMLTreeBuilder::processStartTagForInBody() that was
expecting the root element to be an <html> element when parsing a <frameset>.
While this assertion is true in theory and as per the specification, it does
not hold in WebKit when parsing a DocumentFragment. This is because WebKit
has an optimization causing us to have a DocumentFragment as root element
when parsing a fragment. See the following constructor:
"HTMLTreeBuilder(HTMLDocumentParser&, DocumentFragment&, Element&, ParserContentPolicy, const HTMLParserOptions&)"

which has the following code:
"""
// https://html.spec.whatwg.org/multipage/syntax.html#parsing-html-fragments
// For efficiency, we skip step 5 ("Let root be a new html element with no attributes") and instead use the DocumentFragment as a root node.
m_tree.openElements().pushRootNode(HTMLStackItem::create(fragment));
"""

Update the assertion to expect a DocumentFragment as root element when parsing
a fragment, and keep expecting an <html> element otherwise.

Test: fast/parser/fragment-with-frameset-crash.html

* html/parser/HTMLTreeBuilder.cpp:
(WebCore::HTMLTreeBuilder::processStartTagForInBody):

LayoutTests:

Add layout test coverage. This test passes in all major browsers but used to hit
the bad assertion in WebKit debug builds.

* fast/parser/fragment-with-frameset-crash-expected.txt: Added.
* fast/parser/fragment-with-frameset-crash.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (211644 => 211645)


--- trunk/LayoutTests/ChangeLog	2017-02-03 20:28:40 UTC (rev 211644)
+++ trunk/LayoutTests/ChangeLog	2017-02-03 20:49:39 UTC (rev 211645)
@@ -1,3 +1,17 @@
+2017-02-03  Chris Dumez  <cdu...@apple.com>
+
+        Fix bad assertion under HTMLTreeBuilder::processStartTagForInBody()
+        https://bugs.webkit.org/show_bug.cgi?id=167799
+        <rdar://problem/30237241>
+
+        Reviewed by Brent Fulgham.
+
+        Add layout test coverage. This test passes in all major browsers but used to hit
+        the bad assertion in WebKit debug builds.
+
+        * fast/parser/fragment-with-frameset-crash-expected.txt: Added.
+        * fast/parser/fragment-with-frameset-crash.html: Added.
+
 2017-02-03  Antoine Quint  <grao...@apple.com>
 
         [Modern Media Controls] Skip back button is visible with a live broadcast video

Added: trunk/LayoutTests/fast/parser/fragment-with-frameset-crash-expected.txt (0 => 211645)


--- trunk/LayoutTests/fast/parser/fragment-with-frameset-crash-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/parser/fragment-with-frameset-crash-expected.txt	2017-02-03 20:49:39 UTC (rev 211645)
@@ -0,0 +1,10 @@
+Test that we do not crash when parsing a fragment that contains a frameset.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS frames[0].document.documentElement.innerHTML is "<head></head><frameset cols=\"50%,50%\"><frame src="" src=""
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: trunk/LayoutTests/fast/parser/fragment-with-frameset-crash.html (0 => 211645)


--- trunk/LayoutTests/fast/parser/fragment-with-frameset-crash.html	                        (rev 0)
+++ trunk/LayoutTests/fast/parser/fragment-with-frameset-crash.html	2017-02-03 20:49:39 UTC (rev 211645)
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<html>
+<body>
+<script src=""
+<iframe srcdoc='<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd"><html></html>'></iframe>
+<script>
+description("Test that we do not crash when parsing a fragment that contains a frameset.");
+jsTestIsAsync = true;
+
+_onload_ = function() {
+    frames[0].document.documentElement.innerHTML = "<caption><frameset cols='50%,50%'><frame src=''/><frame src=''></frameset>";
+    shouldBeEqualToString("frames[0].document.documentElement.innerHTML", '<head></head><frameset cols="50%,50%"><frame src="" src=""
+    finishJSTest();
+}
+</script>
+<script src=""
+</body>
+</html>

Modified: trunk/Source/WebCore/ChangeLog (211644 => 211645)


--- trunk/Source/WebCore/ChangeLog	2017-02-03 20:28:40 UTC (rev 211644)
+++ trunk/Source/WebCore/ChangeLog	2017-02-03 20:49:39 UTC (rev 211645)
@@ -1,3 +1,34 @@
+2017-02-03  Chris Dumez  <cdu...@apple.com>
+
+        Fix bad assertion under HTMLTreeBuilder::processStartTagForInBody()
+        https://bugs.webkit.org/show_bug.cgi?id=167799
+        <rdar://problem/30237241>
+
+        Reviewed by Brent Fulgham.
+
+        Fix bad assertion under HTMLTreeBuilder::processStartTagForInBody() that was
+        expecting the root element to be an <html> element when parsing a <frameset>.
+        While this assertion is true in theory and as per the specification, it does
+        not hold in WebKit when parsing a DocumentFragment. This is because WebKit
+        has an optimization causing us to have a DocumentFragment as root element
+        when parsing a fragment. See the following constructor:
+        "HTMLTreeBuilder(HTMLDocumentParser&, DocumentFragment&, Element&, ParserContentPolicy, const HTMLParserOptions&)"
+
+        which has the following code:
+        """
+        // https://html.spec.whatwg.org/multipage/syntax.html#parsing-html-fragments
+        // For efficiency, we skip step 5 ("Let root be a new html element with no attributes") and instead use the DocumentFragment as a root node.
+        m_tree.openElements().pushRootNode(HTMLStackItem::create(fragment));
+        """
+
+        Update the assertion to expect a DocumentFragment as root element when parsing
+        a fragment, and keep expecting an <html> element otherwise.
+
+        Test: fast/parser/fragment-with-frameset-crash.html
+
+        * html/parser/HTMLTreeBuilder.cpp:
+        (WebCore::HTMLTreeBuilder::processStartTagForInBody):
+
 2017-02-03  Antoine Quint  <grao...@apple.com>
 
         [Modern Media Controls] Skip back button is visible with a live broadcast video

Modified: trunk/Source/WebCore/html/parser/HTMLTreeBuilder.cpp (211644 => 211645)


--- trunk/Source/WebCore/html/parser/HTMLTreeBuilder.cpp	2017-02-03 20:28:40 UTC (rev 211644)
+++ trunk/Source/WebCore/html/parser/HTMLTreeBuilder.cpp	2017-02-03 20:49:39 UTC (rev 211645)
@@ -599,7 +599,9 @@
         m_tree.openElements().bodyElement().remove();
         m_tree.openElements().popUntil(m_tree.openElements().bodyElement());
         m_tree.openElements().popHTMLBodyElement();
-        ASSERT(&m_tree.openElements().top() == &m_tree.openElements().htmlElement());
+        // Note: in the fragment case the root is a DocumentFragment instead of a proper html element which is a quirk / optimization in WebKit.
+        ASSERT(!isParsingFragment() || is<DocumentFragment>(m_tree.openElements().topNode()));
+        ASSERT(isParsingFragment() || &m_tree.openElements().top() == &m_tree.openElements().htmlElement());
         m_tree.insertHTMLElement(WTFMove(token));
         m_insertionMode = InsertionMode::InFrameset;
         return;
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to