LayoutTests:
authorantti <antti@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 4 Jul 2007 22:54:49 +0000 (22:54 +0000)
committerantti <antti@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 4 Jul 2007 22:54:49 +0000 (22:54 +0000)
        Reviewed by John.

        Test for Repro crash due to infinite recursion in HTMLParser::handleError @ youos.com
        <rdar://problem/5237811>

        * fast/table/incomplete-table-in-fragment-hang-expected.txt: Added.
        * fast/table/incomplete-table-in-fragment-hang.html: Added.

WebCore:

        Reviewed by John.

        Fix Repro crash due to infinite recursion in HTMLParser::handleError @ youos.com
        <rdar://problem/5237811>

        It is possible to add table parts (thead etc) without table ancestor to a document fragment. If a new table element
        was added to such a part, as in

        div.innerHTML = '<tbody><table>';

        the parser error handling code would try to pop the previous table as normal. However since
        the table does not actually exist nothing would happen and parser would go to infinite recursion.

        Solution here is to pop table parts one by one when handling the error inside a fragment instead of trying to pop
        the table straight away (as it might not exist).

        * html/HTMLParser.cpp:
        (WebCore::HTMLParser::handleError):

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

LayoutTests/ChangeLog
LayoutTests/fast/table/incomplete-table-in-fragment-hang-expected.txt [new file with mode: 0644]
LayoutTests/fast/table/incomplete-table-in-fragment-hang.html [new file with mode: 0644]
WebCore/ChangeLog
WebCore/html/HTMLParser.cpp

index 88659527d066a45a904c1c518993cb7cac176c5c..de015b927877689ac85caa97faa9617de9de0fa9 100644 (file)
@@ -1,3 +1,13 @@
+2007-07-05  Antti Koivisto  <antti@apple.com>
+
+        Reviewed by John.
+        
+        Test for Repro crash due to infinite recursion in HTMLParser::handleError @ youos.com
+        <rdar://problem/5237811>
+
+        * fast/table/incomplete-table-in-fragment-hang-expected.txt: Added.
+        * fast/table/incomplete-table-in-fragment-hang.html: Added.
+
 2007-07-04  Sam Weinig  <sam@webkit.org>
 
         Reviewed by Mitz.
diff --git a/LayoutTests/fast/table/incomplete-table-in-fragment-hang-expected.txt b/LayoutTests/fast/table/incomplete-table-in-fragment-hang-expected.txt
new file mode 100644 (file)
index 0000000..3817327
--- /dev/null
@@ -0,0 +1,16 @@
+Test error handling for incomplete tables inside a document fragment. These should not crash or hang. 
+
+<tbody></tbody><table></table>
+<thead></thead><table></table>
+<tfoot></tfoot><table></table>
+<tr></tr><table></table>
+<td><table></table></td>
+<th><table></table></th>
+<tbody><tr></tr></tbody><table></table>
+<tbody><tr><th><table></table></th></tr></tbody>
+<tbody><tr><td><table></table></td></tr></tbody>
+<tr><td><table></table></td></tr>
+<th><table></table></th>
+<td><table></table></td>
+<tbody><tr><td><table></table></td></tr></tbody>
+<option></option><table><tbody></tbody></table><table></table>
diff --git a/LayoutTests/fast/table/incomplete-table-in-fragment-hang.html b/LayoutTests/fast/table/incomplete-table-in-fragment-hang.html
new file mode 100644 (file)
index 0000000..1127274
--- /dev/null
@@ -0,0 +1,50 @@
+<body>
+<script>
+if (window.layoutTestController)
+    layoutTestController.dumpAsText();
+</script>
+<div id=inner></div>
+Test error handling for incomplete tables inside a document fragment. These should not crash or hang.
+<br><br>
+<div id=console></div>
+<script>
+
+var inner = document.getElementById('inner');
+var console = document.getElementById('console');
+
+function log(t)
+{
+    var line = document.createElement('div');
+    line.innerText = t;
+    console.appendChild(line);
+}
+
+inner.innerHTML = "<tbody><table>";
+log(inner.innerHTML);
+inner.innerHTML = "<thead><table>";
+log(inner.innerHTML);
+inner.innerHTML = "<tfoot><table>";
+log(inner.innerHTML);
+inner.innerHTML = "<tr><table>";
+log(inner.innerHTML);
+inner.innerHTML = "<td><table>";
+log(inner.innerHTML);
+inner.innerHTML = "<th><table>";
+log(inner.innerHTML);
+inner.innerHTML = "<tbody><tr><table>";
+log(inner.innerHTML);
+inner.innerHTML = "<tbody><th><table>";
+log(inner.innerHTML);
+inner.innerHTML = "<tbody><td><table>";
+log(inner.innerHTML);
+inner.innerHTML = "<tr><tbody><table>";
+log(inner.innerHTML);
+inner.innerHTML = "<th><tbody><table>";
+log(inner.innerHTML);
+inner.innerHTML = "<td><tbody><table>";
+log(inner.innerHTML);
+inner.innerHTML = "<tbody><option><table>";
+log(inner.innerHTML);
+inner.innerHTML = "<table><option><table>";
+log(inner.innerHTML);
+</script>
index 4e04229a519a76d1124bc066e6bac30212a0663a..00ee13f8fc40e898726f717016dbede5a718bcb6 100644 (file)
@@ -1,3 +1,24 @@
+2007-07-05  Antti Koivisto  <antti@apple.com>
+
+        Reviewed by John.
+        
+        Fix Repro crash due to infinite recursion in HTMLParser::handleError @ youos.com
+        <rdar://problem/5237811>
+        
+        It is possible to add table parts (thead etc) without table ancestor to a document fragment. If a new table element
+        was added to such a part, as in
+        
+        div.innerHTML = '<tbody><table>';
+        
+        the parser error handling code would try to pop the previous table as normal. However since
+        the table does not actually exist nothing would happen and parser would go to infinite recursion.
+        
+        Solution here is to pop table parts one by one when handling the error inside a fragment instead of trying to pop
+        the table straight away (as it might not exist).
+
+        * html/HTMLParser.cpp:
+        (WebCore::HTMLParser::handleError):
+
 2007-07-04  Qing Zhao  <qing@staikos.net>
 
         Reviewed by George Staikos.
index 58cc6df614c059d6bd36ac05e4d3bd6d82e38b56..ddf1da55c4cc939bea9bf61c9b69450a80ad7171 100644 (file)
@@ -510,6 +510,9 @@ bool HTMLParser::handleError(Node* n, bool flat, const AtomicString& localName,
         } else if (h->hasLocalName(tableTag) || h->hasLocalName(trTag) || isTableSection(h)) {
             if (n->hasTagName(tableTag)) {
                 reportError(MisplacedTableError, &currentTagName);
+                if (m_isParsingFragment && !h->hasLocalName(tableTag))
+                    // fragment may contain table parts without <table> ancestor, pop them one by one
+                    popBlock(h->localName());
                 popBlock(localName); // end the table
                 handled = true;      // ...and start a new one
             } else {