aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gnu/local.mk14
-rw-r--r--gnu/packages/gnuzilla.scm16
-rw-r--r--gnu/packages/patches/icecat-CVE-2016-2818-pt1.patch62
-rw-r--r--gnu/packages/patches/icecat-CVE-2016-2818-pt2.patch29
-rw-r--r--gnu/packages/patches/icecat-CVE-2016-2818-pt3.patch18
-rw-r--r--gnu/packages/patches/icecat-CVE-2016-2818-pt4.patch61
-rw-r--r--gnu/packages/patches/icecat-CVE-2016-2818-pt5.patch266
-rw-r--r--gnu/packages/patches/icecat-CVE-2016-2818-pt6.patch17
-rw-r--r--gnu/packages/patches/icecat-CVE-2016-2818-pt7.patch33
-rw-r--r--gnu/packages/patches/icecat-CVE-2016-2818-pt8.patch267
-rw-r--r--gnu/packages/patches/icecat-CVE-2016-2818-pt9.patch188
-rw-r--r--gnu/packages/patches/icecat-CVE-2016-2819.patch102
-rw-r--r--gnu/packages/patches/icecat-CVE-2016-2821.patch16
-rw-r--r--gnu/packages/patches/icecat-CVE-2016-2824.patch85
-rw-r--r--gnu/packages/patches/icecat-CVE-2016-2828.patch185
-rw-r--r--gnu/packages/patches/icecat-CVE-2016-2831.patch120
16 files changed, 1478 insertions, 1 deletions
diff --git a/gnu/local.mk b/gnu/local.mk
index cc236a7d16..8915c46cdd 100644
--- a/gnu/local.mk
+++ b/gnu/local.mk
@@ -549,6 +549,20 @@ dist_patch_DATA = \
%D%/packages/patches/hypre-doc-tables.patch \
%D%/packages/patches/hypre-ldflags.patch \
%D%/packages/patches/icecat-avoid-bundled-includes.patch \
+ %D%/packages/patches/icecat-CVE-2016-2818-pt1.patch \
+ %D%/packages/patches/icecat-CVE-2016-2818-pt2.patch \
+ %D%/packages/patches/icecat-CVE-2016-2818-pt3.patch \
+ %D%/packages/patches/icecat-CVE-2016-2818-pt4.patch \
+ %D%/packages/patches/icecat-CVE-2016-2818-pt5.patch \
+ %D%/packages/patches/icecat-CVE-2016-2818-pt6.patch \
+ %D%/packages/patches/icecat-CVE-2016-2818-pt7.patch \
+ %D%/packages/patches/icecat-CVE-2016-2818-pt8.patch \
+ %D%/packages/patches/icecat-CVE-2016-2818-pt9.patch \
+ %D%/packages/patches/icecat-CVE-2016-2819.patch \
+ %D%/packages/patches/icecat-CVE-2016-2821.patch \
+ %D%/packages/patches/icecat-CVE-2016-2824.patch \
+ %D%/packages/patches/icecat-CVE-2016-2828.patch \
+ %D%/packages/patches/icecat-CVE-2016-2831.patch \
%D%/packages/patches/icedtea-remove-overrides.patch \
%D%/packages/patches/icu4c-CVE-2014-6585.patch \
%D%/packages/patches/icu4c-CVE-2015-1270.patch \
diff --git a/gnu/packages/gnuzilla.scm b/gnu/packages/gnuzilla.scm
index 4ffa3ac165..46342ee247 100644
--- a/gnu/packages/gnuzilla.scm
+++ b/gnu/packages/gnuzilla.scm
@@ -298,7 +298,21 @@ standards.")
(base32
"0v4k47ziqsyfksv9sn4v1xvk4q414rc883hb1qzld63grj2nxxwp"))
(patches (search-patches
- "icecat-avoid-bundled-includes.patch"))
+ "icecat-avoid-bundled-includes.patch"
+ "icecat-CVE-2016-2818-pt1.patch"
+ "icecat-CVE-2016-2818-pt2.patch"
+ "icecat-CVE-2016-2818-pt3.patch"
+ "icecat-CVE-2016-2818-pt4.patch"
+ "icecat-CVE-2016-2818-pt5.patch"
+ "icecat-CVE-2016-2818-pt6.patch"
+ "icecat-CVE-2016-2818-pt7.patch"
+ "icecat-CVE-2016-2818-pt8.patch"
+ "icecat-CVE-2016-2818-pt9.patch"
+ "icecat-CVE-2016-2819.patch"
+ "icecat-CVE-2016-2821.patch"
+ "icecat-CVE-2016-2824.patch"
+ "icecat-CVE-2016-2828.patch"
+ "icecat-CVE-2016-2831.patch"))
(modules '((guix build utils)))
(snippet
'(begin
diff --git a/gnu/packages/patches/icecat-CVE-2016-2818-pt1.patch b/gnu/packages/patches/icecat-CVE-2016-2818-pt1.patch
new file mode 100644
index 0000000000..57bc45f3c2
--- /dev/null
+++ b/gnu/packages/patches/icecat-CVE-2016-2818-pt1.patch
@@ -0,0 +1,62 @@
+ changeset: 312039:4290826b078c
+ user: Timothy Nikkel <tnikkel@gmail.com>
+ Date: Fri May 13 06:09:38 2016 +0200
+ summary: Bug 1261230. r=mats, a=ritu
+
+diff -r 45a59425b498 -r 4290826b078c layout/generic/nsSubDocumentFrame.cpp
+--- a/layout/generic/nsSubDocumentFrame.cpp Tue May 10 14:12:20 2016 +0200
++++ b/layout/generic/nsSubDocumentFrame.cpp Fri May 13 06:09:38 2016 +0200
+@@ -132,6 +132,7 @@
+ nsCOMPtr<nsIDocument> oldContainerDoc;
+ nsView* detachedViews =
+ frameloader->GetDetachedSubdocView(getter_AddRefs(oldContainerDoc));
++ frameloader->SetDetachedSubdocView(nullptr, nullptr);
+ if (detachedViews) {
+ if (oldContainerDoc == aContent->OwnerDoc()) {
+ // Restore stashed presentation.
+@@ -142,7 +143,6 @@
+ frameloader->Hide();
+ }
+ }
+- frameloader->SetDetachedSubdocView(nullptr, nullptr);
+ }
+
+ nsContentUtils::AddScriptRunner(new AsyncFrameInit(this));
+@@ -936,13 +936,16 @@
+ if (!mPresShell->IsDestroying()) {
+ mPresShell->FlushPendingNotifications(Flush_Frames);
+ }
++
++ // Either the frame has been constructed by now, or it never will be,
++ // either way we want to clear the stashed views.
++ mFrameLoader->SetDetachedSubdocView(nullptr, nullptr);
++
+ nsSubDocumentFrame* frame = do_QueryFrame(mFrameElement->GetPrimaryFrame());
+ if ((!frame && mHideViewerIfFrameless) ||
+ mPresShell->IsDestroying()) {
+ // Either the frame element has no nsIFrame or the presshell is being
+- // destroyed. Hide the nsFrameLoader, which destroys the presentation,
+- // and clear our references to the stashed presentation.
+- mFrameLoader->SetDetachedSubdocView(nullptr, nullptr);
++ // destroyed. Hide the nsFrameLoader, which destroys the presentation.
+ mFrameLoader->Hide();
+ }
+ return NS_OK;
+@@ -968,7 +971,7 @@
+ // Detach the subdocument's views and stash them in the frame loader.
+ // We can then reattach them if we're being reframed (for example if
+ // the frame has been made position:fixed).
+- nsFrameLoader* frameloader = FrameLoader();
++ RefPtr<nsFrameLoader> frameloader = FrameLoader();
+ if (frameloader) {
+ nsView* detachedViews = ::BeginSwapDocShellsForViews(mInnerView->GetFirstChild());
+ frameloader->SetDetachedSubdocView(detachedViews, mContent->OwnerDoc());
+@@ -977,7 +980,7 @@
+ // safely determine whether the frame is being reframed or destroyed.
+ nsContentUtils::AddScriptRunner(
+ new nsHideViewer(mContent,
+- mFrameLoader,
++ frameloader,
+ PresContext()->PresShell(),
+ (mDidCreateDoc || mCallingShow)));
+ }
diff --git a/gnu/packages/patches/icecat-CVE-2016-2818-pt2.patch b/gnu/packages/patches/icecat-CVE-2016-2818-pt2.patch
new file mode 100644
index 0000000000..843e2eb244
--- /dev/null
+++ b/gnu/packages/patches/icecat-CVE-2016-2818-pt2.patch
@@ -0,0 +1,29 @@
+ changeset: 312044:09418166fd77
+ user: Jon Coppeard <jcoppeard@mozilla.com>
+ Date: Wed May 11 10:14:45 2016 +0100
+ summary: Bug 1264575 - Add missing pre-barrier in Ion r=jandem a=ritu
+
+diff -r 9cc65cca1f71 -r 09418166fd77 js/src/jit-test/tests/self-hosting/bug1264575.js
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ b/js/src/jit-test/tests/self-hosting/bug1264575.js Wed May 11 10:14:45 2016 +0100
+@@ -0,0 +1,7 @@
++function f(x, [y]) {}
++f(0, []);
++// jsfunfuzz-generated
++let i = 0;
++for (var z of [0, 0, 0]) {
++ verifyprebarriers();
++}
+diff -r 9cc65cca1f71 -r 09418166fd77 js/src/jit/MCallOptimize.cpp
+--- a/js/src/jit/MCallOptimize.cpp Mon May 16 15:11:24 2016 -0400
++++ b/js/src/jit/MCallOptimize.cpp Wed May 11 10:14:45 2016 +0100
+@@ -2263,7 +2263,8 @@
+
+ callInfo.setImplicitlyUsedUnchecked();
+
+- MStoreFixedSlot* store = MStoreFixedSlot::New(alloc(), callInfo.getArg(0), slot, callInfo.getArg(2));
++ MStoreFixedSlot* store =
++ MStoreFixedSlot::NewBarriered(alloc(), callInfo.getArg(0), slot, callInfo.getArg(2));
+ current->add(store);
+ current->push(store);
+
diff --git a/gnu/packages/patches/icecat-CVE-2016-2818-pt3.patch b/gnu/packages/patches/icecat-CVE-2016-2818-pt3.patch
new file mode 100644
index 0000000000..fab003158c
--- /dev/null
+++ b/gnu/packages/patches/icecat-CVE-2016-2818-pt3.patch
@@ -0,0 +1,18 @@
+ changeset: 312051:9ec3d076fbee
+ parents: 312049:e0a272d5e162
+ user: Eric Faust <efaustbmo@gmail.com>
+ Date: Wed May 04 15:54:43 2016 -0700
+ summary: Bug 1269729 - Handle another OOM case on ARM. (r=jolesen) a=ritu
+
+diff -r e0a272d5e162 -r 9ec3d076fbee js/src/jit/arm/CodeGenerator-arm.cpp
+--- a/js/src/jit/arm/CodeGenerator-arm.cpp Tue May 17 08:26:37 2016 -0400
++++ b/js/src/jit/arm/CodeGenerator-arm.cpp Wed May 04 15:54:43 2016 -0700
+@@ -1116,7 +1116,7 @@
+ for (int32_t i = 0; i < cases; i++) {
+ CodeLabel cl;
+ masm.writeCodePointer(cl.dest());
+- ool->addCodeLabel(cl);
++ masm.propagateOOM(ool->addCodeLabel(cl));
+ }
+ addOutOfLineCode(ool, mir);
+ }
diff --git a/gnu/packages/patches/icecat-CVE-2016-2818-pt4.patch b/gnu/packages/patches/icecat-CVE-2016-2818-pt4.patch
new file mode 100644
index 0000000000..0973203e0f
--- /dev/null
+++ b/gnu/packages/patches/icecat-CVE-2016-2818-pt4.patch
@@ -0,0 +1,61 @@
+ changeset: 312055:b74f1ab939d2
+ user: Olli Pettay <Olli.Pettay@helsinki.fi>
+ Date: Mon May 16 21:42:24 2016 +0300
+ summary: Bug 1273202, make sure to not keep objects alive too long because of some useless event dispatching, r=jwatt a=ritu
+
+diff -r 072992bf176d -r b74f1ab939d2 dom/html/HTMLInputElement.cpp
+--- a/dom/html/HTMLInputElement.cpp Sun May 15 17:03:06 2016 +0300
++++ b/dom/html/HTMLInputElement.cpp Mon May 16 21:42:24 2016 +0300
+@@ -1168,7 +1168,7 @@
+ mFileList->Disconnect();
+ }
+ if (mNumberControlSpinnerIsSpinning) {
+- StopNumberControlSpinnerSpin();
++ StopNumberControlSpinnerSpin(eDisallowDispatchingEvents);
+ }
+ DestroyImageLoadingContent();
+ FreeData();
+@@ -3721,7 +3721,7 @@
+ }
+
+ void
+-HTMLInputElement::StopNumberControlSpinnerSpin()
++HTMLInputElement::StopNumberControlSpinnerSpin(SpinnerStopState aState)
+ {
+ if (mNumberControlSpinnerIsSpinning) {
+ if (nsIPresShell::GetCapturingContent() == this) {
+@@ -3732,11 +3732,16 @@
+
+ mNumberControlSpinnerIsSpinning = false;
+
+- FireChangeEventIfNeeded();
++ if (aState == eAllowDispatchingEvents) {
++ FireChangeEventIfNeeded();
++ }
+
+ nsNumberControlFrame* numberControlFrame =
+ do_QueryFrame(GetPrimaryFrame());
+ if (numberControlFrame) {
++ MOZ_ASSERT(aState == eAllowDispatchingEvents,
++ "Shouldn't have primary frame for the element when we're not "
++ "allowed to dispatch events to it anymore.");
+ numberControlFrame->SpinnerStateChanged();
+ }
+ }
+diff -r 072992bf176d -r b74f1ab939d2 dom/html/HTMLInputElement.h
+--- a/dom/html/HTMLInputElement.h Sun May 15 17:03:06 2016 +0300
++++ b/dom/html/HTMLInputElement.h Mon May 16 21:42:24 2016 +0300
+@@ -721,7 +721,12 @@
+ HTMLInputElement* GetOwnerNumberControl();
+
+ void StartNumberControlSpinnerSpin();
+- void StopNumberControlSpinnerSpin();
++ enum SpinnerStopState {
++ eAllowDispatchingEvents,
++ eDisallowDispatchingEvents
++ };
++ void StopNumberControlSpinnerSpin(SpinnerStopState aState =
++ eAllowDispatchingEvents);
+ void StepNumberControlForUserEvent(int32_t aDirection);
+
+ /**
diff --git a/gnu/packages/patches/icecat-CVE-2016-2818-pt5.patch b/gnu/packages/patches/icecat-CVE-2016-2818-pt5.patch
new file mode 100644
index 0000000000..cd98d0b28b
--- /dev/null
+++ b/gnu/packages/patches/icecat-CVE-2016-2818-pt5.patch
@@ -0,0 +1,266 @@
+ changeset: 312063:88bea96c802a
+ user: Andrea Marchesini <amarchesini@mozilla.com>
+ Date: Tue May 10 10:52:19 2016 +0200
+ summary: Bug 1267130 - Improve the URL segment calculation, r=valentin a=ritu
+
+diff -r 28dcecced055 -r 88bea96c802a netwerk/base/nsStandardURL.cpp
+--- a/netwerk/base/nsStandardURL.cpp Wed May 18 11:55:29 2016 +1200
++++ b/netwerk/base/nsStandardURL.cpp Tue May 10 10:52:19 2016 +0200
+@@ -475,19 +475,28 @@
+ }
+
+ uint32_t
+-nsStandardURL::AppendSegmentToBuf(char *buf, uint32_t i, const char *str, URLSegment &seg, const nsCString *escapedStr, bool useEscaped)
++nsStandardURL::AppendSegmentToBuf(char *buf, uint32_t i, const char *str,
++ const URLSegment &segInput, URLSegment &segOutput,
++ const nsCString *escapedStr,
++ bool useEscaped, int32_t *diff)
+ {
+- if (seg.mLen > 0) {
++ MOZ_ASSERT(segInput.mLen == segOutput.mLen);
++
++ if (diff) *diff = 0;
++
++ if (segInput.mLen > 0) {
+ if (useEscaped) {
+- seg.mLen = escapedStr->Length();
+- memcpy(buf + i, escapedStr->get(), seg.mLen);
++ MOZ_ASSERT(diff);
++ segOutput.mLen = escapedStr->Length();
++ *diff = segOutput.mLen - segInput.mLen;
++ memcpy(buf + i, escapedStr->get(), segOutput.mLen);
++ } else {
++ memcpy(buf + i, str + segInput.mPos, segInput.mLen);
+ }
+- else
+- memcpy(buf + i, str + seg.mPos, seg.mLen);
+- seg.mPos = i;
+- i += seg.mLen;
++ segOutput.mPos = i;
++ i += segOutput.mLen;
+ } else {
+- seg.mPos = i;
++ segOutput.mPos = i;
+ }
+ return i;
+ }
+@@ -598,6 +607,20 @@
+ }
+ }
+
++ // We must take a copy of every single segment because they are pointing to
++ // the |spec| while we are changing their value, in case we must use
++ // encoded strings.
++ URLSegment username(mUsername);
++ URLSegment password(mPassword);
++ URLSegment host(mHost);
++ URLSegment path(mPath);
++ URLSegment filepath(mFilepath);
++ URLSegment directory(mDirectory);
++ URLSegment basename(mBasename);
++ URLSegment extension(mExtension);
++ URLSegment query(mQuery);
++ URLSegment ref(mRef);
++
+ //
+ // generate the normalized URL string
+ //
+@@ -607,9 +630,10 @@
+ char *buf;
+ mSpec.BeginWriting(buf);
+ uint32_t i = 0;
++ int32_t diff = 0;
+
+ if (mScheme.mLen > 0) {
+- i = AppendSegmentToBuf(buf, i, spec, mScheme);
++ i = AppendSegmentToBuf(buf, i, spec, mScheme, mScheme);
+ net_ToLowerCase(buf + mScheme.mPos, mScheme.mLen);
+ i = AppendToBuf(buf, i, "://", 3);
+ }
+@@ -619,15 +643,22 @@
+
+ // append authority
+ if (mUsername.mLen > 0) {
+- i = AppendSegmentToBuf(buf, i, spec, mUsername, &encUsername, useEncUsername);
+- if (mPassword.mLen >= 0) {
++ i = AppendSegmentToBuf(buf, i, spec, username, mUsername,
++ &encUsername, useEncUsername, &diff);
++ ShiftFromPassword(diff);
++ if (password.mLen >= 0) {
+ buf[i++] = ':';
+- i = AppendSegmentToBuf(buf, i, spec, mPassword, &encPassword, useEncPassword);
++ i = AppendSegmentToBuf(buf, i, spec, password, mPassword,
++ &encPassword, useEncPassword, &diff);
++ ShiftFromHost(diff);
+ }
+ buf[i++] = '@';
+ }
+- if (mHost.mLen > 0) {
+- i = AppendSegmentToBuf(buf, i, spec, mHost, &encHost, useEncHost);
++ if (host.mLen > 0) {
++ i = AppendSegmentToBuf(buf, i, spec, host, mHost, &encHost, useEncHost,
++ &diff);
++ ShiftFromPath(diff);
++
+ net_ToLowerCase(buf + mHost.mPos, mHost.mLen);
+ MOZ_ASSERT(mPort >= -1, "Invalid negative mPort");
+ if (mPort != -1 && mPort != mDefaultPort) {
+@@ -652,21 +683,23 @@
+ }
+ else {
+ uint32_t leadingSlash = 0;
+- if (spec[mPath.mPos] != '/') {
++ if (spec[path.mPos] != '/') {
+ LOG(("adding leading slash to path\n"));
+ leadingSlash = 1;
+ buf[i++] = '/';
+ // basename must exist, even if empty (bugs 113508, 429347)
+ if (mBasename.mLen == -1) {
+- mBasename.mPos = i;
+- mBasename.mLen = 0;
++ mBasename.mPos = basename.mPos = i;
++ mBasename.mLen = basename.mLen = 0;
+ }
+ }
+
+ // record corrected (file)path starting position
+ mPath.mPos = mFilepath.mPos = i - leadingSlash;
+
+- i = AppendSegmentToBuf(buf, i, spec, mDirectory, &encDirectory, useEncDirectory);
++ i = AppendSegmentToBuf(buf, i, spec, directory, mDirectory,
++ &encDirectory, useEncDirectory, &diff);
++ ShiftFromBasename(diff);
+
+ // the directory must end with a '/'
+ if (buf[i-1] != '/') {
+@@ -674,7 +707,9 @@
+ mDirectory.mLen++;
+ }
+
+- i = AppendSegmentToBuf(buf, i, spec, mBasename, &encBasename, useEncBasename);
++ i = AppendSegmentToBuf(buf, i, spec, basename, mBasename,
++ &encBasename, useEncBasename, &diff);
++ ShiftFromExtension(diff);
+
+ // make corrections to directory segment if leadingSlash
+ if (leadingSlash) {
+@@ -687,18 +722,24 @@
+
+ if (mExtension.mLen >= 0) {
+ buf[i++] = '.';
+- i = AppendSegmentToBuf(buf, i, spec, mExtension, &encExtension, useEncExtension);
++ i = AppendSegmentToBuf(buf, i, spec, extension, mExtension,
++ &encExtension, useEncExtension, &diff);
++ ShiftFromQuery(diff);
+ }
+ // calculate corrected filepath length
+ mFilepath.mLen = i - mFilepath.mPos;
+
+ if (mQuery.mLen >= 0) {
+ buf[i++] = '?';
+- i = AppendSegmentToBuf(buf, i, spec, mQuery, &encQuery, useEncQuery);
++ i = AppendSegmentToBuf(buf, i, spec, query, mQuery,
++ &encQuery, useEncQuery,
++ &diff);
++ ShiftFromRef(diff);
+ }
+ if (mRef.mLen >= 0) {
+ buf[i++] = '#';
+- i = AppendSegmentToBuf(buf, i, spec, mRef, &encRef, useEncRef);
++ i = AppendSegmentToBuf(buf, i, spec, ref, mRef, &encRef, useEncRef,
++ &diff);
+ }
+ // calculate corrected path length
+ mPath.mLen = i - mPath.mPos;
+@@ -953,6 +994,39 @@
+ #undef GOT_PREF
+ }
+
++#define SHIFT_FROM(name, what) \
++void \
++nsStandardURL::name(int32_t diff) \
++{ \
++ if (!diff) return; \
++ if (what.mLen >= 0) { \
++ CheckedInt<int32_t> pos = what.mPos; \
++ pos += diff; \
++ MOZ_ASSERT(pos.isValid()); \
++ what.mPos = pos.value(); \
++ }
++
++#define SHIFT_FROM_NEXT(name, what, next) \
++ SHIFT_FROM(name, what) \
++ next(diff); \
++}
++
++#define SHIFT_FROM_LAST(name, what) \
++ SHIFT_FROM(name, what) \
++}
++
++SHIFT_FROM_NEXT(ShiftFromAuthority, mAuthority, ShiftFromUsername)
++SHIFT_FROM_NEXT(ShiftFromUsername, mUsername, ShiftFromPassword)
++SHIFT_FROM_NEXT(ShiftFromPassword, mPassword, ShiftFromHost)
++SHIFT_FROM_NEXT(ShiftFromHost, mHost, ShiftFromPath)
++SHIFT_FROM_NEXT(ShiftFromPath, mPath, ShiftFromFilepath)
++SHIFT_FROM_NEXT(ShiftFromFilepath, mFilepath, ShiftFromDirectory)
++SHIFT_FROM_NEXT(ShiftFromDirectory, mDirectory, ShiftFromBasename)
++SHIFT_FROM_NEXT(ShiftFromBasename, mBasename, ShiftFromExtension)
++SHIFT_FROM_NEXT(ShiftFromExtension, mExtension, ShiftFromQuery)
++SHIFT_FROM_NEXT(ShiftFromQuery, mQuery, ShiftFromRef)
++SHIFT_FROM_LAST(ShiftFromRef, mRef)
++
+ //----------------------------------------------------------------------------
+ // nsStandardURL::nsISupports
+ //----------------------------------------------------------------------------
+diff -r 28dcecced055 -r 88bea96c802a netwerk/base/nsStandardURL.h
+--- a/netwerk/base/nsStandardURL.h Wed May 18 11:55:29 2016 +1200
++++ b/netwerk/base/nsStandardURL.h Tue May 10 10:52:19 2016 +0200
+@@ -77,6 +77,7 @@
+
+ URLSegment() : mPos(0), mLen(-1) {}
+ URLSegment(uint32_t pos, int32_t len) : mPos(pos), mLen(len) {}
++ URLSegment(const URLSegment& aCopy) : mPos(aCopy.mPos), mLen(aCopy.mLen) {}
+ void Reset() { mPos = 0; mLen = -1; }
+ // Merge another segment following this one to it if they're contiguous
+ // Assumes we have something like "foo;bar" where this object is 'foo' and right
+@@ -177,7 +178,10 @@
+ bool NormalizeIDN(const nsCSubstring &host, nsCString &result);
+ void CoalescePath(netCoalesceFlags coalesceFlag, char *path);
+
+- uint32_t AppendSegmentToBuf(char *, uint32_t, const char *, URLSegment &, const nsCString *esc=nullptr, bool useEsc = false);
++ uint32_t AppendSegmentToBuf(char *, uint32_t, const char *,
++ const URLSegment &input, URLSegment &output,
++ const nsCString *esc=nullptr,
++ bool useEsc = false, int32_t* diff = nullptr);
+ uint32_t AppendToBuf(char *, uint32_t, const char *, uint32_t);
+
+ nsresult BuildNormalizedSpec(const char *spec);
+@@ -216,17 +220,17 @@
+ const nsDependentCSubstring Ref() { return Segment(mRef); }
+
+ // shift the URLSegments to the right by diff
+- void ShiftFromAuthority(int32_t diff) { mAuthority.mPos += diff; ShiftFromUsername(diff); }
+- void ShiftFromUsername(int32_t diff) { mUsername.mPos += diff; ShiftFromPassword(diff); }
+- void ShiftFromPassword(int32_t diff) { mPassword.mPos += diff; ShiftFromHost(diff); }
+- void ShiftFromHost(int32_t diff) { mHost.mPos += diff; ShiftFromPath(diff); }
+- void ShiftFromPath(int32_t diff) { mPath.mPos += diff; ShiftFromFilepath(diff); }
+- void ShiftFromFilepath(int32_t diff) { mFilepath.mPos += diff; ShiftFromDirectory(diff); }
+- void ShiftFromDirectory(int32_t diff) { mDirectory.mPos += diff; ShiftFromBasename(diff); }
+- void ShiftFromBasename(int32_t diff) { mBasename.mPos += diff; ShiftFromExtension(diff); }
+- void ShiftFromExtension(int32_t diff) { mExtension.mPos += diff; ShiftFromQuery(diff); }
+- void ShiftFromQuery(int32_t diff) { mQuery.mPos += diff; ShiftFromRef(diff); }
+- void ShiftFromRef(int32_t diff) { mRef.mPos += diff; }
++ void ShiftFromAuthority(int32_t diff);
++ void ShiftFromUsername(int32_t diff);
++ void ShiftFromPassword(int32_t diff);
++ void ShiftFromHost(int32_t diff);
++ void ShiftFromPath(int32_t diff);
++ void ShiftFromFilepath(int32_t diff);
++ void ShiftFromDirectory(int32_t diff);
++ void ShiftFromBasename(int32_t diff);
++ void ShiftFromExtension(int32_t diff);
++ void ShiftFromQuery(int32_t diff);
++ void ShiftFromRef(int32_t diff);
+
+ // fastload helper functions
+ nsresult ReadSegment(nsIBinaryInputStream *, URLSegment &);
diff --git a/gnu/packages/patches/icecat-CVE-2016-2818-pt6.patch b/gnu/packages/patches/icecat-CVE-2016-2818-pt6.patch
new file mode 100644
index 0000000000..143b02fa58
--- /dev/null
+++ b/gnu/packages/patches/icecat-CVE-2016-2818-pt6.patch
@@ -0,0 +1,17 @@
+ changeset: 312067:380ddd689680
+ user: Timothy Nikkel <tnikkel@gmail.com>
+ Date: Tue May 10 22:58:26 2016 -0500
+ summary: Bug 1261752. Part 1. r=mats a=ritu
+
+diff -r 02df988a56ae -r 380ddd689680 view/nsViewManager.cpp
+--- a/view/nsViewManager.cpp Thu May 26 10:06:15 2016 -0700
++++ b/view/nsViewManager.cpp Tue May 10 22:58:26 2016 -0500
+@@ -416,7 +416,7 @@
+ if (aWidget->NeedsPaint()) {
+ // If an ancestor widget was hidden and then shown, we could
+ // have a delayed resize to handle.
+- for (nsViewManager *vm = this; vm;
++ for (RefPtr<nsViewManager> vm = this; vm;
+ vm = vm->mRootView->GetParent()
+ ? vm->mRootView->GetParent()->GetViewManager()
+ : nullptr) {
diff --git a/gnu/packages/patches/icecat-CVE-2016-2818-pt7.patch b/gnu/packages/patches/icecat-CVE-2016-2818-pt7.patch
new file mode 100644
index 0000000000..23c509d6c1
--- /dev/null
+++ b/gnu/packages/patches/icecat-CVE-2016-2818-pt7.patch
@@ -0,0 +1,33 @@
+ changeset: 312068:73cc9a2d8fc1
+ user: Timothy Nikkel <tnikkel@gmail.com>
+ Date: Tue May 10 22:58:47 2016 -0500
+ summary: Bug 1261752. Part 2. r=mats a=ritu
+
+diff -r 380ddd689680 -r 73cc9a2d8fc1 view/nsViewManager.cpp
+--- a/view/nsViewManager.cpp Tue May 10 22:58:26 2016 -0500
++++ b/view/nsViewManager.cpp Tue May 10 22:58:47 2016 -0500
+@@ -372,7 +372,7 @@
+ }
+ }
+ if (rootShell->GetViewManager() != this) {
+- return; // 'this' might have been destroyed
++ return; // presentation might have been torn down
+ }
+ if (aFlushDirtyRegion) {
+ nsAutoScriptBlocker scriptBlocker;
+@@ -1069,6 +1069,7 @@
+ if (mPresShell) {
+ mPresShell->GetPresContext()->RefreshDriver()->RevokeViewManagerFlush();
+
++ RefPtr<nsViewManager> strongThis(this);
+ CallWillPaintOnObservers();
+
+ ProcessPendingUpdatesForView(mRootView, true);
+@@ -1085,6 +1086,7 @@
+
+ if (mHasPendingWidgetGeometryChanges) {
+ mHasPendingWidgetGeometryChanges = false;
++ RefPtr<nsViewManager> strongThis(this);
+ ProcessPendingUpdatesForView(mRootView, false);
+ }
+ }
diff --git a/gnu/packages/patches/icecat-CVE-2016-2818-pt8.patch b/gnu/packages/patches/icecat-CVE-2016-2818-pt8.patch
new file mode 100644
index 0000000000..ee5e54e805
--- /dev/null
+++ b/gnu/packages/patches/icecat-CVE-2016-2818-pt8.patch
@@ -0,0 +1,267 @@
+ changeset: 312069:3c2bd9158ad3
+ user: Timothy Nikkel <tnikkel@gmail.com>
+ Date: Tue May 10 22:58:47 2016 -0500
+ summary: Bug 1261752. Part 3. r=mats a=ritu
+
+diff -r 73cc9a2d8fc1 -r 3c2bd9158ad3 layout/forms/nsComboboxControlFrame.cpp
+--- a/layout/forms/nsComboboxControlFrame.cpp Tue May 10 22:58:47 2016 -0500
++++ b/layout/forms/nsComboboxControlFrame.cpp Tue May 10 22:58:47 2016 -0500
+@@ -1417,7 +1417,11 @@
+ // The popup's visibility doesn't update until the minimize animation has
+ // finished, so call UpdateWidgetGeometry to update it right away.
+ nsViewManager* viewManager = mDropdownFrame->GetView()->GetViewManager();
+- viewManager->UpdateWidgetGeometry();
++ viewManager->UpdateWidgetGeometry(); // might destroy us
++ }
++
++ if (!weakFrame.IsAlive()) {
++ return consume;
+ }
+
+ return consume;
+diff -r 73cc9a2d8fc1 -r 3c2bd9158ad3 view/nsViewManager.cpp
+--- a/view/nsViewManager.cpp Tue May 10 22:58:47 2016 -0500
++++ b/view/nsViewManager.cpp Tue May 10 22:58:47 2016 -0500
+@@ -670,15 +670,16 @@
+
+ void nsViewManager::WillPaintWindow(nsIWidget* aWidget)
+ {
+- if (aWidget) {
+- nsView* view = nsView::GetViewFor(aWidget);
+- LayerManager *manager = aWidget->GetLayerManager();
++ RefPtr<nsIWidget> widget(aWidget);
++ if (widget) {
++ nsView* view = nsView::GetViewFor(widget);
++ LayerManager* manager = widget->GetLayerManager();
+ if (view &&
+ (view->ForcedRepaint() || !manager->NeedsWidgetInvalidation())) {
+ ProcessPendingUpdates();
+ // Re-get the view pointer here since the ProcessPendingUpdates might have
+ // destroyed it during CallWillPaintOnObservers.
+- view = nsView::GetViewFor(aWidget);
++ view = nsView::GetViewFor(widget);
+ if (view) {
+ view->SetForcedRepaint(false);
+ }
+diff -r 73cc9a2d8fc1 -r 3c2bd9158ad3 widget/PuppetWidget.cpp
+--- a/widget/PuppetWidget.cpp Tue May 10 22:58:47 2016 -0500
++++ b/widget/PuppetWidget.cpp Tue May 10 22:58:47 2016 -0500
+@@ -823,6 +823,8 @@
+ mDirtyRegion.SetEmpty();
+ mPaintTask.Revoke();
+
++ RefPtr<PuppetWidget> strongThis(this);
++
+ mAttachedWidgetListener->WillPaintWindow(this);
+
+ if (mAttachedWidgetListener) {
+diff -r 73cc9a2d8fc1 -r 3c2bd9158ad3 widget/cocoa/nsChildView.mm
+--- a/widget/cocoa/nsChildView.mm Tue May 10 22:58:47 2016 -0500
++++ b/widget/cocoa/nsChildView.mm Tue May 10 22:58:47 2016 -0500
+@@ -3716,6 +3716,8 @@
+
+ - (void)viewWillDraw
+ {
++ nsAutoRetainCocoaObject kungFuDeathGrip(self);
++
+ if (mGeckoChild) {
+ // The OS normally *will* draw our NSWindow, no matter what we do here.
+ // But Gecko can delete our parent widget(s) (along with mGeckoChild)
+diff -r 73cc9a2d8fc1 -r 3c2bd9158ad3 widget/gonk/nsWindow.cpp
+--- a/widget/gonk/nsWindow.cpp Tue May 10 22:58:47 2016 -0500
++++ b/widget/gonk/nsWindow.cpp Tue May 10 22:58:47 2016 -0500
+@@ -196,7 +196,7 @@
+ return;
+ }
+
+- nsWindow *targetWindow = (nsWindow *)sTopWindows[0];
++ RefPtr<nsWindow> targetWindow = (nsWindow *)sTopWindows[0];
+ while (targetWindow->GetLastChild())
+ targetWindow = (nsWindow *)targetWindow->GetLastChild();
+
+@@ -205,15 +205,15 @@
+ listener->WillPaintWindow(targetWindow);
+ }
+
+- LayerManager* lm = targetWindow->GetLayerManager();
+- if (mozilla::layers::LayersBackend::LAYERS_CLIENT == lm->GetBackendType()) {
+- // No need to do anything, the compositor will handle drawing
+- } else {
+- NS_RUNTIMEABORT("Unexpected layer manager type");
+- }
+-
+ listener = targetWindow->GetWidgetListener();
+ if (listener) {
++ LayerManager* lm = targetWindow->GetLayerManager();
++ if (mozilla::layers::LayersBackend::LAYERS_CLIENT == lm->GetBackendType()) {
++ // No need to do anything, the compositor will handle drawing
++ } else {
++ NS_RUNTIMEABORT("Unexpected layer manager type");
++ }
++
+ listener->DidPaintWindow();
+ }
+ }
+diff -r 73cc9a2d8fc1 -r 3c2bd9158ad3 widget/gtk/nsWindow.cpp
+--- a/widget/gtk/nsWindow.cpp Tue May 10 22:58:47 2016 -0500
++++ b/widget/gtk/nsWindow.cpp Tue May 10 22:58:47 2016 -0500
+@@ -469,6 +469,12 @@
+ }
+ }
+
++nsIWidgetListener*
++nsWindow::GetListener()
++{
++ return mAttachedWidgetListener ? mAttachedWidgetListener : mWidgetListener;
++}
++
+ nsresult
+ nsWindow::DispatchEvent(WidgetGUIEvent* aEvent, nsEventStatus& aStatus)
+ {
+@@ -481,8 +487,7 @@
+ aEvent->refPoint.y = GdkCoordToDevicePixels(aEvent->refPoint.y);
+
+ aStatus = nsEventStatus_eIgnore;
+- nsIWidgetListener* listener =
+- mAttachedWidgetListener ? mAttachedWidgetListener : mWidgetListener;
++ nsIWidgetListener* listener = GetListener();
+ if (listener) {
+ aStatus = listener->HandleEvent(aEvent, mUseAttachedEvents);
+ }
+@@ -2119,8 +2124,7 @@
+ if (!mGdkWindow || mIsFullyObscured || !mHasMappedToplevel)
+ return FALSE;
+
+- nsIWidgetListener *listener =
+- mAttachedWidgetListener ? mAttachedWidgetListener : mWidgetListener;
++ nsIWidgetListener *listener = GetListener();
+ if (!listener)
+ return FALSE;
+
+@@ -2149,6 +2153,8 @@
+ clientLayers->SendInvalidRegion(region);
+ }
+
++ RefPtr<nsWindow> strongThis(this);
++
+ // Dispatch WillPaintWindow notification to allow scripts etc. to run
+ // before we paint
+ {
+@@ -2161,8 +2167,7 @@
+
+ // Re-get the listener since the will paint notification might have
+ // killed it.
+- listener =
+- mAttachedWidgetListener ? mAttachedWidgetListener : mWidgetListener;
++ listener = GetListener();
+ if (!listener)
+ return FALSE;
+ }
+@@ -2223,6 +2228,13 @@
+ // If this widget uses OMTC...
+ if (GetLayerManager()->GetBackendType() == LayersBackend::LAYERS_CLIENT) {
+ listener->PaintWindow(this, region);
++
++ // Re-get the listener since the will paint notification might have
++ // killed it.
++ listener = GetListener();
++ if (!listener)
++ return TRUE;
++
+ listener->DidPaintWindow();
+ return TRUE;
+ }
+@@ -2307,6 +2319,13 @@
+ if (GetLayerManager()->GetBackendType() == LayersBackend::LAYERS_BASIC) {
+ AutoLayerManagerSetup setupLayerManager(this, ctx, layerBuffering);
+ painted = listener->PaintWindow(this, region);
++
++ // Re-get the listener since the will paint notification might have
++ // killed it.
++ listener = GetListener();
++ if (!listener)
++ return TRUE;
++
+ }
+ }
+
+diff -r 73cc9a2d8fc1 -r 3c2bd9158ad3 widget/gtk/nsWindow.h
+--- a/widget/gtk/nsWindow.h Tue May 10 22:58:47 2016 -0500
++++ b/widget/gtk/nsWindow.h Tue May 10 22:58:47 2016 -0500
+@@ -359,6 +359,7 @@
+ GdkWindow** aWindow, gint* aButton,
+ gint* aRootX, gint* aRootY);
+ void ClearCachedResources();
++ nsIWidgetListener* GetListener();
+
+ GtkWidget *mShell;
+ MozContainer *mContainer;
+diff -r 73cc9a2d8fc1 -r 3c2bd9158ad3 widget/qt/nsWindow.cpp
+--- a/widget/qt/nsWindow.cpp Tue May 10 22:58:47 2016 -0500
++++ b/widget/qt/nsWindow.cpp Tue May 10 22:58:47 2016 -0500
+@@ -857,18 +857,28 @@
+
+ // EVENTS
+
++nsIWidgetListener*
++nsWindow::GetPaintListener()
++{
++ return mAttachedWidgetListener ? mAttachedWidgetListener : mWidgetListener;
++}
++
+ void
+ nsWindow::OnPaint()
+ {
+ LOGDRAW(("nsWindow::%s [%p]\n", __FUNCTION__, (void *)this));
+- nsIWidgetListener* listener =
+- mAttachedWidgetListener ? mAttachedWidgetListener : mWidgetListener;
++ nsIWidgetListener* listener = GetPaintListener();
+ if (!listener) {
+ return;
+ }
+
+ listener->WillPaintWindow(this);
+
++ nsIWidgetListener* listener = GetPaintListener();
++ if (!listener) {
++ return;
++ }
++
+ switch (GetLayerManager()->GetBackendType()) {
+ case mozilla::layers::LayersBackend::LAYERS_CLIENT: {
+ nsIntRegion region(nsIntRect(0, 0, mWidget->width(), mWidget->height()));
+@@ -879,6 +889,11 @@
+ NS_ERROR("Invalid layer manager");
+ }
+
++ nsIWidgetListener* listener = GetPaintListener();
++ if (!listener) {
++ return;
++ }
++
+ listener->DidPaintWindow();
+ }
+
+diff -r 73cc9a2d8fc1 -r 3c2bd9158ad3 widget/qt/nsWindow.h
+--- a/widget/qt/nsWindow.h Tue May 10 22:58:47 2016 -0500
++++ b/widget/qt/nsWindow.h Tue May 10 22:58:47 2016 -0500
+@@ -254,6 +254,7 @@
+ bool needDispatch;
+ } MozCachedMoveEvent;
+
++ nsIWidgetListener* GetPaintListener();
+ bool CheckForRollup(double aMouseX, double aMouseY, bool aIsWheel);
+ void* SetupPluginPort(void);
+ nsresult SetWindowIconList(const nsTArray<nsCString> &aIconList);
+diff -r 73cc9a2d8fc1 -r 3c2bd9158ad3 widget/windows/nsWindowGfx.cpp
+--- a/widget/windows/nsWindowGfx.cpp Tue May 10 22:58:47 2016 -0500
++++ b/widget/windows/nsWindowGfx.cpp Tue May 10 22:58:47 2016 -0500
+@@ -298,6 +298,8 @@
+ clientLayerManager->SendInvalidRegion(region);
+ }
+
++ RefPtr<nsWindow> strongThis(this);
++
+ nsIWidgetListener* listener = GetPaintListener();
+ if (listener) {
+ listener->WillPaintWindow(this);
diff --git a/gnu/packages/patches/icecat-CVE-2016-2818-pt9.patch b/gnu/packages/patches/icecat-CVE-2016-2818-pt9.patch
new file mode 100644
index 0000000000..a72698cc0b
--- /dev/null
+++ b/gnu/packages/patches/icecat-CVE-2016-2818-pt9.patch
@@ -0,0 +1,188 @@
+ changeset: 312075:ee870911fabb
+ user: Timothy Nikkel <tnikkel@gmail.com>
+ Date: Wed May 04 16:12:48 2016 -0500
+ summary: Bug 1265577. r=mats, a=lizzard
+
+diff -r 751208d22b91 -r ee870911fabb dom/base/nsFrameLoader.cpp
+--- a/dom/base/nsFrameLoader.cpp Thu May 26 17:07:49 2016 -0400
++++ b/dom/base/nsFrameLoader.cpp Wed May 04 16:12:48 2016 -0500
+@@ -155,7 +155,7 @@
+ nsFrameLoader::nsFrameLoader(Element* aOwner, bool aNetworkCreated)
+ : mOwnerContent(aOwner)
+ , mAppIdSentToPermissionManager(nsIScriptSecurityManager::NO_APP_ID)
+- , mDetachedSubdocViews(nullptr)
++ , mDetachedSubdocFrame(nullptr)
+ , mIsPrerendered(false)
+ , mDepthTooGreat(false)
+ , mIsTopLevelContent(false)
+@@ -2507,18 +2507,18 @@
+ }
+
+ void
+-nsFrameLoader::SetDetachedSubdocView(nsView* aDetachedViews,
+- nsIDocument* aContainerDoc)
++nsFrameLoader::SetDetachedSubdocFrame(nsIFrame* aDetachedFrame,
++ nsIDocument* aContainerDoc)
+ {
+- mDetachedSubdocViews = aDetachedViews;
++ mDetachedSubdocFrame = aDetachedFrame;
+ mContainerDocWhileDetached = aContainerDoc;
+ }
+
+-nsView*
+-nsFrameLoader::GetDetachedSubdocView(nsIDocument** aContainerDoc) const
++nsIFrame*
++nsFrameLoader::GetDetachedSubdocFrame(nsIDocument** aContainerDoc) const
+ {
+ NS_IF_ADDREF(*aContainerDoc = mContainerDocWhileDetached);
+- return mDetachedSubdocViews;
++ return mDetachedSubdocFrame.GetFrame();
+ }
+
+ void
+diff -r 751208d22b91 -r ee870911fabb dom/base/nsFrameLoader.h
+--- a/dom/base/nsFrameLoader.h Thu May 26 17:07:49 2016 -0400
++++ b/dom/base/nsFrameLoader.h Wed May 04 16:12:48 2016 -0500
+@@ -23,6 +23,7 @@
+ #include "mozilla/Attributes.h"
+ #include "FrameMetrics.h"
+ #include "nsStubMutationObserver.h"
++#include "nsIFrame.h"
+
+ class nsIURI;
+ class nsSubDocumentFrame;
+@@ -197,23 +198,23 @@
+ void SetRemoteBrowser(nsITabParent* aTabParent);
+
+ /**
+- * Stashes a detached view on the frame loader. We do this when we're
++ * Stashes a detached nsIFrame on the frame loader. We do this when we're
+ * destroying the nsSubDocumentFrame. If the nsSubdocumentFrame is
+- * being reframed we'll restore the detached view when it's recreated,
++ * being reframed we'll restore the detached nsIFrame when it's recreated,
+ * otherwise we'll discard the old presentation and set the detached
+- * subdoc view to null. aContainerDoc is the document containing the
++ * subdoc nsIFrame to null. aContainerDoc is the document containing the
+ * the subdoc frame. This enables us to detect when the containing
+ * document has changed during reframe, so we can discard the presentation
+ * in that case.
+ */
+- void SetDetachedSubdocView(nsView* aDetachedView,
+- nsIDocument* aContainerDoc);
++ void SetDetachedSubdocFrame(nsIFrame* aDetachedFrame,
++ nsIDocument* aContainerDoc);
+
+ /**
+- * Retrieves the detached view and the document containing the view,
+- * as set by SetDetachedSubdocView().
++ * Retrieves the detached nsIFrame and the document containing the nsIFrame,
++ * as set by SetDetachedSubdocFrame().
+ */
+- nsView* GetDetachedSubdocView(nsIDocument** aContainerDoc) const;
++ nsIFrame* GetDetachedSubdocFrame(nsIDocument** aContainerDoc) const;
+
+ /**
+ * Applies a new set of sandbox flags. These are merged with the sandbox
+@@ -326,12 +327,12 @@
+ nsRefPtr<nsFrameMessageManager> mMessageManager;
+ nsCOMPtr<nsIInProcessContentFrameMessageManager> mChildMessageManager;
+ private:
+- // Stores the root view of the subdocument while the subdocument is being
++ // Stores the root frame of the subdocument while the subdocument is being
+ // reframed. Used to restore the presentation after reframing.
+- nsView* mDetachedSubdocViews;
++ nsWeakFrame mDetachedSubdocFrame;
+ // Stores the containing document of the frame corresponding to this
+ // frame loader. This is reference is kept valid while the subframe's
+- // presentation is detached and stored in mDetachedSubdocViews. This
++ // presentation is detached and stored in mDetachedSubdocFrame. This
+ // enables us to detect whether the frame has moved documents during
+ // a reframe, so that we know not to restore the presentation.
+ nsCOMPtr<nsIDocument> mContainerDocWhileDetached;
+diff -r 751208d22b91 -r ee870911fabb layout/generic/nsSubDocumentFrame.cpp
+--- a/layout/generic/nsSubDocumentFrame.cpp Thu May 26 17:07:49 2016 -0400
++++ b/layout/generic/nsSubDocumentFrame.cpp Wed May 04 16:12:48 2016 -0500
+@@ -130,13 +130,16 @@
+ nsRefPtr<nsFrameLoader> frameloader = FrameLoader();
+ if (frameloader) {
+ nsCOMPtr<nsIDocument> oldContainerDoc;
+- nsView* detachedViews =
+- frameloader->GetDetachedSubdocView(getter_AddRefs(oldContainerDoc));
+- frameloader->SetDetachedSubdocView(nullptr, nullptr);
+- if (detachedViews) {
+- if (oldContainerDoc == aContent->OwnerDoc()) {
++ nsIFrame* detachedFrame =
++ frameloader->GetDetachedSubdocFrame(getter_AddRefs(oldContainerDoc));
++ frameloader->SetDetachedSubdocFrame(nullptr, nullptr);
++ MOZ_ASSERT(oldContainerDoc || !detachedFrame);
++ if (oldContainerDoc) {
++ nsView* detachedView =
++ detachedFrame ? detachedFrame->GetView() : nullptr;
++ if (detachedView && oldContainerDoc == aContent->OwnerDoc()) {
+ // Restore stashed presentation.
+- ::InsertViewsInReverseOrder(detachedViews, mInnerView);
++ ::InsertViewsInReverseOrder(detachedView, mInnerView);
+ ::EndSwapDocShellsForViews(mInnerView->GetFirstChild());
+ } else {
+ // Presentation is for a different document, don't restore it.
+@@ -252,11 +255,12 @@
+ nsRefPtr<nsFrameLoader> frameloader = FrameLoader();
+ if (frameloader) {
+ nsCOMPtr<nsIDocument> oldContainerDoc;
+- nsView* detachedViews =
+- frameloader->GetDetachedSubdocView(getter_AddRefs(oldContainerDoc));
+- if (detachedViews) {
+- nsSize size = detachedViews->GetBounds().Size();
+- nsPresContext* presContext = detachedViews->GetFrame()->PresContext();
++ nsIFrame* detachedFrame =
++ frameloader->GetDetachedSubdocFrame(getter_AddRefs(oldContainerDoc));
++ nsView* view = detachedFrame ? detachedFrame->GetView() : nullptr;
++ if (view) {
++ nsSize size = view->GetBounds().Size();
++ nsPresContext* presContext = detachedFrame->PresContext();
+ return nsIntSize(presContext->AppUnitsToDevPixels(size.width),
+ presContext->AppUnitsToDevPixels(size.height));
+ }
+@@ -939,7 +943,7 @@
+
+ // Either the frame has been constructed by now, or it never will be,
+ // either way we want to clear the stashed views.
+- mFrameLoader->SetDetachedSubdocView(nullptr, nullptr);
++ mFrameLoader->SetDetachedSubdocFrame(nullptr, nullptr);
+
+ nsSubDocumentFrame* frame = do_QueryFrame(mFrameElement->GetPrimaryFrame());
+ if ((!frame && mHideViewerIfFrameless) ||
+@@ -974,15 +978,25 @@
+ RefPtr<nsFrameLoader> frameloader = FrameLoader();
+ if (frameloader) {
+ nsView* detachedViews = ::BeginSwapDocShellsForViews(mInnerView->GetFirstChild());
+- frameloader->SetDetachedSubdocView(detachedViews, mContent->OwnerDoc());
+
+- // We call nsFrameLoader::HideViewer() in a script runner so that we can
+- // safely determine whether the frame is being reframed or destroyed.
+- nsContentUtils::AddScriptRunner(
+- new nsHideViewer(mContent,
+- frameloader,
+- PresContext()->PresShell(),
+- (mDidCreateDoc || mCallingShow)));
++ if (detachedViews && detachedViews->GetFrame()) {
++ MOZ_ASSERT(mContent->OwnerDoc());
++ frameloader->SetDetachedSubdocFrame(
++ detachedViews->GetFrame(), mContent->OwnerDoc());
++
++ // We call nsFrameLoader::HideViewer() in a script runner so that we can
++ // safely determine whether the frame is being reframed or destroyed.
++ nsContentUtils::AddScriptRunner(
++ new nsHideViewer(mContent,
++ frameloader,
++ PresContext()->PresShell(),
++ (mDidCreateDoc || mCallingShow)));
++ } else {
++ frameloader->SetDetachedSubdocFrame(nullptr, nullptr);
++ if (mDidCreateDoc || mCallingShow) {
++ frameloader->Hide();
++ }
++ }
+ }
+
+ nsLeafFrame::DestroyFrom(aDestructRoot);
diff --git a/gnu/packages/patches/icecat-CVE-2016-2819.patch b/gnu/packages/patches/icecat-CVE-2016-2819.patch
new file mode 100644
index 0000000000..cbb833d43d
--- /dev/null
+++ b/gnu/packages/patches/icecat-CVE-2016-2819.patch
@@ -0,0 +1,102 @@
+ changeset: 312054:072992bf176d
+ user: Henri Sivonen <hsivonen@hsivonen.fi>
+ Date: Sun May 15 17:03:06 2016 +0300
+ summary: Bug 1270381. r=wchen. a=ritu
+
+diff -r d30748143c21 -r 072992bf176d parser/html/javasrc/TreeBuilder.java
+--- a/parser/html/javasrc/TreeBuilder.java Mon May 09 18:05:32 2016 -0700
++++ b/parser/html/javasrc/TreeBuilder.java Sun May 15 17:03:06 2016 +0300
+@@ -39,6 +39,11 @@
+ import java.util.HashMap;
+ import java.util.Map;
+
++import org.xml.sax.ErrorHandler;
++import org.xml.sax.Locator;
++import org.xml.sax.SAXException;
++import org.xml.sax.SAXParseException;
++
+ import nu.validator.htmlparser.annotation.Auto;
+ import nu.validator.htmlparser.annotation.Const;
+ import nu.validator.htmlparser.annotation.IdType;
+@@ -54,11 +59,6 @@
+ import nu.validator.htmlparser.common.TokenHandler;
+ import nu.validator.htmlparser.common.XmlViolationPolicy;
+
+-import org.xml.sax.ErrorHandler;
+-import org.xml.sax.Locator;
+-import org.xml.sax.SAXException;
+-import org.xml.sax.SAXParseException;
+-
+ public abstract class TreeBuilder<T> implements TokenHandler,
+ TreeBuilderState<T> {
+
+@@ -1924,7 +1924,6 @@
+ break starttagloop;
+ }
+ generateImpliedEndTags();
+- // XXX is the next if dead code?
+ if (errorHandler != null && !isCurrent("table")) {
+ errNoCheckUnclosedElementsOnStack();
+ }
+@@ -2183,11 +2182,11 @@
+ pop();
+ }
+ break;
+- } else if (node.isSpecial()
++ } else if (eltPos == 0 || (node.isSpecial()
+ && (node.ns != "http://www.w3.org/1999/xhtml"
+- || (node.name != "p"
+- && node.name != "address"
+- && node.name != "div"))) {
++ || (node.name != "p"
++ && node.name != "address"
++ && node.name != "div")))) {
+ break;
+ }
+ eltPos--;
+@@ -3878,7 +3877,7 @@
+ pop();
+ }
+ break endtagloop;
+- } else if (node.isSpecial()) {
++ } else if (eltPos == 0 || node.isSpecial()) {
+ errStrayEndTag(name);
+ break endtagloop;
+ }
+@@ -4745,6 +4744,7 @@
+ int furthestBlockPos = formattingEltStackPos + 1;
+ while (furthestBlockPos <= currentPtr) {
+ StackNode<T> node = stack[furthestBlockPos]; // weak ref
++ assert furthestBlockPos > 0: "How is formattingEltStackPos + 1 not > 0?";
+ if (node.isSpecial()) {
+ break;
+ }
+diff -r d30748143c21 -r 072992bf176d parser/html/nsHtml5TreeBuilder.cpp
+--- a/parser/html/nsHtml5TreeBuilder.cpp Mon May 09 18:05:32 2016 -0700
++++ b/parser/html/nsHtml5TreeBuilder.cpp Sun May 15 17:03:06 2016 +0300
+@@ -1102,7 +1102,7 @@
+ pop();
+ }
+ break;
+- } else if (node->isSpecial() && (node->ns != kNameSpaceID_XHTML || (node->name != nsHtml5Atoms::p && node->name != nsHtml5Atoms::address && node->name != nsHtml5Atoms::div))) {
++ } else if (!eltPos || (node->isSpecial() && (node->ns != kNameSpaceID_XHTML || (node->name != nsHtml5Atoms::p && node->name != nsHtml5Atoms::address && node->name != nsHtml5Atoms::div)))) {
+ break;
+ }
+ eltPos--;
+@@ -2749,7 +2749,7 @@
+ pop();
+ }
+ NS_HTML5_BREAK(endtagloop);
+- } else if (node->isSpecial()) {
++ } else if (!eltPos || node->isSpecial()) {
+ errStrayEndTag(name);
+ NS_HTML5_BREAK(endtagloop);
+ }
+@@ -3593,6 +3593,7 @@
+ int32_t furthestBlockPos = formattingEltStackPos + 1;
+ while (furthestBlockPos <= currentPtr) {
+ nsHtml5StackNode* node = stack[furthestBlockPos];
++ MOZ_ASSERT(furthestBlockPos > 0, "How is formattingEltStackPos + 1 not > 0?");
+ if (node->isSpecial()) {
+ break;
+ }
diff --git a/gnu/packages/patches/icecat-CVE-2016-2821.patch b/gnu/packages/patches/icecat-CVE-2016-2821.patch
new file mode 100644
index 0000000000..8255d60009
--- /dev/null
+++ b/gnu/packages/patches/icecat-CVE-2016-2821.patch
@@ -0,0 +1,16 @@
+ changeset: 312045:7aea44059251
+ user: Olli Pettay <Olli.Pettay@helsinki.fi>
+ Date: Fri May 13 20:10:22 2016 +0300
+ summary: Bug 1271460, don't leak editor created element objects, r=ehsan a=ritu
+
+diff -r 09418166fd77 -r 7aea44059251 editor/libeditor/nsHTMLInlineTableEditor.cpp
+--- a/editor/libeditor/nsHTMLInlineTableEditor.cpp Wed May 11 10:14:45 2016 +0100
++++ b/editor/libeditor/nsHTMLInlineTableEditor.cpp Fri May 13 20:10:22 2016 +0300
+@@ -109,7 +109,6 @@
+
+ // get the root content node.
+ nsCOMPtr<nsIContent> bodyContent = GetRoot();
+- NS_ENSURE_TRUE(bodyContent, NS_ERROR_FAILURE);
+
+ DeleteRefToAnonymousNode(mAddColumnBeforeButton, bodyContent, ps);
+ mAddColumnBeforeButton = nullptr;
diff --git a/gnu/packages/patches/icecat-CVE-2016-2824.patch b/gnu/packages/patches/icecat-CVE-2016-2824.patch
new file mode 100644
index 0000000000..72772ed15f
--- /dev/null
+++ b/gnu/packages/patches/icecat-CVE-2016-2824.patch
@@ -0,0 +1,85 @@
+ changeset: 312070:4b54feddf36c
+ user: JerryShih <hshih@mozilla.com>
+ Date: Wed May 25 16:27:41 2016 +0200
+ summary: Bug 1248580 - strip the uploading element num according to the uniform array size. r=jgilbert a=ritu
+
+diff -r 3c2bd9158ad3 -r 4b54feddf36c dom/canvas/WebGLContextValidate.cpp
+--- a/dom/canvas/WebGLContextValidate.cpp Tue May 10 22:58:47 2016 -0500
++++ b/dom/canvas/WebGLContextValidate.cpp Wed May 25 16:27:41 2016 +0200
+@@ -1531,9 +1531,10 @@
+ if (!loc->ValidateArrayLength(setterElemSize, setterArraySize, this, funcName))
+ return false;
+
++ MOZ_ASSERT((size_t)loc->mActiveInfo->mElemCount > loc->mArrayIndex);
++ size_t uniformElemCount = loc->mActiveInfo->mElemCount - loc->mArrayIndex;
+ *out_rawLoc = loc->mLoc;
+- *out_numElementsToUpload = std::min((size_t)loc->mActiveInfo->mElemCount,
+- setterArraySize / setterElemSize);
++ *out_numElementsToUpload = std::min(uniformElemCount, setterArraySize / setterElemSize);
+ return true;
+ }
+
+diff -r 3c2bd9158ad3 -r 4b54feddf36c dom/canvas/WebGLProgram.cpp
+--- a/dom/canvas/WebGLProgram.cpp Tue May 10 22:58:47 2016 -0500
++++ b/dom/canvas/WebGLProgram.cpp Wed May 25 16:27:41 2016 +0200
+@@ -510,8 +510,14 @@
+ const NS_LossyConvertUTF16toASCII userName(userName_wide);
+
+ nsDependentCString baseUserName;
+- bool isArray;
+- size_t arrayIndex;
++ bool isArray = false;
++ // GLES 2.0.25, Section 2.10, p35
++ // If the the uniform location is an array, then the location of the first
++ // element of that array can be retrieved by either using the name of the
++ // uniform array, or the name of the uniform array appended with "[0]".
++ // The ParseName() can't recognize this rule. So always initialize
++ // arrayIndex with 0.
++ size_t arrayIndex = 0;
+ if (!ParseName(userName, &baseUserName, &isArray, &arrayIndex))
+ return nullptr;
+
+@@ -536,7 +542,8 @@
+ return nullptr;
+
+ nsRefPtr<WebGLUniformLocation> locObj = new WebGLUniformLocation(mContext, LinkInfo(),
+- loc, activeInfo);
++ loc, arrayIndex,
++ activeInfo);
+ return locObj.forget();
+ }
+
+diff -r 3c2bd9158ad3 -r 4b54feddf36c dom/canvas/WebGLUniformLocation.cpp
+--- a/dom/canvas/WebGLUniformLocation.cpp Tue May 10 22:58:47 2016 -0500
++++ b/dom/canvas/WebGLUniformLocation.cpp Wed May 25 16:27:41 2016 +0200
+@@ -16,10 +16,13 @@
+
+ WebGLUniformLocation::WebGLUniformLocation(WebGLContext* webgl,
+ const webgl::LinkedProgramInfo* linkInfo,
+- GLuint loc, const WebGLActiveInfo* activeInfo)
++ GLuint loc,
++ size_t arrayIndex,
++ const WebGLActiveInfo* activeInfo)
+ : WebGLContextBoundObject(webgl)
+ , mLinkInfo(linkInfo)
+ , mLoc(loc)
++ , mArrayIndex(arrayIndex)
+ , mActiveInfo(activeInfo)
+ { }
+
+diff -r 3c2bd9158ad3 -r 4b54feddf36c dom/canvas/WebGLUniformLocation.h
+--- a/dom/canvas/WebGLUniformLocation.h Tue May 10 22:58:47 2016 -0500
++++ b/dom/canvas/WebGLUniformLocation.h Wed May 25 16:27:41 2016 +0200
+@@ -41,10 +41,11 @@
+
+ const WeakPtr<const webgl::LinkedProgramInfo> mLinkInfo;
+ const GLuint mLoc;
++ const size_t mArrayIndex;
+ const WebGLActiveInfo* const mActiveInfo;
+
+ WebGLUniformLocation(WebGLContext* webgl, const webgl::LinkedProgramInfo* linkInfo,
+- GLuint loc, const WebGLActiveInfo* activeInfo);
++ GLuint loc, size_t arrayIndex, const WebGLActiveInfo* activeInfo);
+
+ bool ValidateForProgram(WebGLProgram* prog, WebGLContext* webgl,
+ const char* funcName) const;
diff --git a/gnu/packages/patches/icecat-CVE-2016-2828.patch b/gnu/packages/patches/icecat-CVE-2016-2828.patch
new file mode 100644
index 0000000000..951eb4fc46
--- /dev/null
+++ b/gnu/packages/patches/icecat-CVE-2016-2828.patch
@@ -0,0 +1,185 @@
+ changeset: 312096:dc190bd03d24
+ tag: FIREFOX_45_2_0esr_BUILD2
+ tag: FIREFOX_45_2_0esr_RELEASE
+ user: Jeff Gilbert <jgilbert@mozilla.com>
+ Date: Thu Apr 14 13:50:04 2016 -0700
+ summary: Bug 1224199 - Destroy SharedSurfaces before ~GLContext(). - r=jrmuizel a=lizzard
+
+diff -r b24e1cc592ec -r dc190bd03d24 gfx/gl/GLBlitHelper.cpp
+--- a/gfx/gl/GLBlitHelper.cpp Mon Mar 07 11:51:12 2016 +0000
++++ b/gfx/gl/GLBlitHelper.cpp Thu Apr 14 13:50:04 2016 -0700
+@@ -172,6 +172,9 @@
+
+ GLBlitHelper::~GLBlitHelper()
+ {
++ if (!mGL->MakeCurrent())
++ return;
++
+ DeleteTexBlitProgram();
+
+ GLuint tex[] = {
+diff -r b24e1cc592ec -r dc190bd03d24 gfx/gl/GLContext.cpp
+--- a/gfx/gl/GLContext.cpp Mon Mar 07 11:51:12 2016 +0000
++++ b/gfx/gl/GLContext.cpp Thu Apr 14 13:50:04 2016 -0700
+@@ -2079,12 +2079,13 @@
+ if (IsDestroyed())
+ return;
+
++ // Null these before they're naturally nulled after dtor, as we want GLContext to
++ // still be alive in *their* dtors.
++ mScreen = nullptr;
++ mBlitHelper = nullptr;
++ mReadTexImageHelper = nullptr;
++
+ if (MakeCurrent()) {
+- DestroyScreenBuffer();
+-
+- mBlitHelper = nullptr;
+- mReadTexImageHelper = nullptr;
+-
+ mTexGarbageBin->GLContextTeardown();
+ } else {
+ NS_WARNING("MakeCurrent() failed during MarkDestroyed! Skipping GL object teardown.");
+@@ -2328,8 +2329,6 @@
+ return false;
+ }
+
+- DestroyScreenBuffer();
+-
+ // This will rebind to 0 (Screen) if needed when
+ // it falls out of scope.
+ ScopedBindFramebuffer autoFB(this);
+@@ -2349,12 +2348,6 @@
+ }
+
+ void
+-GLContext::DestroyScreenBuffer()
+-{
+- mScreen = nullptr;
+-}
+-
+-void
+ GLContext::ForceDirtyScreen()
+ {
+ ScopedBindFramebuffer autoFB(0);
+diff -r b24e1cc592ec -r dc190bd03d24 gfx/gl/GLContext.h
+--- a/gfx/gl/GLContext.h Mon Mar 07 11:51:12 2016 +0000
++++ b/gfx/gl/GLContext.h Thu Apr 14 13:50:04 2016 -0700
+@@ -3492,8 +3492,6 @@
+ friend class GLScreenBuffer;
+ UniquePtr<GLScreenBuffer> mScreen;
+
+- void DestroyScreenBuffer();
+-
+ SharedSurface* mLockedSurface;
+
+ public:
+diff -r b24e1cc592ec -r dc190bd03d24 gfx/gl/GLReadTexImageHelper.cpp
+--- a/gfx/gl/GLReadTexImageHelper.cpp Mon Mar 07 11:51:12 2016 +0000
++++ b/gfx/gl/GLReadTexImageHelper.cpp Thu Apr 14 13:50:04 2016 -0700
+@@ -31,6 +31,9 @@
+
+ GLReadTexImageHelper::~GLReadTexImageHelper()
+ {
++ if (!mGL->MakeCurrent())
++ return;
++
+ mGL->fDeleteProgram(mPrograms[0]);
+ mGL->fDeleteProgram(mPrograms[1]);
+ mGL->fDeleteProgram(mPrograms[2]);
+diff -r b24e1cc592ec -r dc190bd03d24 gfx/gl/SharedSurfaceANGLE.cpp
+--- a/gfx/gl/SharedSurfaceANGLE.cpp Mon Mar 07 11:51:12 2016 +0000
++++ b/gfx/gl/SharedSurfaceANGLE.cpp Thu Apr 14 13:50:04 2016 -0700
+@@ -120,8 +120,10 @@
+ {
+ mEGL->fDestroySurface(Display(), mPBuffer);
+
++ if (!mGL->MakeCurrent())
++ return;
++
+ if (mFence) {
+- mGL->MakeCurrent();
+ mGL->fDeleteFences(1, &mFence);
+ }
+ }
+diff -r b24e1cc592ec -r dc190bd03d24 gfx/gl/SharedSurfaceEGL.cpp
+--- a/gfx/gl/SharedSurfaceEGL.cpp Mon Mar 07 11:51:12 2016 +0000
++++ b/gfx/gl/SharedSurfaceEGL.cpp Thu Apr 14 13:50:04 2016 -0700
+@@ -87,9 +87,12 @@
+ {
+ mEGL->fDestroyImage(Display(), mImage);
+
+- mGL->MakeCurrent();
+- mGL->fDeleteTextures(1, &mProdTex);
+- mProdTex = 0;
++ if (mSync) {
++ // We can't call this unless we have the ext, but we will always have
++ // the ext if we have something to destroy.
++ mEGL->fDestroySync(Display(), mSync);
++ mSync = 0;
++ }
+
+ if (mConsTex) {
+ MOZ_ASSERT(mGarbageBin);
+@@ -97,12 +100,11 @@
+ mConsTex = 0;
+ }
+
+- if (mSync) {
+- // We can't call this unless we have the ext, but we will always have
+- // the ext if we have something to destroy.
+- mEGL->fDestroySync(Display(), mSync);
+- mSync = 0;
+- }
++ if (!mGL->MakeCurrent())
++ return;
++
++ mGL->fDeleteTextures(1, &mProdTex);
++ mProdTex = 0;
+ }
+
+ void
+diff -r b24e1cc592ec -r dc190bd03d24 gfx/gl/SharedSurfaceGralloc.cpp
+--- a/gfx/gl/SharedSurfaceGralloc.cpp Mon Mar 07 11:51:12 2016 +0000
++++ b/gfx/gl/SharedSurfaceGralloc.cpp Thu Apr 14 13:50:04 2016 -0700
+@@ -154,7 +154,9 @@
+
+ DEBUG_PRINT("[SharedSurface_Gralloc %p] destroyed\n", this);
+
+- mGL->MakeCurrent();
++ if (!mGL->MakeCurrent())
++ return;
++
+ mGL->fDeleteTextures(1, &mProdTex);
+
+ if (mSync) {
+diff -r b24e1cc592ec -r dc190bd03d24 gfx/gl/SharedSurfaceIO.cpp
+--- a/gfx/gl/SharedSurfaceIO.cpp Mon Mar 07 11:51:12 2016 +0000
++++ b/gfx/gl/SharedSurfaceIO.cpp Thu Apr 14 13:50:04 2016 -0700
+@@ -111,11 +111,10 @@
+
+ SharedSurface_IOSurface::~SharedSurface_IOSurface()
+ {
+- if (mProdTex) {
+- DebugOnly<bool> success = mGL->MakeCurrent();
+- MOZ_ASSERT(success);
+- mGL->fDeleteTextures(1, &mProdTex);
+- }
++ if (!mGL->MakeCurrent())
++ return;
++
++ mGL->fDeleteTextures(1, &mProdTex);
+ }
+
+ ////////////////////////////////////////////////////////////////////////
+diff -r b24e1cc592ec -r dc190bd03d24 gfx/gl/TextureGarbageBin.cpp
+--- a/gfx/gl/TextureGarbageBin.cpp Mon Mar 07 11:51:12 2016 +0000
++++ b/gfx/gl/TextureGarbageBin.cpp Thu Apr 14 13:50:04 2016 -0700
+@@ -36,6 +36,7 @@
+ if (!mGL)
+ return;
+
++ MOZ_RELEASE_ASSERT(mGL->IsCurrent());
+ while (!mGarbageTextures.empty()) {
+ GLuint tex = mGarbageTextures.top();
+ mGarbageTextures.pop();
diff --git a/gnu/packages/patches/icecat-CVE-2016-2831.patch b/gnu/packages/patches/icecat-CVE-2016-2831.patch
new file mode 100644
index 0000000000..b99ecb6458
--- /dev/null
+++ b/gnu/packages/patches/icecat-CVE-2016-2831.patch
@@ -0,0 +1,120 @@
+ changeset: 312091:a3fff31b8b70
+ user: Xidorn Quan <quanxunzhen@gmail.com>
+ Date: Thu Apr 14 17:38:13 2016 +1000
+ summary: Bug 1261933 - Continue unlocking pointer even if the widget has gone. r=smaug a=lizzard
+
+ MozReview-Commit-ID: 1siQhemFf9O
+
+diff -r f5e862ea4a72 -r a3fff31b8b70 dom/base/nsDocument.cpp
+--- a/dom/base/nsDocument.cpp Tue May 31 18:35:26 2016 -0700
++++ b/dom/base/nsDocument.cpp Thu Apr 14 17:38:13 2016 +1000
+@@ -12315,49 +12315,37 @@
+ bool
+ nsDocument::SetPointerLock(Element* aElement, int aCursorStyle)
+ {
+- // NOTE: aElement will be nullptr when unlocking.
+- nsCOMPtr<nsPIDOMWindow> window = GetWindow();
+- if (!window) {
+- NS_WARNING("SetPointerLock(): No Window");
+- return false;
+- }
+-
+- nsIDocShell *docShell = window->GetDocShell();
+- if (!docShell) {
+- NS_WARNING("SetPointerLock(): No DocShell (window already closed?)");
+- return false;
+- }
+-
+- nsRefPtr<nsPresContext> presContext;
+- docShell->GetPresContext(getter_AddRefs(presContext));
+- if (!presContext) {
+- NS_WARNING("SetPointerLock(): Unable to get presContext in \
+- domWindow->GetDocShell()->GetPresContext()");
++ MOZ_ASSERT(!aElement || aElement->OwnerDoc() == this,
++ "We should be either unlocking pointer (aElement is nullptr), "
++ "or locking pointer to an element in this document");
++#ifdef DEBUG
++ if (!aElement) {
++ nsCOMPtr<nsIDocument> pointerLockedDoc =
++ do_QueryReferent(EventStateManager::sPointerLockedDoc);
++ MOZ_ASSERT(pointerLockedDoc == this);
++ }
++#endif
++
++ nsIPresShell* shell = GetShell();
++ if (!shell) {
++ NS_WARNING("SetPointerLock(): No PresShell");
+ return false;
+ }
+-
+- nsCOMPtr<nsIPresShell> shell = presContext->PresShell();
+- if (!shell) {
+- NS_WARNING("SetPointerLock(): Unable to find presContext->PresShell()");
+- return false;
+- }
+-
+- nsIFrame* rootFrame = shell->GetRootFrame();
+- if (!rootFrame) {
+- NS_WARNING("SetPointerLock(): Unable to get root frame");
++ nsPresContext* presContext = shell->GetPresContext();
++ if (!presContext) {
++ NS_WARNING("SetPointerLock(): Unable to get PresContext");
+ return false;
+ }
+
+- nsCOMPtr<nsIWidget> widget = rootFrame->GetNearestWidget();
+- if (!widget) {
+- NS_WARNING("SetPointerLock(): Unable to find widget in \
+- shell->GetRootFrame()->GetNearestWidget();");
+- return false;
+- }
+-
+- if (aElement && (aElement->OwnerDoc() != this)) {
+- NS_WARNING("SetPointerLock(): Element not in this document.");
+- return false;
++ nsCOMPtr<nsIWidget> widget;
++ nsIFrame* rootFrame = shell->GetRootFrame();
++ if (!NS_WARN_IF(!rootFrame)) {
++ widget = rootFrame->GetNearestWidget();
++ NS_WARN_IF_FALSE(widget, "SetPointerLock(): Unable to find widget "
++ "in shell->GetRootFrame()->GetNearestWidget();");
++ if (aElement && !widget) {
++ return false;
++ }
+ }
+
+ // Hide the cursor and set pointer lock for future mouse events
+diff -r f5e862ea4a72 -r a3fff31b8b70 dom/events/EventStateManager.cpp
+--- a/dom/events/EventStateManager.cpp Tue May 31 18:35:26 2016 -0700
++++ b/dom/events/EventStateManager.cpp Thu Apr 14 17:38:13 2016 +1000
+@@ -4128,10 +4128,6 @@
+ // NOTE: aElement will be nullptr when unlocking.
+ sIsPointerLocked = !!aElement;
+
+- if (!aWidget) {
+- return;
+- }
+-
+ // Reset mouse wheel transaction
+ WheelTransaction::EndTransaction();
+
+@@ -4140,6 +4136,8 @@
+ do_GetService("@mozilla.org/widget/dragservice;1");
+
+ if (sIsPointerLocked) {
++ MOZ_ASSERT(aWidget, "Locking pointer requires a widget");
++
+ // Store the last known ref point so we can reposition the pointer after unlock.
+ mPreLockPoint = sLastRefPoint;
+
+@@ -4164,7 +4162,9 @@
+ // pre-pointerlock position, so that the synthetic mouse event reports
+ // no movement.
+ sLastRefPoint = mPreLockPoint;
+- aWidget->SynthesizeNativeMouseMove(mPreLockPoint + aWidget->WidgetToScreenOffset());
++ if (aWidget) {
++ aWidget->SynthesizeNativeMouseMove(mPreLockPoint + aWidget->WidgetToScreenOffset());
++ }
+
+ // Don't retarget events to this element any more.
+ nsIPresShell::SetCapturingContent(nullptr, CAPTURE_POINTERLOCK);