Bug 1270381. r=wchen.
authorHenri Sivonen <hsivonen@hsivonen.fi>
Sun, 15 May 2016 17:03:06 +0300
changeset 336472 5f64adf2773bb89ba6867f60906f390266b6ab4f
parent 336471 0ee18d7a875a77016dfe5f9ac651787bab7a48d9
child 336473 5c9ee46f3b935838e390f52dc23ccca75b8cfbef
push id6249
push userjlund@mozilla.com
push dateMon, 01 Aug 2016 13:59:36 +0000
treeherdermozilla-beta@bad9d4f5bf7e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerswchen
bugs1270381
milestone49.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1270381. r=wchen.
parser/html/javasrc/TreeBuilder.java
parser/html/nsHtml5TreeBuilder.cpp
--- a/parser/html/javasrc/TreeBuilder.java
+++ b/parser/html/javasrc/TreeBuilder.java
@@ -34,36 +34,36 @@
  */
 
 package nu.validator.htmlparser.impl;
 
 import java.util.Arrays;
 import java.util.HashMap;
 import java.util.Map;
 
+import org.xml.sax.ErrorHandler;
+import org.xml.sax.Locator;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXParseException;
+
 import nu.validator.htmlparser.annotation.Auto;
 import nu.validator.htmlparser.annotation.Const;
 import nu.validator.htmlparser.annotation.IdType;
 import nu.validator.htmlparser.annotation.Inline;
 import nu.validator.htmlparser.annotation.Literal;
 import nu.validator.htmlparser.annotation.Local;
 import nu.validator.htmlparser.annotation.NoLength;
 import nu.validator.htmlparser.annotation.NsUri;
 import nu.validator.htmlparser.common.DoctypeExpectation;
 import nu.validator.htmlparser.common.DocumentMode;
 import nu.validator.htmlparser.common.DocumentModeHandler;
 import nu.validator.htmlparser.common.Interner;
 import nu.validator.htmlparser.common.TokenHandler;
 import nu.validator.htmlparser.common.XmlViolationPolicy;
 
-import org.xml.sax.ErrorHandler;
-import org.xml.sax.Locator;
-import org.xml.sax.SAXException;
-import org.xml.sax.SAXParseException;
-
 public abstract class TreeBuilder<T> implements TokenHandler,
         TreeBuilderState<T> {
 
     /**
      * Array version of U+FFFD.
      */
     private static final @NoLength char[] REPLACEMENT_CHARACTER = { '\uFFFD' };
 
@@ -1919,17 +1919,16 @@ public abstract class TreeBuilder<T> imp
                             case TABLE:
                                 errTableSeenWhileTableOpen();
                                 eltPos = findLastInTableScope(name);
                                 if (eltPos == TreeBuilder.NOT_FOUND_ON_STACK) {
                                     assert fragment || isTemplateContents();
                                     break starttagloop;
                                 }
                                 generateImpliedEndTags();
-                                // XXX is the next if dead code?
                                 if (errorHandler != null && !isCurrent("table")) {
                                     errNoCheckUnclosedElementsOnStack();
                                 }
                                 while (currentPtr >= eltPos) {
                                     pop();
                                 }
                                 resetTheInsertionMode();
                                 continue starttagloop;
@@ -2178,21 +2177,21 @@ public abstract class TreeBuilder<T> imp
                                         if (errorHandler != null
                                                 && eltPos != currentPtr) {
                                             errUnclosedElementsImplied(eltPos, name);
                                         }
                                         while (currentPtr >= eltPos) {
                                             pop();
                                         }
                                         break;
-                                    } else if (node.isSpecial()
+                                    } else if (eltPos == 0 || (node.isSpecial()
                                             && (node.ns != "http://www.w3.org/1999/xhtml"
-                                                || (node.name != "p"
-                                                    && node.name != "address"
-                                                    && node.name != "div"))) {
+                                                    || (node.name != "p"
+                                                            && node.name != "address"
+                                                            && node.name != "div")))) {
                                         break;
                                     }
                                     eltPos--;
                                 }
                                 implicitlyCloseP();
                                 appendToCurrentNodeAndPushElementMayFoster(
                                         elementName,
                                         attributes);
@@ -3879,17 +3878,17 @@ public abstract class TreeBuilder<T> imp
                                     if (errorHandler != null
                                             && !isCurrent(name)) {
                                         errUnclosedElements(eltPos, name);
                                     }
                                     while (currentPtr >= eltPos) {
                                         pop();
                                     }
                                     break endtagloop;
-                                } else if (node.isSpecial()) {
+                                } else if (eltPos == 0 || node.isSpecial()) {
                                     errStrayEndTag(name);
                                     break endtagloop;
                                 }
                                 eltPos--;
                             }
                     }
                 case IN_HEAD:
                     switch (group) {
@@ -4746,16 +4745,17 @@ public abstract class TreeBuilder<T> imp
             }
             // stackPos now points to the formatting element and it is in scope
             if (formattingEltStackPos != currentPtr) {
                 errEndTagViolatesNestingRules(name);
             }
             int furthestBlockPos = formattingEltStackPos + 1;
             while (furthestBlockPos <= currentPtr) {
                 StackNode<T> node = stack[furthestBlockPos]; // weak ref
+                assert furthestBlockPos > 0: "How is formattingEltStackPos + 1 not > 0?";
                 if (node.isSpecial()) {
                     break;
                 }
                 furthestBlockPos++;
             }
             if (furthestBlockPos > currentPtr) {
                 // no furthest block
                 while (currentPtr >= formattingEltStackPos) {
--- a/parser/html/nsHtml5TreeBuilder.cpp
+++ b/parser/html/nsHtml5TreeBuilder.cpp
@@ -1097,17 +1097,17 @@ nsHtml5TreeBuilder::startTag(nsHtml5Elem
                   generateImpliedEndTagsExceptFor(node->name);
                   if (!!MOZ_UNLIKELY(mViewSource) && eltPos != currentPtr) {
                     errUnclosedElementsImplied(eltPos, name);
                   }
                   while (currentPtr >= eltPos) {
                     pop();
                   }
                   break;
-                } else if (node->isSpecial() && (node->ns != kNameSpaceID_XHTML || (node->name != nsHtml5Atoms::p && node->name != nsHtml5Atoms::address && node->name != nsHtml5Atoms::div))) {
+                } else if (!eltPos || (node->isSpecial() && (node->ns != kNameSpaceID_XHTML || (node->name != nsHtml5Atoms::p && node->name != nsHtml5Atoms::address && node->name != nsHtml5Atoms::div)))) {
                   break;
                 }
                 eltPos--;
               }
               implicitlyCloseP();
               appendToCurrentNodeAndPushElementMayFoster(elementName, attributes);
               attributes = nullptr;
               NS_HTML5_BREAK(starttagloop);
@@ -2744,17 +2744,17 @@ nsHtml5TreeBuilder::endTag(nsHtml5Elemen
                 generateImpliedEndTags();
                 if (!!MOZ_UNLIKELY(mViewSource) && !isCurrent(name)) {
                   errUnclosedElements(eltPos, name);
                 }
                 while (currentPtr >= eltPos) {
                   pop();
                 }
                 NS_HTML5_BREAK(endtagloop);
-              } else if (node->isSpecial()) {
+              } else if (!eltPos || node->isSpecial()) {
                 errStrayEndTag(name);
                 NS_HTML5_BREAK(endtagloop);
               }
               eltPos--;
             }
           }
         }
       }
@@ -3588,16 +3588,17 @@ nsHtml5TreeBuilder::adoptionAgencyEndTag
       return true;
     }
     if (formattingEltStackPos != currentPtr) {
       errEndTagViolatesNestingRules(name);
     }
     int32_t furthestBlockPos = formattingEltStackPos + 1;
     while (furthestBlockPos <= currentPtr) {
       nsHtml5StackNode* node = stack[furthestBlockPos];
+      MOZ_ASSERT(furthestBlockPos > 0, "How is formattingEltStackPos + 1 not > 0?");
       if (node->isSpecial()) {
         break;
       }
       furthestBlockPos++;
     }
     if (furthestBlockPos > currentPtr) {
       while (currentPtr >= formattingEltStackPos) {
         pop();