Bug 982285 - Update active formatting element list indices in HTML parser adoption agency algorithm. r=hsivonen, a=lsblakk
authorWilliam Chen <wchen@mozilla.com>
Mon, 17 Mar 2014 17:34:47 -0700
changeset 192267 59bb9d5d5c604d51b1d15112e297edf4e8048977
parent 192266 2602ee663acf3cbc2b5d884b389993faf2a8baf4
child 192268 b75e5179a9ef04f9ee46cb561f8a5726c7f1acd6
push id474
push userasasaki@mozilla.com
push dateMon, 02 Jun 2014 21:01:02 +0000
treeherdermozilla-release@967f4cf1b31c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewershsivonen, lsblakk
bugs982285
milestone30.0a2
Bug 982285 - Update active formatting element list indices in HTML parser adoption agency algorithm. r=hsivonen, a=lsblakk
parser/html/javasrc/TreeBuilder.java
parser/html/nsHtml5TreeBuilder.cpp
parser/htmlparser/tests/crashtests/982285-1.html
parser/htmlparser/tests/crashtests/crashtests.list
--- a/parser/html/javasrc/TreeBuilder.java
+++ b/parser/html/javasrc/TreeBuilder.java
@@ -4571,17 +4571,17 @@ public abstract class TreeBuilder<T> imp
      */
     private boolean adoptionAgencyEndTag(@Local String name) throws SAXException {
         // This check intends to ensure that for properly nested tags, closing tags will match
         // against the stack instead of the listOfActiveFormattingElements.
         if (stack[currentPtr].ns == "http://www.w3.org/1999/xhtml" &&
                 stack[currentPtr].name == name &&
                 findInListOfActiveFormattingElements(stack[currentPtr]) == -1) {
             // If the current element matches the name but isn't on the list of active
-            // formatting elements, then it is possible that the list was mangled by the Noah's Arc
+            // formatting elements, then it is possible that the list was mangled by the Noah's Ark
             // clause. In this case, we want to match the end tag against the stack instead of
             // proceeding with the AAA algorithm that may match against the list of
             // active formatting elements (and possibly mangle the tree in unexpected ways).
             pop();
             return true;
         }
 
         // If you crash around here, perhaps some stack node variable claimed to
@@ -4656,16 +4656,26 @@ public abstract class TreeBuilder<T> imp
                 if (nodePos == formattingEltStackPos) {
                     break;
                 }
                 StackNode<T> node = stack[nodePos]; // weak ref
                 int nodeListPos = findInListOfActiveFormattingElements(node);
 
                 if (j > 3 && nodeListPos != -1) {
                     removeFromListOfActiveFormattingElements(nodeListPos);
+
+                    // Adjust the indices into the list to account
+                    // for the removal of nodeListPos.
+                    if (nodeListPos <= formattingEltListPos) {
+                        formattingEltListPos--;
+                    }
+                    if (nodeListPos <= bookmark) {
+                        bookmark--;
+                    }
+
                     // Update position to reflect removal from list.
                     nodeListPos = -1;
                 }
 
                 if (nodeListPos == -1) {
                     assert formattingEltStackPos < nodePos;
                     assert bookmark < nodePos;
                     assert furthestBlockPos > nodePos;
--- a/parser/html/nsHtml5TreeBuilder.cpp
+++ b/parser/html/nsHtml5TreeBuilder.cpp
@@ -3570,16 +3570,22 @@ nsHtml5TreeBuilder::adoptionAgencyEndTag
       nodePos--;
       if (nodePos == formattingEltStackPos) {
         break;
       }
       nsHtml5StackNode* node = stack[nodePos];
       int32_t nodeListPos = findInListOfActiveFormattingElements(node);
       if (j > 3 && nodeListPos != -1) {
         removeFromListOfActiveFormattingElements(nodeListPos);
+        if (nodeListPos <= formattingEltListPos) {
+          formattingEltListPos--;
+        }
+        if (nodeListPos <= bookmark) {
+          bookmark--;
+        }
         nodeListPos = -1;
       }
       if (nodeListPos == -1) {
         MOZ_ASSERT(formattingEltStackPos < nodePos);
         MOZ_ASSERT(bookmark < nodePos);
         MOZ_ASSERT(furthestBlockPos > nodePos);
         removeFromStack(nodePos);
         furthestBlockPos--;
new file mode 100644
--- /dev/null
+++ b/parser/htmlparser/tests/crashtests/982285-1.html
@@ -0,0 +1,19 @@
+<q>
+<u>
+<pre>
+<pre>
+<center>
+<em>
+<center>
+<center>
+</rp>
+<address>
+<address>
+<address>
+</rt>
+<q>
+<q>
+<rt>
+</u>
+<pre>
+</em>
--- a/parser/htmlparser/tests/crashtests/crashtests.list
+++ b/parser/htmlparser/tests/crashtests/crashtests.list
@@ -49,8 +49,9 @@ load 574884-1.html
 load 574884-2.html
 load 591330-1.html
 load 650501-1.xhtml
 load 696651-1.html
 load view-source:699347-1.xml
 load 721313-1.html
 load view-source:742414-1.html
 load 981279-1.html
+load 982285-1.html