9f8552fab5
* gnu/packages/patches/icecat-CVE-2014-1587-bug-1042567.patch, gnu/packages/patches/icecat-CVE-2014-1587-bug-1072847.patch, gnu/packages/patches/icecat-CVE-2014-1587-bug-1079729.patch, gnu/packages/patches/icecat-CVE-2014-1587-bug-1080312.patch, gnu/packages/patches/icecat-CVE-2014-1587-bug-1089207.patch, gnu/packages/patches/icecat-CVE-2014-1590.patch, gnu/packages/patches/icecat-CVE-2014-1592.patch, gnu/packages/patches/icecat-CVE-2014-1593.patch, gnu/packages/patches/icecat-CVE-2014-1594.patch: New files. * gnu-system.am (dist_patch_DATA): Add them. * gnu/packages/gnuzilla.scm (icecat): Add them.
401 lines
14 KiB
Diff
401 lines
14 KiB
Diff
commit 7efadbb03cdffa11ebfc2da3113377d2f33b893b
|
|
Author: Henri Sivonen <hsivonen@hsivonen.fi>
|
|
Date: Mon Nov 3 15:23:26 2014 +0200
|
|
|
|
Bug 1088635. r=smaug, a=bkerensa
|
|
|
|
Modified content/base/src/nsDocument.cpp
|
|
diff --git a/content/base/src/nsDocument.cpp b/content/base/src/nsDocument.cpp
|
|
index cbed38d..3493bce 100644
|
|
--- a/content/base/src/nsDocument.cpp
|
|
+++ b/content/base/src/nsDocument.cpp
|
|
@@ -3916,7 +3916,7 @@ nsDocument::InsertChildAt(nsIContent* aKid, uint32_t aIndex,
|
|
bool aNotify)
|
|
{
|
|
if (aKid->IsElement() && GetRootElement()) {
|
|
- NS_ERROR("Inserting element child when we already have one");
|
|
+ NS_WARNING("Inserting root element when we already have one");
|
|
return NS_ERROR_DOM_HIERARCHY_REQUEST_ERR;
|
|
}
|
|
|
|
Modified parser/html/nsHtml5Parser.cpp
|
|
diff --git a/parser/html/nsHtml5Parser.cpp b/parser/html/nsHtml5Parser.cpp
|
|
index a485be4..f28adb4 100644
|
|
--- a/parser/html/nsHtml5Parser.cpp
|
|
+++ b/parser/html/nsHtml5Parser.cpp
|
|
@@ -237,7 +237,8 @@ nsHtml5Parser::Parse(const nsAString& aSourceBuffer,
|
|
* WillBuildModel to be called before the document has had its
|
|
* script global object set.
|
|
*/
|
|
- mExecutor->WillBuildModel(eDTDMode_unknown);
|
|
+ rv = mExecutor->WillBuildModel(eDTDMode_unknown);
|
|
+ NS_ENSURE_SUCCESS(rv, rv);
|
|
}
|
|
|
|
// Return early if the parser has processed EOF
|
|
@@ -255,7 +256,7 @@ nsHtml5Parser::Parse(const nsAString& aSourceBuffer,
|
|
}
|
|
mDocumentClosed = true;
|
|
if (!mBlocked && !mInDocumentWrite) {
|
|
- ParseUntilBlocked();
|
|
+ return ParseUntilBlocked();
|
|
}
|
|
return NS_OK;
|
|
}
|
|
@@ -378,7 +379,8 @@ nsHtml5Parser::Parse(const nsAString& aSourceBuffer,
|
|
|
|
if (mTreeBuilder->HasScript()) {
|
|
mTreeBuilder->Flush(); // Move ops to the executor
|
|
- mExecutor->FlushDocumentWrite(); // run the ops
|
|
+ rv = mExecutor->FlushDocumentWrite(); // run the ops
|
|
+ NS_ENSURE_SUCCESS(rv, rv);
|
|
// Flushing tree ops can cause all sorts of things.
|
|
// Return early if the parser got terminated.
|
|
if (mExecutor->IsComplete()) {
|
|
@@ -437,7 +439,8 @@ nsHtml5Parser::Parse(const nsAString& aSourceBuffer,
|
|
"Buffer wasn't tokenized to completion?");
|
|
// Scripting semantics require a forced tree builder flush here
|
|
mTreeBuilder->Flush(); // Move ops to the executor
|
|
- mExecutor->FlushDocumentWrite(); // run the ops
|
|
+ rv = mExecutor->FlushDocumentWrite(); // run the ops
|
|
+ NS_ENSURE_SUCCESS(rv, rv);
|
|
} else if (stackBuffer.hasMore()) {
|
|
// The buffer wasn't tokenized to completion. Tokenize the untokenized
|
|
// content in order to preload stuff. This content will be retokenized
|
|
@@ -594,11 +597,13 @@ nsHtml5Parser::IsScriptCreated()
|
|
/* End nsIParser */
|
|
|
|
// not from interface
|
|
-void
|
|
+nsresult
|
|
nsHtml5Parser::ParseUntilBlocked()
|
|
{
|
|
- if (mBlocked || mExecutor->IsComplete() || NS_FAILED(mExecutor->IsBroken())) {
|
|
- return;
|
|
+ nsresult rv = mExecutor->IsBroken();
|
|
+ NS_ENSURE_SUCCESS(rv, rv);
|
|
+ if (mBlocked || mExecutor->IsComplete()) {
|
|
+ return NS_OK;
|
|
}
|
|
NS_ASSERTION(mExecutor->HasStarted(), "Bad life cycle.");
|
|
NS_ASSERTION(!mInDocumentWrite,
|
|
@@ -611,7 +616,7 @@ nsHtml5Parser::ParseUntilBlocked()
|
|
if (mFirstBuffer == mLastBuffer) {
|
|
if (mExecutor->IsComplete()) {
|
|
// something like cache manisfests stopped the parse in mid-flight
|
|
- return;
|
|
+ return NS_OK;
|
|
}
|
|
if (mDocumentClosed) {
|
|
NS_ASSERTION(!GetStreamParser(),
|
|
@@ -620,8 +625,10 @@ nsHtml5Parser::ParseUntilBlocked()
|
|
mTreeBuilder->StreamEnded();
|
|
mTreeBuilder->Flush();
|
|
mExecutor->FlushDocumentWrite();
|
|
+ // The below call does memory cleanup, so call it even if the
|
|
+ // parser has been marked as broken.
|
|
mTokenizer->end();
|
|
- return;
|
|
+ return NS_OK;
|
|
}
|
|
// never release the last buffer.
|
|
NS_ASSERTION(!mLastBuffer->getStart() && !mLastBuffer->getEnd(),
|
|
@@ -643,14 +650,14 @@ nsHtml5Parser::ParseUntilBlocked()
|
|
NS_ASSERTION(mExecutor->IsInFlushLoop(),
|
|
"How did we come here without being in the flush loop?");
|
|
}
|
|
- return; // no more data for now but expecting more
|
|
+ return NS_OK; // no more data for now but expecting more
|
|
}
|
|
mFirstBuffer = mFirstBuffer->next;
|
|
continue;
|
|
}
|
|
|
|
if (mBlocked || mExecutor->IsComplete()) {
|
|
- return;
|
|
+ return NS_OK;
|
|
}
|
|
|
|
// now we have a non-empty buffer
|
|
@@ -667,10 +674,11 @@ nsHtml5Parser::ParseUntilBlocked()
|
|
}
|
|
if (mTreeBuilder->HasScript()) {
|
|
mTreeBuilder->Flush();
|
|
- mExecutor->FlushDocumentWrite();
|
|
+ nsresult rv = mExecutor->FlushDocumentWrite();
|
|
+ NS_ENSURE_SUCCESS(rv, rv);
|
|
}
|
|
if (mBlocked) {
|
|
- return;
|
|
+ return NS_OK;
|
|
}
|
|
}
|
|
continue;
|
|
Modified parser/html/nsHtml5Parser.h
|
|
diff --git a/parser/html/nsHtml5Parser.h b/parser/html/nsHtml5Parser.h
|
|
index aff79c7..e2ef2f8 100644
|
|
--- a/parser/html/nsHtml5Parser.h
|
|
+++ b/parser/html/nsHtml5Parser.h
|
|
@@ -262,7 +262,7 @@ class nsHtml5Parser : public nsIParser,
|
|
/**
|
|
* Parse until pending data is exhausted or a script blocks the parser
|
|
*/
|
|
- void ParseUntilBlocked();
|
|
+ nsresult ParseUntilBlocked();
|
|
|
|
private:
|
|
|
|
Modified parser/html/nsHtml5StreamParser.cpp
|
|
diff --git a/parser/html/nsHtml5StreamParser.cpp b/parser/html/nsHtml5StreamParser.cpp
|
|
index 4790568..7e3917b 100644
|
|
--- a/parser/html/nsHtml5StreamParser.cpp
|
|
+++ b/parser/html/nsHtml5StreamParser.cpp
|
|
@@ -796,7 +796,7 @@ nsHtml5StreamParser::WriteStreamBytes(const uint8_t* aFromSegment,
|
|
// NS_HTML5_STREAM_PARSER_READ_BUFFER_SIZE.
|
|
if (!mLastBuffer) {
|
|
NS_WARNING("mLastBuffer should not be null!");
|
|
- MarkAsBroken();
|
|
+ MarkAsBroken(NS_ERROR_NULL_POINTER);
|
|
return NS_ERROR_NULL_POINTER;
|
|
}
|
|
if (mLastBuffer->getEnd() == NS_HTML5_STREAM_PARSER_READ_BUFFER_SIZE) {
|
|
@@ -902,7 +902,8 @@ nsHtml5StreamParser::OnStartRequest(nsIRequest* aRequest, nsISupports* aContext)
|
|
* WillBuildModel to be called before the document has had its
|
|
* script global object set.
|
|
*/
|
|
- mExecutor->WillBuildModel(eDTDMode_unknown);
|
|
+ rv = mExecutor->WillBuildModel(eDTDMode_unknown);
|
|
+ NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
nsRefPtr<nsHtml5OwningUTF16Buffer> newBuf =
|
|
nsHtml5OwningUTF16Buffer::FalliblyCreate(
|
|
@@ -1003,8 +1004,9 @@ nsHtml5StreamParser::DoStopRequest()
|
|
|
|
if (!mUnicodeDecoder) {
|
|
uint32_t writeCount;
|
|
- if (NS_FAILED(FinalizeSniffing(nullptr, 0, &writeCount, 0))) {
|
|
- MarkAsBroken();
|
|
+ nsresult rv;
|
|
+ if (NS_FAILED(rv = FinalizeSniffing(nullptr, 0, &writeCount, 0))) {
|
|
+ MarkAsBroken(rv);
|
|
return;
|
|
}
|
|
} else if (mFeedChardet) {
|
|
@@ -1076,7 +1078,7 @@ nsHtml5StreamParser::DoDataAvailable(const uint8_t* aBuffer, uint32_t aLength)
|
|
rv = SniffStreamBytes(aBuffer, aLength, &writeCount);
|
|
}
|
|
if (NS_FAILED(rv)) {
|
|
- MarkAsBroken();
|
|
+ MarkAsBroken(rv);
|
|
return;
|
|
}
|
|
NS_ASSERTION(writeCount == aLength, "Wrong number of stream bytes written/sniffed.");
|
|
@@ -1662,13 +1664,13 @@ nsHtml5StreamParser::TimerFlush()
|
|
}
|
|
|
|
void
|
|
-nsHtml5StreamParser::MarkAsBroken()
|
|
+nsHtml5StreamParser::MarkAsBroken(nsresult aRv)
|
|
{
|
|
NS_ASSERTION(IsParserThread(), "Wrong thread!");
|
|
mTokenizerMutex.AssertCurrentThreadOwns();
|
|
|
|
Terminate();
|
|
- mTreeBuilder->MarkAsBroken();
|
|
+ mTreeBuilder->MarkAsBroken(aRv);
|
|
mozilla::DebugOnly<bool> hadOps = mTreeBuilder->Flush(false);
|
|
NS_ASSERTION(hadOps, "Should have had the markAsBroken op!");
|
|
if (NS_FAILED(NS_DispatchToMainThread(mExecutorFlusher))) {
|
|
Modified parser/html/nsHtml5StreamParser.h
|
|
diff --git a/parser/html/nsHtml5StreamParser.h b/parser/html/nsHtml5StreamParser.h
|
|
index c7dcbbe..476ef16 100644
|
|
--- a/parser/html/nsHtml5StreamParser.h
|
|
+++ b/parser/html/nsHtml5StreamParser.h
|
|
@@ -218,7 +218,7 @@ class nsHtml5StreamParser : public nsICharsetDetectionObserver {
|
|
}
|
|
#endif
|
|
|
|
- void MarkAsBroken();
|
|
+ void MarkAsBroken(nsresult aRv);
|
|
|
|
/**
|
|
* Marks the stream parser as interrupted. If you ever add calls to this
|
|
Modified parser/html/nsHtml5TreeBuilderCppSupplement.h
|
|
diff --git a/parser/html/nsHtml5TreeBuilderCppSupplement.h b/parser/html/nsHtml5TreeBuilderCppSupplement.h
|
|
index 4cd5c7c..1e65394 100644
|
|
--- a/parser/html/nsHtml5TreeBuilderCppSupplement.h
|
|
+++ b/parser/html/nsHtml5TreeBuilderCppSupplement.h
|
|
@@ -949,14 +949,14 @@ nsHtml5TreeBuilder::DropHandles()
|
|
}
|
|
|
|
void
|
|
-nsHtml5TreeBuilder::MarkAsBroken()
|
|
+nsHtml5TreeBuilder::MarkAsBroken(nsresult aRv)
|
|
{
|
|
if (MOZ_UNLIKELY(mBuilder)) {
|
|
MOZ_ASSUME_UNREACHABLE("Must not call this with builder.");
|
|
return;
|
|
}
|
|
mOpQueue.Clear(); // Previous ops don't matter anymore
|
|
- mOpQueue.AppendElement()->Init(eTreeOpMarkAsBroken);
|
|
+ mOpQueue.AppendElement()->Init(aRv);
|
|
}
|
|
|
|
void
|
|
Modified parser/html/nsHtml5TreeBuilderHSupplement.h
|
|
diff --git a/parser/html/nsHtml5TreeBuilderHSupplement.h b/parser/html/nsHtml5TreeBuilderHSupplement.h
|
|
index a321e80..8d380eb 100644
|
|
--- a/parser/html/nsHtml5TreeBuilderHSupplement.h
|
|
+++ b/parser/html/nsHtml5TreeBuilderHSupplement.h
|
|
@@ -223,4 +223,4 @@
|
|
|
|
void errEndWithUnclosedElements(nsIAtom* aName);
|
|
|
|
- void MarkAsBroken();
|
|
+ void MarkAsBroken(nsresult aRv);
|
|
Modified parser/html/nsHtml5TreeOpExecutor.cpp
|
|
diff --git a/parser/html/nsHtml5TreeOpExecutor.cpp b/parser/html/nsHtml5TreeOpExecutor.cpp
|
|
index ebcafca..6c52e5f 100644
|
|
--- a/parser/html/nsHtml5TreeOpExecutor.cpp
|
|
+++ b/parser/html/nsHtml5TreeOpExecutor.cpp
|
|
@@ -411,7 +411,11 @@ nsHtml5TreeOpExecutor::RunFlushLoop()
|
|
GetParser()->GetStreamParser();
|
|
// Now parse content left in the document.write() buffer queue if any.
|
|
// This may generate tree ops on its own or dequeue a speculation.
|
|
- GetParser()->ParseUntilBlocked();
|
|
+ nsresult rv = GetParser()->ParseUntilBlocked();
|
|
+ if (NS_FAILED(rv)) {
|
|
+ MarkAsBroken(rv);
|
|
+ return;
|
|
+ }
|
|
}
|
|
|
|
if (mOpQueue.IsEmpty()) {
|
|
@@ -496,21 +500,24 @@ nsHtml5TreeOpExecutor::RunFlushLoop()
|
|
}
|
|
}
|
|
|
|
-void
|
|
+nsresult
|
|
nsHtml5TreeOpExecutor::FlushDocumentWrite()
|
|
{
|
|
+ nsresult rv = IsBroken();
|
|
+ NS_ENSURE_SUCCESS(rv, rv);
|
|
+
|
|
FlushSpeculativeLoads(); // Make sure speculative loads never start after the
|
|
// corresponding normal loads for the same URLs.
|
|
|
|
if (MOZ_UNLIKELY(!mParser)) {
|
|
// The parse has ended.
|
|
mOpQueue.Clear(); // clear in order to be able to assert in destructor
|
|
- return;
|
|
+ return rv;
|
|
}
|
|
|
|
if (mFlushState != eNotFlushing) {
|
|
// XXX Can this happen? In case it can, let's avoid crashing.
|
|
- return;
|
|
+ return rv;
|
|
}
|
|
|
|
mFlushState = eInFlush;
|
|
@@ -545,7 +552,7 @@ nsHtml5TreeOpExecutor::FlushDocumentWrite()
|
|
}
|
|
NS_ASSERTION(mFlushState == eInDocUpdate,
|
|
"Tried to perform tree op outside update batch.");
|
|
- nsresult rv = iter->Perform(this, &scriptElement);
|
|
+ rv = iter->Perform(this, &scriptElement);
|
|
if (NS_FAILED(rv)) {
|
|
MarkAsBroken(rv);
|
|
break;
|
|
@@ -560,13 +567,14 @@ nsHtml5TreeOpExecutor::FlushDocumentWrite()
|
|
|
|
if (MOZ_UNLIKELY(!mParser)) {
|
|
// Ending the doc update caused a call to nsIParser::Terminate().
|
|
- return;
|
|
+ return rv;
|
|
}
|
|
|
|
if (scriptElement) {
|
|
// must be tail call when mFlushState is eNotFlushing
|
|
RunScript(scriptElement);
|
|
}
|
|
+ return rv;
|
|
}
|
|
|
|
// copied from HTML content sink
|
|
Modified parser/html/nsHtml5TreeOpExecutor.h
|
|
diff --git a/parser/html/nsHtml5TreeOpExecutor.h b/parser/html/nsHtml5TreeOpExecutor.h
|
|
index 9617dcb..1f81448 100644
|
|
--- a/parser/html/nsHtml5TreeOpExecutor.h
|
|
+++ b/parser/html/nsHtml5TreeOpExecutor.h
|
|
@@ -173,7 +173,7 @@ class nsHtml5TreeOpExecutor : public nsHtml5DocumentBuilder,
|
|
|
|
void RunFlushLoop();
|
|
|
|
- void FlushDocumentWrite();
|
|
+ nsresult FlushDocumentWrite();
|
|
|
|
void MaybeSuspend();
|
|
|
|
Modified parser/html/nsHtml5TreeOperation.cpp
|
|
diff --git a/parser/html/nsHtml5TreeOperation.cpp b/parser/html/nsHtml5TreeOperation.cpp
|
|
index 48b71dc..7ad65247 100644
|
|
--- a/parser/html/nsHtml5TreeOperation.cpp
|
|
+++ b/parser/html/nsHtml5TreeOperation.cpp
|
|
@@ -214,6 +214,9 @@ nsHtml5TreeOperation::AppendToDocument(nsIContent* aNode,
|
|
nsIDocument* doc = aBuilder->GetDocument();
|
|
uint32_t childCount = doc->GetChildCount();
|
|
rv = doc->AppendChildTo(aNode, false);
|
|
+ if (rv == NS_ERROR_DOM_HIERARCHY_REQUEST_ERR) {
|
|
+ return NS_OK;
|
|
+ }
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
nsNodeUtils::ContentInserted(doc, aNode, childCount);
|
|
|
|
@@ -739,8 +742,7 @@ nsHtml5TreeOperation::Perform(nsHtml5TreeOpExecutor* aBuilder,
|
|
return NS_OK;
|
|
}
|
|
case eTreeOpMarkAsBroken: {
|
|
- aBuilder->MarkAsBroken(NS_ERROR_OUT_OF_MEMORY);
|
|
- return NS_OK;
|
|
+ return mOne.result;
|
|
}
|
|
case eTreeOpRunScript: {
|
|
nsIContent* node = *(mOne.node);
|
|
Modified parser/html/nsHtml5TreeOperation.h
|
|
diff --git a/parser/html/nsHtml5TreeOperation.h b/parser/html/nsHtml5TreeOperation.h
|
|
index 2727733..06d0274 100644
|
|
--- a/parser/html/nsHtml5TreeOperation.h
|
|
+++ b/parser/html/nsHtml5TreeOperation.h
|
|
@@ -435,6 +435,15 @@ class nsHtml5TreeOperation {
|
|
mFour.integer = aInt;
|
|
}
|
|
|
|
+ inline void Init(nsresult aRv)
|
|
+ {
|
|
+ NS_PRECONDITION(mOpCode == eTreeOpUninitialized,
|
|
+ "Op code must be uninitialized when initializing.");
|
|
+ NS_PRECONDITION(NS_FAILED(aRv), "Initialized tree op with non-failure.");
|
|
+ mOpCode = eTreeOpMarkAsBroken;
|
|
+ mOne.result = aRv;
|
|
+ }
|
|
+
|
|
inline void InitAddClass(nsIContentHandle* aNode, const char16_t* aClass)
|
|
{
|
|
NS_PRECONDITION(mOpCode == eTreeOpUninitialized,
|
|
@@ -487,11 +496,12 @@ class nsHtml5TreeOperation {
|
|
nsIAtom* atom;
|
|
nsHtml5HtmlAttributes* attributes;
|
|
nsHtml5DocumentMode mode;
|
|
- char16_t* unicharPtr;
|
|
+ char16_t* unicharPtr;
|
|
char* charPtr;
|
|
nsHtml5TreeOperationStringPair* stringPair;
|
|
nsAHtml5TreeBuilderState* state;
|
|
int32_t integer;
|
|
+ nsresult result;
|
|
} mOne, mTwo, mThree, mFour;
|
|
};
|
|
|