aboutsummaryrefslogtreecommitdiff
path: root/gnu/packages/patches/icecat-CVE-2014-1592.patch
diff options
context:
space:
mode:
Diffstat (limited to 'gnu/packages/patches/icecat-CVE-2014-1592.patch')
-rw-r--r--gnu/packages/patches/icecat-CVE-2014-1592.patch400
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;
+ };
+