~ruther/guix-local

e1820d14439abedb1cb1caa5cd9f68bcfcbbd466 — Mark H Weaver 11 years ago d7cbc91
gnu: icecat: Apply fixes for CVE-2015-{0797,2708,2710,2713,2716}.

* gnu/packages/patches/icecat-CVE-2015-0797.patch,
  gnu/packages/patches/icecat-CVE-2015-2708-pt1.patch,
  gnu/packages/patches/icecat-CVE-2015-2708-pt2.patch,
  gnu/packages/patches/icecat-CVE-2015-2708-pt3.patch,
  gnu/packages/patches/icecat-CVE-2015-2708-pt4.patch,
  gnu/packages/patches/icecat-CVE-2015-2710-pt1.patch,
  gnu/packages/patches/icecat-CVE-2015-2710-pt2.patch,
  gnu/packages/patches/icecat-CVE-2015-2710-pt3.patch,
  gnu/packages/patches/icecat-CVE-2015-2713-pt1.patch,
  gnu/packages/patches/icecat-CVE-2015-2713-pt2.patch,
  gnu/packages/patches/icecat-CVE-2015-2716.patch: New files.
* gnu-system.am (dist_patch_DATA): Add them.
* gnu/packages/gnuzilla.scm (icecat): Add patches.
M gnu-system.am => gnu-system.am +11 -0
@@ 452,6 452,17 @@ dist_patch_DATA =						\
  gnu/packages/patches/gtkglext-disable-disable-deprecated.patch \
  gnu/packages/patches/hop-bigloo-4.0b.patch			\
  gnu/packages/patches/hop-linker-flags.patch			\
  gnu/packages/patches/icecat-CVE-2015-0797.patch		\
  gnu/packages/patches/icecat-CVE-2015-2708-pt1.patch		\
  gnu/packages/patches/icecat-CVE-2015-2708-pt2.patch		\
  gnu/packages/patches/icecat-CVE-2015-2708-pt3.patch		\
  gnu/packages/patches/icecat-CVE-2015-2708-pt4.patch		\
  gnu/packages/patches/icecat-CVE-2015-2710-pt1.patch		\
  gnu/packages/patches/icecat-CVE-2015-2710-pt2.patch		\
  gnu/packages/patches/icecat-CVE-2015-2710-pt3.patch		\
  gnu/packages/patches/icecat-CVE-2015-2713-pt1.patch		\
  gnu/packages/patches/icecat-CVE-2015-2713-pt2.patch		\
  gnu/packages/patches/icecat-CVE-2015-2716.patch		\
  gnu/packages/patches/irrlicht-mesa-10.patch			\
  gnu/packages/patches/jbig2dec-ignore-testtest.patch		\
  gnu/packages/patches/kmod-module-directory.patch		\

M gnu/packages/gnuzilla.scm => gnu/packages/gnuzilla.scm +12 -1
@@ 233,7 233,18 @@ standards.")
                          name "-" version ".tar.bz2"))
      (sha256
       (base32
        "1a4l23msg4cpc4yp59q2z6xv63r6advlbnjy65v4djv6yhgnqf1i"))))
        "1a4l23msg4cpc4yp59q2z6xv63r6advlbnjy65v4djv6yhgnqf1i"))
      (patches (map search-patch '("icecat-CVE-2015-0797.patch"
                                   "icecat-CVE-2015-2708-pt1.patch"
                                   "icecat-CVE-2015-2708-pt2.patch"
                                   "icecat-CVE-2015-2708-pt3.patch"
                                   "icecat-CVE-2015-2708-pt4.patch"
                                   "icecat-CVE-2015-2710-pt1.patch"
                                   "icecat-CVE-2015-2710-pt2.patch"
                                   "icecat-CVE-2015-2710-pt3.patch"
                                   "icecat-CVE-2015-2713-pt1.patch"
                                   "icecat-CVE-2015-2713-pt2.patch"
                                   "icecat-CVE-2015-2716.patch")))))
    (build-system gnu-build-system)
    (inputs
     `(("alsa-lib" ,alsa-lib)

A gnu/packages/patches/icecat-CVE-2015-0797.patch => gnu/packages/patches/icecat-CVE-2015-0797.patch +35 -0
@@ 0,0 1,35 @@
From 147543038273042f71284fa8487c71670163da5f Mon Sep 17 00:00:00 2001
From: Ralph Giles <giles@mozilla.com>
Date: Tue, 31 Mar 2015 16:18:22 -0700
Subject: [PATCH] Bug 1080995 - Don't use the h264parser gstreamer element.
 r=kinetik, a=sledru

---
 content/media/gstreamer/GStreamerFormatHelper.cpp | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/content/media/gstreamer/GStreamerFormatHelper.cpp b/content/media/gstreamer/GStreamerFormatHelper.cpp
index 25095e7..ebd12c2 100644
--- a/content/media/gstreamer/GStreamerFormatHelper.cpp
+++ b/content/media/gstreamer/GStreamerFormatHelper.cpp
@@ -67,6 +67,7 @@ static char const * const sDefaultCodecCaps[][2] = {
 
 static char const * const sPluginBlacklist[] = {
   "flump3dec",
+  "h264parse",
 };
 
 GStreamerFormatHelper::GStreamerFormatHelper()
@@ -251,7 +252,8 @@ static gboolean FactoryFilter(GstPluginFeature *aFeature, gpointer)
   const gchar *className =
     gst_element_factory_get_klass(GST_ELEMENT_FACTORY_CAST(aFeature));
 
-  if (!strstr(className, "Decoder") && !strstr(className, "Demux")) {
+  if (!strstr(className, "Decoder") && !strstr(className, "Demux") &&
+      !strstr(className, "Parser")) {
     return FALSE;
   }
 
-- 
2.2.1


A gnu/packages/patches/icecat-CVE-2015-2708-pt1.patch => gnu/packages/patches/icecat-CVE-2015-2708-pt1.patch +240 -0
@@ 0,0 1,240 @@
From 5f61ae17ec82d288a3fe4892ec999c0e20c486c0 Mon Sep 17 00:00:00 2001
From: "Byron Campen [:bwc]" <docfaraday@gmail.com>
Date: Mon, 6 Apr 2015 11:52:28 -0700
Subject: [PATCH] Bug 1151139 - Simplify how we choose which streams to gather
 stats from. r=mt, a=abillings

---
 ...t_peerConnection_offerRequiresReceiveAudio.html |  2 +
 ...t_peerConnection_offerRequiresReceiveVideo.html |  2 +
 ...rConnection_offerRequiresReceiveVideoAudio.html |  2 +
 media/mtransport/nricectx.h                        | 13 +++++
 media/mtransport/nricemediastream.cpp              |  1 +
 media/mtransport/nricemediastream.h                |  5 +-
 .../src/peerconnection/PeerConnectionImpl.cpp      | 66 ++++++++++------------
 .../src/peerconnection/PeerConnectionImpl.h        |  2 +-
 8 files changed, 54 insertions(+), 39 deletions(-)

diff --git a/dom/media/tests/mochitest/test_peerConnection_offerRequiresReceiveAudio.html b/dom/media/tests/mochitest/test_peerConnection_offerRequiresReceiveAudio.html
index 69d7e49..d68c078 100644
--- a/dom/media/tests/mochitest/test_peerConnection_offerRequiresReceiveAudio.html
+++ b/dom/media/tests/mochitest/test_peerConnection_offerRequiresReceiveAudio.html
@@ -17,6 +17,8 @@
 
   runTest(function() {
     var test = new PeerConnectionTest();
+    test.chain.remove('PC_LOCAL_CHECK_STATS');
+    test.chain.remove('PC_REMOTE_CHECK_STATS');
     test.setOfferConstraints({ mandatory: { OfferToReceiveAudio: true } });
     test.run();
   });
diff --git a/dom/media/tests/mochitest/test_peerConnection_offerRequiresReceiveVideo.html b/dom/media/tests/mochitest/test_peerConnection_offerRequiresReceiveVideo.html
index 5f1d0e5..0ecb0b7 100644
--- a/dom/media/tests/mochitest/test_peerConnection_offerRequiresReceiveVideo.html
+++ b/dom/media/tests/mochitest/test_peerConnection_offerRequiresReceiveVideo.html
@@ -17,6 +17,8 @@
 
   runTest(function() {
     var test = new PeerConnectionTest();
+    test.chain.remove('PC_LOCAL_CHECK_STATS');
+    test.chain.remove('PC_REMOTE_CHECK_STATS');
     test.setOfferConstraints({ mandatory: { OfferToReceiveVideo: true } });
     test.run();
   });
diff --git a/dom/media/tests/mochitest/test_peerConnection_offerRequiresReceiveVideoAudio.html b/dom/media/tests/mochitest/test_peerConnection_offerRequiresReceiveVideoAudio.html
index c3dea10..78eb0d4 100644
--- a/dom/media/tests/mochitest/test_peerConnection_offerRequiresReceiveVideoAudio.html
+++ b/dom/media/tests/mochitest/test_peerConnection_offerRequiresReceiveVideoAudio.html
@@ -17,6 +17,8 @@
 
   runTest(function() {
     var test = new PeerConnectionTest();
+    test.chain.remove('PC_LOCAL_CHECK_STATS');
+    test.chain.remove('PC_REMOTE_CHECK_STATS');
     test.setOfferConstraints({ mandatory: {
       OfferToReceiveVideo: true,
       OfferToReceiveAudio: true
diff --git a/media/mtransport/nricectx.h b/media/mtransport/nricectx.h
index d1209a7..7350666 100644
--- a/media/mtransport/nricectx.h
+++ b/media/mtransport/nricectx.h
@@ -196,6 +196,19 @@ class NrIceCtx {
   RefPtr<NrIceMediaStream> CreateStream(const std::string& name,
                                                  int components);
 
+  RefPtr<NrIceMediaStream> GetStream(size_t index) {
+    if (index < streams_.size()) {
+      return streams_[index];
+    }
+    return nullptr;
+  }
+
+  // Some might be null
+  size_t GetStreamCount() const
+  {
+    return streams_.size();
+  }
+
   // The name of the ctx
   const std::string& name() const { return name_; }
 
diff --git a/media/mtransport/nricemediastream.cpp b/media/mtransport/nricemediastream.cpp
index 9e96cb5..d2b6429 100644
--- a/media/mtransport/nricemediastream.cpp
+++ b/media/mtransport/nricemediastream.cpp
@@ -209,6 +209,7 @@ nsresult NrIceMediaStream::ParseAttributes(std::vector<std::string>&
     return NS_ERROR_FAILURE;
   }
 
+  has_parsed_attrs_ = true;
   return NS_OK;
 }
 
diff --git a/media/mtransport/nricemediastream.h b/media/mtransport/nricemediastream.h
index aba5fc3..2494ecf 100644
--- a/media/mtransport/nricemediastream.h
+++ b/media/mtransport/nricemediastream.h
@@ -149,6 +149,7 @@ class NrIceMediaStream {
 
   // Parse remote attributes
   nsresult ParseAttributes(std::vector<std::string>& candidates);
+  bool HasParsedAttributes() const { return has_parsed_attrs_; }
 
   // Parse trickle ICE candidate
   nsresult ParseTrickleCandidate(const std::string& candidate);
@@ -204,7 +205,8 @@ class NrIceMediaStream {
       name_(name),
       components_(components),
       stream_(nullptr),
-      opaque_(nullptr) {}
+      opaque_(nullptr),
+      has_parsed_attrs_(false) {}
 
   DISALLOW_COPY_ASSIGN(NrIceMediaStream);
 
@@ -214,6 +216,7 @@ class NrIceMediaStream {
   const int components_;
   nr_ice_media_stream *stream_;
   ScopedDeletePtr<NrIceOpaque> opaque_;
+  bool has_parsed_attrs_;
 };
 
 
diff --git a/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp b/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp
index ebcc17d..c70e3e4 100644
--- a/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp
+++ b/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp
@@ -149,7 +149,8 @@ PRLogModuleInfo *signalingLogInfo() {
 namespace sipcc {
 
 #ifdef MOZILLA_INTERNAL_API
-RTCStatsQuery::RTCStatsQuery(bool internal) : internalStats(internal) {
+RTCStatsQuery::RTCStatsQuery(bool internal) : internalStats(internal),
+  grabAllLevels(false) {
 }
 
 RTCStatsQuery::~RTCStatsQuery() {
@@ -2037,32 +2038,8 @@ PeerConnectionImpl::BuildStatsQuery_m(
 
   query->iceCtx = mMedia->ice_ctx();
 
-  // From the list of MediaPipelines, determine the set of NrIceMediaStreams
-  // we are interested in.
-  std::set<size_t> levelsToGrab;
-  if (trackId) {
-    for (size_t p = 0; p < query->pipelines.Length(); ++p) {
-      size_t level = query->pipelines[p]->level();
-      MOZ_ASSERT(level);
-      levelsToGrab.insert(level);
-    }
-  } else {
-    // We want to grab all streams, so ignore the pipelines (this also ends up
-    // grabbing DataChannel streams, which is what we want)
-    for (size_t s = 0; s < mMedia->num_ice_media_streams(); ++s) {
-      levelsToGrab.insert(s + 1); // mIceStreams is 0-indexed
-    }
-  }
-
-  for (auto s = levelsToGrab.begin(); s != levelsToGrab.end(); ++s) {
-    // TODO(bcampen@mozilla.com): I may need to revisit this for bundle.
-    // (Bug 786234)
-    RefPtr<NrIceMediaStream> temp(mMedia->ice_media_stream(*s - 1));
-    RefPtr<TransportFlow> flow(mMedia->GetTransportFlow(*s, false));
-    // flow can be null for unused levels, such as unused DataChannels
-    if (temp && flow) {
-      query->streams.AppendElement(temp);
-    }
+  if (!trackId) {
+    query->grabAllLevels = true;
   }
 
   return rv;
@@ -2103,6 +2080,9 @@ static void RecordIceStats_s(
     bool internalStats,
     DOMHighResTimeStamp now,
     RTCStatsReportInternal* report) {
+  if (!mediaStream.HasParsedAttributes()) {
+    return;
+  }
 
   NS_ConvertASCIItoUTF16 componentId(mediaStream.name().c_str());
   if (internalStats) {
@@ -2292,20 +2272,32 @@ PeerConnectionImpl::ExecuteStatsQuery_s(RTCStatsQuery *query) {
         break;
       }
     }
+
+    if (!query->grabAllLevels) {
+      // If we're grabbing all levels, that means we want datachannels too,
+      // which don't have pipelines.
+      if (query->iceCtx->GetStream(p - 1)) {
+        RecordIceStats_s(*query->iceCtx->GetStream(p - 1),
+                         query->internalStats,
+                         query->now,
+                         &(query->report));
+      }
+    }
   }
 
-  // Gather stats from ICE
-  for (size_t s = 0; s != query->streams.Length(); ++s) {
-    RecordIceStats_s(*query->streams[s],
-                     query->internalStats,
-                     query->now,
-                     &(query->report));
+  if (query->grabAllLevels) {
+    for (size_t i = 0; i < query->iceCtx->GetStreamCount(); ++i) {
+      if (query->iceCtx->GetStream(i)) {
+        RecordIceStats_s(*query->iceCtx->GetStream(i),
+                         query->internalStats,
+                         query->now,
+                         &(query->report));
+      }
+    }
   }
 
-  // NrIceCtx and NrIceMediaStream must be destroyed on STS, so it is not safe
-  // to dispatch them back to main.
-  // We clear streams first to maintain destruction order
-  query->streams.Clear();
+  // NrIceCtx must be destroyed on STS, so it is not safe
+  // to dispatch it back to main.
   query->iceCtx = nullptr;
   return NS_OK;
 }
diff --git a/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.h b/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.h
index 847085c..497230a 100644
--- a/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.h
+++ b/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.h
@@ -174,7 +174,7 @@ class RTCStatsQuery {
     bool internalStats;
     nsTArray<mozilla::RefPtr<mozilla::MediaPipeline>> pipelines;
     mozilla::RefPtr<NrIceCtx> iceCtx;
-    nsTArray<mozilla::RefPtr<NrIceMediaStream>> streams;
+    bool grabAllLevels;
     DOMHighResTimeStamp now;
 };
 #endif // MOZILLA_INTERNAL_API
-- 
2.2.1


A gnu/packages/patches/icecat-CVE-2015-2708-pt2.patch => gnu/packages/patches/icecat-CVE-2015-2708-pt2.patch +284 -0
@@ 0,0 1,284 @@
From 272c1ba11fac7a9ceede2f4f737bb27b4bbcad71 Mon Sep 17 00:00:00 2001
From: Steve Fink <sfink@mozilla.com>
Date: Thu, 19 Mar 2015 20:50:57 -0700
Subject: [PATCH] Bug 1120655 - Suppress zone/compartment collection while
 iterating. r=terrence, a=bkerensa

---
 js/src/gc/Zone.h      |  9 ++++----
 js/src/jsgc.cpp       | 57 +++++++++++++++++++++++++++++++++++----------------
 js/src/jsgc.h         | 11 +++++++++-
 js/src/vm/Runtime.cpp |  1 +
 js/src/vm/Runtime.h   |  3 +++
 5 files changed, 58 insertions(+), 23 deletions(-)

diff --git a/js/src/gc/Zone.h b/js/src/gc/Zone.h
index e7f687a..dd058f0 100644
--- a/js/src/gc/Zone.h
+++ b/js/src/gc/Zone.h
@@ -353,10 +353,11 @@ enum ZoneSelector {
 
 class ZonesIter {
   private:
+    gc::AutoEnterIteration iterMarker;
     JS::Zone **it, **end;
 
   public:
-    ZonesIter(JSRuntime *rt, ZoneSelector selector) {
+    ZonesIter(JSRuntime *rt, ZoneSelector selector) : iterMarker(rt) {
         it = rt->zones.begin();
         end = rt->zones.end();
 
@@ -427,13 +428,13 @@ struct CompartmentsInZoneIter
 template<class ZonesIterT>
 class CompartmentsIterT
 {
-  private:
+    gc::AutoEnterIteration iterMarker;
     ZonesIterT zone;
     mozilla::Maybe<CompartmentsInZoneIter> comp;
 
   public:
     explicit CompartmentsIterT(JSRuntime *rt)
-      : zone(rt)
+      : iterMarker(rt), zone(rt)
     {
         if (zone.done())
             comp.construct();
@@ -442,7 +443,7 @@ class CompartmentsIterT
     }
 
     CompartmentsIterT(JSRuntime *rt, ZoneSelector selector)
-      : zone(rt, selector)
+      : iterMarker(rt), zone(rt, selector)
     {
         if (zone.done())
             comp.construct();
diff --git a/js/src/jsgc.cpp b/js/src/jsgc.cpp
index 15c86c8..1dfe0ab 100644
--- a/js/src/jsgc.cpp
+++ b/js/src/jsgc.cpp
@@ -2525,7 +2525,7 @@ ReleaseObservedTypes(JSRuntime* rt)
  * arbitrary compartment in the zone.
  */
 static void
-SweepCompartments(FreeOp *fop, Zone *zone, bool keepAtleastOne, bool lastGC)
+SweepCompartments(FreeOp *fop, Zone *zone, bool keepAtleastOne, bool destroyingRuntime)
 {
     JSRuntime *rt = zone->runtimeFromMainThread();
     JSDestroyCompartmentCallback callback = rt->destroyCompartmentCallback;
@@ -2543,7 +2543,7 @@ SweepCompartments(FreeOp *fop, Zone *zone, bool keepAtleastOne, bool lastGC)
          * deleted and keepAtleastOne is true.
          */
         bool dontDelete = read == end && !foundOne && keepAtleastOne;
-        if ((!comp->marked && !dontDelete) || lastGC) {
+        if ((!comp->marked && !dontDelete) || destroyingRuntime) {
             if (callback)
                 callback(fop, comp);
             if (comp->principals)
@@ -2559,9 +2559,13 @@ SweepCompartments(FreeOp *fop, Zone *zone, bool keepAtleastOne, bool lastGC)
 }
 
 static void
-SweepZones(FreeOp *fop, bool lastGC)
+SweepZones(FreeOp *fop, bool destroyingRuntime)
 {
     JSRuntime *rt = fop->runtime();
+    MOZ_ASSERT_IF(destroyingRuntime, rt->numActiveZoneIters == 0);
+    if (rt->numActiveZoneIters)
+        return;
+
     JSZoneCallback callback = rt->destroyZoneCallback;
 
     /* Skip the atomsCompartment zone. */
@@ -2576,17 +2580,17 @@ SweepZones(FreeOp* fop, bool lastGC)
 
         if (zone->wasGCStarted()) {
             if ((zone->allocator.arenas.arenaListsAreEmpty() && !zone->hasMarkedCompartments()) ||
-                lastGC)
+                destroyingRuntime)
             {
                 zone->allocator.arenas.checkEmptyFreeLists();
                 if (callback)
                     callback(zone);
-                SweepCompartments(fop, zone, false, lastGC);
+                SweepCompartments(fop, zone, false, destroyingRuntime);
                 JS_ASSERT(zone->compartments.empty());
                 fop->delete_(zone);
                 continue;
             }
-            SweepCompartments(fop, zone, true, lastGC);
+            SweepCompartments(fop, zone, true, destroyingRuntime);
         }
         *write++ = zone;
     }
@@ -3787,7 +3791,7 @@ EndSweepingZoneGroup(JSRuntime *rt)
 }
 
 static void
-BeginSweepPhase(JSRuntime *rt, bool lastGC)
+BeginSweepPhase(JSRuntime *rt, bool destroyingRuntime)
 {
     /*
      * Sweep phase.
@@ -3804,7 +3808,7 @@ BeginSweepPhase(JSRuntime *rt, bool lastGC)
     gcstats::AutoPhase ap(rt->gcStats, gcstats::PHASE_SWEEP);
 
 #ifdef JS_THREADSAFE
-    rt->gcSweepOnBackgroundThread = !lastGC && rt->useHelperThreads();
+    rt->gcSweepOnBackgroundThread = !destroyingRuntime && rt->useHelperThreads();
 #endif
 
 #ifdef DEBUG
@@ -3903,12 +3907,12 @@ SweepPhase(JSRuntime *rt, SliceBudget &sliceBudget)
 }
 
 static void
-EndSweepPhase(JSRuntime *rt, JSGCInvocationKind gckind, bool lastGC)
+EndSweepPhase(JSRuntime *rt, JSGCInvocationKind gckind, bool destroyingRuntime)
 {
     gcstats::AutoPhase ap(rt->gcStats, gcstats::PHASE_SWEEP);
     FreeOp fop(rt, rt->gcSweepOnBackgroundThread);
 
-    JS_ASSERT_IF(lastGC, !rt->gcSweepOnBackgroundThread);
+    JS_ASSERT_IF(destroyingRuntime, !rt->gcSweepOnBackgroundThread);
 
     JS_ASSERT(rt->gcMarker.isDrained());
     rt->gcMarker.stop();
@@ -3959,8 +3963,8 @@ EndSweepPhase(JSRuntime *rt, JSGCInvocationKind gckind, bool lastGC)
          * This removes compartments from rt->compartment, so we do it last to make
          * sure we don't miss sweeping any compartments.
          */
-        if (!lastGC)
-            SweepZones(&fop, lastGC);
+        if (!destroyingRuntime)
+            SweepZones(&fop, destroyingRuntime);
 
         if (!rt->gcSweepOnBackgroundThread) {
             /*
@@ -4001,8 +4005,8 @@ EndSweepPhase(JSRuntime *rt, JSGCInvocationKind gckind, bool lastGC)
         rt->freeLifoAlloc.freeAll();
 
         /* Ensure the compartments get swept if it's the last GC. */
-        if (lastGC)
-            SweepZones(&fop, lastGC);
+        if (destroyingRuntime)
+            SweepZones(&fop, destroyingRuntime);
     }
 
     for (ZonesIter zone(rt, WithAtoms); !zone.done(); zone.next()) {
@@ -4339,7 +4343,7 @@ IncrementalCollectSlice(JSRuntime *rt,
     AutoCopyFreeListToArenasForGC copy(rt);
     AutoGCSlice slice(rt);
 
-    bool lastGC = (reason == JS::gcreason::DESTROY_RUNTIME);
+    bool destroyingRuntime = (reason == JS::gcreason::DESTROY_RUNTIME);
 
     gc::State initialState = rt->gcIncrementalState;
 
@@ -4384,7 +4388,7 @@ IncrementalCollectSlice(JSRuntime *rt,
             return;
         }
 
-        if (!lastGC)
+        if (!destroyingRuntime)
             PushZealSelectedObjects(rt);
 
         rt->gcIncrementalState = MARK;
@@ -4426,7 +4430,7 @@ IncrementalCollectSlice(JSRuntime *rt,
          * This runs to completion, but we don't continue if the budget is
          * now exhasted.
          */
-        BeginSweepPhase(rt, lastGC);
+        BeginSweepPhase(rt, destroyingRuntime);
         if (sliceBudget.isOverBudget())
             break;
 
@@ -4445,7 +4449,7 @@ IncrementalCollectSlice(JSRuntime *rt,
         if (!finished)
             break;
 
-        EndSweepPhase(rt, gckind, lastGC);
+        EndSweepPhase(rt, gckind, destroyingRuntime);
 
         if (rt->gcSweepOnBackgroundThread)
             rt->gcHelperThread.startBackgroundSweep(gckind == GC_SHRINK);
@@ -5386,3 +5390,20 @@ JS::AutoAssertNoGC::~AutoAssertNoGC()
         MOZ_ASSERT(gcNumber == runtime->gcNumber, "GC ran inside an AutoAssertNoGC scope.");
 }
 #endif
+
+namespace js {
+namespace gc {
+
+AutoEnterIteration::AutoEnterIteration(JSRuntime *rt_) : rt(rt_)
+{
+    ++rt->numActiveZoneIters;
+}
+
+AutoEnterIteration::~AutoEnterIteration()
+{
+    MOZ_ASSERT(rt->numActiveZoneIters);
+    --rt->numActiveZoneIters;
+}
+
+} /* namespace gc */
+} /* namespace js */
diff --git a/js/src/jsgc.h b/js/src/jsgc.h
index 825cff5..ca331c0 100644
--- a/js/src/jsgc.h
+++ b/js/src/jsgc.h
@@ -1077,7 +1077,7 @@ MaybeVerifyBarriers(JSContext* cx, bool always = false)
 /*
  * Instances of this class set the |JSRuntime::suppressGC| flag for the duration
  * that they are live. Use of this class is highly discouraged. Please carefully
- * read the comment in jscntxt.h above |suppressGC| and take all appropriate
+ * read the comment in vm/Runtime.h above |suppressGC| and take all appropriate
  * precautions before instantiating this class.
  */
 class AutoSuppressGC
@@ -1113,6 +1113,15 @@ class AutoEnterOOMUnsafeRegion
 class AutoEnterOOMUnsafeRegion {};
 #endif /* DEBUG */
 
+/* Prevent compartments and zones from being collected during iteration. */
+class AutoEnterIteration {
+    JSRuntime *rt;
+
+  public:
+    AutoEnterIteration(JSRuntime *rt_);
+    ~AutoEnterIteration();
+};
+
 } /* namespace gc */
 
 #ifdef DEBUG
diff --git a/js/src/vm/Runtime.cpp b/js/src/vm/Runtime.cpp
index bb5c8680..0d8c6cd 100644
--- a/js/src/vm/Runtime.cpp
+++ b/js/src/vm/Runtime.cpp
@@ -195,6 +195,7 @@ JSRuntime::JSRuntime(JSRuntime *parentRuntime, JSUseHelperThreads useHelperThrea
     gcShouldCleanUpEverything(false),
     gcGrayBitsValid(false),
     gcIsNeeded(0),
+    numActiveZoneIters(0),
     gcStats(thisFromCtor()),
     gcNumber(0),
     gcStartNumber(0),
diff --git a/js/src/vm/Runtime.h b/js/src/vm/Runtime.h
index 5aeb924..ba4180e 100644
--- a/js/src/vm/Runtime.h
+++ b/js/src/vm/Runtime.h
@@ -1061,6 +1061,9 @@ struct JSRuntime : public JS::shadow::Runtime,
      */
     volatile uintptr_t  gcIsNeeded;
 
+    mozilla::Atomic<size_t, mozilla::ReleaseAcquire> numActiveZoneIters;
+    friend class js::gc::AutoEnterIteration;
+
     js::gcstats::Statistics gcStats;
 
     /* Incremented on every GC slice. */
-- 
2.2.1


A gnu/packages/patches/icecat-CVE-2015-2708-pt3.patch => gnu/packages/patches/icecat-CVE-2015-2708-pt3.patch +228 -0
@@ 0,0 1,228 @@
From 4dcbca8b3c26b451e1376cd1b7c88ab984a45b39 Mon Sep 17 00:00:00 2001
From: Mats Palmgren <mats@mozilla.com>
Date: Tue, 14 Apr 2015 22:12:39 -0400
Subject: [PATCH] Bug 1143299 - Make frame insertion methods deal with
 aPrevFrame being on an overflow list. r=roc, a=bkerensa

---
 layout/generic/nsBlockFrame.cpp        | 18 ++++++++++++---
 layout/generic/nsBlockFrame.h          | 14 ++++++++----
 layout/generic/nsContainerFrame.cpp    | 41 +++++++++++++++++++---------------
 layout/tables/nsTableFrame.cpp         |  2 ++
 layout/tables/nsTableRowFrame.cpp      |  2 ++
 layout/tables/nsTableRowGroupFrame.cpp |  2 ++
 6 files changed, 54 insertions(+), 25 deletions(-)

diff --git a/layout/generic/nsBlockFrame.cpp b/layout/generic/nsBlockFrame.cpp
index a011bcf..70d5297 100644
--- a/layout/generic/nsBlockFrame.cpp
+++ b/layout/generic/nsBlockFrame.cpp
@@ -1049,7 +1049,7 @@ nsBlockFrame::Reflow(nsPresContext*           aPresContext,
   state.mOverflowTracker = &tracker;
 
   // Drain & handle pushed floats
-  DrainPushedFloats(state);
+  DrainPushedFloats();
   nsOverflowAreas fcBounds;
   nsReflowStatus fcStatus = NS_FRAME_COMPLETE;
   ReflowPushedFloats(state, fcBounds, fcStatus);
@@ -4438,9 +4438,13 @@ nsBlockFrame::DrainSelfOverflowList()
  * might push some of them on).  Floats with placeholders in this block
  * are reflowed by (nsBlockReflowState/nsLineLayout)::AddFloat, which
  * also maintains these invariants.
+ *
+ * DrainSelfPushedFloats moves any pushed floats from this block's own
+ * PushedFloats list back into mFloats.  DrainPushedFloats additionally
+ * moves frames from its prev-in-flow's PushedFloats list into mFloats.
  */
 void
-nsBlockFrame::DrainPushedFloats(nsBlockReflowState& aState)
+nsBlockFrame::DrainSelfPushedFloats()
 {
 #ifdef DEBUG
   // Between when we drain pushed floats and when we complete reflow,
@@ -4503,12 +4507,18 @@ nsBlockFrame::DrainPushedFloats(nsBlockReflowState& aState)
       RemovePushedFloats()->Delete(presContext->PresShell());
     }
   }
+}
+
+void
+nsBlockFrame::DrainPushedFloats()
+{
+  DrainSelfPushedFloats();
 
   // After our prev-in-flow has completed reflow, it may have a pushed
   // floats list, containing floats that we need to own.  Take these.
   nsBlockFrame* prevBlock = static_cast<nsBlockFrame*>(GetPrevInFlow());
   if (prevBlock) {
-    AutoFrameListPtr list(presContext, prevBlock->RemovePushedFloats());
+    AutoFrameListPtr list(PresContext(), prevBlock->RemovePushedFloats());
     if (list && list->NotEmpty()) {
       mFloats.InsertFrames(this, nullptr, *list);
     }
@@ -4711,6 +4721,7 @@ nsBlockFrame::AppendFrames(ChildListID  aListID,
       return nsContainerFrame::AppendFrames(aListID, aFrameList);
     }
     else if (kFloatList == aListID) {
+      DrainSelfPushedFloats(); // ensure the last frame is in mFloats
       mFloats.AppendFrames(nullptr, aFrameList);
       return NS_OK;
     }
@@ -4757,6 +4768,7 @@ nsBlockFrame::InsertFrames(ChildListID aListID,
       return nsContainerFrame::InsertFrames(aListID, aPrevFrame, aFrameList);
     }
     else if (kFloatList == aListID) {
+      DrainSelfPushedFloats(); // ensure aPrevFrame is in mFloats
       mFloats.InsertFrames(this, aPrevFrame, aFrameList);
       return NS_OK;
     }
diff --git a/layout/generic/nsBlockFrame.h b/layout/generic/nsBlockFrame.h
index 1a6bb1e..07f7508 100644
--- a/layout/generic/nsBlockFrame.h
+++ b/layout/generic/nsBlockFrame.h
@@ -533,10 +533,16 @@ protected:
     return GetStateBits() & NS_BLOCK_HAS_OVERFLOW_OUT_OF_FLOWS;
   }
 
-  /** grab pushed floats from this block's prevInFlow, and splice
-    * them into this block's mFloats list.
-    */
-  void DrainPushedFloats(nsBlockReflowState& aState);
+  /**
+   * Moves frames from our PushedFloats list back into our mFloats list.
+   */
+  void DrainSelfPushedFloats();
+
+  /**
+   * First calls DrainSelfPushedFloats() then grabs pushed floats from this
+   * block's prev-in-flow, and splice them into this block's mFloats list too.
+   */
+  void DrainPushedFloats();
 
   /** Load all our floats into the float manager (without reflowing them).
    *  Assumes float manager is in our own coordinate system.
diff --git a/layout/generic/nsContainerFrame.cpp b/layout/generic/nsContainerFrame.cpp
index 76f0748..3ffcba7 100644
--- a/layout/generic/nsContainerFrame.cpp
+++ b/layout/generic/nsContainerFrame.cpp
@@ -102,16 +102,18 @@ nsContainerFrame::AppendFrames(ChildListID  aListID,
       return NS_ERROR_INVALID_ARG;
     }
   }
-  if (aFrameList.NotEmpty()) {
-    mFrames.AppendFrames(this, aFrameList);
 
-    // Ask the parent frame to reflow me.
-    if (aListID == kPrincipalList)
-    {
-      PresContext()->PresShell()->
-        FrameNeedsReflow(this, nsIPresShell::eTreeChange,
-                         NS_FRAME_HAS_DIRTY_CHILDREN);
-    }
+  if (MOZ_UNLIKELY(aFrameList.IsEmpty())) {
+    return NS_OK;
+  }
+
+  DrainSelfOverflowList(); // ensure the last frame is in mFrames
+  mFrames.AppendFrames(this, aFrameList);
+
+  if (aListID != kNoReflowPrincipalList) {
+    PresContext()->PresShell()->
+      FrameNeedsReflow(this, nsIPresShell::eTreeChange,
+                       NS_FRAME_HAS_DIRTY_CHILDREN);
   }
   return NS_OK;
 }
@@ -131,16 +133,19 @@ nsContainerFrame::InsertFrames(ChildListID aListID,
       return NS_ERROR_INVALID_ARG;
     }
   }
-  if (aFrameList.NotEmpty()) {
-    // Insert frames after aPrevFrame
-    mFrames.InsertFrames(this, aPrevFrame, aFrameList);
 
-    if (aListID == kPrincipalList)
-    {
-      PresContext()->PresShell()->
-        FrameNeedsReflow(this, nsIPresShell::eTreeChange,
-                         NS_FRAME_HAS_DIRTY_CHILDREN);
-    }
+  if (MOZ_UNLIKELY(aFrameList.IsEmpty())) {
+    return NS_OK;
+  }
+
+  DrainSelfOverflowList(); // ensure aPrevFrame is in mFrames
+  mFrames.InsertFrames(this, aPrevFrame, aFrameList);
+
+  if (aListID != kNoReflowPrincipalList) {
+    PresContext()->PresShell()->
+      FrameNeedsReflow(this, nsIPresShell::eTreeChange,
+                       NS_FRAME_HAS_DIRTY_CHILDREN);
+
   }
   return NS_OK;
 }
diff --git a/layout/tables/nsTableFrame.cpp b/layout/tables/nsTableFrame.cpp
index 60613ba..44088da 100644
--- a/layout/tables/nsTableFrame.cpp
+++ b/layout/tables/nsTableFrame.cpp
@@ -2232,6 +2232,7 @@ nsTableFrame::AppendFrames(ChildListID     aListID,
       InsertColGroups(startColIndex,
                       nsFrameList::Slice(mColGroups, f, f->GetNextSibling()));
     } else if (IsRowGroup(display->mDisplay)) {
+      DrainSelfOverflowList(); // ensure the last frame is in mFrames
       // Append the new row group frame to the sibling chain
       mFrames.AppendFrame(nullptr, f);
 
@@ -2404,6 +2405,7 @@ nsTableFrame::HomogenousInsertFrames(ChildListID     aListID,
     InsertColGroups(startColIndex, newColgroups);
   } else if (IsRowGroup(display->mDisplay)) {
     NS_ASSERTION(aListID == kPrincipalList, "unexpected child list");
+    DrainSelfOverflowList(); // ensure aPrevFrame is in mFrames
     // Insert the frames in the sibling chain
     const nsFrameList::Slice& newRowGroups =
       mFrames.InsertFrames(nullptr, aPrevFrame, aFrameList);
diff --git a/layout/tables/nsTableRowFrame.cpp b/layout/tables/nsTableRowFrame.cpp
index d1c493b..2351de3 100644
--- a/layout/tables/nsTableRowFrame.cpp
+++ b/layout/tables/nsTableRowFrame.cpp
@@ -182,6 +182,7 @@ nsTableRowFrame::AppendFrames(ChildListID     aListID,
 {
   NS_ASSERTION(aListID == kPrincipalList, "unexpected child list");
 
+  DrainSelfOverflowList(); // ensure the last frame is in mFrames
   const nsFrameList::Slice& newCells = mFrames.AppendFrames(nullptr, aFrameList);
 
   // Add the new cell frames to the table
@@ -208,6 +209,7 @@ nsTableRowFrame::InsertFrames(ChildListID     aListID,
   NS_ASSERTION(aListID == kPrincipalList, "unexpected child list");
   NS_ASSERTION(!aPrevFrame || aPrevFrame->GetParent() == this,
                "inserting after sibling frame with different parent");
+  DrainSelfOverflowList(); // ensure aPrevFrame is in mFrames
   //Insert Frames in the frame list
   const nsFrameList::Slice& newCells = mFrames.InsertFrames(nullptr, aPrevFrame, aFrameList);
 
diff --git a/layout/tables/nsTableRowGroupFrame.cpp b/layout/tables/nsTableRowGroupFrame.cpp
index 34aaf02..40b349b 100644
--- a/layout/tables/nsTableRowGroupFrame.cpp
+++ b/layout/tables/nsTableRowGroupFrame.cpp
@@ -1389,6 +1389,7 @@ nsTableRowGroupFrame::AppendFrames(ChildListID     aListID,
 {
   NS_ASSERTION(aListID == kPrincipalList, "unexpected child list");
 
+  DrainSelfOverflowList(); // ensure the last frame is in mFrames
   ClearRowCursor();
 
   // collect the new row frames in an array
@@ -1430,6 +1431,7 @@ nsTableRowGroupFrame::InsertFrames(ChildListID     aListID,
   NS_ASSERTION(!aPrevFrame || aPrevFrame->GetParent() == this,
                "inserting after sibling frame with different parent");
 
+  DrainSelfOverflowList(); // ensure aPrevFrame is in mFrames
   ClearRowCursor();
 
   // collect the new row frames in an array
-- 
2.2.1


A gnu/packages/patches/icecat-CVE-2015-2708-pt4.patch => gnu/packages/patches/icecat-CVE-2015-2708-pt4.patch +26 -0
@@ 0,0 1,26 @@
From e6082e031f0fa2a4a7a63ff124c6f22aeb75393d Mon Sep 17 00:00:00 2001
From: Terrence Cole <terrence@mozilla.com>
Date: Fri, 10 Apr 2015 08:58:26 -0700
Subject: [PATCH] Bug 1152177 - Make jsid and Value pre barriers symetrical.
 r=jonco, a=abillings

---
 js/src/gc/Barrier.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/js/src/gc/Barrier.h b/js/src/gc/Barrier.h
index 7efd785..9fc6bd0 100644
--- a/js/src/gc/Barrier.h
+++ b/js/src/gc/Barrier.h
@@ -1062,6 +1062,8 @@ class BarrieredId
                 JS_ASSERT(obj == JSID_TO_OBJECT(value));
             }
         } else if (JSID_IS_STRING(value)) {
+            if (StringIsPermanentAtom(JSID_TO_STRING(value)))
+                return;
             JSString *str = JSID_TO_STRING(value);
             JS::shadow::Zone *shadowZone = ShadowZoneOfStringFromAnyThread(str);
             if (shadowZone->needsBarrier()) {
-- 
2.2.1


A gnu/packages/patches/icecat-CVE-2015-2710-pt1.patch => gnu/packages/patches/icecat-CVE-2015-2710-pt1.patch +199 -0
@@ 0,0 1,199 @@
From 0bd8486f4088c0845514986f61861688e0be011d Mon Sep 17 00:00:00 2001
From: Cameron McCormack <cam@mcc.id.au>
Date: Mon, 6 Apr 2015 09:11:55 -0400
Subject: [PATCH] Bug 1149542 - Part 1: Return early from SVG text layout if we
 discover mPositions is not long enough. r=dholbert, a=sledru

---
 layout/svg/SVGTextFrame.cpp | 59 +++++++++++++++++++++++++++++++--------------
 layout/svg/SVGTextFrame.h   | 23 ++++++++++++------
 2 files changed, 56 insertions(+), 26 deletions(-)

diff --git a/layout/svg/SVGTextFrame.cpp b/layout/svg/SVGTextFrame.cpp
index 721e699..45327881 100644
--- a/layout/svg/SVGTextFrame.cpp
+++ b/layout/svg/SVGTextFrame.cpp
@@ -14,6 +14,7 @@
 #include "gfxTypes.h"
 #include "LookAndFeel.h"
 #include "mozilla/gfx/2D.h"
+#include "mozilla/Likely.h"
 #include "nsAlgorithm.h"
 #include "nsBlockFrame.h"
 #include "nsCaret.h"
@@ -4316,23 +4317,28 @@ ShouldStartRunAtIndex(const nsTArray<CharPosition>& aPositions,
   return false;
 }
 
-uint32_t
-SVGTextFrame::ResolvePositions(nsIContent* aContent,
-                               uint32_t aIndex,
-                               bool aInTextPath,
-                               bool& aForceStartOfChunk,
-                               nsTArray<gfxPoint>& aDeltas)
+bool
+SVGTextFrame::ResolvePositionsForNode(nsIContent* aContent,
+                                      uint32_t& aIndex,
+                                      bool aInTextPath,
+                                      bool& aForceStartOfChunk,
+                                      nsTArray<gfxPoint>& aDeltas)
 {
   if (aContent->IsNodeOfType(nsINode::eTEXT)) {
     // We found a text node.
     uint32_t length = static_cast<nsTextNode*>(aContent)->TextLength();
     if (length) {
+      uint32_t end = aIndex + length;
+      if (MOZ_UNLIKELY(end > mPositions.Length())) {
+        MOZ_ASSERT_UNREACHABLE("length of mPositions does not match characters "
+                               "found by iterating content");
+        return false;
+      }
       if (aForceStartOfChunk) {
         // Note this character as starting a new anchored chunk.
         mPositions[aIndex].mStartOfChunk = true;
         aForceStartOfChunk = false;
       }
-      uint32_t end = aIndex + length;
       while (aIndex < end) {
         // Record whether each of these characters should start a new rendered
         // run.  That is always the case for characters on a text path.
@@ -4345,18 +4351,23 @@ SVGTextFrame::ResolvePositions(nsIContent* aContent,
         aIndex++;
       }
     }
-    return aIndex;
+    return true;
   }
 
   // Skip past elements that aren't text content elements.
   if (!IsTextContentElement(aContent)) {
-    return aIndex;
+    return true;
   }
 
   if (aContent->Tag() == nsGkAtoms::textPath) {
     // <textPath> elements are as if they are specified with x="0" y="0", but
     // only if they actually have some text content.
     if (HasTextContent(aContent)) {
+      if (MOZ_UNLIKELY(aIndex >= mPositions.Length())) {
+        MOZ_ASSERT_UNREACHABLE("length of mPositions does not match characters "
+                               "found by iterating content");
+        return false;
+      }
       mPositions[aIndex].mPosition = gfxPoint();
       mPositions[aIndex].mStartOfChunk = true;
     }
@@ -4376,8 +4387,14 @@ SVGTextFrame::ResolvePositions(nsIContent* aContent,
       rotate = &animatedRotate->GetAnimValue();
     }
 
-    uint32_t count = GetTextContentLength(aContent);
     bool percentages = false;
+    uint32_t count = GetTextContentLength(aContent);
+
+    if (MOZ_UNLIKELY(aIndex + count > mPositions.Length())) {
+      MOZ_ASSERT_UNREACHABLE("length of mPositions does not match characters "
+                             "found by iterating content");
+      return false;
+    }
 
     // New text anchoring chunks start at each character assigned a position
     // with x="" or y="", or if we forced one with aForceStartOfChunk due to
@@ -4456,8 +4473,11 @@ SVGTextFrame::ResolvePositions(nsIContent* aContent,
   for (nsIContent* child = aContent->GetFirstChild();
        child;
        child = child->GetNextSibling()) {
-    aIndex = ResolvePositions(child, aIndex, inTextPath, aForceStartOfChunk,
-                              aDeltas);
+    bool ok = ResolvePositionsForNode(child, aIndex, inTextPath,
+                                      aForceStartOfChunk, aDeltas);
+    if (!ok) {
+      return false;
+    }
   }
 
   if (aContent->Tag() == nsGkAtoms::textPath) {
@@ -4465,7 +4485,7 @@ SVGTextFrame::ResolvePositions(nsIContent* aContent,
     aForceStartOfChunk = true;
   }
 
-  return aIndex;
+  return true;
 }
 
 bool
@@ -4501,8 +4521,10 @@ SVGTextFrame::ResolvePositions(nsTArray<gfxPoint>& aDeltas,
 
   // Recurse over the content and fill in character positions as we go.
   bool forceStartOfChunk = false;
-  return ResolvePositions(mContent, 0, aRunPerGlyph,
-                          forceStartOfChunk, aDeltas) != 0;
+  index = 0;
+  bool ok = ResolvePositionsForNode(mContent, index, aRunPerGlyph,
+                                    forceStartOfChunk, aDeltas);
+  return ok && index > 0;
 }
 
 void
@@ -4958,9 +4980,10 @@ SVGTextFrame::DoGlyphPositioning()
   // Get the x, y, dx, dy, rotate values for the subtree.
   nsTArray<gfxPoint> deltas;
   if (!ResolvePositions(deltas, adjustingTextLength)) {
-    // If ResolvePositions returned false, it means that there were some
-    // characters in the DOM but none of them are displayed.  Clear out
-    // mPositions so that we don't attempt to do any painting later.
+    // If ResolvePositions returned false, it means either there were some
+    // characters in the DOM but none of them are displayed, or there was
+    // an error in processing mPositions.  Clear out mPositions so that we don't
+    // attempt to do any painting later.
     mPositions.Clear();
     return;
   }
diff --git a/layout/svg/SVGTextFrame.h b/layout/svg/SVGTextFrame.h
index 48951f7..912af8b 100644
--- a/layout/svg/SVGTextFrame.h
+++ b/layout/svg/SVGTextFrame.h
@@ -505,15 +505,18 @@ private:
    * Recursive helper for ResolvePositions below.
    *
    * @param aContent The current node.
-   * @param aIndex The current character index.
+   * @param aIndex (in/out) The current character index.
    * @param aInTextPath Whether we are currently under a <textPath> element.
-   * @param aForceStartOfChunk Whether the next character we find should start a
-   *   new anchored chunk.
-   * @return The character index we got up to.
+   * @param aForceStartOfChunk (in/out) Whether the next character we find
+   *   should start a new anchored chunk.
+   * @param aDeltas (in/out) Receives the resolved dx/dy values for each
+   *   character.
+   * @return false if we discover that mPositions did not have enough
+   *   elements; true otherwise.
    */
-  uint32_t ResolvePositions(nsIContent* aContent, uint32_t aIndex,
-                            bool aInTextPath, bool& aForceStartOfChunk,
-                            nsTArray<gfxPoint>& aDeltas);
+  bool ResolvePositionsForNode(nsIContent* aContent, uint32_t& aIndex,
+                               bool aInTextPath, bool& aForceStartOfChunk,
+                               nsTArray<gfxPoint>& aDeltas);
 
   /**
    * Initializes mPositions with character position information based on
@@ -521,9 +524,13 @@ private:
    * was not given for that character.  Also fills aDeltas with values based on
    * dx/dy attributes.
    *
+   * @param aDeltas (in/out) Receives the resolved dx/dy values for each
+   *   character.
    * @param aRunPerGlyph Whether mPositions should record that a new run begins
    *   at each glyph.
-   * @return True if we recorded any positions.
+   * @return false if we did not record any positions (due to having no
+   *   displayed characters) or if we discover that mPositions did not have
+   *   enough elements; true otherwise.
    */
   bool ResolvePositions(nsTArray<gfxPoint>& aDeltas, bool aRunPerGlyph);
 
-- 
2.2.1


A gnu/packages/patches/icecat-CVE-2015-2710-pt2.patch => gnu/packages/patches/icecat-CVE-2015-2710-pt2.patch +64 -0
@@ 0,0 1,64 @@
From f7c0070831e72735c43beb426ac0c2ce33403f4f Mon Sep 17 00:00:00 2001
From: Cameron McCormack <cam@mcc.id.au>
Date: Mon, 6 Apr 2015 09:12:06 -0400
Subject: [PATCH] Bug 1149542 - Part 2: Track undisplayed characters before
 empty text frames properly. r=dholbert, a=sledru

---
 layout/svg/SVGTextFrame.cpp | 29 ++++++++++++++++-------------
 1 file changed, 16 insertions(+), 13 deletions(-)

diff --git a/layout/svg/SVGTextFrame.cpp b/layout/svg/SVGTextFrame.cpp
index 45327881..9d331b8 100644
--- a/layout/svg/SVGTextFrame.cpp
+++ b/layout/svg/SVGTextFrame.cpp
@@ -290,22 +290,25 @@ GetNonEmptyTextFrameAndNode(nsIFrame* aFrame,
                             nsTextNode*& aTextNode)
 {
   nsTextFrame* text = do_QueryFrame(aFrame);
-  if (!text) {
-    return false;
-  }
+  bool isNonEmptyTextFrame = text && text->GetContentLength() != 0;
 
-  nsIContent* content = text->GetContent();
-  NS_ASSERTION(content && content->IsNodeOfType(nsINode::eTEXT),
-               "unexpected content type for nsTextFrame");
+  if (isNonEmptyTextFrame) {
+    nsIContent* content = text->GetContent();
+    NS_ASSERTION(content && content->IsNodeOfType(nsINode::eTEXT),
+                 "unexpected content type for nsTextFrame");
 
-  nsTextNode* node = static_cast<nsTextNode*>(content);
-  if (node->TextLength() == 0) {
-    return false;
+    nsTextNode* node = static_cast<nsTextNode*>(content);
+    MOZ_ASSERT(node->TextLength() != 0,
+               "frame's GetContentLength() should be 0 if the text node "
+               "has no content");
+
+    aTextFrame = text;
+    aTextNode = node;
   }
 
-  aTextFrame = text;
-  aTextNode = node;
-  return true;
+  MOZ_ASSERT(IsNonEmptyTextFrame(aFrame) == isNonEmptyTextFrame,
+             "our logic should agree with IsNonEmptyTextFrame");
+  return isNonEmptyTextFrame;
 }
 
 /**
@@ -1298,7 +1301,7 @@ GetUndisplayedCharactersBeforeFrame(nsTextFrame* aFrame)
 /**
  * Traverses the nsTextFrames for an SVGTextFrame and records a
  * TextNodeCorrespondenceProperty on each for the number of undisplayed DOM
- * characters between each frame.  This is done by iterating simultaenously
+ * characters between each frame.  This is done by iterating simultaneously
  * over the nsTextNodes and nsTextFrames and noting when nsTextNodes (or
  * parts of them) are skipped when finding the next nsTextFrame.
  */
-- 
2.2.1


A gnu/packages/patches/icecat-CVE-2015-2710-pt3.patch => gnu/packages/patches/icecat-CVE-2015-2710-pt3.patch +50 -0
@@ 0,0 1,50 @@
From 2cda46e6158a459b56b392c8e389b055fdf740ca Mon Sep 17 00:00:00 2001
From: Ryan VanderMeulen <ryanvm@gmail.com>
Date: Mon, 6 Apr 2015 22:59:41 -0400
Subject: [PATCH] Bug 1149542 - Replace MOZ_ASSERT_UNREACHABLE with MOZ_ASSERT.
 r=dholbert, a=bustage

---
 layout/svg/SVGTextFrame.cpp | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/layout/svg/SVGTextFrame.cpp b/layout/svg/SVGTextFrame.cpp
index 9d331b8..e7b7275 100644
--- a/layout/svg/SVGTextFrame.cpp
+++ b/layout/svg/SVGTextFrame.cpp
@@ -4333,8 +4333,8 @@ SVGTextFrame::ResolvePositionsForNode(nsIContent* aContent,
     if (length) {
       uint32_t end = aIndex + length;
       if (MOZ_UNLIKELY(end > mPositions.Length())) {
-        MOZ_ASSERT_UNREACHABLE("length of mPositions does not match characters "
-                               "found by iterating content");
+        MOZ_ASSERT(false, "length of mPositions does not match characters "
+                          "found by iterating content");
         return false;
       }
       if (aForceStartOfChunk) {
@@ -4367,8 +4367,8 @@ SVGTextFrame::ResolvePositionsForNode(nsIContent* aContent,
     // only if they actually have some text content.
     if (HasTextContent(aContent)) {
       if (MOZ_UNLIKELY(aIndex >= mPositions.Length())) {
-        MOZ_ASSERT_UNREACHABLE("length of mPositions does not match characters "
-                               "found by iterating content");
+        MOZ_ASSERT(false, "length of mPositions does not match characters "
+                          "found by iterating content");
         return false;
       }
       mPositions[aIndex].mPosition = gfxPoint();
@@ -4394,8 +4394,8 @@ SVGTextFrame::ResolvePositionsForNode(nsIContent* aContent,
     uint32_t count = GetTextContentLength(aContent);
 
     if (MOZ_UNLIKELY(aIndex + count > mPositions.Length())) {
-      MOZ_ASSERT_UNREACHABLE("length of mPositions does not match characters "
-                             "found by iterating content");
+      MOZ_ASSERT(false, "length of mPositions does not match characters "
+                        "found by iterating content");
       return false;
     }
 
-- 
2.2.1


A gnu/packages/patches/icecat-CVE-2015-2713-pt1.patch => gnu/packages/patches/icecat-CVE-2015-2713-pt1.patch +102 -0
@@ 0,0 1,102 @@
From 2b1c90da3e849e1c9d7457658290aa8eb01d0fa9 Mon Sep 17 00:00:00 2001
From: Mats Palmgren <mats@mozilla.com>
Date: Thu, 16 Apr 2015 09:04:19 +0000
Subject: [PATCH] Bug 1153478 - Part 1: Add nsInlineFrame::StealFrame and make
 it deal with being called on the wrong parent for aChild (due to lazy
 reparenting). r=roc, a=sledru

---
 layout/generic/nsContainerFrame.cpp |  7 +++----
 layout/generic/nsInlineFrame.cpp    | 39 +++++++++++++++++++++++++++++++++++++
 layout/generic/nsInlineFrame.h      |  4 +++-
 3 files changed, 45 insertions(+), 5 deletions(-)

diff --git a/layout/generic/nsContainerFrame.cpp b/layout/generic/nsContainerFrame.cpp
index 3ffcba7..34878af 100644
--- a/layout/generic/nsContainerFrame.cpp
+++ b/layout/generic/nsContainerFrame.cpp
@@ -172,13 +172,12 @@ nsContainerFrame::RemoveFrame(ChildListID aListID,
   nsIPresShell* shell = PresContext()->PresShell();
   nsContainerFrame* lastParent = nullptr;
   while (aOldFrame) {
-    //XXXfr probably should use StealFrame here. I'm not sure if we need to
-    //      check the overflow lists atm, but we'll need a prescontext lookup
-    //      for overflow containers once we can split abspos elements with
-    //      inline containing blocks.
     nsIFrame* oldFrameNextContinuation = aOldFrame->GetNextContinuation();
     nsContainerFrame* parent =
       static_cast<nsContainerFrame*>(aOldFrame->GetParent());
+    // Please note that 'parent' may not actually be where 'aOldFrame' lives.
+    // We really MUST use StealFrame() and nothing else here.
+    // @see nsInlineFrame::StealFrame for details.
     parent->StealFrame(aOldFrame, true);
     aOldFrame->Destroy();
     aOldFrame = oldFrameNextContinuation;
diff --git a/layout/generic/nsInlineFrame.cpp b/layout/generic/nsInlineFrame.cpp
index 526041e..a392a15 100644
--- a/layout/generic/nsInlineFrame.cpp
+++ b/layout/generic/nsInlineFrame.cpp
@@ -172,6 +172,45 @@ nsInlineFrame::PeekOffsetCharacter(bool aForward, int32_t* aOffset,
   return CONTINUE;
 }
 
+nsresult
+nsInlineFrame::StealFrame(nsIFrame* aChild,
+                          bool      aForceNormal)
+{
+  if (aChild->HasAnyStateBits(NS_FRAME_IS_OVERFLOW_CONTAINER) &&
+      !aForceNormal) {
+    return nsContainerFrame::StealFrame(aChild, aForceNormal);
+  }
+
+  nsInlineFrame* parent = this;
+  bool removed = false;
+  do {
+    removed = parent->mFrames.StartRemoveFrame(aChild);
+    if (removed) {
+      break;
+    }
+
+    // We didn't find the child in our principal child list.
+    // Maybe it's on the overflow list?
+    nsFrameList* frameList = parent->GetOverflowFrames();
+    if (frameList) {
+      removed = frameList->ContinueRemoveFrame(aChild);
+      if (frameList->IsEmpty()) {
+        parent->DestroyOverflowList();
+      }
+      if (removed) {
+        break;
+      }
+    }
+
+    // Due to our "lazy reparenting" optimization 'aChild' might not actually
+    // be on any of our child lists, but instead in one of our next-in-flows.
+    parent = static_cast<nsInlineFrame*>(parent->GetNextInFlow());
+  } while (parent);
+
+  MOZ_ASSERT(removed, "nsInlineFrame::StealFrame: can't find aChild");
+  return removed ? NS_OK : NS_ERROR_UNEXPECTED;
+}
+
 void
 nsInlineFrame::BuildDisplayList(nsDisplayListBuilder*   aBuilder,
                                 const nsRect&           aDirtyRect,
diff --git a/layout/generic/nsInlineFrame.h b/layout/generic/nsInlineFrame.h
index 1a9899e..3e49241 100644
--- a/layout/generic/nsInlineFrame.h
+++ b/layout/generic/nsInlineFrame.h
@@ -61,7 +61,9 @@ public:
 
   virtual FrameSearchResult PeekOffsetCharacter(bool aForward, int32_t* aOffset,
                                      bool aRespectClusters = true) MOZ_OVERRIDE;
-  
+
+  virtual nsresult StealFrame(nsIFrame* aChild, bool aForceNormal) MOZ_OVERRIDE;
+
   // nsIHTMLReflow overrides
   virtual void AddInlineMinWidth(nsRenderingContext *aRenderingContext,
                                  InlineMinWidthData *aData) MOZ_OVERRIDE;
-- 
2.2.1


A gnu/packages/patches/icecat-CVE-2015-2713-pt2.patch => gnu/packages/patches/icecat-CVE-2015-2713-pt2.patch +47 -0
@@ 0,0 1,47 @@
From d84ed2990dd2304fef752213f1908280ff24d77c Mon Sep 17 00:00:00 2001
From: Mats Palmgren <mats@mozilla.com>
Date: Thu, 16 Apr 2015 09:04:19 +0000
Subject: [PATCH] Bug 1153478 - Part 2: Remove useless assertions. r=roc,
 a=sledru

---
 layout/generic/nsContainerFrame.cpp | 1 -
 layout/generic/nsInlineFrame.cpp    | 3 ---
 2 files changed, 4 deletions(-)

diff --git a/layout/generic/nsContainerFrame.cpp b/layout/generic/nsContainerFrame.cpp
index 34878af..b95bddd 100644
--- a/layout/generic/nsContainerFrame.cpp
+++ b/layout/generic/nsContainerFrame.cpp
@@ -1516,7 +1516,6 @@ nsContainerFrame::DrainSelfOverflowList()
 {
   AutoFrameListPtr overflowFrames(PresContext(), StealOverflowFrames());
   if (overflowFrames) {
-    NS_ASSERTION(mFrames.NotEmpty(), "overflow list w/o frames");
     mFrames.AppendFrames(nullptr, *overflowFrames);
     return true;
   }
diff --git a/layout/generic/nsInlineFrame.cpp b/layout/generic/nsInlineFrame.cpp
index a392a15..e0922bb 100644
--- a/layout/generic/nsInlineFrame.cpp
+++ b/layout/generic/nsInlineFrame.cpp
@@ -449,7 +449,6 @@ nsInlineFrame::DrainSelfOverflowListInternal(DrainFlags aFlags,
 {
   AutoFrameListPtr overflowFrames(PresContext(), StealOverflowFrames());
   if (overflowFrames) {
-    NS_ASSERTION(mFrames.NotEmpty(), "overflow list w/o frames");
     // The frames on our own overflowlist may have been pushed by a
     // previous lazilySetParentPointer Reflow so we need to ensure the
     // correct parent pointer.  This is sometimes skipped by Reflow.
@@ -1157,8 +1156,6 @@ nsFirstLineFrame::DrainSelfOverflowList()
 {
   AutoFrameListPtr overflowFrames(PresContext(), StealOverflowFrames());
   if (overflowFrames) {
-    NS_ASSERTION(mFrames.NotEmpty(), "overflow list w/o frames");
-
     bool result = !overflowFrames->IsEmpty();
     const nsFrameList::Slice& newFrames =
       mFrames.AppendFrames(nullptr, *overflowFrames);
-- 
2.2.1


A gnu/packages/patches/icecat-CVE-2015-2716.patch => gnu/packages/patches/icecat-CVE-2015-2716.patch +62 -0
@@ 0,0 1,62 @@
From 9dcb4563847cb6e2a8112dca03d2684907f96313 Mon Sep 17 00:00:00 2001
From: Eric Rahm <erahm@mozilla.com>
Date: Fri, 10 Apr 2015 15:50:23 -0700
Subject: [PATCH] Bug 1140537 - Sanity check size calculations. r=peterv,
 a=abillings

---
 parser/expat/lib/xmlparse.c | 23 +++++++++++++++++++++--
 1 file changed, 21 insertions(+), 2 deletions(-)

diff --git a/parser/expat/lib/xmlparse.c b/parser/expat/lib/xmlparse.c
index 70acf1a..436b735 100644
--- a/parser/expat/lib/xmlparse.c
+++ b/parser/expat/lib/xmlparse.c
@@ -1651,6 +1651,12 @@ XML_ParseBuffer(XML_Parser parser, int len, int isFinal)
 void * XMLCALL
 XML_GetBuffer(XML_Parser parser, int len)
 {
+/* BEGIN MOZILLA CHANGE (sanity check len) */
+  if (len < 0) {
+    errorCode = XML_ERROR_NO_MEMORY;
+    return NULL;
+  }
+/* END MOZILLA CHANGE */
   switch (ps_parsing) {
   case XML_SUSPENDED:
     errorCode = XML_ERROR_SUSPENDED;
@@ -1662,8 +1668,13 @@ XML_GetBuffer(XML_Parser parser, int len)
   }
 
   if (len > bufferLim - bufferEnd) {
-    /* FIXME avoid integer overflow */
     int neededSize = len + (int)(bufferEnd - bufferPtr);
+/* BEGIN MOZILLA CHANGE (sanity check neededSize) */
+    if (neededSize < 0) {
+      errorCode = XML_ERROR_NO_MEMORY;
+      return NULL;
+    }
+/* END MOZILLA CHANGE */
 #ifdef XML_CONTEXT_BYTES
     int keep = (int)(bufferPtr - buffer);
 
@@ -1692,7 +1703,15 @@ XML_GetBuffer(XML_Parser parser, int len)
         bufferSize = INIT_BUFFER_SIZE;
       do {
         bufferSize *= 2;
-      } while (bufferSize < neededSize);
+/* BEGIN MOZILLA CHANGE (prevent infinite loop on overflow) */
+      } while (bufferSize < neededSize && bufferSize > 0);
+/* END MOZILLA CHANGE */
+/* BEGIN MOZILLA CHANGE (sanity check bufferSize) */
+      if (bufferSize <= 0) {
+        errorCode = XML_ERROR_NO_MEMORY;
+        return NULL;
+      }
+/* END MOZILLA CHANGE */
       newBuf = (char *)MALLOC(bufferSize);
       if (newBuf == 0) {
         errorCode = XML_ERROR_NO_MEMORY;
-- 
2.2.1