summary refs log tree commit diff
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;
+ };
+