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:
Henri Sivonen 2017-09-12 16:57:05 +03:00
parent 39d84173d2
commit 7fdbc91b91
19 changed files with 6347 additions and 204 deletions

View File

@ -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.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@ -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

View File

@ -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.
*

View File

@ -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

View File

@ -31,8 +31,6 @@ class nsAHtml5TreeBuilderState {
virtual nsIContentHandle* getHeadPointer() = 0;
virtual nsIContentHandle* getDeepTreeSurrogateParent() = 0;
virtual int32_t getMode() = 0;
virtual int32_t getOriginalMode() = 0;

View File

@ -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; }

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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);

View File

@ -138,6 +138,8 @@ bool EnsureBufferSpace(int32_t aLength);
void EnableViewSource(nsHtml5Highlighter* aHighlighter);
void errDeepTree();
void errStrayStartTag(nsAtom* aName);
void errStrayEndTag(nsAtom* aName);

View File

@ -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());

View File

@ -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; }

View File

@ -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;

View File

@ -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.");