--- a/parser/html/nsHtml5TreeBuilderCppSupplement.h
+++ b/parser/html/nsHtml5TreeBuilderCppSupplement.h
@@ -118,18 +118,21 @@ nsHtml5TreeBuilder::createElement(int32_
if (MOZ_UNLIKELY(aAttributes != tokenizer->GetAttributes() &&
aAttributes != nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES)) {
delete aAttributes;
}
return elem;
}
nsIContentHandle* content = AllocateContentHandle();
- nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
- NS_ASSERTION(treeOp, "Tree op allocation failed.");
+ nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement(mozilla::fallible);
+ if (MOZ_UNLIKELY(!treeOp)) {
+ MarkAsBrokenAndRequestSuspensionWithoutBuilder(NS_ERROR_OUT_OF_MEMORY);
+ return nullptr;
+ }
treeOp->Init(aNamespace,
aName,
aAttributes,
content,
aIntendedParent,
!!mSpeculativeLoadStage,
aCreator);
// mSpeculativeLoadStage is non-null only in the off-the-main-thread
@@ -165,18 +168,23 @@ nsHtml5TreeBuilder::createElement(int32_
nsHtml5String type =
aAttributes->getValue(nsHtml5AttributeName::ATTR_TYPE);
nsHtml5String media =
aAttributes->getValue(nsHtml5AttributeName::ATTR_MEDIA);
mSpeculativeLoadQueue.AppendElement()->InitPictureSource(
srcset, sizes, type, media);
}
} else if (nsGkAtoms::script == aName) {
- nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
- NS_ASSERTION(treeOp, "Tree op allocation failed.");
+ nsHtml5TreeOperation* treeOp =
+ mOpQueue.AppendElement(mozilla::fallible);
+ if (MOZ_UNLIKELY(!treeOp)) {
+ MarkAsBrokenAndRequestSuspensionWithoutBuilder(
+ NS_ERROR_OUT_OF_MEMORY);
+ return nullptr;
+ }
treeOp->Init(eTreeOpSetScriptLineNumberAndFreeze, content, tokenizer->getLineNumber());
nsHtml5String url =
aAttributes->getValue(nsHtml5AttributeName::ATTR_SRC);
if (url) {
nsHtml5String charset =
aAttributes->getValue(nsHtml5AttributeName::ATTR_CHARSET);
nsHtml5String type =
@@ -235,18 +243,23 @@ nsHtml5TreeBuilder::createElement(int32_
} else if (nsGkAtoms::video == aName) {
nsHtml5String url =
aAttributes->getValue(nsHtml5AttributeName::ATTR_POSTER);
if (url) {
mSpeculativeLoadQueue.AppendElement()->InitImage(
url, nullptr, nullptr, nullptr, nullptr);
}
} else if (nsGkAtoms::style == aName) {
- nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
- NS_ASSERTION(treeOp, "Tree op allocation failed.");
+ nsHtml5TreeOperation* treeOp =
+ mOpQueue.AppendElement(mozilla::fallible);
+ if (MOZ_UNLIKELY(!treeOp)) {
+ MarkAsBrokenAndRequestSuspensionWithoutBuilder(
+ NS_ERROR_OUT_OF_MEMORY);
+ return nullptr;
+ }
treeOp->Init(eTreeOpSetStyleLineNumber, content, tokenizer->getLineNumber());
} else if (nsGkAtoms::html == aName) {
nsHtml5String url =
aAttributes->getValue(nsHtml5AttributeName::ATTR_MANIFEST);
mSpeculativeLoadQueue.AppendElement()->InitManifest(url);
} else if (nsGkAtoms::base == aName) {
nsHtml5String url =
aAttributes->getValue(nsHtml5AttributeName::ATTR_HREF);
@@ -279,18 +292,23 @@ nsHtml5TreeBuilder::createElement(int32_
if (nsGkAtoms::image == aName) {
nsHtml5String url =
aAttributes->getValue(nsHtml5AttributeName::ATTR_XLINK_HREF);
if (url) {
mSpeculativeLoadQueue.AppendElement()->InitImage(
url, nullptr, nullptr, nullptr, nullptr);
}
} else if (nsGkAtoms::script == aName) {
- nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
- NS_ASSERTION(treeOp, "Tree op allocation failed.");
+ nsHtml5TreeOperation* treeOp =
+ mOpQueue.AppendElement(mozilla::fallible);
+ if (MOZ_UNLIKELY(!treeOp)) {
+ MarkAsBrokenAndRequestSuspensionWithoutBuilder(
+ NS_ERROR_OUT_OF_MEMORY);
+ return nullptr;
+ }
treeOp->Init(eTreeOpSetScriptLineNumberAndFreeze, content, tokenizer->getLineNumber());
nsHtml5String url =
aAttributes->getValue(nsHtml5AttributeName::ATTR_XLINK_HREF);
if (url) {
nsHtml5String type =
aAttributes->getValue(nsHtml5AttributeName::ATTR_TYPE);
nsHtml5String crossOrigin =
@@ -303,18 +321,23 @@ nsHtml5TreeBuilder::createElement(int32_
type,
crossOrigin,
integrity,
mode == nsHtml5TreeBuilder::IN_HEAD,
false,
false);
}
} else if (nsGkAtoms::style == aName) {
- nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
- NS_ASSERTION(treeOp, "Tree op allocation failed.");
+ nsHtml5TreeOperation* treeOp =
+ mOpQueue.AppendElement(mozilla::fallible);
+ if (MOZ_UNLIKELY(!treeOp)) {
+ MarkAsBrokenAndRequestSuspensionWithoutBuilder(
+ NS_ERROR_OUT_OF_MEMORY);
+ return nullptr;
+ }
treeOp->Init(eTreeOpSetStyleLineNumber, content, tokenizer->getLineNumber());
nsHtml5String url =
aAttributes->getValue(nsHtml5AttributeName::ATTR_XLINK_HREF);
if (url) {
nsHtml5String crossOrigin =
aAttributes->getValue(nsHtml5AttributeName::ATTR_CROSSORIGIN);
nsHtml5String integrity =
@@ -325,35 +348,46 @@ nsHtml5TreeBuilder::createElement(int32_
url, nullptr, crossOrigin, referrerPolicy, integrity);
}
}
break;
}
} else if (aNamespace != kNameSpaceID_MathML) {
// No speculative loader--just line numbers and defer/async check
if (nsGkAtoms::style == aName) {
- nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
- NS_ASSERTION(treeOp, "Tree op allocation failed.");
+ nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement(mozilla::fallible);
+ if (MOZ_UNLIKELY(!treeOp)) {
+ MarkAsBrokenAndRequestSuspensionWithoutBuilder(NS_ERROR_OUT_OF_MEMORY);
+ return nullptr;
+ }
treeOp->Init(eTreeOpSetStyleLineNumber, content, tokenizer->getLineNumber());
} else if (nsGkAtoms::script == aName) {
- nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
- NS_ASSERTION(treeOp, "Tree op allocation failed.");
+ nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement(mozilla::fallible);
+ if (MOZ_UNLIKELY(!treeOp)) {
+ MarkAsBrokenAndRequestSuspensionWithoutBuilder(NS_ERROR_OUT_OF_MEMORY);
+ return nullptr;
+ }
treeOp->Init(eTreeOpSetScriptLineNumberAndFreeze, content, tokenizer->getLineNumber());
if (aNamespace == kNameSpaceID_XHTML) {
mCurrentHtmlScriptIsAsyncOrDefer =
aAttributes->contains(nsHtml5AttributeName::ATTR_SRC) &&
(aAttributes->contains(nsHtml5AttributeName::ATTR_ASYNC) ||
aAttributes->contains(nsHtml5AttributeName::ATTR_DEFER));
}
} else if (aNamespace == kNameSpaceID_XHTML) {
if (nsGkAtoms::html == aName) {
nsHtml5String url =
aAttributes->getValue(nsHtml5AttributeName::ATTR_MANIFEST);
- nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
- NS_ASSERTION(treeOp, "Tree op allocation failed.");
+ nsHtml5TreeOperation* treeOp =
+ mOpQueue.AppendElement(mozilla::fallible);
+ if (MOZ_UNLIKELY(!treeOp)) {
+ MarkAsBrokenAndRequestSuspensionWithoutBuilder(
+ NS_ERROR_OUT_OF_MEMORY);
+ return nullptr;
+ }
if (url) {
nsString
urlString; // Not Auto, because using it to hold nsStringBuffer*
url.ToString(urlString);
treeOp->Init(eTreeOpProcessOfflineManifest, urlString);
} else {
treeOp->Init(eTreeOpProcessOfflineManifest, EmptyString());
}
@@ -382,18 +416,21 @@ nsHtml5TreeBuilder::createElement(int32_
{
nsIContentHandle* content =
createElement(aNamespace, aName, aAttributes, aIntendedParent, aCreator);
if (aFormElement) {
if (mBuilder) {
nsHtml5TreeOperation::SetFormElement(static_cast<nsIContent*>(content),
static_cast<nsIContent*>(aFormElement));
} else {
- nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
- NS_ASSERTION(treeOp, "Tree op allocation failed.");
+ nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement(mozilla::fallible);
+ if (MOZ_UNLIKELY(!treeOp)) {
+ MarkAsBrokenAndRequestSuspensionWithoutBuilder(NS_ERROR_OUT_OF_MEMORY);
+ return nullptr;
+ }
treeOp->Init(eTreeOpSetFormElement, content, aFormElement);
}
}
return content;
}
nsIContentHandle*
nsHtml5TreeBuilder::createHtmlElementSetAsRoot(nsHtml5HtmlAttributes* aAttributes)
@@ -402,21 +439,24 @@ nsHtml5TreeBuilder::createHtmlElementSet
// <html> uses NS_NewHTMLSharedElement creator
creator.html = NS_NewHTMLSharedElement;
nsIContentHandle* content = createElement(
kNameSpaceID_XHTML, nsGkAtoms::html, aAttributes, nullptr, creator);
if (mBuilder) {
nsresult rv = nsHtml5TreeOperation::AppendToDocument(static_cast<nsIContent*>(content),
mBuilder);
if (NS_FAILED(rv)) {
- MarkAsBrokenAndRequestSuspension(rv);
+ MarkAsBrokenAndRequestSuspensionWithBuilder(rv);
}
} else {
- nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
- NS_ASSERTION(treeOp, "Tree op allocation failed.");
+ nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement(mozilla::fallible);
+ if (MOZ_UNLIKELY(!treeOp)) {
+ MarkAsBrokenAndRequestSuspensionWithoutBuilder(NS_ERROR_OUT_OF_MEMORY);
+ return nullptr;
+ }
treeOp->Init(eTreeOpAppendToDocument, content);
}
return content;
}
nsIContentHandle*
nsHtml5TreeBuilder::createAndInsertFosterParentedElement(
int32_t aNamespace,
@@ -469,18 +509,21 @@ nsHtml5TreeBuilder::detachFromParent(nsI
NS_PRECONDITION(aElement, "Null element");
if (mBuilder) {
nsHtml5TreeOperation::Detach(static_cast<nsIContent*>(aElement),
mBuilder);
return;
}
- nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
- NS_ASSERTION(treeOp, "Tree op allocation failed.");
+ nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement(mozilla::fallible);
+ if (MOZ_UNLIKELY(!treeOp)) {
+ MarkAsBrokenAndRequestSuspensionWithoutBuilder(NS_ERROR_OUT_OF_MEMORY);
+ return;
+ }
treeOp->Init(eTreeOpDetach, aElement);
}
void
nsHtml5TreeBuilder::appendElement(nsIContentHandle* aChild, nsIContentHandle* aParent)
{
NS_PRECONDITION(aChild, "Null child");
NS_PRECONDITION(aParent, "Null parent");
@@ -488,45 +531,51 @@ nsHtml5TreeBuilder::appendElement(nsICon
return;
}
if (mBuilder) {
nsresult rv = nsHtml5TreeOperation::Append(static_cast<nsIContent*>(aChild),
static_cast<nsIContent*>(aParent),
mBuilder);
if (NS_FAILED(rv)) {
- MarkAsBrokenAndRequestSuspension(rv);
+ MarkAsBrokenAndRequestSuspensionWithBuilder(rv);
}
return;
}
- nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
- NS_ASSERTION(treeOp, "Tree op allocation failed.");
+ nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement(mozilla::fallible);
+ if (MOZ_UNLIKELY(!treeOp)) {
+ MarkAsBrokenAndRequestSuspensionWithoutBuilder(NS_ERROR_OUT_OF_MEMORY);
+ return;
+ }
treeOp->Init(eTreeOpAppend, aChild, aParent);
}
void
nsHtml5TreeBuilder::appendChildrenToNewParent(nsIContentHandle* aOldParent, nsIContentHandle* aNewParent)
{
NS_PRECONDITION(aOldParent, "Null old parent");
NS_PRECONDITION(aNewParent, "Null new parent");
if (mBuilder) {
nsresult rv = nsHtml5TreeOperation::AppendChildrenToNewParent(
static_cast<nsIContent*>(aOldParent),
static_cast<nsIContent*>(aNewParent),
mBuilder);
if (NS_FAILED(rv)) {
- MarkAsBrokenAndRequestSuspension(rv);
+ MarkAsBrokenAndRequestSuspensionWithBuilder(rv);
}
return;
}
- nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
- NS_ASSERTION(treeOp, "Tree op allocation failed.");
+ nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement(mozilla::fallible);
+ if (MOZ_UNLIKELY(!treeOp)) {
+ MarkAsBrokenAndRequestSuspensionWithoutBuilder(NS_ERROR_OUT_OF_MEMORY);
+ return;
+ }
treeOp->Init(eTreeOpAppendChildrenToNewParent, aOldParent, aNewParent);
}
void
nsHtml5TreeBuilder::insertFosterParentedCharacters(char16_t* aBuffer, int32_t aStart, int32_t aLength, nsIContentHandle* aTable, nsIContentHandle* aStackParent)
{
NS_PRECONDITION(aBuffer, "Null buffer");
NS_PRECONDITION(aTable, "Null table");
@@ -536,34 +585,37 @@ nsHtml5TreeBuilder::insertFosterParented
if (mBuilder) {
nsresult rv = nsHtml5TreeOperation::FosterParentText(
static_cast<nsIContent*>(aStackParent),
aBuffer, // XXX aStart always ignored???
aLength,
static_cast<nsIContent*>(aTable),
mBuilder);
if (NS_FAILED(rv)) {
- MarkAsBrokenAndRequestSuspension(rv);
+ MarkAsBrokenAndRequestSuspensionWithBuilder(rv);
}
return;
}
char16_t* bufferCopy = new (mozilla::fallible) char16_t[aLength];
if (!bufferCopy) {
// Just assigning mBroken instead of generating tree op. The caller
// of tokenizeBuffer() will call MarkAsBroken() as appropriate.
mBroken = NS_ERROR_OUT_OF_MEMORY;
requestSuspension();
return;
}
memcpy(bufferCopy, aBuffer, aLength * sizeof(char16_t));
-
- nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
- NS_ASSERTION(treeOp, "Tree op allocation failed.");
+
+ nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement(mozilla::fallible);
+ if (MOZ_UNLIKELY(!treeOp)) {
+ MarkAsBrokenAndRequestSuspensionWithoutBuilder(NS_ERROR_OUT_OF_MEMORY);
+ return;
+ }
treeOp->Init(eTreeOpFosterParentText, bufferCopy, aLength, aStackParent, aTable);
}
void
nsHtml5TreeBuilder::insertFosterParentedChild(nsIContentHandle* aChild, nsIContentHandle* aTable, nsIContentHandle* aStackParent)
{
NS_PRECONDITION(aChild, "Null child");
NS_PRECONDITION(aTable, "Null table");
@@ -571,23 +623,26 @@ nsHtml5TreeBuilder::insertFosterParented
if (mBuilder) {
nsresult rv = nsHtml5TreeOperation::FosterParent(
static_cast<nsIContent*>(aChild),
static_cast<nsIContent*>(aStackParent),
static_cast<nsIContent*>(aTable),
mBuilder);
if (NS_FAILED(rv)) {
- MarkAsBrokenAndRequestSuspension(rv);
+ MarkAsBrokenAndRequestSuspensionWithBuilder(rv);
}
return;
}
- nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
- NS_ASSERTION(treeOp, "Tree op allocation failed.");
+ nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement(mozilla::fallible);
+ if (MOZ_UNLIKELY(!treeOp)) {
+ MarkAsBrokenAndRequestSuspensionWithoutBuilder(NS_ERROR_OUT_OF_MEMORY);
+ return;
+ }
treeOp->Init(eTreeOpFosterParent, aChild, aStackParent, aTable);
}
void
nsHtml5TreeBuilder::appendCharacters(nsIContentHandle* aParent, char16_t* aBuffer, int32_t aStart, int32_t aLength)
{
NS_PRECONDITION(aBuffer, "Null buffer");
NS_PRECONDITION(aParent, "Null parent");
@@ -596,34 +651,37 @@ nsHtml5TreeBuilder::appendCharacters(nsI
if (mBuilder) {
nsresult rv = nsHtml5TreeOperation::AppendText(
aBuffer, // XXX aStart always ignored???
aLength,
static_cast<nsIContent*>(deepTreeSurrogateParent ?
deepTreeSurrogateParent : aParent),
mBuilder);
if (NS_FAILED(rv)) {
- MarkAsBrokenAndRequestSuspension(rv);
+ MarkAsBrokenAndRequestSuspensionWithBuilder(rv);
}
return;
}
char16_t* bufferCopy = new (mozilla::fallible) char16_t[aLength];
if (!bufferCopy) {
// Just assigning mBroken instead of generating tree op. The caller
// of tokenizeBuffer() will call MarkAsBroken() as appropriate.
mBroken = NS_ERROR_OUT_OF_MEMORY;
requestSuspension();
return;
}
memcpy(bufferCopy, aBuffer, aLength * sizeof(char16_t));
-
- nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
- NS_ASSERTION(treeOp, "Tree op allocation failed.");
+
+ nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement(mozilla::fallible);
+ if (MOZ_UNLIKELY(!treeOp)) {
+ MarkAsBrokenAndRequestSuspensionWithoutBuilder(NS_ERROR_OUT_OF_MEMORY);
+ return;
+ }
treeOp->Init(eTreeOpAppendText, bufferCopy, aLength,
deepTreeSurrogateParent ? deepTreeSurrogateParent : aParent);
}
void
nsHtml5TreeBuilder::appendComment(nsIContentHandle* aParent, char16_t* aBuffer, int32_t aStart, int32_t aLength)
{
NS_PRECONDITION(aBuffer, "Null buffer");
@@ -636,67 +694,73 @@ nsHtml5TreeBuilder::appendComment(nsICon
if (mBuilder) {
nsresult rv = nsHtml5TreeOperation::AppendComment(
static_cast<nsIContent*>(aParent),
aBuffer, // XXX aStart always ignored???
aLength,
mBuilder);
if (NS_FAILED(rv)) {
- MarkAsBrokenAndRequestSuspension(rv);
+ MarkAsBrokenAndRequestSuspensionWithBuilder(rv);
}
return;
}
char16_t* bufferCopy = new (mozilla::fallible) char16_t[aLength];
if (!bufferCopy) {
// Just assigning mBroken instead of generating tree op. The caller
// of tokenizeBuffer() will call MarkAsBroken() as appropriate.
mBroken = NS_ERROR_OUT_OF_MEMORY;
requestSuspension();
return;
}
memcpy(bufferCopy, aBuffer, aLength * sizeof(char16_t));
-
- nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
- NS_ASSERTION(treeOp, "Tree op allocation failed.");
+
+ nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement(mozilla::fallible);
+ if (MOZ_UNLIKELY(!treeOp)) {
+ MarkAsBrokenAndRequestSuspensionWithoutBuilder(NS_ERROR_OUT_OF_MEMORY);
+ return;
+ }
treeOp->Init(eTreeOpAppendComment, bufferCopy, aLength, aParent);
}
void
nsHtml5TreeBuilder::appendCommentToDocument(char16_t* aBuffer, int32_t aStart, int32_t aLength)
{
NS_PRECONDITION(aBuffer, "Null buffer");
MOZ_ASSERT(!aStart, "aStart must always be zero.");
if (mBuilder) {
nsresult rv = nsHtml5TreeOperation::AppendCommentToDocument(
aBuffer, // XXX aStart always ignored???
aLength,
mBuilder);
if (NS_FAILED(rv)) {
- MarkAsBrokenAndRequestSuspension(rv);
+ MarkAsBrokenAndRequestSuspensionWithBuilder(rv);
}
return;
}
char16_t* bufferCopy = new (mozilla::fallible) char16_t[aLength];
if (!bufferCopy) {
// Just assigning mBroken instead of generating tree op. The caller
// of tokenizeBuffer() will call MarkAsBroken() as appropriate.
mBroken = NS_ERROR_OUT_OF_MEMORY;
requestSuspension();
return;
}
memcpy(bufferCopy, aBuffer, aLength * sizeof(char16_t));
-
- nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
- NS_ASSERTION(treeOp, "Tree op allocation failed.");
+
+ nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement(mozilla::fallible);
+ if (MOZ_UNLIKELY(!treeOp)) {
+ MarkAsBrokenAndRequestSuspensionWithoutBuilder(NS_ERROR_OUT_OF_MEMORY);
+ return;
+ }
treeOp->Init(eTreeOpAppendCommentToDocument, bufferCopy, aLength);
}
void
nsHtml5TreeBuilder::addAttributesToElement(nsIContentHandle* aElement, nsHtml5HtmlAttributes* aAttributes)
{
NS_PRECONDITION(aElement, "Null element");
NS_PRECONDITION(aAttributes, "Null attributes");
@@ -708,39 +772,45 @@ nsHtml5TreeBuilder::addAttributesToEleme
if (mBuilder) {
MOZ_ASSERT(aAttributes == tokenizer->GetAttributes(),
"Using attribute other than the tokenizer's to add to body or html.");
nsresult rv = nsHtml5TreeOperation::AddAttributes(
static_cast<nsIContent*>(aElement),
aAttributes,
mBuilder);
if (NS_FAILED(rv)) {
- MarkAsBrokenAndRequestSuspension(rv);
+ MarkAsBrokenAndRequestSuspensionWithBuilder(rv);
}
return;
}
- nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
- NS_ASSERTION(treeOp, "Tree op allocation failed.");
+ nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement(mozilla::fallible);
+ if (MOZ_UNLIKELY(!treeOp)) {
+ MarkAsBrokenAndRequestSuspensionWithoutBuilder(NS_ERROR_OUT_OF_MEMORY);
+ return;
+ }
treeOp->Init(aElement, aAttributes);
}
void
nsHtml5TreeBuilder::markMalformedIfScript(nsIContentHandle* aElement)
{
NS_PRECONDITION(aElement, "Null element");
if (mBuilder) {
nsHtml5TreeOperation::MarkMalformedIfScript(
static_cast<nsIContent*>(aElement));
return;
}
- nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
- NS_ASSERTION(treeOp, "Tree op allocation failed.");
+ nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement(mozilla::fallible);
+ if (MOZ_UNLIKELY(!treeOp)) {
+ MarkAsBrokenAndRequestSuspensionWithoutBuilder(NS_ERROR_OUT_OF_MEMORY);
+ return;
+ }
treeOp->Init(eTreeOpMarkMalformedIfScript, aElement);
}
void
nsHtml5TreeBuilder::start(bool fragment)
{
mCurrentHtmlScriptIsAsyncOrDefer = false;
deepTreeSurrogateParent = nullptr;
@@ -768,23 +838,26 @@ nsHtml5TreeBuilder::appendDoctypeToDocum
nsString systemId; // Not Auto, because using it to hold nsStringBuffer*
aPublicId.ToString(publicId);
aSystemId.ToString(systemId);
if (mBuilder) {
RefPtr<nsAtom> name = nsHtml5TreeOperation::Reget(aName);
nsresult rv = nsHtml5TreeOperation::AppendDoctypeToDocument(
name, publicId, systemId, mBuilder);
if (NS_FAILED(rv)) {
- MarkAsBrokenAndRequestSuspension(rv);
+ MarkAsBrokenAndRequestSuspensionWithBuilder(rv);
}
return;
}
- nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
- NS_ASSERTION(treeOp, "Tree op allocation failed.");
+ nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement(mozilla::fallible);
+ if (MOZ_UNLIKELY(!treeOp)) {
+ MarkAsBrokenAndRequestSuspensionWithoutBuilder(NS_ERROR_OUT_OF_MEMORY);
+ return;
+ }
treeOp->Init(aName, publicId, systemId);
// nsXMLContentSink can flush here, but what's the point?
// It can also interrupt here, but we can't.
}
void
nsHtml5TreeBuilder::elementPushed(int32_t aNamespace, nsAtom* aName, nsIContentHandle* aElement)
{
@@ -820,18 +893,21 @@ nsHtml5TreeBuilder::elementPushed(int32_
if (aNamespace != kNameSpaceID_XHTML) {
return;
}
if (aName == nsGkAtoms::body || aName == nsGkAtoms::frameset) {
if (mBuilder) {
// InnerHTML and DOMParser shouldn't start layout anyway
return;
}
- nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
- NS_ASSERTION(treeOp, "Tree op allocation failed.");
+ nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement(mozilla::fallible);
+ if (MOZ_UNLIKELY(!treeOp)) {
+ MarkAsBrokenAndRequestSuspensionWithoutBuilder(NS_ERROR_OUT_OF_MEMORY);
+ return;
+ }
treeOp->Init(eTreeOpStartLayout);
return;
}
if (aName == nsGkAtoms::input || aName == nsGkAtoms::button) {
if (mBuilder) {
nsHtml5TreeOperation::DoneCreatingElement(static_cast<nsIContent*>(aElement));
} else {
mOpQueue.AppendElement()->Init(eTreeOpDoneCreatingElement, aElement);
@@ -879,83 +955,104 @@ nsHtml5TreeBuilder::elementPopped(int32_
return;
}
if (mBuilder) {
return;
}
if (mCurrentHtmlScriptIsAsyncOrDefer) {
NS_ASSERTION(aNamespace == kNameSpaceID_XHTML,
"Only HTML scripts may be async/defer.");
- nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
- NS_ASSERTION(treeOp, "Tree op allocation failed.");
+ nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement(mozilla::fallible);
+ if (MOZ_UNLIKELY(!treeOp)) {
+ MarkAsBrokenAndRequestSuspensionWithoutBuilder(NS_ERROR_OUT_OF_MEMORY);
+ return;
+ }
treeOp->Init(eTreeOpRunScriptAsyncDefer, aElement);
mCurrentHtmlScriptIsAsyncOrDefer = false;
return;
}
requestSuspension();
- nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
- NS_ASSERTION(treeOp, "Tree op allocation failed.");
+ nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement(mozilla::fallible);
+ if (MOZ_UNLIKELY(!treeOp)) {
+ MarkAsBrokenAndRequestSuspensionWithoutBuilder(NS_ERROR_OUT_OF_MEMORY);
+ return;
+ }
treeOp->InitScript(aElement);
return;
}
if (aName == nsGkAtoms::title) {
if (mBuilder) {
nsHtml5TreeOperation::DoneAddingChildren(static_cast<nsIContent*>(aElement));
return;
}
- nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
- NS_ASSERTION(treeOp, "Tree op allocation failed.");
+ nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement(mozilla::fallible);
+ if (MOZ_UNLIKELY(!treeOp)) {
+ MarkAsBrokenAndRequestSuspensionWithoutBuilder(NS_ERROR_OUT_OF_MEMORY);
+ return;
+ }
treeOp->Init(eTreeOpDoneAddingChildren, aElement);
return;
}
if (aName == nsGkAtoms::style ||
(aNamespace == kNameSpaceID_XHTML && aName == nsGkAtoms::link)) {
if (mBuilder) {
MOZ_ASSERT(!nsContentUtils::IsSafeToRunScript(),
"Scripts must be blocked.");
mBuilder->UpdateStyleSheet(static_cast<nsIContent*>(aElement));
return;
}
- nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
- NS_ASSERTION(treeOp, "Tree op allocation failed.");
+ nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement(mozilla::fallible);
+ if (MOZ_UNLIKELY(!treeOp)) {
+ MarkAsBrokenAndRequestSuspensionWithoutBuilder(NS_ERROR_OUT_OF_MEMORY);
+ return;
+ }
treeOp->Init(eTreeOpUpdateStyleSheet, aElement);
return;
}
if (aNamespace == kNameSpaceID_SVG) {
if (aName == nsGkAtoms::svg) {
if (mBuilder) {
nsHtml5TreeOperation::SvgLoad(static_cast<nsIContent*>(aElement));
return;
}
- nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
- NS_ASSERTION(treeOp, "Tree op allocation failed.");
+ nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement(mozilla::fallible);
+ if (MOZ_UNLIKELY(!treeOp)) {
+ MarkAsBrokenAndRequestSuspensionWithoutBuilder(NS_ERROR_OUT_OF_MEMORY);
+ return;
+ }
treeOp->Init(eTreeOpSvgLoad, aElement);
}
return;
}
// we now have only HTML
// Some HTML nodes need DoneAddingChildren() called to initialize
// properly (e.g. form state restoration).
// XXX expose ElementName group here and do switch
if (aName == nsGkAtoms::object ||
aName == nsGkAtoms::select ||
aName == nsGkAtoms::textarea ||
aName == nsGkAtoms::output) {
if (mBuilder) {
nsHtml5TreeOperation::DoneAddingChildren(static_cast<nsIContent*>(aElement));
return;
}
- nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
- NS_ASSERTION(treeOp, "Tree op allocation failed.");
+ nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement(mozilla::fallible);
+ if (MOZ_UNLIKELY(!treeOp)) {
+ MarkAsBrokenAndRequestSuspensionWithoutBuilder(NS_ERROR_OUT_OF_MEMORY);
+ return;
+ }
treeOp->Init(eTreeOpDoneAddingChildren, aElement);
return;
}
if (aName == nsGkAtoms::meta && !fragment && !mBuilder) {
- nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
- NS_ASSERTION(treeOp, "Tree op allocation failed.");
+ nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement(mozilla::fallible);
+ if (MOZ_UNLIKELY(!treeOp)) {
+ MarkAsBrokenAndRequestSuspensionWithoutBuilder(NS_ERROR_OUT_OF_MEMORY);
+ return;
+ }
treeOp->Init(eTreeOpProcessMeta, aElement);
return;
}
if (mSpeculativeLoadStage && aName == nsGkAtoms::picture) {
// mSpeculativeLoadStage is non-null only in the off-the-main-thread
// tree builder, which handles the network stream
//
// See comments in nsHtml5SpeculativeLoad.h about <picture> preloading
@@ -1110,32 +1207,38 @@ nsHtml5TreeBuilder::SetDocumentCharset(N
}
}
void
nsHtml5TreeBuilder::StreamEnded()
{
MOZ_ASSERT(!mBuilder, "Must not call StreamEnded with builder.");
MOZ_ASSERT(!fragment, "Must not parse fragments off the main thread.");
- nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
- NS_ASSERTION(treeOp, "Tree op allocation failed.");
+ nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement(mozilla::fallible);
+ if (MOZ_UNLIKELY(!treeOp)) {
+ MarkAsBrokenAndRequestSuspensionWithoutBuilder(NS_ERROR_OUT_OF_MEMORY);
+ return;
+ }
treeOp->Init(eTreeOpStreamEnded);
}
void
nsHtml5TreeBuilder::NeedsCharsetSwitchTo(NotNull<const Encoding*> aEncoding,
int32_t aCharsetSource,
int32_t aLineNumber)
{
if (MOZ_UNLIKELY(mBuilder)) {
MOZ_ASSERT_UNREACHABLE("Must never switch charset with builder.");
return;
}
- nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
- NS_ASSERTION(treeOp, "Tree op allocation failed.");
+ nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement(mozilla::fallible);
+ if (MOZ_UNLIKELY(!treeOp)) {
+ MarkAsBrokenAndRequestSuspensionWithoutBuilder(NS_ERROR_OUT_OF_MEMORY);
+ return;
+ }
treeOp->Init(eTreeOpNeedsCharsetSwitchTo,
aEncoding,
aCharsetSource,
aLineNumber);
}
void
nsHtml5TreeBuilder::MaybeComplainAboutCharset(const char* aMsgId,
@@ -1180,17 +1283,17 @@ nsHtml5TreeBuilder::MarkAsBroken(nsresul
mOpQueue.Clear(); // Previous ops don't matter anymore
mOpQueue.AppendElement()->Init(aRv);
}
void
nsHtml5TreeBuilder::MarkAsBrokenFromPortability(nsresult aRv)
{
if (mBuilder) {
- MarkAsBrokenAndRequestSuspension(aRv);
+ MarkAsBrokenAndRequestSuspensionWithBuilder(aRv);
return;
}
mBroken = aRv;
requestSuspension();
}
void
nsHtml5TreeBuilder::StartPlainTextViewSource(const nsAutoString& aTitle)
@@ -1247,29 +1350,35 @@ nsHtml5TreeBuilder::documentMode(nsHtml5
if (mBuilder) {
mBuilder->SetDocumentMode(m);
return;
}
if (mSpeculativeLoadStage) {
mSpeculativeLoadQueue.AppendElement()->InitSetDocumentMode(m);
return;
}
- nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
- NS_ASSERTION(treeOp, "Tree op allocation failed.");
+ nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement(mozilla::fallible);
+ if (MOZ_UNLIKELY(!treeOp)) {
+ MarkAsBrokenAndRequestSuspensionWithoutBuilder(NS_ERROR_OUT_OF_MEMORY);
+ return;
+ }
treeOp->Init(m);
}
nsIContentHandle*
nsHtml5TreeBuilder::getDocumentFragmentForTemplate(nsIContentHandle* aTemplate)
{
if (mBuilder) {
return nsHtml5TreeOperation::GetDocumentFragmentForTemplate(static_cast<nsIContent*>(aTemplate));
}
- nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
- NS_ASSERTION(treeOp, "Tree op allocation failed.");
+ nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement(mozilla::fallible);
+ if (MOZ_UNLIKELY(!treeOp)) {
+ MarkAsBrokenAndRequestSuspensionWithoutBuilder(NS_ERROR_OUT_OF_MEMORY);
+ return nullptr;
+ }
nsIContentHandle* fragHandle = AllocateContentHandle();
treeOp->Init(eTreeOpGetDocumentFragmentForTemplate, aTemplate, fragHandle);
return fragHandle;
}
nsIContentHandle*
nsHtml5TreeBuilder::getFormPointerForContext(nsIContentHandle* aContext)
{