diff options
Diffstat (limited to 'gnu/packages/patches/icecat-CVE-2014-1592.patch')
-rw-r--r-- | gnu/packages/patches/icecat-CVE-2014-1592.patch | 400 |
1 files changed, 400 insertions, 0 deletions
diff --git a/gnu/packages/patches/icecat-CVE-2014-1592.patch b/gnu/packages/patches/icecat-CVE-2014-1592.patch new file mode 100644 index 0000000000..6de1b6fe4a --- /dev/null +++ b/gnu/packages/patches/icecat-CVE-2014-1592.patch @@ -0,0 +1,400 @@ +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; + }; + |