mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-28 07:13:20 +00:00
Bug 256180 parser part - Insert elements as siblings instead of children at the Blink-defined magic depth for compatibility. r=smaug.
MozReview-Commit-ID: K8fgv3rgklt
This commit is contained in:
parent
39d84173d2
commit
7fdbc91b91
@ -83,6 +83,7 @@ errNoSpaceBetweenPublicAndSystemIds=No space between the doctype public and syst
|
||||
errNoSpaceBetweenDoctypePublicKeywordAndQuote=No space between the doctype “PUBLIC” keyword and the quote.
|
||||
|
||||
# Tree builder errors
|
||||
errDeepTree=The document tree is too deep. The tree will be flattened to be 513 elements deep.
|
||||
errStrayStartTag2=Stray start tag “%1$S”.
|
||||
errStrayEndTag=Stray end tag “%1$S”.
|
||||
errUnclosedElements=End tag “%1$S” seen, but there were open elements.
|
||||
|
2004
layout/reftests/bugs/256180-5-ref.html
Normal file
2004
layout/reftests/bugs/256180-5-ref.html
Normal file
File diff suppressed because it is too large
Load Diff
2042
layout/reftests/bugs/256180-5.html
Normal file
2042
layout/reftests/bugs/256180-5.html
Normal file
File diff suppressed because it is too large
Load Diff
2004
layout/reftests/bugs/256180-6-ref.html
Normal file
2004
layout/reftests/bugs/256180-6-ref.html
Normal file
File diff suppressed because it is too large
Load Diff
48
layout/reftests/bugs/256180-6.html
Normal file
48
layout/reftests/bugs/256180-6.html
Normal file
File diff suppressed because one or more lines are too long
@ -49,6 +49,8 @@ skip-if(isDebugBuild||(winWidget&&(!is64Bit))) == 256180-2.html 256180-2-ref.htm
|
||||
skip-if(isDebugBuild||AddressSanitizer||(winWidget&&(!is64Bit))) == 256180-3.html 256180-3-ref.html
|
||||
# Debug builds have larger stack frames, so skipped.
|
||||
skip-if(isDebugBuild) == 256180-4.html 256180-4-ref.html
|
||||
skip-if(isDebugBuild) == 256180-6.html 256180-6-ref.html
|
||||
skip-if(isDebugBuild) == 256180-5.html 256180-5-ref.html
|
||||
== 25888-1l.html 25888-1l-ref.html
|
||||
!= 25888-1l.html 25888-1l-notref.html
|
||||
== 25888-1r.html 25888-1r-ref.html
|
||||
|
@ -37,8 +37,6 @@ public class StateSnapshot<T> implements TreeBuilderState<T> {
|
||||
|
||||
private final T headPointer;
|
||||
|
||||
private final T deepTreeSurrogateParent;
|
||||
|
||||
private final int mode;
|
||||
|
||||
private final int originalMode;
|
||||
@ -62,23 +60,21 @@ public class StateSnapshot<T> implements TreeBuilderState<T> {
|
||||
* @param needToDropLF
|
||||
* @param quirks
|
||||
*/
|
||||
StateSnapshot(StackNode<T>[] stack,
|
||||
StackNode<T>[] listOfActiveFormattingElements, int[] templateModeStack, T formPointer,
|
||||
T headPointer, T deepTreeSurrogateParent, int mode, int originalMode,
|
||||
boolean framesetOk, boolean needToDropLF, boolean quirks) {
|
||||
this.stack = stack;
|
||||
this.listOfActiveFormattingElements = listOfActiveFormattingElements;
|
||||
this.templateModeStack = templateModeStack;
|
||||
this.formPointer = formPointer;
|
||||
this.headPointer = headPointer;
|
||||
this.deepTreeSurrogateParent = deepTreeSurrogateParent;
|
||||
this.mode = mode;
|
||||
this.originalMode = originalMode;
|
||||
this.framesetOk = framesetOk;
|
||||
this.needToDropLF = needToDropLF;
|
||||
this.quirks = quirks;
|
||||
StateSnapshot(StackNode<T>[] stack, StackNode<T>[] listOfActiveFormattingElements,
|
||||
int[] templateModeStack, T formPointer, T headPointer, int mode, int originalMode,
|
||||
boolean framesetOk, boolean needToDropLF, boolean quirks) {
|
||||
this.stack = stack;
|
||||
this.listOfActiveFormattingElements = listOfActiveFormattingElements;
|
||||
this.templateModeStack = templateModeStack;
|
||||
this.formPointer = formPointer;
|
||||
this.headPointer = headPointer;
|
||||
this.mode = mode;
|
||||
this.originalMode = originalMode;
|
||||
this.framesetOk = framesetOk;
|
||||
this.needToDropLF = needToDropLF;
|
||||
this.quirks = quirks;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @see nu.validator.htmlparser.impl.TreeBuilderState#getStack()
|
||||
*/
|
||||
@ -121,16 +117,6 @@ public class StateSnapshot<T> implements TreeBuilderState<T> {
|
||||
return headPointer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the deepTreeSurrogateParent.
|
||||
*
|
||||
* @return the deepTreeSurrogateParent
|
||||
*/
|
||||
@Override
|
||||
public T getDeepTreeSurrogateParent() {
|
||||
return deepTreeSurrogateParent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the mode.
|
||||
*
|
||||
|
@ -444,11 +444,6 @@ public abstract class TreeBuilder<T> implements TokenHandler,
|
||||
|
||||
private T headPointer;
|
||||
|
||||
/**
|
||||
* Used to work around Gecko limitations. Not used in Java.
|
||||
*/
|
||||
private T deepTreeSurrogateParent;
|
||||
|
||||
protected @Auto char[] charBuffer;
|
||||
|
||||
protected int charBufferLen = 0;
|
||||
@ -615,7 +610,6 @@ public abstract class TreeBuilder<T> implements TokenHandler,
|
||||
listPtr = -1;
|
||||
formPointer = null;
|
||||
headPointer = null;
|
||||
deepTreeSurrogateParent = null;
|
||||
// [NOCPP[
|
||||
html4 = false;
|
||||
idLocations.clear();
|
||||
@ -1644,7 +1638,6 @@ public abstract class TreeBuilder<T> implements TokenHandler,
|
||||
public final void endTokenization() throws SAXException {
|
||||
formPointer = null;
|
||||
headPointer = null;
|
||||
deepTreeSurrogateParent = null;
|
||||
templateModeStack = null;
|
||||
if (stack != null) {
|
||||
while (currentPtr > -1) {
|
||||
@ -4741,7 +4734,12 @@ public abstract class TreeBuilder<T> implements TokenHandler,
|
||||
removeFromListOfActiveFormattingElements(formattingEltListPos);
|
||||
return true;
|
||||
}
|
||||
// commonAncestor is used for running the algorithm and
|
||||
// insertionCommonAncestor is used for the actual insertions to
|
||||
// keep them depth-limited.
|
||||
StackNode<T> commonAncestor = stack[formattingEltStackPos - 1]; // weak ref
|
||||
T insertionCommonAncestor =
|
||||
nodeFromStackWithBlinkCompat(formattingEltStackPos - 1); // weak ref
|
||||
StackNode<T> furthestBlock = stack[furthestBlockPos]; // weak ref
|
||||
// detachFromParent(furthestBlock.node); XXX AAA CHANGE
|
||||
int bookmark = formattingEltListPos;
|
||||
@ -4788,10 +4786,10 @@ public abstract class TreeBuilder<T> implements TokenHandler,
|
||||
// if (hasChildren(node.node)) { XXX AAA CHANGE
|
||||
assert node == listOfActiveFormattingElements[nodeListPos];
|
||||
assert node == stack[nodePos];
|
||||
T clone = createElement("http://www.w3.org/1999/xhtml",
|
||||
node.name, node.attributes.cloneAttributes(), commonAncestor.node
|
||||
// CPPONLY: , htmlCreator(node.getHtmlCreator())
|
||||
);
|
||||
T clone = createElement("http://www.w3.org/1999/xhtml", node.name,
|
||||
node.attributes.cloneAttributes(), insertionCommonAncestor
|
||||
// CPPONLY: , htmlCreator(node.getHtmlCreator())
|
||||
);
|
||||
StackNode<T> newNode = createStackNode(node.getFlags(), node.ns,
|
||||
node.name, clone, node.popName, node.attributes
|
||||
// CPPONLY: , node.getHtmlCreator()
|
||||
@ -4808,16 +4806,18 @@ public abstract class TreeBuilder<T> implements TokenHandler,
|
||||
node = newNode;
|
||||
// } XXX AAA CHANGE
|
||||
detachFromParent(lastNode.node);
|
||||
appendElement(lastNode.node, node.node);
|
||||
appendElement(lastNode.node, nodeFromStackWithBlinkCompat(nodePos));
|
||||
lastNode = node;
|
||||
}
|
||||
// If we insert into a foster parent, for simplicity, we insert
|
||||
// accoding to the spec without Blink's depth limit.
|
||||
if (commonAncestor.isFosterParenting()) {
|
||||
fatal();
|
||||
detachFromParent(lastNode.node);
|
||||
insertIntoFosterParent(lastNode.node);
|
||||
} else {
|
||||
detachFromParent(lastNode.node);
|
||||
appendElement(lastNode.node, commonAncestor.node);
|
||||
appendElement(lastNode.node, insertionCommonAncestor);
|
||||
}
|
||||
T clone = createElement("http://www.w3.org/1999/xhtml",
|
||||
formattingElt.name,
|
||||
@ -5003,20 +5003,21 @@ public abstract class TreeBuilder<T> implements TokenHandler,
|
||||
while (entryPos < listPtr) {
|
||||
entryPos++;
|
||||
StackNode<T> entry = listOfActiveFormattingElements[entryPos];
|
||||
StackNode<T> currentNode = stack[currentPtr];
|
||||
StackNode<T> current = stack[currentPtr];
|
||||
|
||||
T clone;
|
||||
if (currentNode.isFosterParenting()) {
|
||||
clone = createAndInsertFosterParentedElement("http://www.w3.org/1999/xhtml", entry.name,
|
||||
entry.attributes.cloneAttributes()
|
||||
// CPPONLY: , htmlCreator(entry.getHtmlCreator())
|
||||
);
|
||||
if (current.isFosterParenting()) {
|
||||
clone = createAndInsertFosterParentedElement(
|
||||
"http://www.w3.org/1999/xhtml", entry.name, entry.attributes.cloneAttributes()
|
||||
// CPPONLY: , htmlCreator(entry.getHtmlCreator())
|
||||
);
|
||||
} else {
|
||||
clone = createElement("http://www.w3.org/1999/xhtml", entry.name,
|
||||
entry.attributes.cloneAttributes(), currentNode.node
|
||||
// CPPONLY: , htmlCreator(entry.getHtmlCreator())
|
||||
);
|
||||
appendElement(clone, currentNode.node);
|
||||
T currentNode = nodeFromStackWithBlinkCompat(currentPtr);
|
||||
clone = createElement("http://www.w3.org/1999/xhtml", entry.name,
|
||||
entry.attributes.cloneAttributes(), currentNode
|
||||
// CPPONLY: , htmlCreator(entry.getHtmlCreator())
|
||||
);
|
||||
appendElement(clone, currentNode);
|
||||
}
|
||||
|
||||
StackNode<T> entryClone = createStackNode(entry.getFlags(),
|
||||
@ -5370,7 +5371,7 @@ public abstract class TreeBuilder<T> implements TokenHandler,
|
||||
// [NOCPP[
|
||||
checkAttributes(attributes, "http://www.w3.org/1999/xhtml");
|
||||
// ]NOCPP]
|
||||
T currentNode = stack[currentPtr].node;
|
||||
T currentNode = nodeFromStackWithBlinkCompat(currentPtr);
|
||||
T elt = createElement("http://www.w3.org/1999/xhtml", "head", attributes, currentNode
|
||||
/*
|
||||
* head uses NS_NewHTMLSharedElement creator
|
||||
@ -5412,10 +5413,11 @@ public abstract class TreeBuilder<T> implements TokenHandler,
|
||||
// CPPONLY: , htmlCreator(NS_NewHTMLFormElement)
|
||||
);
|
||||
} else {
|
||||
elt = createElement("http://www.w3.org/1999/xhtml", "form", attributes, current.node
|
||||
// CPPONLY: , htmlCreator(NS_NewHTMLFormElement)
|
||||
);
|
||||
appendElement(elt, current.node);
|
||||
T currentNode = nodeFromStackWithBlinkCompat(currentPtr);
|
||||
elt = createElement("http://www.w3.org/1999/xhtml", "form", attributes, currentNode
|
||||
// CPPONLY: , htmlCreator(NS_NewHTMLFormElement)
|
||||
);
|
||||
appendElement(elt, currentNode);
|
||||
}
|
||||
|
||||
if (!isTemplateContents()) {
|
||||
@ -5449,10 +5451,12 @@ public abstract class TreeBuilder<T> implements TokenHandler,
|
||||
// CPPONLY: , htmlCreator(elementName.getHtmlCreator())
|
||||
);
|
||||
} else {
|
||||
elt = createElement("http://www.w3.org/1999/xhtml", elementName.getName(), attributes, current.node
|
||||
// CPPONLY: , htmlCreator(elementName.getHtmlCreator())
|
||||
);
|
||||
appendElement(elt, current.node);
|
||||
T currentNode = nodeFromStackWithBlinkCompat(currentPtr);
|
||||
elt = createElement(
|
||||
"http://www.w3.org/1999/xhtml", elementName.getName(), attributes, currentNode
|
||||
// CPPONLY: , htmlCreator(elementName.getHtmlCreator())
|
||||
);
|
||||
appendElement(elt, currentNode);
|
||||
}
|
||||
StackNode<T> node = createStackNode(elementName, elt, clone
|
||||
// [NOCPP[
|
||||
@ -5471,7 +5475,7 @@ public abstract class TreeBuilder<T> implements TokenHandler,
|
||||
checkAttributes(attributes, "http://www.w3.org/1999/xhtml");
|
||||
// ]NOCPP]
|
||||
// This method can't be called for custom elements
|
||||
T currentNode = stack[currentPtr].node;
|
||||
T currentNode = nodeFromStackWithBlinkCompat(currentPtr);
|
||||
T elt = createElement("http://www.w3.org/1999/xhtml", elementName.getName(), attributes, currentNode
|
||||
// CPPONLY: , htmlCreator(elementName.getHtmlCreator())
|
||||
);
|
||||
@ -5505,10 +5509,11 @@ public abstract class TreeBuilder<T> implements TokenHandler,
|
||||
// CPPONLY: , htmlCreator(elementName.getHtmlCreator())
|
||||
);
|
||||
} else {
|
||||
elt = createElement("http://www.w3.org/1999/xhtml", popName, attributes, current.node
|
||||
// CPPONLY: , htmlCreator(elementName.getHtmlCreator())
|
||||
);
|
||||
appendElement(elt, current.node);
|
||||
T currentNode = nodeFromStackWithBlinkCompat(currentPtr);
|
||||
elt = createElement("http://www.w3.org/1999/xhtml", popName, attributes, currentNode
|
||||
// CPPONLY: , htmlCreator(elementName.getHtmlCreator())
|
||||
);
|
||||
appendElement(elt, currentNode);
|
||||
}
|
||||
StackNode<T> node = createStackNode(elementName, elt, popName
|
||||
// [NOCPP[
|
||||
@ -5543,10 +5548,11 @@ public abstract class TreeBuilder<T> implements TokenHandler,
|
||||
// CPPONLY: , htmlCreator(null)
|
||||
);
|
||||
} else {
|
||||
elt = createElement("http://www.w3.org/1998/Math/MathML", popName, attributes, current.node
|
||||
// CPPONLY: , htmlCreator(null)
|
||||
);
|
||||
appendElement(elt, current.node);
|
||||
T currentNode = nodeFromStackWithBlinkCompat(currentPtr);
|
||||
elt = createElement("http://www.w3.org/1998/Math/MathML", popName, attributes, currentNode
|
||||
// CPPONLY: , htmlCreator(null)
|
||||
);
|
||||
appendElement(elt, currentNode);
|
||||
}
|
||||
StackNode<T> node = createStackNode(elementName, elt, popName,
|
||||
markAsHtmlIntegrationPoint
|
||||
@ -5596,10 +5602,11 @@ public abstract class TreeBuilder<T> implements TokenHandler,
|
||||
// CPPONLY: , svgCreator(elementName.getSvgCreator())
|
||||
);
|
||||
} else {
|
||||
elt = createElement("http://www.w3.org/2000/svg", popName, attributes, current.node
|
||||
// CPPONLY: , svgCreator(elementName.getSvgCreator())
|
||||
);
|
||||
appendElement(elt, current.node);
|
||||
T currentNode = nodeFromStackWithBlinkCompat(currentPtr);
|
||||
elt = createElement("http://www.w3.org/2000/svg", popName, attributes, currentNode
|
||||
// CPPONLY: , svgCreator(elementName.getSvgCreator())
|
||||
);
|
||||
appendElement(elt, currentNode);
|
||||
}
|
||||
StackNode<T> node = createStackNode(elementName, popName, elt
|
||||
// [NOCPP[
|
||||
@ -5626,11 +5633,12 @@ public abstract class TreeBuilder<T> implements TokenHandler,
|
||||
// CPPONLY: , htmlCreator(elementName.getHtmlCreator())
|
||||
);
|
||||
} else {
|
||||
elt = createElement("http://www.w3.org/1999/xhtml", elementName.getName(),
|
||||
attributes, formOwner, current.node
|
||||
// CPPONLY: , htmlCreator(elementName.getHtmlCreator())
|
||||
);
|
||||
appendElement(elt, current.node);
|
||||
T currentNode = nodeFromStackWithBlinkCompat(currentPtr);
|
||||
elt = createElement("http://www.w3.org/1999/xhtml", elementName.getName(), attributes,
|
||||
formOwner, currentNode
|
||||
// CPPONLY: , htmlCreator(elementName.getHtmlCreator())
|
||||
);
|
||||
appendElement(elt, currentNode);
|
||||
}
|
||||
StackNode<T> node = createStackNode(elementName, elt
|
||||
// [NOCPP[
|
||||
@ -5657,11 +5665,12 @@ public abstract class TreeBuilder<T> implements TokenHandler,
|
||||
// CPPONLY: , htmlCreator(elementName.getHtmlCreator())
|
||||
);
|
||||
} else {
|
||||
elt = createElement("http://www.w3.org/1999/xhtml", name,
|
||||
attributes, formOwner, current.node
|
||||
// CPPONLY: , htmlCreator(elementName.getHtmlCreator())
|
||||
);
|
||||
appendElement(elt, current.node);
|
||||
T currentNode = nodeFromStackWithBlinkCompat(currentPtr);
|
||||
elt =
|
||||
createElement("http://www.w3.org/1999/xhtml", name, attributes, formOwner, currentNode
|
||||
// CPPONLY: , htmlCreator(elementName.getHtmlCreator())
|
||||
);
|
||||
appendElement(elt, currentNode);
|
||||
}
|
||||
elementPushed("http://www.w3.org/1999/xhtml", name, elt);
|
||||
elementPopped("http://www.w3.org/1999/xhtml", name, elt);
|
||||
@ -5685,10 +5694,11 @@ public abstract class TreeBuilder<T> implements TokenHandler,
|
||||
// CPPONLY: , htmlCreator(elementName.getHtmlCreator())
|
||||
);
|
||||
} else {
|
||||
elt = createElement("http://www.w3.org/1999/xhtml", popName, attributes, current.node
|
||||
// CPPONLY: , htmlCreator(elementName.getHtmlCreator())
|
||||
);
|
||||
appendElement(elt, current.node);
|
||||
T currentNode = nodeFromStackWithBlinkCompat(currentPtr);
|
||||
elt = createElement("http://www.w3.org/1999/xhtml", popName, attributes, currentNode
|
||||
// CPPONLY: , htmlCreator(elementName.getHtmlCreator())
|
||||
);
|
||||
appendElement(elt, currentNode);
|
||||
}
|
||||
elementPushed("http://www.w3.org/1999/xhtml", popName, elt);
|
||||
elementPopped("http://www.w3.org/1999/xhtml", popName, elt);
|
||||
@ -5712,10 +5722,11 @@ public abstract class TreeBuilder<T> implements TokenHandler,
|
||||
// CPPONLY: , svgCreator(elementName.getSvgCreator())
|
||||
);
|
||||
} else {
|
||||
elt = createElement("http://www.w3.org/2000/svg", popName, attributes, current.node
|
||||
// CPPONLY: , svgCreator(elementName.getSvgCreator())
|
||||
);
|
||||
appendElement(elt, current.node);
|
||||
T currentNode = nodeFromStackWithBlinkCompat(currentPtr);
|
||||
elt = createElement("http://www.w3.org/2000/svg", popName, attributes, currentNode
|
||||
// CPPONLY: , svgCreator(elementName.getSvgCreator())
|
||||
);
|
||||
appendElement(elt, currentNode);
|
||||
}
|
||||
elementPushed("http://www.w3.org/2000/svg", popName, elt);
|
||||
elementPopped("http://www.w3.org/2000/svg", popName, elt);
|
||||
@ -5739,10 +5750,11 @@ public abstract class TreeBuilder<T> implements TokenHandler,
|
||||
// CPPONLY: , htmlCreator(null)
|
||||
);
|
||||
} else {
|
||||
elt = createElement("http://www.w3.org/1998/Math/MathML", popName, attributes, current.node
|
||||
// CPPONLY: , htmlCreator(null)
|
||||
);
|
||||
appendElement(elt, current.node);
|
||||
T currentNode = nodeFromStackWithBlinkCompat(currentPtr);
|
||||
elt = createElement("http://www.w3.org/1998/Math/MathML", popName, attributes, currentNode
|
||||
// CPPONLY: , htmlCreator(null)
|
||||
);
|
||||
appendElement(elt, currentNode);
|
||||
}
|
||||
elementPushed("http://www.w3.org/1998/Math/MathML", popName, elt);
|
||||
elementPopped("http://www.w3.org/1998/Math/MathML", popName, elt);
|
||||
@ -5753,7 +5765,7 @@ public abstract class TreeBuilder<T> implements TokenHandler,
|
||||
checkAttributes(attributes, "http://www.w3.org/1999/xhtml");
|
||||
// ]NOCPP]
|
||||
// Can't be called for custom elements
|
||||
T currentNode = stack[currentPtr].node;
|
||||
T currentNode = nodeFromStackWithBlinkCompat(currentPtr);
|
||||
T elt = createElement("http://www.w3.org/1999/xhtml", "input", attributes,
|
||||
form == null || fragment || isTemplateContents() ? null : form, currentNode
|
||||
// CPPONLY: , htmlCreator(NS_NewHTMLInputElement)
|
||||
@ -5767,7 +5779,7 @@ public abstract class TreeBuilder<T> implements TokenHandler,
|
||||
// [NOCPP[
|
||||
checkAttributes(attributes, "http://www.w3.org/1999/xhtml");
|
||||
// ]NOCPP]
|
||||
T currentNode = stack[currentPtr].node;
|
||||
T currentNode = nodeFromStackWithBlinkCompat(currentPtr);
|
||||
T elt = createElement("http://www.w3.org/1999/xhtml", "form",
|
||||
attributes, currentNode
|
||||
// CPPONLY: , htmlCreator(NS_NewHTMLFormElement)
|
||||
@ -6179,8 +6191,7 @@ public abstract class TreeBuilder<T> implements TokenHandler,
|
||||
System.arraycopy(templateModeStack, 0, templateModeStackCopy, 0,
|
||||
templateModeStackCopy.length);
|
||||
return new StateSnapshot<T>(stackCopy, listCopy, templateModeStackCopy, formPointer,
|
||||
headPointer, deepTreeSurrogateParent, mode, originalMode, framesetOk,
|
||||
needToDropLF, quirks);
|
||||
headPointer, mode, originalMode, framesetOk, needToDropLF, quirks);
|
||||
}
|
||||
|
||||
public boolean snapshotMatches(TreeBuilderState<T> snapshot) {
|
||||
@ -6196,7 +6207,6 @@ public abstract class TreeBuilder<T> implements TokenHandler,
|
||||
|| templateModeStackLen != templateModePtr + 1
|
||||
|| formPointer != snapshot.getFormPointer()
|
||||
|| headPointer != snapshot.getHeadPointer()
|
||||
|| deepTreeSurrogateParent != snapshot.getDeepTreeSurrogateParent()
|
||||
|| mode != snapshot.getMode()
|
||||
|| originalMode != snapshot.getOriginalMode()
|
||||
|| framesetOk != snapshot.isFramesetOk()
|
||||
@ -6303,7 +6313,6 @@ public abstract class TreeBuilder<T> implements TokenHandler,
|
||||
System.arraycopy(templateModeStackCopy, 0, templateModeStack, 0, templateModeStackLen);
|
||||
formPointer = snapshot.getFormPointer();
|
||||
headPointer = snapshot.getHeadPointer();
|
||||
deepTreeSurrogateParent = snapshot.getDeepTreeSurrogateParent();
|
||||
mode = snapshot.getMode();
|
||||
originalMode = snapshot.getOriginalMode();
|
||||
framesetOk = snapshot.isFramesetOk();
|
||||
@ -6320,6 +6329,32 @@ public abstract class TreeBuilder<T> implements TokenHandler,
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns <code>stack[stackPos].node</code> if <code>stackPos</code> is
|
||||
* smaller than Blink's magic limit or the node at Blink's magic limit
|
||||
* otherwise.
|
||||
*
|
||||
* In order to get Blink-compatible handling of excessive deeply-nested
|
||||
* markup, this method must be used to obtain the node that is used as the
|
||||
* parent node of an insertion.
|
||||
*
|
||||
* Blink's magic number is 512, but our counting is off by one compared to
|
||||
* Blink's way of counting, so in order to get the same
|
||||
* externally-observable outcome, we use 511 as our magic number.
|
||||
*
|
||||
* @param stackPos the stack position to attempt to read
|
||||
* @return node at the position capped to Blink's magic number
|
||||
* @throws SAXException
|
||||
*/
|
||||
private T nodeFromStackWithBlinkCompat(int stackPos) throws SAXException {
|
||||
// Magic number if off by one relative to Blink's magic number, but the
|
||||
// outcome is the same, because the counting is different by one.
|
||||
if (stackPos > 511) {
|
||||
errDeepTree();
|
||||
return stack[511].node;
|
||||
}
|
||||
return stack[stackPos].node;
|
||||
}
|
||||
/**
|
||||
* @see nu.validator.htmlparser.impl.TreeBuilderState#getFormPointer()
|
||||
*/
|
||||
@ -6338,16 +6373,6 @@ public abstract class TreeBuilder<T> implements TokenHandler,
|
||||
return headPointer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the deepTreeSurrogateParent.
|
||||
*
|
||||
* @return the deepTreeSurrogateParent
|
||||
*/
|
||||
@Override
|
||||
public T getDeepTreeSurrogateParent() {
|
||||
return deepTreeSurrogateParent;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see nu.validator.htmlparser.impl.TreeBuilderState#getListOfActiveFormattingElements()
|
||||
*/
|
||||
@ -6446,6 +6471,16 @@ public abstract class TreeBuilder<T> implements TokenHandler,
|
||||
return templateModePtr + 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Complains about an over-deep tree. Theoretically this should just be
|
||||
* a warning, but in practice authors should take this as an error.
|
||||
*
|
||||
* @throws SAXException
|
||||
*/
|
||||
private void errDeepTree() throws SAXException {
|
||||
err("The document tree is more than 513 elements deep, which causes Firefox and Chrome flatten the tree.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Reports a stray start tag.
|
||||
* @param name the name of the stray tag
|
||||
|
@ -31,8 +31,6 @@ class nsAHtml5TreeBuilderState {
|
||||
|
||||
virtual nsIContentHandle* getHeadPointer() = 0;
|
||||
|
||||
virtual nsIContentHandle* getDeepTreeSurrogateParent() = 0;
|
||||
|
||||
virtual int32_t getMode() = 0;
|
||||
|
||||
virtual int32_t getOriginalMode() = 0;
|
||||
|
@ -58,15 +58,13 @@ nsHtml5StateSnapshot::nsHtml5StateSnapshot(
|
||||
jArray<nsHtml5StackNode*, int32_t> stack,
|
||||
jArray<nsHtml5StackNode*, int32_t> listOfActiveFormattingElements,
|
||||
jArray<int32_t, int32_t> templateModeStack, nsIContentHandle* formPointer,
|
||||
nsIContentHandle* headPointer, nsIContentHandle* deepTreeSurrogateParent,
|
||||
int32_t mode, int32_t originalMode, bool framesetOk, bool needToDropLF,
|
||||
bool quirks)
|
||||
nsIContentHandle* headPointer, int32_t mode, int32_t originalMode,
|
||||
bool framesetOk, bool needToDropLF, bool quirks)
|
||||
: stack(stack),
|
||||
listOfActiveFormattingElements(listOfActiveFormattingElements),
|
||||
templateModeStack(templateModeStack),
|
||||
formPointer(formPointer),
|
||||
headPointer(headPointer),
|
||||
deepTreeSurrogateParent(deepTreeSurrogateParent),
|
||||
mode(mode),
|
||||
originalMode(originalMode),
|
||||
framesetOk(framesetOk),
|
||||
@ -92,10 +90,6 @@ nsIContentHandle* nsHtml5StateSnapshot::getFormPointer() { return formPointer; }
|
||||
|
||||
nsIContentHandle* nsHtml5StateSnapshot::getHeadPointer() { return headPointer; }
|
||||
|
||||
nsIContentHandle* nsHtml5StateSnapshot::getDeepTreeSurrogateParent() {
|
||||
return deepTreeSurrogateParent;
|
||||
}
|
||||
|
||||
int32_t nsHtml5StateSnapshot::getMode() { return mode; }
|
||||
|
||||
int32_t nsHtml5StateSnapshot::getOriginalMode() { return originalMode; }
|
||||
|
@ -61,7 +61,6 @@ class nsHtml5StateSnapshot : public nsAHtml5TreeBuilderState {
|
||||
autoJArray<int32_t, int32_t> templateModeStack;
|
||||
nsIContentHandle* formPointer;
|
||||
nsIContentHandle* headPointer;
|
||||
nsIContentHandle* deepTreeSurrogateParent;
|
||||
int32_t mode;
|
||||
int32_t originalMode;
|
||||
bool framesetOk;
|
||||
@ -73,16 +72,14 @@ class nsHtml5StateSnapshot : public nsAHtml5TreeBuilderState {
|
||||
jArray<nsHtml5StackNode*, int32_t> stack,
|
||||
jArray<nsHtml5StackNode*, int32_t> listOfActiveFormattingElements,
|
||||
jArray<int32_t, int32_t> templateModeStack, nsIContentHandle* formPointer,
|
||||
nsIContentHandle* headPointer, nsIContentHandle* deepTreeSurrogateParent,
|
||||
int32_t mode, int32_t originalMode, bool framesetOk, bool needToDropLF,
|
||||
bool quirks);
|
||||
nsIContentHandle* headPointer, int32_t mode, int32_t originalMode,
|
||||
bool framesetOk, bool needToDropLF, bool quirks);
|
||||
jArray<nsHtml5StackNode*, int32_t> getStack() override;
|
||||
jArray<int32_t, int32_t> getTemplateModeStack() override;
|
||||
jArray<nsHtml5StackNode*, int32_t> getListOfActiveFormattingElements()
|
||||
override;
|
||||
nsIContentHandle* getFormPointer() override;
|
||||
nsIContentHandle* getHeadPointer() override;
|
||||
nsIContentHandle* getDeepTreeSurrogateParent() override;
|
||||
int32_t getMode() override;
|
||||
int32_t getOriginalMode() override;
|
||||
bool isFramesetOk() override;
|
||||
|
@ -143,7 +143,6 @@ void nsHtml5TreeBuilder::startTokenization(nsHtml5Tokenizer* self) {
|
||||
listPtr = -1;
|
||||
formPointer = nullptr;
|
||||
headPointer = nullptr;
|
||||
deepTreeSurrogateParent = nullptr;
|
||||
start(fragment);
|
||||
charBufferLen = 0;
|
||||
charBuffer = nullptr;
|
||||
@ -655,7 +654,6 @@ eofloop_end:;
|
||||
void nsHtml5TreeBuilder::endTokenization() {
|
||||
formPointer = nullptr;
|
||||
headPointer = nullptr;
|
||||
deepTreeSurrogateParent = nullptr;
|
||||
templateModeStack = nullptr;
|
||||
if (stack) {
|
||||
while (currentPtr > -1) {
|
||||
@ -3722,6 +3720,8 @@ bool nsHtml5TreeBuilder::adoptionAgencyEndTag(nsAtom* name) {
|
||||
return true;
|
||||
}
|
||||
nsHtml5StackNode* commonAncestor = stack[formattingEltStackPos - 1];
|
||||
nsIContentHandle* insertionCommonAncestor =
|
||||
nodeFromStackWithBlinkCompat(formattingEltStackPos - 1);
|
||||
nsHtml5StackNode* furthestBlock = stack[furthestBlockPos];
|
||||
int32_t bookmark = formattingEltListPos;
|
||||
int32_t nodePos = furthestBlockPos;
|
||||
@ -3760,7 +3760,7 @@ bool nsHtml5TreeBuilder::adoptionAgencyEndTag(nsAtom* name) {
|
||||
MOZ_ASSERT(node == stack[nodePos]);
|
||||
nsIContentHandle* clone = createElement(
|
||||
kNameSpaceID_XHTML, node->name, node->attributes->cloneAttributes(),
|
||||
commonAncestor->node, htmlCreator(node->getHtmlCreator()));
|
||||
insertionCommonAncestor, htmlCreator(node->getHtmlCreator()));
|
||||
nsHtml5StackNode* newNode = createStackNode(
|
||||
node->getFlags(), node->ns, node->name, clone, node->popName,
|
||||
node->attributes, node->getHtmlCreator());
|
||||
@ -3772,7 +3772,7 @@ bool nsHtml5TreeBuilder::adoptionAgencyEndTag(nsAtom* name) {
|
||||
node->release(this);
|
||||
node = newNode;
|
||||
detachFromParent(lastNode->node);
|
||||
appendElement(lastNode->node, node->node);
|
||||
appendElement(lastNode->node, nodeFromStackWithBlinkCompat(nodePos));
|
||||
lastNode = node;
|
||||
}
|
||||
if (commonAncestor->isFosterParenting()) {
|
||||
@ -3780,7 +3780,7 @@ bool nsHtml5TreeBuilder::adoptionAgencyEndTag(nsAtom* name) {
|
||||
insertIntoFosterParent(lastNode->node);
|
||||
} else {
|
||||
detachFromParent(lastNode->node);
|
||||
appendElement(lastNode->node, commonAncestor->node);
|
||||
appendElement(lastNode->node, insertionCommonAncestor);
|
||||
}
|
||||
nsIContentHandle* clone = createElement(
|
||||
kNameSpaceID_XHTML, formattingElt->name,
|
||||
@ -3937,17 +3937,18 @@ void nsHtml5TreeBuilder::reconstructTheActiveFormattingElements() {
|
||||
while (entryPos < listPtr) {
|
||||
entryPos++;
|
||||
nsHtml5StackNode* entry = listOfActiveFormattingElements[entryPos];
|
||||
nsHtml5StackNode* currentNode = stack[currentPtr];
|
||||
nsHtml5StackNode* current = stack[currentPtr];
|
||||
nsIContentHandle* clone;
|
||||
if (currentNode->isFosterParenting()) {
|
||||
if (current->isFosterParenting()) {
|
||||
clone = createAndInsertFosterParentedElement(
|
||||
kNameSpaceID_XHTML, entry->name, entry->attributes->cloneAttributes(),
|
||||
htmlCreator(entry->getHtmlCreator()));
|
||||
} else {
|
||||
clone = createElement(
|
||||
kNameSpaceID_XHTML, entry->name, entry->attributes->cloneAttributes(),
|
||||
currentNode->node, htmlCreator(entry->getHtmlCreator()));
|
||||
appendElement(clone, currentNode->node);
|
||||
nsIContentHandle* currentNode = nodeFromStackWithBlinkCompat(currentPtr);
|
||||
clone = createElement(kNameSpaceID_XHTML, entry->name,
|
||||
entry->attributes->cloneAttributes(), currentNode,
|
||||
htmlCreator(entry->getHtmlCreator()));
|
||||
appendElement(clone, currentNode);
|
||||
}
|
||||
nsHtml5StackNode* entryClone = createStackNode(
|
||||
entry->getFlags(), entry->ns, entry->name, clone, entry->popName,
|
||||
@ -4127,7 +4128,7 @@ void nsHtml5TreeBuilder::appendHtmlElementToDocumentAndPush() {
|
||||
|
||||
void nsHtml5TreeBuilder::appendToCurrentNodeAndPushHeadElement(
|
||||
nsHtml5HtmlAttributes* attributes) {
|
||||
nsIContentHandle* currentNode = stack[currentPtr]->node;
|
||||
nsIContentHandle* currentNode = nodeFromStackWithBlinkCompat(currentPtr);
|
||||
nsIContentHandle* elt =
|
||||
createElement(kNameSpaceID_XHTML, nsGkAtoms::head, attributes,
|
||||
currentNode, htmlCreator(NS_NewHTMLSharedElement));
|
||||
@ -4155,9 +4156,10 @@ void nsHtml5TreeBuilder::appendToCurrentNodeAndPushFormElementMayFoster(
|
||||
kNameSpaceID_XHTML, nsGkAtoms::form, attributes,
|
||||
htmlCreator(NS_NewHTMLFormElement));
|
||||
} else {
|
||||
nsIContentHandle* currentNode = nodeFromStackWithBlinkCompat(currentPtr);
|
||||
elt = createElement(kNameSpaceID_XHTML, nsGkAtoms::form, attributes,
|
||||
current->node, htmlCreator(NS_NewHTMLFormElement));
|
||||
appendElement(elt, current->node);
|
||||
currentNode, htmlCreator(NS_NewHTMLFormElement));
|
||||
appendElement(elt, currentNode);
|
||||
}
|
||||
if (!isTemplateContents()) {
|
||||
formPointer = elt;
|
||||
@ -4176,10 +4178,11 @@ void nsHtml5TreeBuilder::appendToCurrentNodeAndPushFormattingElementMayFoster(
|
||||
kNameSpaceID_XHTML, elementName->getName(), attributes,
|
||||
htmlCreator(elementName->getHtmlCreator()));
|
||||
} else {
|
||||
elt = createElement(kNameSpaceID_XHTML, elementName->getName(), attributes,
|
||||
current->node,
|
||||
htmlCreator(elementName->getHtmlCreator()));
|
||||
appendElement(elt, current->node);
|
||||
nsIContentHandle* currentNode = nodeFromStackWithBlinkCompat(currentPtr);
|
||||
elt =
|
||||
createElement(kNameSpaceID_XHTML, elementName->getName(), attributes,
|
||||
currentNode, htmlCreator(elementName->getHtmlCreator()));
|
||||
appendElement(elt, currentNode);
|
||||
}
|
||||
nsHtml5StackNode* node = createStackNode(elementName, elt, clone);
|
||||
push(node);
|
||||
@ -4189,7 +4192,7 @@ void nsHtml5TreeBuilder::appendToCurrentNodeAndPushFormattingElementMayFoster(
|
||||
|
||||
void nsHtml5TreeBuilder::appendToCurrentNodeAndPushElement(
|
||||
nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes) {
|
||||
nsIContentHandle* currentNode = stack[currentPtr]->node;
|
||||
nsIContentHandle* currentNode = nodeFromStackWithBlinkCompat(currentPtr);
|
||||
nsIContentHandle* elt =
|
||||
createElement(kNameSpaceID_XHTML, elementName->getName(), attributes,
|
||||
currentNode, htmlCreator(elementName->getHtmlCreator()));
|
||||
@ -4211,9 +4214,10 @@ void nsHtml5TreeBuilder::appendToCurrentNodeAndPushElementMayFoster(
|
||||
kNameSpaceID_XHTML, popName, attributes,
|
||||
htmlCreator(elementName->getHtmlCreator()));
|
||||
} else {
|
||||
elt = createElement(kNameSpaceID_XHTML, popName, attributes, current->node,
|
||||
nsIContentHandle* currentNode = nodeFromStackWithBlinkCompat(currentPtr);
|
||||
elt = createElement(kNameSpaceID_XHTML, popName, attributes, currentNode,
|
||||
htmlCreator(elementName->getHtmlCreator()));
|
||||
appendElement(elt, current->node);
|
||||
appendElement(elt, currentNode);
|
||||
}
|
||||
nsHtml5StackNode* node = createStackNode(elementName, elt, popName);
|
||||
push(node);
|
||||
@ -4233,9 +4237,10 @@ void nsHtml5TreeBuilder::appendToCurrentNodeAndPushElementMayFosterMathML(
|
||||
elt = createAndInsertFosterParentedElement(
|
||||
kNameSpaceID_MathML, popName, attributes, htmlCreator(nullptr));
|
||||
} else {
|
||||
elt = createElement(kNameSpaceID_MathML, popName, attributes, current->node,
|
||||
nsIContentHandle* currentNode = nodeFromStackWithBlinkCompat(currentPtr);
|
||||
elt = createElement(kNameSpaceID_MathML, popName, attributes, currentNode,
|
||||
htmlCreator(nullptr));
|
||||
appendElement(elt, current->node);
|
||||
appendElement(elt, currentNode);
|
||||
}
|
||||
nsHtml5StackNode* node =
|
||||
createStackNode(elementName, elt, popName, markAsHtmlIntegrationPoint);
|
||||
@ -4265,9 +4270,10 @@ void nsHtml5TreeBuilder::appendToCurrentNodeAndPushElementMayFosterSVG(
|
||||
kNameSpaceID_SVG, popName, attributes,
|
||||
svgCreator(elementName->getSvgCreator()));
|
||||
} else {
|
||||
elt = createElement(kNameSpaceID_SVG, popName, attributes, current->node,
|
||||
nsIContentHandle* currentNode = nodeFromStackWithBlinkCompat(currentPtr);
|
||||
elt = createElement(kNameSpaceID_SVG, popName, attributes, currentNode,
|
||||
svgCreator(elementName->getSvgCreator()));
|
||||
appendElement(elt, current->node);
|
||||
appendElement(elt, currentNode);
|
||||
}
|
||||
nsHtml5StackNode* node = createStackNode(elementName, popName, elt);
|
||||
push(node);
|
||||
@ -4285,10 +4291,11 @@ void nsHtml5TreeBuilder::appendToCurrentNodeAndPushElementMayFoster(
|
||||
kNameSpaceID_XHTML, elementName->getName(), attributes, formOwner,
|
||||
htmlCreator(elementName->getHtmlCreator()));
|
||||
} else {
|
||||
nsIContentHandle* currentNode = nodeFromStackWithBlinkCompat(currentPtr);
|
||||
elt = createElement(kNameSpaceID_XHTML, elementName->getName(), attributes,
|
||||
formOwner, current->node,
|
||||
formOwner, currentNode,
|
||||
htmlCreator(elementName->getHtmlCreator()));
|
||||
appendElement(elt, current->node);
|
||||
appendElement(elt, currentNode);
|
||||
}
|
||||
nsHtml5StackNode* node = createStackNode(elementName, elt);
|
||||
push(node);
|
||||
@ -4307,10 +4314,11 @@ void nsHtml5TreeBuilder::appendVoidElementToCurrentMayFoster(
|
||||
kNameSpaceID_XHTML, name, attributes, formOwner,
|
||||
htmlCreator(elementName->getHtmlCreator()));
|
||||
} else {
|
||||
elt = createElement(kNameSpaceID_XHTML, name, attributes, formOwner,
|
||||
current->node,
|
||||
htmlCreator(elementName->getHtmlCreator()));
|
||||
appendElement(elt, current->node);
|
||||
nsIContentHandle* currentNode = nodeFromStackWithBlinkCompat(currentPtr);
|
||||
elt =
|
||||
createElement(kNameSpaceID_XHTML, name, attributes, formOwner,
|
||||
currentNode, htmlCreator(elementName->getHtmlCreator()));
|
||||
appendElement(elt, currentNode);
|
||||
}
|
||||
elementPushed(kNameSpaceID_XHTML, name, elt);
|
||||
elementPopped(kNameSpaceID_XHTML, name, elt);
|
||||
@ -4326,9 +4334,10 @@ void nsHtml5TreeBuilder::appendVoidElementToCurrentMayFoster(
|
||||
kNameSpaceID_XHTML, popName, attributes,
|
||||
htmlCreator(elementName->getHtmlCreator()));
|
||||
} else {
|
||||
elt = createElement(kNameSpaceID_XHTML, popName, attributes, current->node,
|
||||
nsIContentHandle* currentNode = nodeFromStackWithBlinkCompat(currentPtr);
|
||||
elt = createElement(kNameSpaceID_XHTML, popName, attributes, currentNode,
|
||||
htmlCreator(elementName->getHtmlCreator()));
|
||||
appendElement(elt, current->node);
|
||||
appendElement(elt, currentNode);
|
||||
}
|
||||
elementPushed(kNameSpaceID_XHTML, popName, elt);
|
||||
elementPopped(kNameSpaceID_XHTML, popName, elt);
|
||||
@ -4344,9 +4353,10 @@ void nsHtml5TreeBuilder::appendVoidElementToCurrentMayFosterSVG(
|
||||
kNameSpaceID_SVG, popName, attributes,
|
||||
svgCreator(elementName->getSvgCreator()));
|
||||
} else {
|
||||
elt = createElement(kNameSpaceID_SVG, popName, attributes, current->node,
|
||||
nsIContentHandle* currentNode = nodeFromStackWithBlinkCompat(currentPtr);
|
||||
elt = createElement(kNameSpaceID_SVG, popName, attributes, currentNode,
|
||||
svgCreator(elementName->getSvgCreator()));
|
||||
appendElement(elt, current->node);
|
||||
appendElement(elt, currentNode);
|
||||
}
|
||||
elementPushed(kNameSpaceID_SVG, popName, elt);
|
||||
elementPopped(kNameSpaceID_SVG, popName, elt);
|
||||
@ -4361,9 +4371,10 @@ void nsHtml5TreeBuilder::appendVoidElementToCurrentMayFosterMathML(
|
||||
elt = createAndInsertFosterParentedElement(
|
||||
kNameSpaceID_MathML, popName, attributes, htmlCreator(nullptr));
|
||||
} else {
|
||||
elt = createElement(kNameSpaceID_MathML, popName, attributes, current->node,
|
||||
nsIContentHandle* currentNode = nodeFromStackWithBlinkCompat(currentPtr);
|
||||
elt = createElement(kNameSpaceID_MathML, popName, attributes, currentNode,
|
||||
htmlCreator(nullptr));
|
||||
appendElement(elt, current->node);
|
||||
appendElement(elt, currentNode);
|
||||
}
|
||||
elementPushed(kNameSpaceID_MathML, popName, elt);
|
||||
elementPopped(kNameSpaceID_MathML, popName, elt);
|
||||
@ -4371,7 +4382,7 @@ void nsHtml5TreeBuilder::appendVoidElementToCurrentMayFosterMathML(
|
||||
|
||||
void nsHtml5TreeBuilder::appendVoidInputToCurrent(
|
||||
nsHtml5HtmlAttributes* attributes, nsIContentHandle* form) {
|
||||
nsIContentHandle* currentNode = stack[currentPtr]->node;
|
||||
nsIContentHandle* currentNode = nodeFromStackWithBlinkCompat(currentPtr);
|
||||
nsIContentHandle* elt =
|
||||
createElement(kNameSpaceID_XHTML, nsGkAtoms::input, attributes,
|
||||
!form || fragment || isTemplateContents() ? nullptr : form,
|
||||
@ -4383,7 +4394,7 @@ void nsHtml5TreeBuilder::appendVoidInputToCurrent(
|
||||
|
||||
void nsHtml5TreeBuilder::appendVoidFormToCurrent(
|
||||
nsHtml5HtmlAttributes* attributes) {
|
||||
nsIContentHandle* currentNode = stack[currentPtr]->node;
|
||||
nsIContentHandle* currentNode = nodeFromStackWithBlinkCompat(currentPtr);
|
||||
nsIContentHandle* elt =
|
||||
createElement(kNameSpaceID_XHTML, nsGkAtoms::form, attributes,
|
||||
currentNode, htmlCreator(NS_NewHTMLFormElement));
|
||||
@ -4514,8 +4525,7 @@ nsAHtml5TreeBuilderState* nsHtml5TreeBuilder::newSnapshot() {
|
||||
nsHtml5ArrayCopy::arraycopy(templateModeStack, templateModeStackCopy,
|
||||
templateModeStackCopy.length);
|
||||
return new nsHtml5StateSnapshot(stackCopy, listCopy, templateModeStackCopy,
|
||||
formPointer, headPointer,
|
||||
deepTreeSurrogateParent, mode, originalMode,
|
||||
formPointer, headPointer, mode, originalMode,
|
||||
framesetOk, needToDropLF, quirks);
|
||||
}
|
||||
|
||||
@ -4532,7 +4542,6 @@ bool nsHtml5TreeBuilder::snapshotMatches(nsAHtml5TreeBuilderState* snapshot) {
|
||||
templateModeStackLen != templateModePtr + 1 ||
|
||||
formPointer != snapshot->getFormPointer() ||
|
||||
headPointer != snapshot->getHeadPointer() ||
|
||||
deepTreeSurrogateParent != snapshot->getDeepTreeSurrogateParent() ||
|
||||
mode != snapshot->getMode() ||
|
||||
originalMode != snapshot->getOriginalMode() ||
|
||||
framesetOk != snapshot->isFramesetOk() ||
|
||||
@ -4623,7 +4632,6 @@ void nsHtml5TreeBuilder::loadState(nsAHtml5TreeBuilderState* snapshot) {
|
||||
templateModeStackLen);
|
||||
formPointer = snapshot->getFormPointer();
|
||||
headPointer = snapshot->getHeadPointer();
|
||||
deepTreeSurrogateParent = snapshot->getDeepTreeSurrogateParent();
|
||||
mode = snapshot->getMode();
|
||||
originalMode = snapshot->getOriginalMode();
|
||||
framesetOk = snapshot->isFramesetOk();
|
||||
@ -4641,14 +4649,19 @@ int32_t nsHtml5TreeBuilder::findInArray(
|
||||
return -1;
|
||||
}
|
||||
|
||||
nsIContentHandle* nsHtml5TreeBuilder::nodeFromStackWithBlinkCompat(
|
||||
int32_t stackPos) {
|
||||
if (stackPos > 511) {
|
||||
errDeepTree();
|
||||
return stack[511]->node;
|
||||
}
|
||||
return stack[stackPos]->node;
|
||||
}
|
||||
|
||||
nsIContentHandle* nsHtml5TreeBuilder::getFormPointer() { return formPointer; }
|
||||
|
||||
nsIContentHandle* nsHtml5TreeBuilder::getHeadPointer() { return headPointer; }
|
||||
|
||||
nsIContentHandle* nsHtml5TreeBuilder::getDeepTreeSurrogateParent() {
|
||||
return deepTreeSurrogateParent;
|
||||
}
|
||||
|
||||
jArray<nsHtml5StackNode*, int32_t>
|
||||
nsHtml5TreeBuilder::getListOfActiveFormattingElements() {
|
||||
return listOfActiveFormattingElements;
|
||||
|
@ -309,7 +309,6 @@ class nsHtml5TreeBuilder : public nsAHtml5TreeBuilderState {
|
||||
int32_t listPtr;
|
||||
nsIContentHandle* formPointer;
|
||||
nsIContentHandle* headPointer;
|
||||
nsIContentHandle* deepTreeSurrogateParent;
|
||||
|
||||
protected:
|
||||
autoJArray<char16_t, int32_t> charBuffer;
|
||||
@ -569,11 +568,11 @@ class nsHtml5TreeBuilder : public nsAHtml5TreeBuilderState {
|
||||
private:
|
||||
int32_t findInArray(nsHtml5StackNode* node,
|
||||
jArray<nsHtml5StackNode*, int32_t> arr);
|
||||
nsIContentHandle* nodeFromStackWithBlinkCompat(int32_t stackPos);
|
||||
|
||||
public:
|
||||
nsIContentHandle* getFormPointer() override;
|
||||
nsIContentHandle* getHeadPointer() override;
|
||||
nsIContentHandle* getDeepTreeSurrogateParent() override;
|
||||
jArray<nsHtml5StackNode*, int32_t> getListOfActiveFormattingElements()
|
||||
override;
|
||||
jArray<nsHtml5StackNode*, int32_t> getStack() override;
|
||||
|
@ -7,7 +7,6 @@
|
||||
#include "nsError.h"
|
||||
#include "nsIPresShell.h"
|
||||
#include "nsNodeUtils.h"
|
||||
#include "nsIFrame.h"
|
||||
#include "mozilla/CheckedInt.h"
|
||||
#include "mozilla/Likely.h"
|
||||
#include "mozilla/UniquePtr.h"
|
||||
@ -30,7 +29,6 @@ nsHtml5TreeBuilder::nsHtml5TreeBuilder(nsHtml5OplessBuilder* aBuilder)
|
||||
listPtr(0),
|
||||
formPointer(nullptr),
|
||||
headPointer(nullptr),
|
||||
deepTreeSurrogateParent(nullptr),
|
||||
charBufferLen(0),
|
||||
quirks(false),
|
||||
isSrcdocDocument(false),
|
||||
@ -70,7 +68,6 @@ nsHtml5TreeBuilder::nsHtml5TreeBuilder(nsAHtml5TreeOpSink* aOpSink,
|
||||
listPtr(0),
|
||||
formPointer(nullptr),
|
||||
headPointer(nullptr),
|
||||
deepTreeSurrogateParent(nullptr),
|
||||
charBufferLen(0),
|
||||
quirks(false),
|
||||
isSrcdocDocument(false),
|
||||
@ -528,9 +525,6 @@ void nsHtml5TreeBuilder::appendElement(nsIContentHandle* aChild,
|
||||
nsIContentHandle* aParent) {
|
||||
MOZ_ASSERT(aChild, "Null child");
|
||||
MOZ_ASSERT(aParent, "Null parent");
|
||||
if (deepTreeSurrogateParent) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (mBuilder) {
|
||||
nsresult rv = nsHtml5TreeOperation::Append(
|
||||
@ -648,10 +642,7 @@ void nsHtml5TreeBuilder::appendCharacters(nsIContentHandle* aParent,
|
||||
if (mBuilder) {
|
||||
nsresult rv = nsHtml5TreeOperation::AppendText(
|
||||
aBuffer, // XXX aStart always ignored???
|
||||
aLength,
|
||||
static_cast<nsIContent*>(
|
||||
deepTreeSurrogateParent ? deepTreeSurrogateParent : aParent),
|
||||
mBuilder);
|
||||
aLength, static_cast<nsIContent*>(aParent), mBuilder);
|
||||
if (NS_FAILED(rv)) {
|
||||
MarkAsBrokenAndRequestSuspensionWithBuilder(rv);
|
||||
}
|
||||
@ -674,8 +665,7 @@ void nsHtml5TreeBuilder::appendCharacters(nsIContentHandle* aParent,
|
||||
MarkAsBrokenAndRequestSuspensionWithoutBuilder(NS_ERROR_OUT_OF_MEMORY);
|
||||
return;
|
||||
}
|
||||
treeOp->Init(eTreeOpAppendText, bufferCopy.release(), aLength,
|
||||
deepTreeSurrogateParent ? deepTreeSurrogateParent : aParent);
|
||||
treeOp->Init(eTreeOpAppendText, bufferCopy.release(), aLength, aParent);
|
||||
}
|
||||
|
||||
void nsHtml5TreeBuilder::appendComment(nsIContentHandle* aParent,
|
||||
@ -685,10 +675,6 @@ void nsHtml5TreeBuilder::appendComment(nsIContentHandle* aParent,
|
||||
MOZ_ASSERT(aParent, "Null parent");
|
||||
MOZ_ASSERT(!aStart, "aStart must always be zero.");
|
||||
|
||||
if (deepTreeSurrogateParent) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (mBuilder) {
|
||||
nsresult rv = nsHtml5TreeOperation::AppendComment(
|
||||
static_cast<nsIContent*>(aParent),
|
||||
@ -802,7 +788,6 @@ void nsHtml5TreeBuilder::markMalformedIfScript(nsIContentHandle* aElement) {
|
||||
|
||||
void nsHtml5TreeBuilder::start(bool fragment) {
|
||||
mCurrentHtmlScriptIsAsyncOrDefer = false;
|
||||
deepTreeSurrogateParent = nullptr;
|
||||
#ifdef DEBUG
|
||||
mActive = true;
|
||||
#endif
|
||||
@ -869,13 +854,6 @@ void nsHtml5TreeBuilder::elementPushed(int32_t aNamespace, nsAtom* aName,
|
||||
* table elements shouldn't be used as surrogate parents for user experience
|
||||
* reasons.
|
||||
*/
|
||||
if (!deepTreeSurrogateParent && currentPtr >= MAX_REFLOW_DEPTH &&
|
||||
!(aName == nsGkAtoms::script || aName == nsGkAtoms::table ||
|
||||
aName == nsGkAtoms::thead || aName == nsGkAtoms::tfoot ||
|
||||
aName == nsGkAtoms::tbody || aName == nsGkAtoms::tr ||
|
||||
aName == nsGkAtoms::colgroup || aName == nsGkAtoms::style)) {
|
||||
deepTreeSurrogateParent = aElement;
|
||||
}
|
||||
if (aNamespace != kNameSpaceID_XHTML) {
|
||||
return;
|
||||
}
|
||||
@ -928,9 +906,6 @@ void nsHtml5TreeBuilder::elementPopped(int32_t aNamespace, nsAtom* aName,
|
||||
"Element isn't HTML, SVG or MathML!");
|
||||
NS_ASSERTION(aName, "Element doesn't have local name!");
|
||||
NS_ASSERTION(aElement, "No element!");
|
||||
if (deepTreeSurrogateParent && currentPtr <= MAX_REFLOW_DEPTH) {
|
||||
deepTreeSurrogateParent = nullptr;
|
||||
}
|
||||
if (aNamespace == kNameSpaceID_MathML) {
|
||||
return;
|
||||
}
|
||||
@ -1385,6 +1360,16 @@ void nsHtml5TreeBuilder::EnableViewSource(nsHtml5Highlighter* aHighlighter) {
|
||||
mViewSource = aHighlighter;
|
||||
}
|
||||
|
||||
void nsHtml5TreeBuilder::errDeepTree() {
|
||||
if (MOZ_UNLIKELY(mViewSource)) {
|
||||
mViewSource->AddErrorToCurrentRun("errDeepTree");
|
||||
} else if (!mBuilder) {
|
||||
nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
|
||||
MOZ_ASSERT(treeOp, "Tree op allocation failed.");
|
||||
treeOp->InitDeepTree(tokenizer->getLineNumber());
|
||||
}
|
||||
}
|
||||
|
||||
void nsHtml5TreeBuilder::errStrayStartTag(nsAtom* aName) {
|
||||
if (MOZ_UNLIKELY(mViewSource)) {
|
||||
mViewSource->AddErrorToCurrentRun("errStrayStartTag2", aName);
|
||||
|
@ -138,6 +138,8 @@ bool EnsureBufferSpace(int32_t aLength);
|
||||
|
||||
void EnableViewSource(nsHtml5Highlighter* aHighlighter);
|
||||
|
||||
void errDeepTree();
|
||||
|
||||
void errStrayStartTag(nsAtom* aName);
|
||||
|
||||
void errStrayEndTag(nsAtom* aName);
|
||||
|
@ -103,7 +103,8 @@ nsHtml5TreeOpExecutor::nsHtml5TreeOpExecutor()
|
||||
mStarted(false),
|
||||
mRunFlushLoopOnStack(false),
|
||||
mCallContinueInterruptedParsingIfEnabled(false),
|
||||
mAlreadyComplainedAboutCharset(false) {}
|
||||
mAlreadyComplainedAboutCharset(false),
|
||||
mAlreadyComplainedAboutDeepTree(false) {}
|
||||
|
||||
nsHtml5TreeOpExecutor::~nsHtml5TreeOpExecutor() {
|
||||
if (gBackgroundFlushList && isInList()) {
|
||||
@ -802,6 +803,17 @@ void nsHtml5TreeOpExecutor::ComplainAboutBogusProtocolCharset(Document* aDoc) {
|
||||
nsContentUtils::eHTMLPARSER_PROPERTIES, "EncProtocolUnsupported");
|
||||
}
|
||||
|
||||
void nsHtml5TreeOpExecutor::MaybeComplainAboutDeepTree(uint32_t aLineNumber) {
|
||||
if (mAlreadyComplainedAboutDeepTree) {
|
||||
return;
|
||||
}
|
||||
mAlreadyComplainedAboutDeepTree = true;
|
||||
nsContentUtils::ReportToConsole(
|
||||
nsIScriptError::errorFlag, NS_LITERAL_CSTRING("HTML parser"), mDocument,
|
||||
nsContentUtils::eHTMLPARSER_PROPERTIES, "errDeepTree", nullptr, 0,
|
||||
nullptr, EmptyString(), aLineNumber);
|
||||
}
|
||||
|
||||
nsHtml5Parser* nsHtml5TreeOpExecutor::GetParser() {
|
||||
MOZ_ASSERT(!mRunsToCompletion);
|
||||
return static_cast<nsHtml5Parser*>(mParser.get());
|
||||
|
@ -96,6 +96,12 @@ class nsHtml5TreeOpExecutor final
|
||||
*/
|
||||
bool mAlreadyComplainedAboutCharset;
|
||||
|
||||
/**
|
||||
* Whether this executor has already complained about the tree being too
|
||||
* deep.
|
||||
*/
|
||||
bool mAlreadyComplainedAboutDeepTree;
|
||||
|
||||
public:
|
||||
nsHtml5TreeOpExecutor();
|
||||
|
||||
@ -191,6 +197,8 @@ class nsHtml5TreeOpExecutor final
|
||||
|
||||
void ComplainAboutBogusProtocolCharset(mozilla::dom::Document*);
|
||||
|
||||
void MaybeComplainAboutDeepTree(uint32_t aLineNumber);
|
||||
|
||||
bool HasStarted() { return mStarted; }
|
||||
|
||||
bool IsFlushing() { return mFlushState >= eInFlush; }
|
||||
|
@ -975,6 +975,11 @@ nsresult nsHtml5TreeOperation::Perform(nsHtml5TreeOpExecutor* aBuilder,
|
||||
doc->EnableEncodingMenu();
|
||||
return NS_OK;
|
||||
}
|
||||
case eTreeOpMaybeComplainAboutDeepTree: {
|
||||
int32_t lineNumber = mOne.integer;
|
||||
aBuilder->MaybeComplainAboutDeepTree((uint32_t)lineNumber);
|
||||
return NS_OK;
|
||||
}
|
||||
case eTreeOpAddClass: {
|
||||
Element* element = (*(mOne.node))->AsElement();
|
||||
char16_t* str = mTwo.unicharPtr;
|
||||
|
@ -62,6 +62,7 @@ enum eHtml5TreeOperation {
|
||||
eTreeOpSetScriptLineNumberAndFreeze,
|
||||
eTreeOpSvgLoad,
|
||||
eTreeOpMaybeComplainAboutCharset,
|
||||
eTreeOpMaybeComplainAboutDeepTree,
|
||||
eTreeOpAddClass,
|
||||
eTreeOpAddViewSourceHref,
|
||||
eTreeOpAddViewSourceBase,
|
||||
@ -406,6 +407,13 @@ class nsHtml5TreeOperation final {
|
||||
mThree.integer = aLineNumber;
|
||||
}
|
||||
|
||||
inline void InitDeepTree(int32_t aLineNumber) {
|
||||
MOZ_ASSERT(mOpCode == eTreeOpUninitialized,
|
||||
"Op code must be uninitialized when initializing.");
|
||||
mOpCode = eTreeOpMaybeComplainAboutDeepTree;
|
||||
mOne.integer = aLineNumber;
|
||||
}
|
||||
|
||||
inline void Init(eHtml5TreeOperation aOpCode, const nsAString& aString) {
|
||||
MOZ_ASSERT(mOpCode == eTreeOpUninitialized,
|
||||
"Op code must be uninitialized when initializing.");
|
||||
|
Loading…
Reference in New Issue
Block a user