summary refs log tree commit diff
path: root/gnu/packages/patches
diff options
context:
space:
mode:
Diffstat (limited to 'gnu/packages/patches')
-rw-r--r--gnu/packages/patches/bitlbee-configure-doc-fix.patch15
-rw-r--r--gnu/packages/patches/einstein-build.patch401
-rw-r--r--gnu/packages/patches/gitolite-openssh-6.8-compat.patch25
-rw-r--r--gnu/packages/patches/icecat-CVE-2015-4477.patch37
-rw-r--r--gnu/packages/patches/icecat-CVE-2015-7207.patch1140
-rw-r--r--gnu/packages/patches/icecat-CVE-2016-1952-pt01.patch356
-rw-r--r--gnu/packages/patches/icecat-CVE-2016-1952-pt02.patch58
-rw-r--r--gnu/packages/patches/icecat-CVE-2016-1952-pt03.patch60
-rw-r--r--gnu/packages/patches/icecat-CVE-2016-1952-pt04.patch53
-rw-r--r--gnu/packages/patches/icecat-CVE-2016-1952-pt05.patch32
-rw-r--r--gnu/packages/patches/icecat-CVE-2016-1952-pt06.patch103
-rw-r--r--gnu/packages/patches/icecat-CVE-2016-1954.patch32
-rw-r--r--gnu/packages/patches/icecat-CVE-2016-1960.patch55
-rw-r--r--gnu/packages/patches/icecat-CVE-2016-1961.patch33
-rw-r--r--gnu/packages/patches/icecat-CVE-2016-1962.patch107
-rw-r--r--gnu/packages/patches/icecat-CVE-2016-1964.patch54
-rw-r--r--gnu/packages/patches/icecat-CVE-2016-1965.patch44
-rw-r--r--gnu/packages/patches/icecat-CVE-2016-1966.patch36
-rw-r--r--gnu/packages/patches/icecat-CVE-2016-1974.patch530
-rw-r--r--gnu/packages/patches/icecat-bug-1248851.patch37
-rw-r--r--gnu/packages/patches/icecat-update-graphite2-pt2.patch861
-rw-r--r--gnu/packages/patches/ilmbase-fix-tests.patch149
-rw-r--r--gnu/packages/patches/jasper-CVE-2016-1577.patch19
-rw-r--r--gnu/packages/patches/jasper-CVE-2016-2089.patch90
-rw-r--r--gnu/packages/patches/jasper-CVE-2016-2116.patch19
-rw-r--r--gnu/packages/patches/libotr-test-auth-fix.patch15
-rw-r--r--gnu/packages/patches/mupdf-buildsystem-fix.patch69
-rw-r--r--gnu/packages/patches/openssl-c-rehash-in.patch17
-rw-r--r--gnu/packages/patches/perl-CVE-2016-2381.patch116
-rw-r--r--gnu/packages/patches/procmail-ambiguous-getline-debian.patch61
-rw-r--r--gnu/packages/patches/python-rarfile-fix-tests.patch14
-rw-r--r--gnu/packages/patches/scribus-qobject.patch17
-rw-r--r--gnu/packages/patches/vorbis-tools-CVE-2015-6749.patch44
33 files changed, 4573 insertions, 126 deletions
diff --git a/gnu/packages/patches/bitlbee-configure-doc-fix.patch b/gnu/packages/patches/bitlbee-configure-doc-fix.patch
deleted file mode 100644
index ade0b7f25c..0000000000
--- a/gnu/packages/patches/bitlbee-configure-doc-fix.patch
+++ /dev/null
@@ -1,15 +0,0 @@
-Fix the check for the prebuilt helpfile when xsltproc is not available.
-
---- bitlbee-3.4/configure.orig	2015-03-25 18:09:10.000000000 -0400
-+++ bitlbee-3.4/configure	2015-05-20 14:51:33.627975970 -0400
-@@ -650,8 +650,8 @@
- 
- if [ "$doc" = "1" ]; then
- 	if [ ! -e doc/user-guide/help.txt ] && \
--	     ! type xmlto > /dev/null 2> /dev/null || \
--	     ! type xsltproc > /dev/null 2> /dev/null
-+	     (! type xmlto > /dev/null 2> /dev/null || \
-+	      ! type xsltproc > /dev/null 2> /dev/null)
- 	then
- 		echo
- 		echo 'WARNING: Building from an unreleased source tree without prebuilt helpfile.'
diff --git a/gnu/packages/patches/einstein-build.patch b/gnu/packages/patches/einstein-build.patch
new file mode 100644
index 0000000000..b0d3087a7a
--- /dev/null
+++ b/gnu/packages/patches/einstein-build.patch
@@ -0,0 +1,401 @@
+These patches are required to build with a modern GCC; most of them
+are taken from the Debian package. Upstream has disappeared.
+
+diff -r -u einstein-2.0.orig/convert.h einstein-2.0/convert.h
+--- einstein-2.0.orig/convert.h	2005-08-14 04:40:58.000000000 +0200
++++ einstein-2.0/convert.h	2016-03-05 18:25:08.488917021 +0100
+@@ -5,6 +5,7 @@
+ #include <iostream>
+ #include <sstream>
+ #include <string>
++#include <typeinfo>
+ 
+ #include "exceptions.h"
+ #include "unicode.h"
+diff -r -u einstein-2.0.orig/descr.cpp einstein-2.0/descr.cpp
+--- einstein-2.0.orig/descr.cpp	2005-08-17 15:42:29.000000000 +0200
++++ einstein-2.0/descr.cpp	2016-03-05 18:29:27.960352230 +0100
+@@ -139,9 +139,9 @@
+ {
+     currentPage = 0;
+     //area.add(parentArea, false);
+-    titleFont = new Font(L"nova.ttf", 26);
+-    buttonFont = new Font(L"laudcn2.ttf", 14);
+-    textFont = new Font(L"laudcn2.ttf", 16);
++    titleFont = new Font(L"DejaVuSans.ttf", 26);
++    buttonFont = new Font(L"DejaVuSans.ttf", 14);
++    textFont = new Font(L"DejaVuSans.ttf", 16);
+     textHeight = (int)(textFont->getHeight(L"A") * 1.0);
+     text = new TextParser(msg(L"rulesText"), *textFont, START_X, START_Y, 
+                 CLIENT_WIDTH, CLIENT_HEIGHT);
+diff -r -u einstein-2.0.orig/font.h einstein-2.0/font.h
+--- einstein-2.0.orig/font.h	2005-08-16 00:33:17.000000000 +0200
++++ einstein-2.0/font.h	2016-03-05 18:22:05.563794039 +0100
+@@ -3,7 +3,7 @@
+ 
+ 
+ #include <string>
+-#include <SDL_ttf.h>
++#include <SDL/SDL_ttf.h>
+ 
+ 
+ class Font
+diff -r -u einstein-2.0.orig/formatter.cpp einstein-2.0/formatter.cpp
+--- einstein-2.0.orig/formatter.cpp	2005-08-14 04:40:58.000000000 +0200
++++ einstein-2.0/formatter.cpp	2016-03-05 18:18:41.146882565 +0100
+@@ -58,7 +58,7 @@
+             if ((c.type == INT_ARG) || (c.type == STRING_ARG) ||
+                     (c.type == FLOAT_ARG) || (c.type == DOUBLE_ARG))
+             {
+-                int no = (int)c.data;
++                long no = (long)c.data;
+                 args[no - 1] = c.type;
+             }
+         }
+@@ -123,7 +123,7 @@
+ std::wstring Formatter::format(std::vector<ArgValue*> &argValues) const
+ {
+     std::wstring s;
+-    int no;
++    long no;
+ 
+     for (int i = 0; i < commandsCnt; i++) {
+         Command *cmd = &commands[i];
+@@ -135,8 +135,8 @@
+                 
+             case STRING_ARG:
+             case INT_ARG:
+-                no = (int)cmd->data - 1;
+-                if (no < (int)argValues.size())
++                no = (long)cmd->data - 1;
++                if (no < (long)argValues.size())
+                     s += argValues[no]->format(cmd);
+                 break;
+ 
+diff -r -u einstein-2.0.orig/game.cpp einstein-2.0/game.cpp
+--- einstein-2.0.orig/game.cpp	2005-08-23 00:44:54.000000000 +0200
++++ einstein-2.0/game.cpp	2016-03-05 18:29:27.960352230 +0100
+@@ -33,7 +33,7 @@
+     screen.draw(8, 10, tile);
+     SDL_FreeSurface(tile);
+     
+-    Font titleFont(L"nova.ttf", 28);
++    Font titleFont(L"DejaVuSans.ttf", 28);
+     titleFont.draw(screen.getSurface(), 20, 20, 255,255,0, true, 
+             msg(L"einsteinPuzzle"));
+     
+@@ -89,7 +89,7 @@
+ {
+     lastRun = elapsed = lastUpdate = 0;
+     stop();
+-    font = new Font(L"luximb.ttf", 16);
++    font = new Font(L"DejaVuSans.ttf", 16);
+ }
+ 
+ Watch::Watch(std::istream &stream)
+@@ -97,7 +97,7 @@
+     elapsed = readInt(stream);
+     lastUpdate = 0;
+     stop();
+-    font = new Font(L"luximb.ttf", 16);
++    font = new Font(L"DejaVuSans.ttf", 16);
+ }
+ 
+ Watch::~Watch()
+@@ -178,7 +178,7 @@
+             watch->stop();
+             Area area;
+             area.add(background, false);
+-            Font font(L"laudcn2.ttf", 16);
++            Font font(L"DejaVuSans.ttf", 16);
+             area.add(new Window(280, 275, 240, 50, L"greenpattern.bmp", 6));
+             area.add(new Label(&font, 280, 275, 240, 50, Label::ALIGN_CENTER,
+                 Label::ALIGN_MIDDLE, 255,255,0, msg(L"paused")));
+@@ -209,7 +209,7 @@
+         virtual void doAction() {
+             sound->play(L"applause.wav");
+             watch->stop();
+-            Font font(L"laudcn2.ttf", 20);
++            Font font(L"DejaVuSans.ttf", 20);
+             showMessageWindow(gameArea, L"marble1.bmp", 
+                     500, 70, &font, 255,0,0, msg(L"won"));
+             gameArea->draw();
+@@ -257,8 +257,8 @@
+             sound->play(L"glasbk2.wav");
+             bool restart = false;
+             bool newGame = false;
+-            Font font(L"laudcn2.ttf", 24);
+-            Font btnFont(L"laudcn2.ttf", 14);
++            Font font(L"DejaVuSans.ttf", 24);
++            Font btnFont(L"DejaVuSans.ttf", 14);
+             Area area;
+             area.add(gameArea);
+             area.add(new Window(220, 240, 360, 140, L"redpattern.bmp", 6));
+@@ -329,7 +329,7 @@
+         CheatCommand(Area *a) { gameArea = a; };
+         
+         virtual void doAction() {
+-            Font font(L"nova.ttf", 30);
++            Font font(L"DejaVuSans.ttf", 30);
+             showMessageWindow(gameArea, L"darkpattern.bmp", 
+                     500, 100, &font, 255,255,255, 
+                     msg(L"iddqd"));
+@@ -475,7 +475,7 @@
+     drawWallpaper(L"rain.bmp");
+     Window window(230, 260, 340, 80, L"greenpattern.bmp", 6);
+     window.draw();
+-    Font font(L"laudcn2.ttf", 16);
++    Font font(L"DejaVuSans.ttf", 16);
+     Label label(&font, 280, 275, 240, 50, Label::ALIGN_CENTER,
+                 Label::ALIGN_MIDDLE, 255,255,0, msg(L"loading"));
+     label.draw();
+@@ -533,7 +533,7 @@
+ void Game::run()
+ {
+     Area area;
+-    Font btnFont(L"laudcn2.ttf", 14);
++    Font btnFont(L"DejaVuSans.ttf", 14);
+     
+     area.setTimer(300, watch);
+ 
+diff -r -u einstein-2.0.orig/main.cpp einstein-2.0/main.cpp
+--- einstein-2.0.orig/main.cpp	2005-09-26 12:32:54.000000000 +0200
++++ einstein-2.0/main.cpp	2016-03-05 18:29:27.960352230 +0100
+@@ -2,7 +2,7 @@
+ #include <iostream>
+ #include <SDL.h>
+ #include <SDL_main.h>
+-#include <SDL_ttf.h>
++#include <SDL/SDL_ttf.h>
+ #include "main.h"
+ #include "utils.h"
+ #include "storage.h"
+@@ -78,7 +78,7 @@
+ /*static void checkBetaExpire()
+ {
+     if (1124832535L + 60L*60L*24L*40L < time(NULL)) {
+-        Font font(L"laudcn2.ttf", 16);
++        Font font(L"DejaVuSans.ttf", 16);
+         Area area;
+         showMessageWindow(&area, L"darkpattern.bmp", 
+                 700, 100, &font, 255,255,255, 
+diff -r -u einstein-2.0.orig/Makefile einstein-2.0/Makefile
+--- einstein-2.0.orig/Makefile	2005-09-25 23:20:30.000000000 +0200
++++ einstein-2.0/Makefile	2016-03-05 18:14:22.365450608 +0100
+@@ -49,10 +49,14 @@
+ 
+ 
+ $(TARGET): $(OBJECTS)
++	cd mkres && make
++	cd res && ../mkres/mkres --source resources.descr --output ../einstein.res
+ 	$(CXX) $(LNFLAGS) $(OBJECTS) -o $(TARGET)
+ 
+ clean:
+ 	rm -f $(OBJECTS) core* *core $(TARGET) *~
++	cd res && rm -f einstein.res
++	cd mkres && make clean
+ 
+ depend:
+ 	@makedepend $(SOURCES) 2> /dev/null
+diff -r -u einstein-2.0.orig/menu.cpp einstein-2.0/menu.cpp
+--- einstein-2.0.orig/menu.cpp	2005-09-25 22:51:00.000000000 +0200
++++ einstein-2.0/menu.cpp	2016-03-05 18:29:27.960352230 +0100
+@@ -23,11 +23,11 @@
+     SDL_Surface *title = loadImage(L"nova.bmp");
+     screen.draw(0, 0, title);
+     SDL_FreeSurface(title);
+-    Font font(L"nova.ttf", 28);
++    Font font(L"DejaVuSans.ttf", 28);
+     std::wstring s(msg(L"einsteinFlowix"));
+     int width = font.getWidth(s);
+     font.draw((screen.getWidth() - width) / 2, 30, 255,255,255, true, s);
+-    Font urlFont(L"luximb.ttf", 16);
++    Font urlFont(L"DejaVuSans.ttf", 16);
+     s = L"http://games.flowix.com";
+     width = urlFont.getWidth(s);
+     urlFont.draw((screen.getWidth() - width) / 2, 60, 255,255,0, true, s);
+@@ -133,9 +133,9 @@
+ 
+         virtual void doAction() {
+             Area area;
+-            Font titleFont(L"nova.ttf", 26);
+-            Font font(L"laudcn2.ttf", 14);
+-            Font urlFont(L"luximb.ttf", 16);
++            Font titleFont(L"DejaVuSans.ttf", 26);
++            Font font(L"DejaVuSans.ttf", 14);
++            Font urlFont(L"DejaVuSans.ttf", 16);
+ 
+ #define LABEL(pos, c, f, text) area.add(new Label(&f, 220, pos, 360, 20, \
+             Label::ALIGN_CENTER, Label::ALIGN_MIDDLE, 255,255,c, text));
+@@ -171,7 +171,7 @@
+ void menu()
+ {
+     Area area;
+-    Font font(L"laudcn2.ttf", 20);
++    Font font(L"DejaVuSans.ttf", 20);
+ 
+     area.add(new MenuBackground());
+     area.draw();
+diff -r -u einstein-2.0.orig/mkres/compressor.cpp einstein-2.0/mkres/compressor.cpp
+--- einstein-2.0.orig/mkres/compressor.cpp	2005-08-14 04:40:58.000000000 +0200
++++ einstein-2.0/mkres/compressor.cpp	2016-03-05 18:26:13.194264129 +0100
+@@ -2,6 +2,7 @@
+ #include <zlib.h>
+ #include "convert.h"
+ #include "exceptions.h"
++#include "string.h"
+ 
+ 
+ ResourceCompressor::ResourceCompressor() 
+diff -r -u einstein-2.0.orig/mkres/convert.h einstein-2.0/mkres/convert.h
+--- einstein-2.0.orig/mkres/convert.h	2005-08-14 04:40:58.000000000 +0200
++++ einstein-2.0/mkres/convert.h	2016-03-05 18:25:21.479990669 +0100
+@@ -5,6 +5,7 @@
+ #include <iostream>
+ #include <sstream>
+ #include <string>
++#include <typeinfo>
+ 
+ #include "exceptions.h"
+ #include "unicode.h"
+diff -r -u einstein-2.0.orig/mkres/main.cpp einstein-2.0/mkres/main.cpp
+--- einstein-2.0.orig/mkres/main.cpp	2005-08-14 04:40:58.000000000 +0200
++++ einstein-2.0/mkres/main.cpp	2016-03-05 18:25:55.062765900 +0100
+@@ -1,5 +1,6 @@
+ #include "compressor.h"
+ #include "exceptions.h"
++#include "string.h"
+ #include "unicode.h"
+ #include "table.h"
+ 
+diff -r -u einstein-2.0.orig/mkres/unicode.cpp einstein-2.0/mkres/unicode.cpp
+--- einstein-2.0.orig/mkres/unicode.cpp	2005-08-14 04:40:58.000000000 +0200
++++ einstein-2.0/mkres/unicode.cpp	2016-03-05 18:26:28.065492890 +0100
+@@ -5,6 +5,7 @@
+ #endif
+ #include "unicode.h"
+ #include "exceptions.h"
++#include "string.h"
+ 
+ 
+ /// Returns length of wide character in utf-8
+diff -r -u einstein-2.0.orig/opensave.cpp einstein-2.0/opensave.cpp
+--- einstein-2.0.orig/opensave.cpp	2005-08-14 23:33:36.000000000 +0200
++++ einstein-2.0/opensave.cpp	2016-03-05 18:29:27.960352230 +0100
+@@ -160,7 +160,7 @@
+ static void showListWindow(SavesList &list, Command **commands,
+         const std::wstring &title, Area &area, Font *font)
+ {
+-    Font titleFont(L"nova.ttf", 26);
++    Font titleFont(L"DejaVuSans.ttf", 26);
+ 
+     area.add(new Window(250, 90, 300, 420, L"blue.bmp"));
+     area.add(new Label(&titleFont, 250, 95, 300, 40, Label::ALIGN_CENTER,
+@@ -189,7 +189,7 @@
+     
+     Area area;
+     area.add(parentArea, false);
+-    Font font(L"laudcn2.ttf", 14);
++    Font font(L"DejaVuSans.ttf", 14);
+     bool saved = false;
+     
+     SavesList list;
+@@ -258,7 +258,7 @@
+     
+     Area area;
+     area.add(parentArea, false);
+-    Font font(L"laudcn2.ttf", 14);
++    Font font(L"DejaVuSans.ttf", 14);
+     
+     Game *newGame = NULL;
+     
+diff -r -u einstein-2.0.orig/options.cpp einstein-2.0/options.cpp
+--- einstein-2.0.orig/options.cpp	2005-09-26 12:33:18.000000000 +0200
++++ einstein-2.0/options.cpp	2016-03-05 18:29:27.960352230 +0100
+@@ -53,8 +53,8 @@
+ 
+ void showOptionsWindow(Area *parentArea)
+ {
+-    Font titleFont(L"nova.ttf", 26);
+-    Font font(L"laudcn2.ttf", 14);
++    Font titleFont(L"DejaVuSans.ttf", 26);
++    Font font(L"DejaVuSans.ttf", 14);
+ 
+     bool fullscreen = (getStorage()->get(L"fullscreen", 1) != 0);
+     bool niceCursor = (getStorage()->get(L"niceCursor", 1) != 0);
+diff -r -u einstein-2.0.orig/res/resources.descr einstein-2.0/res/resources.descr
+--- einstein-2.0.orig/res/resources.descr	2005-09-25 22:51:14.000000000 +0200
++++ einstein-2.0/res/resources.descr	2016-03-05 18:30:08.563704873 +0100
+@@ -89,13 +89,11 @@
+     { name = "title.bmp" }
+     { name = "marble1.bmp" }
+     { name = "blue.bmp" }
+-    { name = "luximb.ttf" }
+     { name = "redpattern.bmp" }
+     { name = "greenpattern.bmp" }
+     { name = "darkpattern.bmp" }
+     { name = "nova.bmp" }
+-    { name = "nova.ttf" }
+-    { name = "laudcn2.ttf" }
++    { name = "DejaVuSans.ttf" }
+     { name = "btn.bmp" }
+     { name = "rules.txt", format = "messages" group = "messages" }
+     { name = "rules_ru.txt", format = "messages" group = "messages" }
+Only in einstein-2.0/res: resources.descr.orig
+diff -r -u einstein-2.0.orig/sound.h einstein-2.0/sound.h
+--- einstein-2.0.orig/sound.h	2005-09-24 08:24:20.000000000 +0200
++++ einstein-2.0/sound.h	2016-03-05 18:22:19.314931225 +0100
+@@ -4,7 +4,7 @@
+ 
+ #include <string>
+ #include <map>
+-#include <SDL_mixer.h>
++#include <SDL/SDL_mixer.h>
+ 
+ 
+ class Sound
+diff -r -u einstein-2.0.orig/topscores.cpp einstein-2.0/topscores.cpp
+--- einstein-2.0.orig/topscores.cpp	2005-08-14 23:08:43.000000000 +0200
++++ einstein-2.0/topscores.cpp	2016-03-05 18:29:27.970353055 +0100
+@@ -103,9 +103,9 @@
+ ScoresWindow::ScoresWindow(int x, int y, TopScores *scores, int highlight): 
+                 Window(x, y, 320, 350, L"blue.bmp")
+ {
+-    Font titleFont(L"nova.ttf", 26);
+-    Font entryFont(L"laudcn2.ttf", 14);
+-    Font timeFont(L"luximb.ttf", 14);
++    Font titleFont(L"DejaVuSans.ttf", 26);
++    Font entryFont(L"DejaVuSans.ttf", 14);
++    Font timeFont(L"DejaVuSans.ttf", 14);
+     
+     std::wstring txt = msg(L"topScores");
+     int w = titleFont.getWidth(txt);
+@@ -139,7 +139,7 @@
+ {
+     Area area;
+ 
+-    Font font(L"laudcn2.ttf", 16);
++    Font font(L"DejaVuSans.ttf", 16);
+     area.add(parentArea);
+     area.add(new ScoresWindow(240, 125, scores, highlight));
+     ExitCommand exitCmd(area);
+@@ -154,7 +154,7 @@
+ {
+     Area area;
+     
+-    Font font(L"laudcn2.ttf", 16);
++    Font font(L"DejaVuSans.ttf", 16);
+     area.add(parentArea);
+     area.add(new Window(170, 280, 460, 100, L"blue.bmp"));
+     Storage *storage = getStorage();
+diff -r -u einstein-2.0.orig/unicode.cpp einstein-2.0/unicode.cpp
+--- einstein-2.0.orig/unicode.cpp	2005-08-14 04:40:58.000000000 +0200
++++ einstein-2.0/unicode.cpp	2016-03-05 18:26:55.747780024 +0100
+@@ -5,6 +5,7 @@
+ #endif
+ #include "unicode.h"
+ #include "exceptions.h"
++#include "string.h"
+ 
+ 
+ /// Returns length of wide character in utf-8
diff --git a/gnu/packages/patches/gitolite-openssh-6.8-compat.patch b/gnu/packages/patches/gitolite-openssh-6.8-compat.patch
deleted file mode 100644
index d7fc2e6b12..0000000000
--- a/gnu/packages/patches/gitolite-openssh-6.8-compat.patch
+++ /dev/null
@@ -1,25 +0,0 @@
-From ed807a40c6683960e357bc995b3acf721ec088b4 Mon Sep 17 00:00:00 2001
-From: Sitaram Chamarty <sitaram@atc.tcs.com>
-Date: Thu, 19 Mar 2015 05:17:59 +0530
-Subject: [PATCH] openssh 6.8 compat
-
----
- src/triggers/post-compile/ssh-authkeys | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/src/triggers/post-compile/ssh-authkeys b/src/triggers/post-compile/ssh-authkeys
-index 84dda73..d5f5d8b 100755
---- a/src/triggers/post-compile/ssh-authkeys
-+++ b/src/triggers/post-compile/ssh-authkeys
-@@ -115,7 +115,7 @@ sub fp_file {
-     my $f  = shift;
-     my $fp = `ssh-keygen -l -f '$f'`;
-     chomp($fp);
--    _die "fingerprinting failed for '$f'" unless $fp =~ /([0-9a-f][0-9a-f](:[0-9a-f][0-9a-f])+)/;
-+    _die "fingerprinting failed for '$f'" unless $fp =~ /([0-9a-f][0-9a-f](:[0-9a-f][0-9a-f])+)/ or $fp =~ m(SHA256:([A-ZA-z0-9+/]+));
-     $fp = $1;
-     return $fp;
- }
---
-2.2.1
-
diff --git a/gnu/packages/patches/icecat-CVE-2015-4477.patch b/gnu/packages/patches/icecat-CVE-2015-4477.patch
new file mode 100644
index 0000000000..c010c5ecec
--- /dev/null
+++ b/gnu/packages/patches/icecat-CVE-2015-4477.patch
@@ -0,0 +1,37 @@
+Copied from upstream:
+https://hg.mozilla.org/releases/mozilla-esr38/raw-rev/beae8783b8c2
+
+# HG changeset patch
+# User Paul Adenot <paul@paul.cx>
+# Date 1456422965 0
+# Node ID beae8783b8c2c672da12a95c70ae663cbd0d5016
+# Parent  3a606f8182c82480f8f350b622ab55a170ec1eb6
+Bug 1179484. r=roc
+
+MozReview-Commit-ID: HNaYLyMe3sM
+
+diff --git a/dom/media/webaudio/MediaStreamAudioDestinationNode.cpp b/dom/media/webaudio/MediaStreamAudioDestinationNode.cpp
+--- a/dom/media/webaudio/MediaStreamAudioDestinationNode.cpp
++++ b/dom/media/webaudio/MediaStreamAudioDestinationNode.cpp
+@@ -69,16 +69,20 @@ MediaStreamAudioDestinationNode::MediaSt
+               ChannelInterpretation::Speakers)
+   , mDOMStream(DOMAudioNodeMediaStream::CreateTrackUnionStream(GetOwner(),
+                                                                this))
+ {
+   TrackUnionStream* tus = static_cast<TrackUnionStream*>(mDOMStream->GetStream());
+   MOZ_ASSERT(tus == mDOMStream->GetStream()->AsProcessedStream());
+   tus->SetTrackIDFilter(FilterAudioNodeStreamTrack);
+ 
++  if (aContext->Graph() != tus->Graph()) {
++    return;
++  }
++
+   MediaStreamDestinationEngine* engine = new MediaStreamDestinationEngine(this, tus);
+   mStream = aContext->Graph()->CreateAudioNodeStream(engine, MediaStreamGraph::INTERNAL_STREAM);
+   mPort = tus->AllocateInputPort(mStream, 0);
+ 
+   nsIDocument* doc = aContext->GetParentObject()->GetExtantDoc();
+   if (doc) {
+     mDOMStream->CombineWithPrincipal(doc->NodePrincipal());
+   }
+
diff --git a/gnu/packages/patches/icecat-CVE-2015-7207.patch b/gnu/packages/patches/icecat-CVE-2015-7207.patch
new file mode 100644
index 0000000000..db5fc6ce66
--- /dev/null
+++ b/gnu/packages/patches/icecat-CVE-2015-7207.patch
@@ -0,0 +1,1140 @@
+Copied from upstream:
+https://hg.mozilla.org/releases/mozilla-esr38/raw-rev/532544c91db7
+
+# HG changeset patch
+# User Dragana Damjanovic <dd.mozilla@gmail.com>
+# Date 1456962626 28800
+# Node ID 532544c91db7f13c39be1b7b7c4461cd03126e9c
+# Parent  f4220254d5bd0851a439467da39ba431e0ce2804
+Bug 1185256 - Save originURI to the history. r=bz ba=ritu
+
+MozReview-Commit-ID: Lvh9C84RQUc
+
+diff --git a/docshell/base/nsDocShell.cpp b/docshell/base/nsDocShell.cpp
+--- a/docshell/base/nsDocShell.cpp
++++ b/docshell/base/nsDocShell.cpp
+@@ -1020,16 +1020,17 @@ nsDocShell::DestroyChildren()
+ //*****************************************************************************
+ // nsDocShell::nsISupports
+ //*****************************************************************************
+ 
+ NS_IMPL_ADDREF_INHERITED(nsDocShell, nsDocLoader)
+ NS_IMPL_RELEASE_INHERITED(nsDocShell, nsDocLoader)
+ 
+ NS_INTERFACE_MAP_BEGIN(nsDocShell)
++  NS_INTERFACE_MAP_ENTRY(nsIDocShell_ESR38_2)
+   NS_INTERFACE_MAP_ENTRY(nsIDocShell_ESR38)
+   NS_INTERFACE_MAP_ENTRY(nsIDocShell)
+   NS_INTERFACE_MAP_ENTRY(nsIDocShellTreeItem)
+   NS_INTERFACE_MAP_ENTRY(nsIWebNavigation)
+   NS_INTERFACE_MAP_ENTRY(nsIBaseWindow)
+   NS_INTERFACE_MAP_ENTRY(nsIScrollable)
+   NS_INTERFACE_MAP_ENTRY(nsITextScroll)
+   NS_INTERFACE_MAP_ENTRY(nsIDocCharset)
+@@ -1372,16 +1373,17 @@ nsDocShell::LoadURI(nsIURI* aURI,
+     return NS_OK; // JS may not handle returning of an error code
+   }
+ 
+   if (DoAppRedirectIfNeeded(aURI, aLoadInfo, aFirstParty)) {
+     return NS_OK;
+   }
+ 
+   nsCOMPtr<nsIURI> referrer;
++  nsCOMPtr<nsIURI> originalURI;
+   nsCOMPtr<nsIInputStream> postStream;
+   nsCOMPtr<nsIInputStream> headersStream;
+   nsCOMPtr<nsISupports> owner;
+   bool inheritOwner = false;
+   bool ownerIsExplicit = false;
+   bool sendReferrer = true;
+   uint32_t referrerPolicy = mozilla::net::RP_Default;
+   bool isSrcdoc = false;
+@@ -1398,16 +1400,20 @@ nsDocShell::LoadURI(nsIURI* aURI,
+   if (!StartupTimeline::HasRecord(StartupTimeline::FIRST_LOAD_URI) &&
+       mItemType == typeContent && !NS_IsAboutBlank(aURI)) {
+     StartupTimeline::RecordOnce(StartupTimeline::FIRST_LOAD_URI);
+   }
+ 
+   // Extract the info from the DocShellLoadInfo struct...
+   if (aLoadInfo) {
+     aLoadInfo->GetReferrer(getter_AddRefs(referrer));
++    nsCOMPtr<nsIDocShellLoadInfo_ESR38> liESR38 = do_QueryInterface(aLoadInfo);
++    if (liESR38) {
++      liESR38->GetOriginalURI(getter_AddRefs(originalURI));
++    }
+ 
+     nsDocShellInfoLoadType lt = nsIDocShellLoadInfo::loadNormal;
+     aLoadInfo->GetLoadType(&lt);
+     // Get the appropriate loadType from nsIDocShellLoadInfo type
+     loadType = ConvertDocShellLoadInfoToLoadType(lt);
+ 
+     aLoadInfo->GetOwner(getter_AddRefs(owner));
+     aLoadInfo->GetInheritOwner(&inheritOwner);
+@@ -1652,34 +1658,35 @@ nsDocShell::LoadURI(nsIURI* aURI,
+   if (aLoadFlags & LOAD_FLAGS_FORCE_ALLOW_COOKIES) {
+     flags |= INTERNAL_LOAD_FLAGS_FORCE_ALLOW_COOKIES;
+   }
+ 
+   if (isSrcdoc) {
+     flags |= INTERNAL_LOAD_FLAGS_IS_SRCDOC;
+   }
+ 
+-  return InternalLoad(aURI,
+-                      referrer,
+-                      referrerPolicy,
+-                      owner,
+-                      flags,
+-                      target.get(),
+-                      nullptr,      // No type hint
+-                      NullString(), // No forced download
+-                      postStream,
+-                      headersStream,
+-                      loadType,
+-                      nullptr, // No SHEntry
+-                      aFirstParty,
+-                      srcdoc,
+-                      sourceDocShell,
+-                      baseURI,
+-                      nullptr,  // No nsIDocShell
+-                      nullptr); // No nsIRequest
++  return InternalLoad2(aURI,
++                       originalURI,
++                       referrer,
++                       referrerPolicy,
++                       owner,
++                       flags,
++                       target.get(),
++                       nullptr,      // No type hint
++                       NullString(), // No forced download
++                       postStream,
++                       headersStream,
++                       loadType,
++                       nullptr, // No SHEntry
++                       aFirstParty,
++                       srcdoc,
++                       sourceDocShell,
++                       baseURI,
++                       nullptr,  // No nsIDocShell
++                       nullptr); // No nsIRequest
+ }
+ 
+ NS_IMETHODIMP
+ nsDocShell::LoadStream(nsIInputStream* aStream, nsIURI* aURI,
+                        const nsACString& aContentType,
+                        const nsACString& aContentCharset,
+                        nsIDocShellLoadInfo* aLoadInfo)
+ {
+@@ -5398,21 +5405,21 @@ nsDocShell::LoadErrorPage(nsIURI* aURI, 
+   // end of the URL, so append it last.
+   errorPageUrl.AppendLiteral("&d=");
+   errorPageUrl.AppendASCII(escapedDescription.get());
+ 
+   nsCOMPtr<nsIURI> errorPageURI;
+   rv = NS_NewURI(getter_AddRefs(errorPageURI), errorPageUrl);
+   NS_ENSURE_SUCCESS(rv, rv);
+ 
+-  return InternalLoad(errorPageURI, nullptr, mozilla::net::RP_Default,
+-                      nullptr, INTERNAL_LOAD_FLAGS_INHERIT_OWNER, nullptr,
+-                      nullptr, NullString(), nullptr, nullptr, LOAD_ERROR_PAGE,
+-                      nullptr, true, NullString(), this, nullptr, nullptr,
+-                      nullptr);
++  return InternalLoad2(errorPageURI, nullptr, nullptr, mozilla::net::RP_Default,
++                       nullptr, INTERNAL_LOAD_FLAGS_INHERIT_OWNER, nullptr,
++                       nullptr, NullString(), nullptr, nullptr, LOAD_ERROR_PAGE,
++                       nullptr, true, NullString(), this, nullptr, nullptr,
++                       nullptr);
+ }
+ 
+ NS_IMETHODIMP
+ nsDocShell::Reload(uint32_t aReloadFlags)
+ {
+   if (!IsNavigationAllowed()) {
+     return NS_OK; // JS may not handle returning of an error code
+   }
+@@ -5448,44 +5455,54 @@ nsDocShell::Reload(uint32_t aReloadFlags
+     nsCOMPtr<nsIDocument> doc(GetDocument());
+ 
+     // Do not inherit owner from document
+     uint32_t flags = INTERNAL_LOAD_FLAGS_NONE;
+     nsAutoString srcdoc;
+     nsIPrincipal* principal = nullptr;
+     nsAutoString contentTypeHint;
+     nsCOMPtr<nsIURI> baseURI;
++    nsCOMPtr<nsIURI> originalURI;
+     if (doc) {
+       principal = doc->NodePrincipal();
+       doc->GetContentType(contentTypeHint);
+ 
+       if (doc->IsSrcdocDocument()) {
+         doc->GetSrcdocData(srcdoc);
+         flags |= INTERNAL_LOAD_FLAGS_IS_SRCDOC;
+         baseURI = doc->GetBaseURI();
+       }
+-    }
+-    rv = InternalLoad(mCurrentURI,
+-                      mReferrerURI,
+-                      mReferrerPolicy,
+-                      principal,
+-                      flags,
+-                      nullptr,         // No window target
+-                      NS_LossyConvertUTF16toASCII(contentTypeHint).get(),
+-                      NullString(),    // No forced download
+-                      nullptr,         // No post data
+-                      nullptr,         // No headers data
+-                      loadType,        // Load type
+-                      nullptr,         // No SHEntry
+-                      true,
+-                      srcdoc,          // srcdoc argument for iframe
+-                      this,            // For reloads we are the source
+-                      baseURI,
+-                      nullptr,         // No nsIDocShell
+-                      nullptr);        // No nsIRequest
++      nsCOMPtr<nsIChannel> chan = doc->GetChannel();
++      if (chan) {
++        nsCOMPtr<nsIHttpChannel> httpChan(do_QueryInterface(chan));
++        if (httpChan) {
++          httpChan->GetOriginalURI(getter_AddRefs(originalURI));
++        }
++      } 
++    }
++
++    rv = InternalLoad2(mCurrentURI,
++                       originalURI,
++                       mReferrerURI,
++                       mReferrerPolicy,
++                       principal,
++                       flags,
++                       nullptr,         // No window target
++                       NS_LossyConvertUTF16toASCII(contentTypeHint).get(),
++                       NullString(),    // No forced download
++                       nullptr,         // No post data
++                       nullptr,         // No headers data
++                       loadType,        // Load type
++                       nullptr,         // No SHEntry
++                       true,
++                       srcdoc,          // srcdoc argument for iframe
++                       this,            // For reloads we are the source
++                       baseURI,
++                       nullptr,         // No nsIDocShell
++                       nullptr);        // No nsIRequest
+   }
+ 
+   return rv;
+ }
+ 
+ NS_IMETHODIMP
+ nsDocShell::Stop(uint32_t aStopFlags)
+ {
+@@ -9463,27 +9480,28 @@ CopyFavicon(nsIURI* aOldURI, nsIURI* aNe
+ #endif
+ }
+ 
+ } // anonymous namespace
+ 
+ class InternalLoadEvent : public nsRunnable
+ {
+ public:
+-  InternalLoadEvent(nsDocShell* aDocShell, nsIURI* aURI,
++  InternalLoadEvent(nsDocShell* aDocShell, nsIURI* aURI, nsIURI* aOriginalURI,
+                     nsIURI* aReferrer, uint32_t aReferrerPolicy,
+                     nsISupports* aOwner, uint32_t aFlags,
+                     const char* aTypeHint, nsIInputStream* aPostData,
+                     nsIInputStream* aHeadersData, uint32_t aLoadType,
+                     nsISHEntry* aSHEntry, bool aFirstParty,
+                     const nsAString& aSrcdoc, nsIDocShell* aSourceDocShell,
+                     nsIURI* aBaseURI)
+     : mSrcdoc(aSrcdoc)
+     , mDocShell(aDocShell)
+     , mURI(aURI)
++    , mOriginalURI(aOriginalURI)
+     , mReferrer(aReferrer)
+     , mReferrerPolicy(aReferrerPolicy)
+     , mOwner(aOwner)
+     , mPostData(aPostData)
+     , mHeadersData(aHeadersData)
+     , mSHEntry(aSHEntry)
+     , mFlags(aFlags)
+     , mLoadType(aLoadType)
+@@ -9494,34 +9512,36 @@ public:
+     // Make sure to keep null things null as needed
+     if (aTypeHint) {
+       mTypeHint = aTypeHint;
+     }
+   }
+ 
+   NS_IMETHOD Run()
+   {
+-    return mDocShell->InternalLoad(mURI, mReferrer,
+-                                   mReferrerPolicy,
+-                                   mOwner, mFlags,
+-                                   nullptr, mTypeHint.get(),
+-                                   NullString(), mPostData, mHeadersData,
+-                                   mLoadType, mSHEntry, mFirstParty,
+-                                   mSrcdoc, mSourceDocShell, mBaseURI,
+-                                   nullptr, nullptr);
++    return mDocShell->InternalLoad2(mURI, mOriginalURI,
++                                    mReferrer,
++                                    mReferrerPolicy,
++                                    mOwner, mFlags,
++                                    nullptr, mTypeHint.get(),
++                                    NullString(), mPostData, mHeadersData,
++                                    mLoadType, mSHEntry, mFirstParty,
++                                    mSrcdoc, mSourceDocShell, mBaseURI,
++                                    nullptr, nullptr);
+   }
+ 
+ private:
+   // Use IDL strings so .get() returns null by default
+   nsXPIDLString mWindowTarget;
+   nsXPIDLCString mTypeHint;
+   nsString mSrcdoc;
+ 
+   nsRefPtr<nsDocShell> mDocShell;
+   nsCOMPtr<nsIURI> mURI;
++  nsCOMPtr<nsIURI> mOriginalURI;
+   nsCOMPtr<nsIURI> mReferrer;
+   uint32_t mReferrerPolicy;
+   nsCOMPtr<nsISupports> mOwner;
+   nsCOMPtr<nsIInputStream> mPostData;
+   nsCOMPtr<nsIInputStream> mHeadersData;
+   nsCOMPtr<nsISHEntry> mSHEntry;
+   uint32_t mFlags;
+   uint32_t mLoadType;
+@@ -9584,16 +9604,43 @@ nsDocShell::InternalLoad(nsIURI* aURI,
+                          nsISHEntry* aSHEntry,
+                          bool aFirstParty,
+                          const nsAString& aSrcdoc,
+                          nsIDocShell* aSourceDocShell,
+                          nsIURI* aBaseURI,
+                          nsIDocShell** aDocShell,
+                          nsIRequest** aRequest)
+ {
++  return InternalLoad2(aURI, nullptr, aReferrer, aReferrerPolicy, aOwner,
++                       aFlags, aWindowTarget, aTypeHint, aFileName, aPostData,
++                       aHeadersData, aLoadType, aSHEntry, aFirstParty, aSrcdoc,
++                       aSourceDocShell, aBaseURI, aDocShell, aRequest);
++}
++
++NS_IMETHODIMP
++nsDocShell::InternalLoad2(nsIURI* aURI,
++                          nsIURI* aOriginalURI,
++                          nsIURI* aReferrer,
++                          uint32_t aReferrerPolicy,
++                          nsISupports* aOwner,
++                          uint32_t aFlags,
++                          const char16_t* aWindowTarget,
++                          const char* aTypeHint,
++                          const nsAString& aFileName,
++                          nsIInputStream* aPostData,
++                          nsIInputStream* aHeadersData,
++                          uint32_t aLoadType,
++                          nsISHEntry* aSHEntry,
++                          bool aFirstParty,
++                          const nsAString& aSrcdoc,
++                          nsIDocShell* aSourceDocShell,
++                          nsIURI* aBaseURI,
++                          nsIDocShell** aDocShell,
++                          nsIRequest** aRequest)
++{
+   nsresult rv = NS_OK;
+   mOriginalUriString.Truncate();
+ 
+ #ifdef PR_LOGGING
+   if (gDocShellLeakLog && PR_LOG_TEST(gDocShellLeakLog, PR_LOG_DEBUG)) {
+     nsAutoCString spec;
+     if (aURI) {
+       aURI->GetSpec(spec);
+@@ -9831,34 +9878,58 @@ nsDocShell::InternalLoad(nsIURI* aURI,
+       targetDocShell = do_QueryInterface(webNav);
+     }
+ 
+     //
+     // Transfer the load to the target DocShell...  Pass nullptr as the
+     // window target name from to prevent recursive retargeting!
+     //
+     if (NS_SUCCEEDED(rv) && targetDocShell) {
+-      rv = targetDocShell->InternalLoad(aURI,
+-                                        aReferrer,
+-                                        aReferrerPolicy,
+-                                        owner,
+-                                        aFlags,
+-                                        nullptr,         // No window target
+-                                        aTypeHint,
+-                                        NullString(),    // No forced download
+-                                        aPostData,
+-                                        aHeadersData,
+-                                        aLoadType,
+-                                        aSHEntry,
+-                                        aFirstParty,
+-                                        aSrcdoc,
+-                                        aSourceDocShell,
+-                                        aBaseURI,
+-                                        aDocShell,
+-                                        aRequest);
++      nsCOMPtr<nsIDocShell_ESR38_2> dsESR38 = do_QueryInterface(targetDocShell);
++      if (dsESR38) {
++        rv = dsESR38->InternalLoad2(aURI,
++                                    aOriginalURI,
++                                    aReferrer,
++                                    aReferrerPolicy,
++                                    owner,
++                                    aFlags,
++                                    nullptr,         // No window target
++                                    aTypeHint,
++                                    NullString(),    // No forced download
++                                    aPostData,
++                                    aHeadersData,
++                                    aLoadType,
++                                    aSHEntry,
++                                    aFirstParty,
++                                    aSrcdoc,
++                                    aSourceDocShell,
++                                    aBaseURI,
++                                    aDocShell,
++                                    aRequest);
++      } else {
++        rv = targetDocShell->InternalLoad(aURI,
++                                          aReferrer,
++                                          aReferrerPolicy,
++                                          owner,
++                                          aFlags,
++                                          nullptr,         // No window target
++                                          aTypeHint,
++                                          NullString(),    // No forced download
++                                          aPostData,
++                                          aHeadersData,
++                                          aLoadType,
++                                          aSHEntry,
++                                          aFirstParty,
++                                          aSrcdoc,
++                                          aSourceDocShell,
++                                          aBaseURI,
++                                          aDocShell,
++                                          aRequest);
++      }
++
+       if (rv == NS_ERROR_NO_CONTENT) {
+         // XXXbz except we never reach this code!
+         if (isNewWindow) {
+           //
+           // At this point, a new window has been created, but the
+           // URI did not have any data associated with it...
+           //
+           // So, the best we can do, is to tear down the new window
+@@ -9913,17 +9984,17 @@ nsDocShell::InternalLoad(nsIURI* aURI,
+       // the unload event also a replace load, so we don't
+       // create extra history entries.
+       if (LOAD_TYPE_HAS_FLAGS(aLoadType, LOAD_FLAGS_REPLACE_HISTORY)) {
+         mLoadType = LOAD_NORMAL_REPLACE;
+       }
+ 
+       // Do this asynchronously
+       nsCOMPtr<nsIRunnable> ev =
+-        new InternalLoadEvent(this, aURI, aReferrer,
++        new InternalLoadEvent(this, aURI, aOriginalURI, aReferrer,
+                               aReferrerPolicy, aOwner, aFlags,
+                               aTypeHint, aPostData, aHeadersData,
+                               aLoadType, aSHEntry, aFirstParty, aSrcdoc,
+                               aSourceDocShell, aBaseURI);
+       return NS_DispatchToCurrentThread(ev);
+     }
+ 
+     // Just ignore this load attempt
+@@ -10371,17 +10442,17 @@ nsDocShell::InternalLoad(nsIURI* aURI,
+   }
+ 
+   net::PredictorLearn(aURI, nullptr,
+                       nsINetworkPredictor::LEARN_LOAD_TOPLEVEL, this);
+   net::PredictorPredict(aURI, nullptr,
+                         nsINetworkPredictor::PREDICT_LOAD, this, nullptr);
+ 
+   nsCOMPtr<nsIRequest> req;
+-  rv = DoURILoad(aURI, aReferrer,
++  rv = DoURILoad(aURI, aOriginalURI, aReferrer,
+                  !(aFlags & INTERNAL_LOAD_FLAGS_DONT_SEND_REFERRER),
+                  aReferrerPolicy,
+                  owner, aTypeHint, aFileName, aPostData, aHeadersData,
+                  aFirstParty, aDocShell, getter_AddRefs(req),
+                  (aFlags & INTERNAL_LOAD_FLAGS_FIRST_LOAD) != 0,
+                  (aFlags & INTERNAL_LOAD_FLAGS_BYPASS_CLASSIFIER) != 0,
+                  (aFlags & INTERNAL_LOAD_FLAGS_FORCE_ALLOW_COOKIES) != 0,
+                  srcdoc, aBaseURI, contentType);
+@@ -10445,16 +10516,17 @@ nsDocShell::GetInheritedPrincipal(bool a
+     return docPrincipal;
+   }
+ 
+   return nullptr;
+ }
+ 
+ nsresult
+ nsDocShell::DoURILoad(nsIURI* aURI,
++                      nsIURI* aOriginalURI,
+                       nsIURI* aReferrerURI,
+                       bool aSendReferrer,
+                       uint32_t aReferrerPolicy,
+                       nsISupports* aOwner,
+                       const char* aTypeHint,
+                       const nsAString& aFileName,
+                       nsIInputStream* aPostData,
+                       nsIInputStream* aHeadersData,
+@@ -10652,17 +10724,22 @@ nsDocShell::DoURILoad(nsIURI* aURI,
+   }
+ 
+   // Make sure to give the caller a channel if we managed to create one
+   // This is important for correct error page/session history interaction
+   if (aRequest) {
+     NS_ADDREF(*aRequest = channel);
+   }
+ 
+-  channel->SetOriginalURI(aURI);
++  if (aOriginalURI) {
++    channel->SetOriginalURI(aOriginalURI);
++  } else {
++    channel->SetOriginalURI(aURI);
++  }
++
+   if (aTypeHint && *aTypeHint) {
+     channel->SetContentType(nsDependentCString(aTypeHint));
+     mContentTypeHint = aTypeHint;
+   } else {
+     mContentTypeHint.Truncate();
+   }
+ 
+   if (!aFileName.IsVoid()) {
+@@ -11624,16 +11701,20 @@ nsDocShell::AddState(JS::Handle<JS::Valu
+ 
+     // AddToSessionHistory may not modify mOSHE.  In case it doesn't,
+     // we'll just set mOSHE here.
+     mOSHE = newSHEntry;
+ 
+   } else {
+     newSHEntry = mOSHE;
+     newSHEntry->SetURI(newURI);
++    nsCOMPtr<nsISHEntry_ESR38> entryESR38 = do_QueryInterface(newSHEntry);
++    if (entryESR38) {
++      entryESR38->SetOriginalURI(newURI);
++    }
+   }
+ 
+   // Step 4: Modify new/original session history entry and clear its POST
+   // data, if there is any.
+   newSHEntry->SetStateData(scContainer);
+   newSHEntry->SetPostData(nullptr);
+ 
+   // If this push/replaceState changed the document's current URI and the new
+@@ -11816,16 +11897,17 @@ nsDocShell::AddToSessionHistory(nsIURI* 
+ 
+     if (!entry) {
+       return NS_ERROR_OUT_OF_MEMORY;
+     }
+   }
+ 
+   // Get the post data & referrer
+   nsCOMPtr<nsIInputStream> inputStream;
++  nsCOMPtr<nsIURI> originalURI;
+   nsCOMPtr<nsIURI> referrerURI;
+   uint32_t referrerPolicy = mozilla::net::RP_Default;
+   nsCOMPtr<nsISupports> cacheKey;
+   nsCOMPtr<nsISupports> owner = aOwner;
+   bool expired = false;
+   bool discardLayoutState = false;
+   nsCOMPtr<nsICachingChannel> cacheChannel;
+   if (aChannel) {
+@@ -11843,16 +11925,17 @@ nsDocShell::AddToSessionHistory(nsIURI* 
+     if (!httpChannel) {
+       GetHttpChannel(aChannel, getter_AddRefs(httpChannel));
+     }
+     if (httpChannel) {
+       nsCOMPtr<nsIUploadChannel> uploadChannel(do_QueryInterface(httpChannel));
+       if (uploadChannel) {
+         uploadChannel->GetUploadStream(getter_AddRefs(inputStream));
+       }
++      httpChannel->GetOriginalURI(getter_AddRefs(originalURI));
+       httpChannel->GetReferrer(getter_AddRefs(referrerURI));
+       httpChannel->GetReferrerPolicy(&referrerPolicy);
+ 
+       discardLayoutState = ShouldDiscardLayoutState(httpChannel);
+     }
+     aChannel->GetOwner(getter_AddRefs(owner));
+     if (!owner) {
+       nsCOMPtr<nsILoadInfo> loadInfo;
+@@ -11875,16 +11958,21 @@ nsDocShell::AddToSessionHistory(nsIURI* 
+                 EmptyString(),     // Title
+                 inputStream,       // Post data stream
+                 nullptr,           // LayoutHistory state
+                 cacheKey,          // CacheKey
+                 mContentTypeHint,  // Content-type
+                 owner,             // Channel or provided owner
+                 mHistoryID,
+                 mDynamicallyCreated);
++
++  nsCOMPtr<nsISHEntry_ESR38> entryESR38 = do_QueryInterface(entry);
++  if (entryESR38) {
++    entryESR38->SetOriginalURI(originalURI);
++  }
+   entry->SetReferrerURI(referrerURI);
+   entry->SetReferrerPolicy(referrerPolicy);
+   nsCOMPtr<nsIInputStreamChannel> inStrmChan = do_QueryInterface(aChannel);
+   if (inStrmChan) {
+     bool isSrcdocChannel;
+     inStrmChan->GetIsSrcdocChannel(&isSrcdocChannel);
+     if (isSrcdocChannel) {
+       nsAutoString srcdoc;
+@@ -11976,25 +12064,32 @@ nsDocShell::AddToSessionHistory(nsIURI* 
+ nsresult
+ nsDocShell::LoadHistoryEntry(nsISHEntry* aEntry, uint32_t aLoadType)
+ {
+   if (!IsNavigationAllowed()) {
+     return NS_OK;
+   }
+ 
+   nsCOMPtr<nsIURI> uri;
++  nsCOMPtr<nsIURI> originalURI;
+   nsCOMPtr<nsIInputStream> postData;
+   nsCOMPtr<nsIURI> referrerURI;
+   uint32_t referrerPolicy;
+   nsAutoCString contentType;
+   nsCOMPtr<nsISupports> owner;
+ 
+   NS_ENSURE_TRUE(aEntry, NS_ERROR_FAILURE);
+ 
+   NS_ENSURE_SUCCESS(aEntry->GetURI(getter_AddRefs(uri)), NS_ERROR_FAILURE);
++
++  nsCOMPtr<nsISHEntry_ESR38> entryESR38 = do_QueryInterface(aEntry);
++  if (entryESR38) {
++    NS_ENSURE_SUCCESS(entryESR38->GetOriginalURI(getter_AddRefs(originalURI)),
++                      NS_ERROR_FAILURE);
++  }
+   NS_ENSURE_SUCCESS(aEntry->GetReferrerURI(getter_AddRefs(referrerURI)),
+                     NS_ERROR_FAILURE);
+   NS_ENSURE_SUCCESS(aEntry->GetReferrerPolicy(&referrerPolicy),
+                     NS_ERROR_FAILURE);
+   NS_ENSURE_SUCCESS(aEntry->GetPostData(getter_AddRefs(postData)),
+                     NS_ERROR_FAILURE);
+   NS_ENSURE_SUCCESS(aEntry->GetContentType(contentType), NS_ERROR_FAILURE);
+   NS_ENSURE_SUCCESS(aEntry->GetOwner(getter_AddRefs(owner)), NS_ERROR_FAILURE);
+@@ -12064,34 +12159,35 @@ nsDocShell::LoadHistoryEntry(nsISHEntry*
+   } else {
+     srcdoc = NullString();
+   }
+ 
+   // Passing nullptr as aSourceDocShell gives the same behaviour as before
+   // aSourceDocShell was introduced. According to spec we should be passing
+   // the source browsing context that was used when the history entry was
+   // first created. bug 947716 has been created to address this issue.
+-  rv = InternalLoad(uri,
+-                    referrerURI,
+-                    referrerPolicy,
+-                    owner,
+-                    flags,
+-                    nullptr,            // No window target
+-                    contentType.get(),  // Type hint
+-                    NullString(),       // No forced file download
+-                    postData,           // Post data stream
+-                    nullptr,            // No headers stream
+-                    aLoadType,          // Load type
+-                    aEntry,             // SHEntry
+-                    true,
+-                    srcdoc,
+-                    nullptr,            // Source docshell, see comment above
+-                    baseURI,
+-                    nullptr,            // No nsIDocShell
+-                    nullptr);           // No nsIRequest
++  rv = InternalLoad2(uri,
++                     originalURI,
++                     referrerURI,
++                     referrerPolicy,
++                     owner,
++                     flags,
++                     nullptr,            // No window target
++                     contentType.get(),  // Type hint
++                     NullString(),       // No forced file download
++                     postData,           // Post data stream
++                     nullptr,            // No headers stream
++                     aLoadType,          // Load type
++                     aEntry,             // SHEntry
++                     true,
++                     srcdoc,
++                     nullptr,            // Source docshell, see comment above
++                     baseURI,
++                     nullptr,            // No nsIDocShell
++                     nullptr);           // No nsIRequest
+   return rv;
+ }
+ 
+ NS_IMETHODIMP
+ nsDocShell::GetShouldSaveLayoutState(bool* aShould)
+ {
+   *aShould = false;
+   if (mOSHE) {
+@@ -13527,35 +13623,36 @@ nsDocShell::OnLinkClickSync(nsIContent* 
+   // with it under InternalLoad; we do _not_ want to change the URI
+   // our caller passed in.
+   nsCOMPtr<nsIURI> clonedURI;
+   aURI->Clone(getter_AddRefs(clonedURI));
+   if (!clonedURI) {
+     return NS_ERROR_OUT_OF_MEMORY;
+   }
+ 
+-  nsresult rv = InternalLoad(clonedURI,                 // New URI
+-                             referer,                   // Referer URI
+-                             refererPolicy,             // Referer policy
+-                             aContent->NodePrincipal(), // Owner is our node's
+-                                                        // principal
+-                             flags,
+-                             target.get(),              // Window target
+-                             NS_LossyConvertUTF16toASCII(typeHint).get(),
+-                             aFileName,                 // Download as file
+-                             aPostDataStream,           // Post data stream
+-                             aHeadersDataStream,        // Headers stream
+-                             LOAD_LINK,                 // Load type
+-                             nullptr,                   // No SHEntry
+-                             true,                      // first party site
+-                             NullString(),              // No srcdoc
+-                             this,                      // We are the source
+-                             nullptr,                   // baseURI not needed
+-                             aDocShell,                 // DocShell out-param
+-                             aRequest);                 // Request out-param
++  nsresult rv = InternalLoad2(clonedURI,                 // New URI
++                              nullptr,                   // Original URI
++                              referer,                   // Referer URI
++                              refererPolicy,             // Referer policy
++                              aContent->NodePrincipal(), // Owner is our node's
++                                                         // principal
++                              flags,
++                              target.get(),              // Window target
++                              NS_LossyConvertUTF16toASCII(typeHint).get(),
++                              aFileName,                 // Download as file
++                              aPostDataStream,           // Post data stream
++                              aHeadersDataStream,        // Headers stream
++                              LOAD_LINK,                 // Load type
++                              nullptr,                   // No SHEntry
++                              true,                      // first party site
++                              NullString(),              // No srcdoc
++                              this,                      // We are the source
++                              nullptr,                   // baseURI not needed
++                              aDocShell,                 // DocShell out-param
++                              aRequest);                 // Request out-param
+   if (NS_SUCCEEDED(rv)) {
+     DispatchPings(aContent, aURI, referer, refererPolicy);
+   }
+   return rv;
+ }
+ 
+ NS_IMETHODIMP
+ nsDocShell::OnOverLink(nsIContent* aContent,
+diff --git a/docshell/base/nsDocShell.h b/docshell/base/nsDocShell.h
+--- a/docshell/base/nsDocShell.h
++++ b/docshell/base/nsDocShell.h
+@@ -132,17 +132,17 @@ enum eCharsetReloadState
+ };
+ 
+ //*****************************************************************************
+ //***    nsDocShell
+ //*****************************************************************************
+ 
+ class nsDocShell final
+   : public nsDocLoader
+-  , public nsIDocShell_ESR38
++  , public nsIDocShell_ESR38_2
+   , public nsIWebNavigation
+   , public nsIBaseWindow
+   , public nsIScrollable
+   , public nsITextScroll
+   , public nsIDocCharset
+   , public nsIContentViewerContainer
+   , public nsIRefreshURI
+   , public nsIWebProgressListener
+@@ -164,16 +164,17 @@ public:
+   nsDocShell();
+ 
+   NS_DECL_AND_IMPL_ZEROING_OPERATOR_NEW
+ 
+   virtual nsresult Init() override;
+ 
+   NS_DECL_ISUPPORTS_INHERITED
+ 
++  NS_DECL_NSIDOCSHELL_ESR38_2
+   NS_DECL_NSIDOCSHELL_ESR38
+   NS_DECL_NSIDOCSHELL
+   NS_DECL_NSIDOCSHELLTREEITEM
+   NS_DECL_NSIWEBNAVIGATION
+   NS_DECL_NSIBASEWINDOW
+   NS_DECL_NSISCROLLABLE
+   NS_DECL_NSITEXTSCROLL
+   NS_DECL_NSIDOCCHARSET
+@@ -312,17 +313,20 @@ protected:
+   // at the parent.
+   nsIPrincipal* GetInheritedPrincipal(bool aConsiderCurrentDocument);
+ 
+   // Actually open a channel and perform a URI load.  Note: whatever owner is
+   // passed to this function will be set on the channel.  Callers who wish to
+   // not have an owner on the channel should just pass null.
+   // If aSrcdoc is not void, the load will be considered as a srcdoc load,
+   // and the contents of aSrcdoc will be loaded instead of aURI.
++  // aOriginalURI will be set as the originalURI on the channel that does the
++  // load. If aOriginalURI is null, aURI will be set as the originalURI.
+   nsresult DoURILoad(nsIURI* aURI,
++                     nsIURI* aOriginalURI,
+                      nsIURI* aReferrer,
+                      bool aSendReferrer,
+                      uint32_t aReferrerPolicy,
+                      nsISupports* aOwner,
+                      const char* aTypeHint,
+                      const nsAString& aFileName,
+                      nsIInputStream* aPostData,
+                      nsIInputStream* aHeadersData,
+diff --git a/docshell/base/nsDocShellLoadInfo.cpp b/docshell/base/nsDocShellLoadInfo.cpp
+--- a/docshell/base/nsDocShellLoadInfo.cpp
++++ b/docshell/base/nsDocShellLoadInfo.cpp
+@@ -34,16 +34,17 @@ nsDocShellLoadInfo::~nsDocShellLoadInfo(
+ // nsDocShellLoadInfo::nsISupports
+ //*****************************************************************************
+ 
+ NS_IMPL_ADDREF(nsDocShellLoadInfo)
+ NS_IMPL_RELEASE(nsDocShellLoadInfo)
+ 
+ NS_INTERFACE_MAP_BEGIN(nsDocShellLoadInfo)
+   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDocShellLoadInfo)
++  NS_INTERFACE_MAP_ENTRY(nsIDocShellLoadInfo_ESR38)
+   NS_INTERFACE_MAP_ENTRY(nsIDocShellLoadInfo)
+ NS_INTERFACE_MAP_END
+ 
+ //*****************************************************************************
+ // nsDocShellLoadInfo::nsIDocShellLoadInfo
+ //*****************************************************************************
+ 
+ NS_IMETHODIMP
+@@ -59,16 +60,33 @@ nsDocShellLoadInfo::GetReferrer(nsIURI**
+ NS_IMETHODIMP
+ nsDocShellLoadInfo::SetReferrer(nsIURI* aReferrer)
+ {
+   mReferrer = aReferrer;
+   return NS_OK;
+ }
+ 
+ NS_IMETHODIMP
++nsDocShellLoadInfo::GetOriginalURI(nsIURI** aOriginalURI)
++{
++  NS_ENSURE_ARG_POINTER(aOriginalURI);
++
++  *aOriginalURI = mOriginalURI;
++  NS_IF_ADDREF(*aOriginalURI);
++  return NS_OK;
++}
++
++NS_IMETHODIMP
++nsDocShellLoadInfo::SetOriginalURI(nsIURI* aOriginalURI)
++{
++  mOriginalURI = aOriginalURI;
++  return NS_OK;
++}
++
++NS_IMETHODIMP
+ nsDocShellLoadInfo::GetOwner(nsISupports** aOwner)
+ {
+   NS_ENSURE_ARG_POINTER(aOwner);
+ 
+   *aOwner = mOwner;
+   NS_IF_ADDREF(*aOwner);
+   return NS_OK;
+ }
+diff --git a/docshell/base/nsDocShellLoadInfo.h b/docshell/base/nsDocShellLoadInfo.h
+--- a/docshell/base/nsDocShellLoadInfo.h
++++ b/docshell/base/nsDocShellLoadInfo.h
+@@ -14,29 +14,31 @@
+ // Interfaces Needed
+ #include "nsIDocShellLoadInfo.h"
+ 
+ class nsIInputStream;
+ class nsISHEntry;
+ class nsIURI;
+ class nsIDocShell;
+ 
+-class nsDocShellLoadInfo : public nsIDocShellLoadInfo
++class nsDocShellLoadInfo : public nsIDocShellLoadInfo_ESR38
+ {
+ public:
+   nsDocShellLoadInfo();
+ 
+   NS_DECL_ISUPPORTS
++  NS_DECL_NSIDOCSHELLLOADINFO_ESR38
+   NS_DECL_NSIDOCSHELLLOADINFO
+ 
+ protected:
+   virtual ~nsDocShellLoadInfo();
+ 
+ protected:
+   nsCOMPtr<nsIURI> mReferrer;
++  nsCOMPtr<nsIURI> mOriginalURI;
+   nsCOMPtr<nsISupports> mOwner;
+   bool mInheritOwner;
+   bool mOwnerIsExplicit;
+   bool mSendReferrer;
+   nsDocShellInfoReferrerPolicy mReferrerPolicy;
+   nsDocShellInfoLoadType mLoadType;
+   nsCOMPtr<nsISHEntry> mSHEntry;
+   nsString mTarget;
+diff --git a/docshell/base/nsIDocShell.idl b/docshell/base/nsIDocShell.idl
+--- a/docshell/base/nsIDocShell.idl
++++ b/docshell/base/nsIDocShell.idl
+@@ -1059,8 +1059,66 @@ interface nsIDocShell : nsIDocShellTreeI
+ interface nsIDocShell_ESR38 : nsIDocShell
+ {
+   /**
+    * True if new child docshells should allow content retargeting.
+    * Setting allowContentRetargeting also overwrites this value.
+    */
+   [infallible] attribute boolean allowContentRetargetingOnChildren;
+ };
++
++[scriptable, builtinclass, uuid(607604b6-8fe0-4d2c-8a6c-44f5f31a6e02)]
++interface nsIDocShell_ESR38_2 : nsIDocShell_ESR38
++{
++  /**
++   * Loads the given URI.  This method is identical to loadURI(...) except
++   * that its parameter list is broken out instead of being packaged inside
++   * of an nsIDocShellLoadInfo object...
++   *
++   * @param aURI            - The URI to load.
++   * @param aOriginalURI    - The URI to set as the originalURI on the channel
++   *                          that does the load. If null, aURI will be set as
++   *                          the originalURI.
++   * @param aReferrer       - Referring URI
++   * @param aReferrerPolicy - Referrer policy
++   * @param aOwner          - Owner (security principal) 
++   * @param aInheritOwner   - Flag indicating whether the owner of the current
++   *                          document should be inherited if aOwner is null.
++   * @param aStopActiveDoc  - Flag indicating whether loading the current
++   *                          document should be stopped.
++   * @param aWindowTarget   - Window target for the load.
++   * @param aTypeHint       - A hint as to the content-type of the resulting
++   *                          data.  May be null or empty if no hint.
++   * @param aFileName       - Non-null when the link should be downloaded as
++                              the given filename.
++   * @param aPostDataStream - Post data stream (if POSTing)
++   * @param aHeadersStream  - Stream containing "extra" request headers...
++   * @param aLoadFlags      - Flags to modify load behaviour. Flags are defined
++   *                          in nsIWebNavigation.
++   * @param aSHEntry        - Active Session History entry (if loading from SH)
++   * @param aSrcdoc           When INTERNAL_LOAD_FLAGS_IS_SRCDOC is set, the
++   *                          contents of this parameter will be loaded instead
++   *                          of aURI.
++   * @param aSourceDocShell - The source browsing context for the navigation.
++   * @param aBaseURI        - The base URI to be used for the load.  Set in
++   *                          srcdoc loads as it cannot otherwise be inferred
++   *                          in certain situations such as view-source.
++   */
++  [noscript]void internalLoad2(in nsIURI aURI,
++                               in nsIURI aOriginalURI,
++                               in nsIURI aReferrer,
++                               in unsigned long aReferrerPolicy,
++                               in nsISupports aOwner,
++                               in uint32_t aFlags,
++                               in wstring aWindowTarget,
++                               in string aTypeHint,
++                               in AString aFileName,
++                               in nsIInputStream aPostDataStream,
++                               in nsIInputStream aHeadersStream,
++                               in unsigned long aLoadFlags,
++                               in nsISHEntry aSHEntry,
++                               in boolean firstParty,
++                               in AString aSrcdoc,
++                               in nsIDocShell aSourceDocShell,
++                               in nsIURI aBaseURI,
++                               out nsIDocShell aDocShell,
++                               out nsIRequest aRequest);
++};
+diff --git a/docshell/base/nsIDocShellLoadInfo.idl b/docshell/base/nsIDocShellLoadInfo.idl
+--- a/docshell/base/nsIDocShellLoadInfo.idl
++++ b/docshell/base/nsIDocShellLoadInfo.idl
+@@ -106,8 +106,17 @@ interface nsIDocShellLoadInfo : nsISuppo
+     attribute nsIDocShell sourceDocShell;
+ 
+     /**
+      * Used for srcdoc loads to give view-source knowledge of the load's base
+      * URI as this information isn't embedded in the load's URI.
+      */
+     attribute nsIURI baseURI;
+ };
++
++[scriptable, uuid(9d3bc466-5efe-414d-ae8b-3830b45877bb)]
++interface nsIDocShellLoadInfo_ESR38 : nsIDocShellLoadInfo
++{
++    /**
++     * The originalURI to be passed to nsIDocShell.internalLoad. May be null.
++     */
++    attribute nsIURI originalURI;
++};
+diff --git a/docshell/shistory/public/nsISHEntry.idl b/docshell/shistory/public/nsISHEntry.idl
+--- a/docshell/shistory/public/nsISHEntry.idl
++++ b/docshell/shistory/public/nsISHEntry.idl
+@@ -319,8 +319,18 @@ interface nsISHEntryInternal : nsISuppor
+ #define NS_SHENTRY_CID \
+ {0xbfd1a791, 0xad9f, 0x11d3, {0xbd, 0xc7, 0x0, 0x50, 0x4, 0xa, 0x9b, 0x44}}
+ 
+ #define NS_SHENTRY_CONTRACTID \
+     "@mozilla.org/browser/session-history-entry;1"
+ 
+ %}
+ 
++[scriptable, uuid(e45ab6ef-3485-449c-b91c-0846b2bf6faf)]
++interface nsISHEntry_ESR38 : nsISHEntry
++{
++    /**
++     * A readonly property that returns the original URI of the current entry.
++     * If an entry is the result of a redirect this attribute holds original
++     * URI. The object returned is of type nsIURI
++     */
++    attribute nsIURI originalURI;
++};
+diff --git a/docshell/shistory/src/nsSHEntry.cpp b/docshell/shistory/src/nsSHEntry.cpp
+--- a/docshell/shistory/src/nsSHEntry.cpp
++++ b/docshell/shistory/src/nsSHEntry.cpp
+@@ -38,16 +38,17 @@ nsSHEntry::nsSHEntry()
+   , mIsSrcdocEntry(false)
+ {
+   mShared = new nsSHEntryShared();
+ }
+ 
+ nsSHEntry::nsSHEntry(const nsSHEntry &other)
+   : mShared(other.mShared)
+   , mURI(other.mURI)
++  , mOriginalURI(other.mOriginalURI)
+   , mReferrerURI(other.mReferrerURI)
+   , mReferrerPolicy(other.mReferrerPolicy)
+   , mTitle(other.mTitle)
+   , mPostData(other.mPostData)
+   , mLoadType(0)         // XXX why not copy?
+   , mID(other.mID)
+   , mScrollPositionX(0)  // XXX why not copy?
+   , mScrollPositionY(0)  // XXX why not copy?
+@@ -74,17 +75,17 @@ nsSHEntry::~nsSHEntry()
+   // Null out the mParent pointers on all our kids.
+   mChildren.EnumerateForwards(ClearParentPtr, nullptr);
+ }
+ 
+ //*****************************************************************************
+ //    nsSHEntry: nsISupports
+ //*****************************************************************************
+ 
+-NS_IMPL_ISUPPORTS(nsSHEntry, nsISHContainer, nsISHEntry, nsISHEntryInternal)
++NS_IMPL_ISUPPORTS(nsSHEntry, nsISHContainer, nsISHEntry_ESR38, nsISHEntry, nsISHEntryInternal)
+ 
+ //*****************************************************************************
+ //    nsSHEntry: nsISHEntry
+ //*****************************************************************************
+ 
+ NS_IMETHODIMP nsSHEntry::SetScrollPosition(int32_t x, int32_t y)
+ {
+   mScrollPositionX = x;
+@@ -119,16 +120,29 @@ NS_IMETHODIMP nsSHEntry::GetURI(nsIURI**
+ }
+ 
+ NS_IMETHODIMP nsSHEntry::SetURI(nsIURI* aURI)
+ {
+   mURI = aURI;
+   return NS_OK;
+ }
+ 
++NS_IMETHODIMP nsSHEntry::GetOriginalURI(nsIURI** aOriginalURI)
++{
++  *aOriginalURI = mOriginalURI;
++  NS_IF_ADDREF(*aOriginalURI);
++  return NS_OK;
++}
++
++NS_IMETHODIMP nsSHEntry::SetOriginalURI(nsIURI* aOriginalURI)
++{
++  mOriginalURI = aOriginalURI;
++  return NS_OK;
++}
++
+ NS_IMETHODIMP nsSHEntry::GetReferrerURI(nsIURI **aReferrerURI)
+ {
+   *aReferrerURI = mReferrerURI;
+   NS_IF_ADDREF(*aReferrerURI);
+   return NS_OK;
+ }
+ 
+ NS_IMETHODIMP nsSHEntry::SetReferrerURI(nsIURI *aReferrerURI)
+diff --git a/docshell/shistory/src/nsSHEntry.h b/docshell/shistory/src/nsSHEntry.h
+--- a/docshell/shistory/src/nsSHEntry.h
++++ b/docshell/shistory/src/nsSHEntry.h
+@@ -17,25 +17,26 @@
+ // Interfaces needed
+ #include "nsISHEntry.h"
+ #include "nsISHContainer.h"
+ 
+ class nsSHEntryShared;
+ class nsIInputStream;
+ class nsIURI;
+ 
+-class nsSHEntry final : public nsISHEntry,
++class nsSHEntry final : public nsISHEntry_ESR38,
+                             public nsISHContainer,
+                             public nsISHEntryInternal
+ {
+ public: 
+   nsSHEntry();
+   nsSHEntry(const nsSHEntry &other);
+ 
+   NS_DECL_ISUPPORTS
++  NS_DECL_NSISHENTRY_ESR38
+   NS_DECL_NSISHENTRY
+   NS_DECL_NSISHENTRYINTERNAL
+   NS_DECL_NSISHCONTAINER
+ 
+   void DropPresentationState();
+ 
+   static nsresult Startup();
+   static void Shutdown();
+@@ -44,16 +45,17 @@ private:
+   ~nsSHEntry();
+ 
+   // We share the state in here with other SHEntries which correspond to the
+   // same document.
+   nsRefPtr<nsSHEntryShared> mShared;
+ 
+   // See nsSHEntry.idl for comments on these members.
+   nsCOMPtr<nsIURI>         mURI;
++  nsCOMPtr<nsIURI>         mOriginalURI;
+   nsCOMPtr<nsIURI>         mReferrerURI;
+   uint32_t                 mReferrerPolicy;
+   nsString                 mTitle;
+   nsCOMPtr<nsIInputStream> mPostData;
+   uint32_t                 mLoadType;
+   uint32_t                 mID;
+   int32_t                  mScrollPositionX;
+   int32_t                  mScrollPositionY;
+diff --git a/docshell/shistory/src/nsSHistory.cpp b/docshell/shistory/src/nsSHistory.cpp
+--- a/docshell/shistory/src/nsSHistory.cpp
++++ b/docshell/shistory/src/nsSHistory.cpp
+@@ -1779,16 +1779,26 @@ nsSHistory::InitiateLoad(nsISHEntry * aF
+    * so that proper loadType is maintained through out a frameset
+    */
+   aFrameEntry->SetLoadType(aLoadType);    
+   aFrameDS->CreateLoadInfo (getter_AddRefs(loadInfo));
+ 
+   loadInfo->SetLoadType(aLoadType);
+   loadInfo->SetSHEntry(aFrameEntry);
+ 
++  nsCOMPtr<nsIURI> originalURI;
++  nsCOMPtr<nsISHEntry_ESR38> feESR38 = do_QueryInterface(aFrameEntry);
++  if (feESR38) {
++    feESR38->GetOriginalURI(getter_AddRefs(originalURI));
++  }
++  nsCOMPtr<nsIDocShellLoadInfo_ESR38> liESR38 = do_QueryInterface(loadInfo);
++  if (liESR38) {
++    liESR38->SetOriginalURI(originalURI);
++  }
++
+   nsCOMPtr<nsIURI> nextURI;
+   aFrameEntry->GetURI(getter_AddRefs(nextURI));
+   // Time   to initiate a document load
+   return aFrameDS->LoadURI(nextURI, loadInfo, nsIWebNavigation::LOAD_FLAGS_NONE, false);
+ 
+ }
+ 
+ 
+
diff --git a/gnu/packages/patches/icecat-CVE-2016-1952-pt01.patch b/gnu/packages/patches/icecat-CVE-2016-1952-pt01.patch
new file mode 100644
index 0000000000..2b711b1761
--- /dev/null
+++ b/gnu/packages/patches/icecat-CVE-2016-1952-pt01.patch
@@ -0,0 +1,356 @@
+Copied from upstream:
+https://hg.mozilla.org/releases/mozilla-esr38/raw-rev/c1d67bd4c993
+
+# HG changeset patch
+# User Timothy Nikkel <tnikkel@gmail.com>
+# Date 1454023801 21600
+# Node ID c1d67bd4c993b9e344c68954e6f0392c82b81e38
+# Parent  530559abe159d3c23f078d673d30ff03d9c244e2
+Bug 1224979 - Check if we compute usable filters for the downscaler, and if not put the downscaler in error state so it's not used. r=edwin, a=al
+
+diff --git a/image/Downscaler.cpp b/image/Downscaler.cpp
+new file mode 100644
+--- /dev/null
++++ b/image/Downscaler.cpp
+@@ -0,0 +1,340 @@
++/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
++ *
++ * This Source Code Form is subject to the terms of the Mozilla Public
++ * License, v. 2.0. If a copy of the MPL was not distributed with this
++ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
++
++#include "Downscaler.h"
++
++#include <algorithm>
++#include <ctime>
++#include "gfxPrefs.h"
++#include "image_operations.h"
++#include "mozilla/SSE.h"
++#include "convolver.h"
++#include "skia/include/core/SkTypes.h"
++
++using std::max;
++using std::swap;
++
++namespace mozilla {
++namespace image {
++
++Downscaler::Downscaler(const nsIntSize& aTargetSize)
++  : mTargetSize(aTargetSize)
++  , mOutputBuffer(nullptr)
++  , mXFilter(MakeUnique<skia::ConvolutionFilter1D>())
++  , mYFilter(MakeUnique<skia::ConvolutionFilter1D>())
++  , mWindowCapacity(0)
++  , mHasAlpha(true)
++  , mFlipVertically(false)
++{
++  MOZ_ASSERT(gfxPrefs::ImageDownscaleDuringDecodeEnabled(),
++             "Downscaling even though downscale-during-decode is disabled?");
++  MOZ_ASSERT(mTargetSize.width > 0 && mTargetSize.height > 0,
++             "Invalid target size");
++}
++
++Downscaler::~Downscaler()
++{
++  ReleaseWindow();
++}
++
++void
++Downscaler::ReleaseWindow()
++{
++  if (!mWindow) {
++    return;
++  }
++
++  for (int32_t i = 0; i < mWindowCapacity; ++i) {
++    delete[] mWindow[i];
++  }
++
++  mWindow = nullptr;
++  mWindowCapacity = 0;
++}
++
++nsresult
++Downscaler::BeginFrame(const nsIntSize& aOriginalSize,
++                       const Maybe<nsIntRect>& aFrameRect,
++                       uint8_t* aOutputBuffer,
++                       bool aHasAlpha,
++                       bool aFlipVertically /* = false */)
++{
++  MOZ_ASSERT(aOutputBuffer);
++  MOZ_ASSERT(mTargetSize != aOriginalSize,
++             "Created a downscaler, but not downscaling?");
++  MOZ_ASSERT(mTargetSize.width <= aOriginalSize.width,
++             "Created a downscaler, but width is larger");
++  MOZ_ASSERT(mTargetSize.height <= aOriginalSize.height,
++             "Created a downscaler, but height is larger");
++  MOZ_ASSERT(aOriginalSize.width > 0 && aOriginalSize.height > 0,
++             "Invalid original size");
++
++  mFrameRect = aFrameRect.valueOr(nsIntRect(nsIntPoint(), aOriginalSize));
++  MOZ_ASSERT(mFrameRect.x >= 0 && mFrameRect.y >= 0 &&
++             mFrameRect.width >= 0 && mFrameRect.height >= 0,
++             "Frame rect must have non-negative components");
++  MOZ_ASSERT(nsIntRect(0, 0, aOriginalSize.width, aOriginalSize.height)
++               .Contains(mFrameRect),
++             "Frame rect must fit inside image");
++  MOZ_ASSERT_IF(!nsIntRect(0, 0, aOriginalSize.width, aOriginalSize.height)
++                  .IsEqualEdges(mFrameRect),
++                aHasAlpha);
++
++  mOriginalSize = aOriginalSize;
++  mScale = gfxSize(double(mOriginalSize.width) / mTargetSize.width,
++                   double(mOriginalSize.height) / mTargetSize.height);
++  mOutputBuffer = aOutputBuffer;
++  mHasAlpha = aHasAlpha;
++  mFlipVertically = aFlipVertically;
++
++  ReleaseWindow();
++
++  auto resizeMethod = skia::ImageOperations::RESIZE_LANCZOS3;
++
++  skia::resize::ComputeFilters(resizeMethod,
++                               mOriginalSize.width, mTargetSize.width,
++                               0, mTargetSize.width,
++                               mXFilter.get());
++
++  if (mXFilter->max_filter() <= 0 || mXFilter->num_values() != mTargetSize.width) {
++    NS_WARNING("Failed to compute filters for image downscaling");
++    return NS_ERROR_OUT_OF_MEMORY;
++  }
++
++  skia::resize::ComputeFilters(resizeMethod,
++                               mOriginalSize.height, mTargetSize.height,
++                               0, mTargetSize.height,
++                               mYFilter.get());
++
++  if (mYFilter->max_filter() <= 0 || mYFilter->num_values() != mTargetSize.height) {
++    NS_WARNING("Failed to compute filters for image downscaling");
++    return NS_ERROR_OUT_OF_MEMORY;
++  }
++
++  // Allocate the buffer, which contains scanlines of the original image.
++  // pad by 15 to handle overreads by the simd code
++  size_t bufferLen = mOriginalSize.width * sizeof(uint32_t) + 15;
++  mRowBuffer.reset(new (fallible) uint8_t[bufferLen]);
++  if (MOZ_UNLIKELY(!mRowBuffer)) {
++    return NS_ERROR_OUT_OF_MEMORY;
++  }
++
++  // Zero buffer to keep valgrind happy.
++  memset(mRowBuffer.get(), 0, bufferLen);
++
++  // Allocate the window, which contains horizontally downscaled scanlines. (We
++  // can store scanlines which are already downscale because our downscaling
++  // filter is separable.)
++  mWindowCapacity = mYFilter->max_filter();
++  mWindow.reset(new (fallible) uint8_t*[mWindowCapacity]);
++  if (MOZ_UNLIKELY(!mWindow)) {
++    return NS_ERROR_OUT_OF_MEMORY;
++  }
++
++  bool anyAllocationFailed = false;
++  // pad by 15 to handle overreads by the simd code
++  const int rowSize = mTargetSize.width * sizeof(uint32_t) + 15;
++  for (int32_t i = 0; i < mWindowCapacity; ++i) {
++    mWindow[i] = new (fallible) uint8_t[rowSize];
++    anyAllocationFailed = anyAllocationFailed || mWindow[i] == nullptr;
++  }
++
++  if (MOZ_UNLIKELY(anyAllocationFailed)) {
++    // We intentionally iterate through the entire array even if an allocation
++    // fails, to ensure that all the pointers in it are either valid or nullptr.
++    // That in turn ensures that ReleaseWindow() can clean up correctly.
++    return NS_ERROR_OUT_OF_MEMORY;
++  }
++
++  ResetForNextProgressivePass();
++
++  return NS_OK;
++}
++
++void
++Downscaler::SkipToRow(int32_t aRow)
++{
++  if (mCurrentInLine < aRow) {
++    ClearRow();
++    do {
++      CommitRow();
++    } while (mCurrentInLine < aRow);
++  }
++}
++
++void
++Downscaler::ResetForNextProgressivePass()
++{
++  mPrevInvalidatedLine = 0;
++  mCurrentOutLine = 0;
++  mCurrentInLine = 0;
++  mLinesInBuffer = 0;
++
++  if (mFrameRect.IsEmpty()) {
++    // Our frame rect is zero size; commit rows until the end of the image.
++    SkipToRow(mOriginalSize.height - 1);
++  } else {
++    // If we have a vertical offset, commit rows to shift us past it.
++    SkipToRow(mFrameRect.y);
++  }
++}
++
++static void
++GetFilterOffsetAndLength(UniquePtr<skia::ConvolutionFilter1D>& aFilter,
++                         int32_t aOutputImagePosition,
++                         int32_t* aFilterOffsetOut,
++                         int32_t* aFilterLengthOut)
++{
++  MOZ_ASSERT(aOutputImagePosition < aFilter->num_values());
++  aFilter->FilterForValue(aOutputImagePosition,
++                          aFilterOffsetOut,
++                          aFilterLengthOut);
++}
++
++void
++Downscaler::ClearRow(uint32_t aStartingAtCol)
++{
++  MOZ_ASSERT(int64_t(mOriginalSize.width) > int64_t(aStartingAtCol));
++  uint32_t bytesToClear = (mOriginalSize.width - aStartingAtCol)
++                        * sizeof(uint32_t);
++  memset(mRowBuffer.get() + (aStartingAtCol * sizeof(uint32_t)),
++         0, bytesToClear);
++}
++
++void
++Downscaler::CommitRow()
++{
++  MOZ_ASSERT(mOutputBuffer, "Should have a current frame");
++  MOZ_ASSERT(mCurrentInLine < mOriginalSize.height, "Past end of input");
++
++  if (mCurrentOutLine < mTargetSize.height) {
++    int32_t filterOffset = 0;
++    int32_t filterLength = 0;
++    GetFilterOffsetAndLength(mYFilter, mCurrentOutLine,
++                             &filterOffset, &filterLength);
++
++    int32_t inLineToRead = filterOffset + mLinesInBuffer;
++    MOZ_ASSERT(mCurrentInLine <= inLineToRead, "Reading past end of input");
++    if (mCurrentInLine == inLineToRead) {
++      skia::ConvolveHorizontally(mRowBuffer.get(), *mXFilter,
++                                 mWindow[mLinesInBuffer++], mHasAlpha,
++                                 supports_sse2());
++    }
++
++    MOZ_ASSERT(mCurrentOutLine < mTargetSize.height,
++               "Writing past end of output");
++
++    while (mLinesInBuffer == filterLength) {
++      DownscaleInputLine();
++
++      if (mCurrentOutLine == mTargetSize.height) {
++        break;  // We're done.
++      }
++
++      GetFilterOffsetAndLength(mYFilter, mCurrentOutLine,
++                               &filterOffset, &filterLength);
++    }
++  }
++
++  mCurrentInLine += 1;
++
++  // If we're at the end of the part of the original image that has data, commit
++  // rows to shift us to the end.
++  if (mCurrentInLine == (mFrameRect.y + mFrameRect.height)) {
++    SkipToRow(mOriginalSize.height - 1);
++  }
++}
++
++bool
++Downscaler::HasInvalidation() const
++{
++  return mCurrentOutLine > mPrevInvalidatedLine;
++}
++
++DownscalerInvalidRect
++Downscaler::TakeInvalidRect()
++{
++  if (MOZ_UNLIKELY(!HasInvalidation())) {
++    return DownscalerInvalidRect();
++  }
++
++  DownscalerInvalidRect invalidRect;
++
++  // Compute the target size invalid rect.
++  if (mFlipVertically) {
++    // We need to flip it. This will implicitly flip the original size invalid
++    // rect, since we compute it by scaling this rect.
++    invalidRect.mTargetSizeRect =
++      IntRect(0, mTargetSize.height - mCurrentOutLine,
++              mTargetSize.width, mCurrentOutLine - mPrevInvalidatedLine);
++  } else {
++    invalidRect.mTargetSizeRect =
++      IntRect(0, mPrevInvalidatedLine,
++              mTargetSize.width, mCurrentOutLine - mPrevInvalidatedLine);
++  }
++
++  mPrevInvalidatedLine = mCurrentOutLine;
++
++  // Compute the original size invalid rect.
++  invalidRect.mOriginalSizeRect = invalidRect.mTargetSizeRect;
++  invalidRect.mOriginalSizeRect.ScaleRoundOut(mScale.width, mScale.height);
++
++  return invalidRect;
++}
++
++void
++Downscaler::DownscaleInputLine()
++{
++  typedef skia::ConvolutionFilter1D::Fixed FilterValue;
++
++  MOZ_ASSERT(mOutputBuffer);
++  MOZ_ASSERT(mCurrentOutLine < mTargetSize.height,
++             "Writing past end of output");
++
++  int32_t filterOffset = 0;
++  int32_t filterLength = 0;
++  MOZ_ASSERT(mCurrentOutLine < mYFilter->num_values());
++  auto filterValues =
++    mYFilter->FilterForValue(mCurrentOutLine, &filterOffset, &filterLength);
++
++  int32_t currentOutLine = mFlipVertically
++                         ? mTargetSize.height - (mCurrentOutLine + 1)
++                         : mCurrentOutLine;
++  MOZ_ASSERT(currentOutLine >= 0);
++
++  uint8_t* outputLine =
++    &mOutputBuffer[currentOutLine * mTargetSize.width * sizeof(uint32_t)];
++  skia::ConvolveVertically(static_cast<const FilterValue*>(filterValues),
++                           filterLength, mWindow.get(), mXFilter->num_values(),
++                           outputLine, mHasAlpha, supports_sse2());
++
++  mCurrentOutLine += 1;
++
++  if (mCurrentOutLine == mTargetSize.height) {
++    // We're done.
++    return;
++  }
++
++  int32_t newFilterOffset = 0;
++  int32_t newFilterLength = 0;
++  GetFilterOffsetAndLength(mYFilter, mCurrentOutLine,
++                           &newFilterOffset, &newFilterLength);
++
++  int diff = newFilterOffset - filterOffset;
++  MOZ_ASSERT(diff >= 0, "Moving backwards in the filter?");
++
++  // Shift the buffer. We're just moving pointers here, so this is cheap.
++  mLinesInBuffer -= diff;
++  mLinesInBuffer = max(mLinesInBuffer, 0);
++  for (int32_t i = 0; i < mLinesInBuffer; ++i) {
++    swap(mWindow[i], mWindow[filterLength - mLinesInBuffer + i]);
++  }
++}
++
++
++
++} // namespace image
++} // namespace mozilla
+
diff --git a/gnu/packages/patches/icecat-CVE-2016-1952-pt02.patch b/gnu/packages/patches/icecat-CVE-2016-1952-pt02.patch
new file mode 100644
index 0000000000..e01b5eaf2f
--- /dev/null
+++ b/gnu/packages/patches/icecat-CVE-2016-1952-pt02.patch
@@ -0,0 +1,58 @@
+Copied from upstream:
+https://hg.mozilla.org/releases/mozilla-esr38/raw-rev/9719b71d72dd
+
+# HG changeset patch
+# User Byron Campen [:bwc] <docfaraday@gmail.com>
+# Date 1454100887 21600
+# Node ID 9719b71d72dd2a3c5ee12ace156af2a63d9595ac
+# Parent  b68673d974a10f65390f80b36d4307eb31e44669
+Bug 1234578 - Assert if PCM is destroyed improperly. r=rjesup, a=sylvestre
+
+diff --git a/media/webrtc/signaling/src/peerconnection/PeerConnectionMedia.cpp b/media/webrtc/signaling/src/peerconnection/PeerConnectionMedia.cpp
+--- a/media/webrtc/signaling/src/peerconnection/PeerConnectionMedia.cpp
++++ b/media/webrtc/signaling/src/peerconnection/PeerConnectionMedia.cpp
+@@ -712,16 +712,18 @@ PeerConnectionMedia::SelfDestruct_m()
+ {
+   CSFLogDebug(logTag, "%s: ", __FUNCTION__);
+ 
+   ASSERT_ON_THREAD(mMainThread);
+ 
+   mLocalSourceStreams.Clear();
+   mRemoteSourceStreams.Clear();
+ 
++  mMainThread = nullptr;
++
+   // Final self-destruct.
+   this->Release();
+ }
+ 
+ void
+ PeerConnectionMedia::ShutdownMediaTransport_s()
+ {
+   ASSERT_ON_THREAD(mSTSThread);
+diff --git a/media/webrtc/signaling/src/peerconnection/PeerConnectionMedia.h b/media/webrtc/signaling/src/peerconnection/PeerConnectionMedia.h
+--- a/media/webrtc/signaling/src/peerconnection/PeerConnectionMedia.h
++++ b/media/webrtc/signaling/src/peerconnection/PeerConnectionMedia.h
+@@ -210,17 +210,20 @@ class RemoteSourceStreamInfo : public So
+   std::vector<std::string> mTrackIdMap;
+ 
+   // True iff SetPullEnabled(true) has been called on the DOMMediaStream. This
+   // happens when offer/answer concludes.
+   bool mReceiving;
+ };
+ 
+ class PeerConnectionMedia : public sigslot::has_slots<> {
+-  ~PeerConnectionMedia() {}
++  ~PeerConnectionMedia()
++  {
++    MOZ_RELEASE_ASSERT(!mMainThread);
++  }
+ 
+  public:
+   explicit PeerConnectionMedia(PeerConnectionImpl *parent);
+ 
+   PeerConnectionImpl* GetPC() { return mParent; }
+   nsresult Init(const std::vector<NrIceStunServer>& stun_servers,
+                 const std::vector<NrIceTurnServer>& turn_servers);
+   // WARNING: This destroys the object!
+
diff --git a/gnu/packages/patches/icecat-CVE-2016-1952-pt03.patch b/gnu/packages/patches/icecat-CVE-2016-1952-pt03.patch
new file mode 100644
index 0000000000..96b83c118c
--- /dev/null
+++ b/gnu/packages/patches/icecat-CVE-2016-1952-pt03.patch
@@ -0,0 +1,60 @@
+Copied from upstream:
+https://hg.mozilla.org/releases/mozilla-esr38/raw-rev/2839062f84fb
+
+# HG changeset patch
+# User Jan de Mooij <jdemooij@mozilla.com>
+# Date 1455119320 -3600
+# Node ID 2839062f84fb6cba2781ea8d59150f13d4813ddc
+# Parent  185b233ea03f3811404e3979b65ec86b29d13555
+Bug 1242279 - r=bhackett1024 a=sylvestre
+
+diff --git a/js/src/vm/TypeInference.cpp b/js/src/vm/TypeInference.cpp
+--- a/js/src/vm/TypeInference.cpp
++++ b/js/src/vm/TypeInference.cpp
+@@ -3961,16 +3961,22 @@ JSScript::maybeSweepTypes(AutoClearTypeI
+ 
+     unsigned num = TypeScript::NumTypeSets(this);
+     StackTypeSet* typeArray = types_->typeArray();
+ 
+     // Remove constraints and references to dead objects from stack type sets.
+     for (unsigned i = 0; i < num; i++)
+         typeArray[i].sweep(zone(), *oom);
+ 
++    if (oom->hadOOM()) {
++        // It's possible we OOM'd while copying freeze constraints, so they
++        // need to be regenerated.
++        hasFreezeConstraints_ = false;
++    }
++
+     // Update the recompile indexes in any IonScripts still on the script.
+     if (hasIonScript())
+         ionScript()->recompileInfoRef().shouldSweep(types);
+ }
+ 
+ void
+ TypeScript::destroy()
+ {
+diff --git a/js/src/vm/TypeInference.h b/js/src/vm/TypeInference.h
+--- a/js/src/vm/TypeInference.h
++++ b/js/src/vm/TypeInference.h
+@@ -566,16 +566,19 @@ class AutoClearTypeInferenceStateOnOOM
+       : zone(zone), oom(false)
+     {}
+ 
+     ~AutoClearTypeInferenceStateOnOOM();
+ 
+     void setOOM() {
+         oom = true;
+     }
++    bool hadOOM() const {
++        return oom;
++    }
+ };
+ 
+ /* Superclass common to stack and heap type sets. */
+ class ConstraintTypeSet : public TypeSet
+ {
+   public:
+     /* Chain of constraints which propagate changes out from this type set. */
+     TypeConstraint* constraintList;
+
diff --git a/gnu/packages/patches/icecat-CVE-2016-1952-pt04.patch b/gnu/packages/patches/icecat-CVE-2016-1952-pt04.patch
new file mode 100644
index 0000000000..4eeb2377b0
--- /dev/null
+++ b/gnu/packages/patches/icecat-CVE-2016-1952-pt04.patch
@@ -0,0 +1,53 @@
+Copied from upstream:
+https://hg.mozilla.org/releases/mozilla-esr38/raw-rev/9dd60e798819
+
+# HG changeset patch
+# User Olli Pettay <bugs@pettay.fi>
+# Date 1455204078 -3600
+# Node ID 9dd60e798819fe2ebf1e5bd36aa9006ecd2f82c9
+# Parent  c1d67bd4c993b9e344c68954e6f0392c82b81e38
+Bug 1244250 - r=mats, a=al
+
+diff --git a/layout/style/nsAnimationManager.cpp b/layout/style/nsAnimationManager.cpp
+--- a/layout/style/nsAnimationManager.cpp
++++ b/layout/style/nsAnimationManager.cpp
+@@ -715,16 +715,17 @@ nsAnimationManager::FlushAnimations(Flus
+   }
+ 
+   DispatchEvents(); // may destroy us
+ }
+ 
+ void
+ nsAnimationManager::DoDispatchEvents()
+ {
++  nsRefPtr<nsAnimationManager> kungFuDeathGrip(this);
+   EventArray events;
+   mPendingEvents.SwapElements(events);
+   for (uint32_t i = 0, i_end = events.Length(); i < i_end; ++i) {
+     AnimationEventInfo &info = events[i];
+     EventDispatcher::Dispatch(info.mElement, mPresContext, &info.mEvent);
+ 
+     if (!mPresContext) {
+       break;
+diff --git a/layout/style/nsTransitionManager.cpp b/layout/style/nsTransitionManager.cpp
+--- a/layout/style/nsTransitionManager.cpp
++++ b/layout/style/nsTransitionManager.cpp
+@@ -753,16 +753,17 @@ nsTransitionManager::FlushTransitions(Fl
+       }
+     }
+   }
+ 
+   if (didThrottle) {
+     mPresContext->Document()->SetNeedStyleFlush();
+   }
+ 
++  nsRefPtr<nsTransitionManager> kungFuDeathGrip(this);
+   for (uint32_t i = 0, i_end = events.Length(); i < i_end; ++i) {
+     TransitionEventInfo &info = events[i];
+     EventDispatcher::Dispatch(info.mElement, mPresContext, &info.mEvent);
+ 
+     if (!mPresContext) {
+       break;
+     }
+   }
+
diff --git a/gnu/packages/patches/icecat-CVE-2016-1952-pt05.patch b/gnu/packages/patches/icecat-CVE-2016-1952-pt05.patch
new file mode 100644
index 0000000000..d222feff2a
--- /dev/null
+++ b/gnu/packages/patches/icecat-CVE-2016-1952-pt05.patch
@@ -0,0 +1,32 @@
+Copied from upstream:
+https://hg.mozilla.org/releases/mozilla-esr38/raw-rev/1dd0ca8e70bd
+
+# HG changeset patch
+# User Nicolas B. Pierron <nicolas.b.pierron@mozilla.com>
+# Date 1456161361 0
+# Node ID 1dd0ca8e70bd77b6fd93f36cc4e9c2cebfe8ba0a
+# Parent  95ff874886905ef46a7bbc760981d15ad0831096
+Bug 1221872 - ValueNumbering: Set the dominator index of fixup blocks when they are created. r=sunfish, a=ritu
+
+diff --git a/js/src/jit/ValueNumbering.cpp b/js/src/jit/ValueNumbering.cpp
+--- a/js/src/jit/ValueNumbering.cpp
++++ b/js/src/jit/ValueNumbering.cpp
+@@ -433,16 +433,17 @@ ValueNumberer::fixupOSROnlyLoop(MBasicBl
+     MBasicBlock* fake = MBasicBlock::NewAsmJS(graph_, block->info(),
+                                               nullptr, MBasicBlock::NORMAL);
+     if (fake == nullptr)
+         return false;
+ 
+     graph_.insertBlockBefore(block, fake);
+     fake->setImmediateDominator(fake);
+     fake->addNumDominated(1);
++    fake->setDomIndex(fake->id());
+ 
+     // Create zero-input phis to use as inputs for any phis in |block|.
+     // Again, this is a little odd, but it's the least-odd thing we can do
+     // without significant complexity.
+     for (MPhiIterator iter(block->phisBegin()), end(block->phisEnd()); iter != end; ++iter) {
+         MPhi* phi = *iter;
+         MPhi* fakePhi = MPhi::New(graph_.alloc(), phi->type());
+         fake->addPhi(fakePhi);
+
diff --git a/gnu/packages/patches/icecat-CVE-2016-1952-pt06.patch b/gnu/packages/patches/icecat-CVE-2016-1952-pt06.patch
new file mode 100644
index 0000000000..3de568493b
--- /dev/null
+++ b/gnu/packages/patches/icecat-CVE-2016-1952-pt06.patch
@@ -0,0 +1,103 @@
+Copied from upstream:
+https://hg.mozilla.org/releases/mozilla-esr38/raw-rev/6f4d51302387
+
+# HG changeset patch
+# User Andrew McCreight <continuation@gmail.com>
+# Date 1456273423 28800
+# Node ID 6f4d5130238790fa5810c76ffeb9eccc65efa8c9
+# Parent  70f6c59d9d73a5edefd216b48ca74a931da12cf1
+Bug 1249685 - Use more nsCOMPtrs for stack variables in DOM code. r=smaug, a=ritu
+
+diff --git a/dom/base/nsRange.cpp b/dom/base/nsRange.cpp
+--- a/dom/base/nsRange.cpp
++++ b/dom/base/nsRange.cpp
+@@ -1985,17 +1985,17 @@ nsRange::CutContents(DocumentFragment** 
+       rv = closestAncestor ? PrependChild(closestAncestor, nodeToResult)
+                            : PrependChild(commonCloneAncestor, nodeToResult);
+       NS_ENSURE_SUCCESS(rv, rv);
+       NS_ENSURE_STATE(!guard.Mutated(parent ? 2 : 1) ||
+                       ValidateCurrentNode(this, iter));
+     } else if (nodeToResult) {
+       nsMutationGuard guard;
+       nsCOMPtr<nsINode> node = nodeToResult;
+-      nsINode* parent = node->GetParentNode();
++      nsCOMPtr<nsINode> parent = node->GetParentNode();
+       if (parent) {
+         mozilla::ErrorResult error;
+         parent->RemoveChild(*node, error);
+         NS_ENSURE_FALSE(error.Failed(), error.ErrorCode());
+       }
+       NS_ENSURE_STATE(!guard.Mutated(1) ||
+                       ValidateCurrentNode(this, iter));
+     }
+diff --git a/dom/base/nsTreeSanitizer.cpp b/dom/base/nsTreeSanitizer.cpp
+--- a/dom/base/nsTreeSanitizer.cpp
++++ b/dom/base/nsTreeSanitizer.cpp
+@@ -1423,18 +1423,18 @@ nsTreeSanitizer::SanitizeChildren(nsINod
+                              mAllowStyles,
+                              false);
+         }
+         node = node->GetNextNonChildNode(aRoot);
+         continue;
+       }
+       if (MustFlatten(ns, localName)) {
+         RemoveAllAttributes(node);
+-        nsIContent* next = node->GetNextNode(aRoot);
+-        nsIContent* parent = node->GetParent();
++        nsCOMPtr<nsIContent> next = node->GetNextNode(aRoot);
++        nsCOMPtr<nsIContent> parent = node->GetParent();
+         nsCOMPtr<nsIContent> child; // Must keep the child alive during move
+         ErrorResult rv;
+         while ((child = node->GetFirstChild())) {
+           parent->InsertBefore(*child, node, rv);
+           if (rv.Failed()) {
+             break;
+           }
+         }
+diff --git a/dom/html/HTMLSelectElement.cpp b/dom/html/HTMLSelectElement.cpp
+--- a/dom/html/HTMLSelectElement.cpp
++++ b/dom/html/HTMLSelectElement.cpp
+@@ -624,17 +624,17 @@ HTMLSelectElement::Add(nsGenericHTMLElem
+ {
+   if (!aBefore) {
+     Element::AppendChild(aElement, aError);
+     return;
+   }
+ 
+   // Just in case we're not the parent, get the parent of the reference
+   // element
+-  nsINode* parent = aBefore->Element::GetParentNode();
++  nsCOMPtr<nsINode> parent = aBefore->Element::GetParentNode();
+   if (!parent || !nsContentUtils::ContentIsDescendantOf(parent, this)) {
+     // NOT_FOUND_ERR: Raised if before is not a descendant of the SELECT
+     // element.
+     aError.Throw(NS_ERROR_DOM_NOT_FOUND_ERR);
+     return;
+   }
+ 
+   // If the before parameter is not null, we are equivalent to the
+diff --git a/dom/html/HTMLTableElement.cpp b/dom/html/HTMLTableElement.cpp
+--- a/dom/html/HTMLTableElement.cpp
++++ b/dom/html/HTMLTableElement.cpp
+@@ -516,18 +516,18 @@ HTMLTableElement::InsertRow(int32_t aInd
+   if (rowCount > 0) {
+     if (refIndex == rowCount || aIndex == -1) {
+       // we set refIndex to the last row so we can get the last row's
+       // parent we then do an AppendChild below if (rowCount<aIndex)
+ 
+       refIndex = rowCount - 1;
+     }
+ 
+-    Element* refRow = rows->Item(refIndex);
+-    nsINode* parent = refRow->GetParentNode();
++    RefPtr<Element> refRow = rows->Item(refIndex);
++    nsCOMPtr<nsINode> parent = refRow->GetParentNode();
+ 
+     // create the row
+     nsRefPtr<mozilla::dom::NodeInfo> nodeInfo;
+     nsContentUtils::NameChanged(mNodeInfo, nsGkAtoms::tr,
+                                 getter_AddRefs(nodeInfo));
+ 
+     newRow = NS_NewHTMLTableRowElement(nodeInfo.forget());
+ 
+
diff --git a/gnu/packages/patches/icecat-CVE-2016-1954.patch b/gnu/packages/patches/icecat-CVE-2016-1954.patch
new file mode 100644
index 0000000000..bbb4b3217c
--- /dev/null
+++ b/gnu/packages/patches/icecat-CVE-2016-1954.patch
@@ -0,0 +1,32 @@
+Copied from upstream:
+https://hg.mozilla.org/releases/mozilla-esr38/raw-rev/a5c4c18849b4
+
+# HG changeset patch
+# User Christoph Kerschbaumer <mozilla@christophkerschbaumer.com>
+# Date 1456157874 28800
+# Node ID a5c4c18849b486ef8693e20421b69239a2cbe574
+# Parent  e93aeb25e2a44df8d22f5a065b4410620e2c8730
+Bug 1243178: CSP - Skip sending reports for non http schemes (r=dveditz) a=ritu
+
+diff --git a/dom/security/nsCSPContext.cpp b/dom/security/nsCSPContext.cpp
+--- a/dom/security/nsCSPContext.cpp
++++ b/dom/security/nsCSPContext.cpp
+@@ -798,16 +798,17 @@ nsCSPContext::SendReports(nsISupports* a
+       (NS_SUCCEEDED(reportURI->SchemeIs("https", &isHttpScheme)) && isHttpScheme);
+ 
+     if (!isHttpScheme) {
+       const char16_t* params[] = { reportURIs[r].get() };
+       CSP_LogLocalizedStr(NS_LITERAL_STRING("reportURInotHttpsOrHttp2").get(),
+                           params, ArrayLength(params),
+                           aSourceFile, aScriptSample, aLineNum, 0,
+                           nsIScriptError::errorFlag, "CSP", mInnerWindowID);
++      continue;
+     }
+ 
+     // make sure this is an anonymous request (no cookies) so in case the
+     // policy URI is injected, it can't be abused for CSRF.
+     nsLoadFlags flags;
+     rv = reportChannel->GetLoadFlags(&flags);
+     NS_ENSURE_SUCCESS(rv, rv);
+     flags |= nsIRequest::LOAD_ANONYMOUS;
+
diff --git a/gnu/packages/patches/icecat-CVE-2016-1960.patch b/gnu/packages/patches/icecat-CVE-2016-1960.patch
new file mode 100644
index 0000000000..6c5c885e8b
--- /dev/null
+++ b/gnu/packages/patches/icecat-CVE-2016-1960.patch
@@ -0,0 +1,55 @@
+Copied from upstream:
+https://hg.mozilla.org/releases/mozilla-esr38/raw-rev/185b233ea03f
+
+# HG changeset patch
+# User Henri Sivonen <hsivonen@hsivonen.fi>
+# Date 1455100746 -7200
+# Node ID 185b233ea03f3811404e3979b65ec86b29d13555
+# Parent  271e3a5a53d96871141e89271f611033b512e3e4
+Bug 1246014. r=wchen. a=sylvestre
+
+diff --git a/parser/html/javasrc/TreeBuilder.java b/parser/html/javasrc/TreeBuilder.java
+--- a/parser/html/javasrc/TreeBuilder.java
++++ b/parser/html/javasrc/TreeBuilder.java
+@@ -4437,17 +4437,17 @@ public abstract class TreeBuilder<T> imp
+         return TreeBuilder.NOT_FOUND_ON_STACK;
+     }
+ 
+     private void clearStackBackTo(int eltPos) throws SAXException {
+         int eltGroup = stack[eltPos].getGroup();
+         while (currentPtr > eltPos) { // > not >= intentional
+             if (stack[currentPtr].ns == "http://www.w3.org/1999/xhtml"
+                     && stack[currentPtr].getGroup() == TEMPLATE
+-                    && (eltGroup == TABLE || eltGroup == TBODY_OR_THEAD_OR_TFOOT|| eltGroup == TR || eltGroup == HTML)) {
++                    && (eltGroup == TABLE || eltGroup == TBODY_OR_THEAD_OR_TFOOT|| eltGroup == TR || eltPos == 0)) {
+                 return;
+             }
+             pop();
+         }
+     }
+ 
+     private void resetTheInsertionMode() {
+         StackNode<T> node;
+diff --git a/parser/html/nsHtml5TreeBuilder.cpp b/parser/html/nsHtml5TreeBuilder.cpp
+--- a/parser/html/nsHtml5TreeBuilder.cpp
++++ b/parser/html/nsHtml5TreeBuilder.cpp
+@@ -3301,17 +3301,17 @@ nsHtml5TreeBuilder::findLastInTableScope
+   return NS_HTML5TREE_BUILDER_NOT_FOUND_ON_STACK;
+ }
+ 
+ void 
+ nsHtml5TreeBuilder::clearStackBackTo(int32_t eltPos)
+ {
+   int32_t eltGroup = stack[eltPos]->getGroup();
+   while (currentPtr > eltPos) {
+-    if (stack[currentPtr]->ns == kNameSpaceID_XHTML && stack[currentPtr]->getGroup() == NS_HTML5TREE_BUILDER_TEMPLATE && (eltGroup == NS_HTML5TREE_BUILDER_TABLE || eltGroup == NS_HTML5TREE_BUILDER_TBODY_OR_THEAD_OR_TFOOT || eltGroup == NS_HTML5TREE_BUILDER_TR || eltGroup == NS_HTML5TREE_BUILDER_HTML)) {
++    if (stack[currentPtr]->ns == kNameSpaceID_XHTML && stack[currentPtr]->getGroup() == NS_HTML5TREE_BUILDER_TEMPLATE && (eltGroup == NS_HTML5TREE_BUILDER_TABLE || eltGroup == NS_HTML5TREE_BUILDER_TBODY_OR_THEAD_OR_TFOOT || eltGroup == NS_HTML5TREE_BUILDER_TR || !eltPos)) {
+       return;
+     }
+     pop();
+   }
+ }
+ 
+ void 
+ nsHtml5TreeBuilder::resetTheInsertionMode()
+
diff --git a/gnu/packages/patches/icecat-CVE-2016-1961.patch b/gnu/packages/patches/icecat-CVE-2016-1961.patch
new file mode 100644
index 0000000000..10162be24b
--- /dev/null
+++ b/gnu/packages/patches/icecat-CVE-2016-1961.patch
@@ -0,0 +1,33 @@
+Copied from upstream:
+https://hg.mozilla.org/releases/mozilla-esr38/raw-rev/e93aeb25e2a4
+
+# HG changeset patch
+# User Andrew McCreight <continuation@gmail.com>
+# Date 1455891967 28800
+# Node ID e93aeb25e2a44df8d22f5a065b4410620e2c8730
+# Parent  221de852fda32714a9e484774ceafafb450ea73c
+Bug 1249377 - Hold a strong reference to |root| in nsHTMLDocument::SetBody. r=bz, a=sylvestre
+
+diff --git a/dom/html/nsHTMLDocument.cpp b/dom/html/nsHTMLDocument.cpp
+--- a/dom/html/nsHTMLDocument.cpp
++++ b/dom/html/nsHTMLDocument.cpp
+@@ -1044,17 +1044,17 @@ nsHTMLDocument::SetBody(nsIDOMHTMLElemen
+   ErrorResult rv;
+   SetBody(static_cast<nsGenericHTMLElement*>(newBody.get()), rv);
+   return rv.ErrorCode();
+ }
+ 
+ void
+ nsHTMLDocument::SetBody(nsGenericHTMLElement* newBody, ErrorResult& rv)
+ {
+-  Element* root = GetRootElement();
++  nsCOMPtr<Element> root = GetRootElement();
+ 
+   // The body element must be either a body tag or a frameset tag. And we must
+   // have a html root tag, otherwise GetBody will not return the newly set
+   // body.
+   if (!newBody || !(newBody->Tag() == nsGkAtoms::body ||
+                     newBody->Tag() == nsGkAtoms::frameset) ||
+       !root || !root->IsHTML() ||
+       root->Tag() != nsGkAtoms::html) {
+
diff --git a/gnu/packages/patches/icecat-CVE-2016-1962.patch b/gnu/packages/patches/icecat-CVE-2016-1962.patch
new file mode 100644
index 0000000000..7eb4e072a1
--- /dev/null
+++ b/gnu/packages/patches/icecat-CVE-2016-1962.patch
@@ -0,0 +1,107 @@
+Copied from upstream:
+https://hg.mozilla.org/releases/mozilla-esr38/raw-rev/221de852fda3
+
+# HG changeset patch
+# User Randell Jesup <rjesup@jesup.org>
+# Date 1455862087 18000
+# Node ID 221de852fda32714a9e484774ceafafb450ea73c
+# Parent  b03db72e32f6e3acdc9f8705371cb222d7e6c456
+Bug 1240760: Update DataChannel::Close() r=mcmanus, a=ritu
+
+MozReview-Commit-ID: 7nN9h3M3O8w
+
+diff --git a/netwerk/sctp/datachannel/DataChannel.cpp b/netwerk/sctp/datachannel/DataChannel.cpp
+--- a/netwerk/sctp/datachannel/DataChannel.cpp
++++ b/netwerk/sctp/datachannel/DataChannel.cpp
+@@ -1771,17 +1771,17 @@ DataChannelConnection::HandleStreamReset
+           }
+           NS_DispatchToMainThread(new DataChannelOnMessageAvailable(
+                                     DataChannelOnMessageAvailable::ON_CHANNEL_CLOSED, this,
+                                     channel));
+           mStreams[channel->mStream] = nullptr;
+ 
+           LOG(("Disconnected DataChannel %p from connection %p",
+                (void *) channel.get(), (void *) channel->mConnection.get()));
+-          channel->Destroy();
++          channel->DestroyLocked();
+           // At this point when we leave here, the object is a zombie held alive only by the DOM object
+         } else {
+           LOG(("Can't find incoming channel %d",i));
+         }
+       }
+     }
+   }
+ 
+@@ -2498,17 +2498,17 @@ DataChannelConnection::CloseInt(DataChan
+       mStreams[channel->mStream] = nullptr;
+     } else {
+       SendOutgoingStreamReset();
+     }
+   }
+   aChannel->mState = CLOSING;
+   if (mState == CLOSED) {
+     // we're not going to hang around waiting
+-    channel->Destroy();
++    channel->DestroyLocked();
+   }
+   // At this point when we leave here, the object is a zombie held alive only by the DOM object
+ }
+ 
+ void DataChannelConnection::CloseAll()
+ {
+   LOG(("Closing all channels (connection %p)", (void*) this));
+   // Don't need to lock here
+@@ -2552,23 +2552,25 @@ DataChannel::~DataChannel()
+   // wrong, nothing bad happens.  A worst it's a leak.
+   NS_ASSERTION(mState == CLOSED || mState == CLOSING, "unexpected state in ~DataChannel");
+ }
+ 
+ void
+ DataChannel::Close()
+ {
+   ENSURE_DATACONNECTION;
++  RefPtr<DataChannelConnection> connection(mConnection);
+   mConnection->Close(this);
+ }
+ 
+ // Used when disconnecting from the DataChannelConnection
+ void
+-DataChannel::Destroy()
++DataChannel::DestroyLocked()
+ {
++  mConnection->mLock.AssertCurrentThreadOwns();
+   ENSURE_DATACONNECTION;
+ 
+   LOG(("Destroying Data channel %u", mStream));
+   MOZ_ASSERT_IF(mStream != INVALID_STREAM,
+                 !mConnection->FindChannelByStream(mStream));
+   mStream = INVALID_STREAM;
+   mState = CLOSED;
+   mConnection = nullptr;
+diff --git a/netwerk/sctp/datachannel/DataChannel.h b/netwerk/sctp/datachannel/DataChannel.h
+--- a/netwerk/sctp/datachannel/DataChannel.h
++++ b/netwerk/sctp/datachannel/DataChannel.h
+@@ -331,19 +331,20 @@ public:
+     {
+       NS_ASSERTION(mConnection,"NULL connection");
+     }
+ 
+ private:
+   ~DataChannel();
+ 
+ public:
+-  void Destroy(); // when we disconnect from the connection after stream RESET
++  NS_INLINE_DECL_THREADSAFE_REFCOUNTING(DataChannel)
+ 
+-  NS_INLINE_DECL_THREADSAFE_REFCOUNTING(DataChannel)
++  // when we disconnect from the connection after stream RESET
++  void DestroyLocked();
+ 
+   // Close this DataChannel.  Can be called multiple times.  MUST be called
+   // before destroying the DataChannel (state must be CLOSED or CLOSING).
+   void Close();
+ 
+   // Set the listener (especially for channels created from the other side)
+   void SetListener(DataChannelListener *aListener, nsISupports *aContext);
+ 
+
diff --git a/gnu/packages/patches/icecat-CVE-2016-1964.patch b/gnu/packages/patches/icecat-CVE-2016-1964.patch
new file mode 100644
index 0000000000..e53fc749b5
--- /dev/null
+++ b/gnu/packages/patches/icecat-CVE-2016-1964.patch
@@ -0,0 +1,54 @@
+Copied from upstream:
+https://hg.mozilla.org/releases/mozilla-esr38/raw-rev/a653013e7b50
+
+# HG changeset patch
+# User Peter Van der Beken <peterv@propagandism.org>
+# Date 1454340035 -3600
+# Node ID a653013e7b503912a32621e8da64a37171316588
+# Parent  0d0d7e8292f7ecf5f1149d528c0524f04447c4ad
+Bug 1243335 - report bad QName. r=sicking, a=sylvestre
+
+diff --git a/dom/xslt/xslt/txInstructions.cpp b/dom/xslt/xslt/txInstructions.cpp
+--- a/dom/xslt/xslt/txInstructions.cpp
++++ b/dom/xslt/xslt/txInstructions.cpp
+@@ -93,16 +93,19 @@ txAttribute::txAttribute(nsAutoPtr<Expr>
+                          txNamespaceMap* aMappings)
+     : mName(Move(aName)), mNamespace(Move(aNamespace)), mMappings(aMappings)
+ {
+ }
+ 
+ nsresult
+ txAttribute::execute(txExecutionState& aEs)
+ {
++    nsAutoPtr<txTextHandler> handler(
++        static_cast<txTextHandler*>(aEs.popResultHandler()));
++
+     nsAutoString name;
+     nsresult rv = mName->evaluateToString(aEs.getEvalContext(), name);
+     NS_ENSURE_SUCCESS(rv, rv);
+ 
+     const char16_t* colon;
+     if (!XMLUtils::isValidQName(name, &colon) ||
+         TX_StringEqualsAtom(name, nsGkAtoms::xmlns)) {
+         return NS_OK;
+@@ -125,19 +128,16 @@ txAttribute::execute(txExecutionState& a
+         if (!nspace.IsEmpty()) {
+             nsId = txNamespaceManager::getNamespaceID(nspace);
+         }
+     }
+     else if (colon) {
+         nsId = mMappings->lookupNamespace(prefix);
+     }
+ 
+-    nsAutoPtr<txTextHandler> handler(
+-        static_cast<txTextHandler*>(aEs.popResultHandler()));
+-
+     // add attribute if everything was ok
+     return nsId != kNameSpaceID_Unknown ?
+            aEs.mResultHandler->attribute(prefix, Substring(name, lnameStart),
+                                          nsId, handler->mValue) :
+            NS_OK;
+ }
+ 
+ txCallTemplate::txCallTemplate(const txExpandedName& aName)
+
diff --git a/gnu/packages/patches/icecat-CVE-2016-1965.patch b/gnu/packages/patches/icecat-CVE-2016-1965.patch
new file mode 100644
index 0000000000..8a37d4975c
--- /dev/null
+++ b/gnu/packages/patches/icecat-CVE-2016-1965.patch
@@ -0,0 +1,44 @@
+Copied from upstream:
+https://hg.mozilla.org/releases/mozilla-esr38/raw-rev/b4467681abd6
+
+# HG changeset patch
+# User Gijs Kruitbosch <gijskruitbosch@gmail.com>
+# Date 1455276061 0
+# Node ID b4467681abd676cd5575cbdf922927f8f54d2ad9
+# Parent  8c1d40e45a72c6432e879137a0afa519dc6c9841
+Bug 1245264 - r=bz, r=ritu
+
+MozReview-Commit-ID: I0sVdritpD3
+
+diff --git a/dom/base/nsLocation.cpp b/dom/base/nsLocation.cpp
+--- a/dom/base/nsLocation.cpp
++++ b/dom/base/nsLocation.cpp
+@@ -735,16 +735,27 @@ nsLocation::SetProtocol(const nsAString&
+     return rv;
+   }
+ 
+   rv = uri->SetScheme(NS_ConvertUTF16toUTF8(aProtocol));
+   if (NS_WARN_IF(NS_FAILED(rv))) {
+     return rv;
+   }
+ 
++  nsAutoCString newSpec;
++  rv = uri->GetSpec(newSpec);
++  if (NS_FAILED(rv)) {
++    return rv;
++  }
++  // We may want a new URI class for the new URI, so recreate it:
++  rv = NS_NewURI(getter_AddRefs(uri), newSpec);
++  if (NS_FAILED(rv)) {
++    return rv;
++  }
++
+   return SetURI(uri);
+ }
+ 
+ void
+ nsLocation::GetUsername(nsAString& aUsername, ErrorResult& aError)
+ {
+   if (!CallerSubsumes()) {
+     aError.Throw(NS_ERROR_DOM_SECURITY_ERR);
+
diff --git a/gnu/packages/patches/icecat-CVE-2016-1966.patch b/gnu/packages/patches/icecat-CVE-2016-1966.patch
new file mode 100644
index 0000000000..6bf5f9f95e
--- /dev/null
+++ b/gnu/packages/patches/icecat-CVE-2016-1966.patch
@@ -0,0 +1,36 @@
+Copied from upstream:
+https://hg.mozilla.org/releases/mozilla-esr38/raw-rev/291c2f31c48c
+
+# HG changeset patch
+# User Nicholas Nethercote <nnethercote@mozilla.com>
+# Date 1454650565 -39600
+# Node ID 291c2f31c48c7e96b1884b55273355970fa0fc30
+# Parent  11e6614756551cfd7291e73eefb90c52873a8480
+Bug 1246054 - Fix an erroneous nsNPObjWrapper assertion. r=froydnj. a=ritu
+
+diff --git a/dom/plugins/base/nsJSNPRuntime.cpp b/dom/plugins/base/nsJSNPRuntime.cpp
+--- a/dom/plugins/base/nsJSNPRuntime.cpp
++++ b/dom/plugins/base/nsJSNPRuntime.cpp
+@@ -1915,18 +1915,19 @@ nsNPObjWrapper::GetNewOrUsed(NPP npp, JS
+   // No existing JSObject, create one.
+ 
+   JS::Rooted<JSObject*> obj(cx, ::JS_NewObject(cx, js::Jsvalify(&sNPObjectJSWrapperClass)));
+ 
+   if (generation != sNPObjWrappers.Generation()) {
+       // Reload entry if the JS_NewObject call caused a GC and reallocated
+       // the table (see bug 445229). This is guaranteed to succeed.
+ 
+-      NS_ASSERTION(PL_DHashTableSearch(&sNPObjWrappers, npobj),
+-                   "Hashtable didn't find what we just added?");
++      entry = static_cast<NPObjWrapperHashEntry*>
++        (PL_DHashTableSearch(&sNPObjWrappers, npobj));
++      NS_ASSERTION(entry, "Hashtable didn't find what we just added?");
+   }
+ 
+   if (!obj) {
+     // OOM? Remove the stale entry from the hash.
+ 
+     PL_DHashTableRawRemove(&sNPObjWrappers, entry);
+ 
+     return nullptr;
+
diff --git a/gnu/packages/patches/icecat-CVE-2016-1974.patch b/gnu/packages/patches/icecat-CVE-2016-1974.patch
new file mode 100644
index 0000000000..70fc23b8f3
--- /dev/null
+++ b/gnu/packages/patches/icecat-CVE-2016-1974.patch
@@ -0,0 +1,530 @@
+Copied from upstream:
+https://hg.mozilla.org/releases/mozilla-esr38/raw-rev/271e3a5a53d9
+
+# HG changeset patch
+# User Henri Sivonen <hsivonen@hsivonen.fi>
+# Date 1455014759 -7200
+# Node ID 271e3a5a53d96871141e89271f611033b512e3e4
+# Parent  9719b71d72dd2a3c5ee12ace156af2a63d9595ac
+Bug 1228103. r=smaug. a=sylvestre
+
+diff --git a/parser/htmlparser/nsExpatDriver.cpp b/parser/htmlparser/nsExpatDriver.cpp
+--- a/parser/htmlparser/nsExpatDriver.cpp
++++ b/parser/htmlparser/nsExpatDriver.cpp
+@@ -1127,22 +1127,28 @@ nsExpatDriver::ConsumeToken(nsScanner& a
+       XML_Size lastLineLength = XML_GetCurrentColumnNumber(mExpatParser);
+ 
+       if (lastLineLength <= consumed) {
+         // The length of the last line was less than what expat consumed, so
+         // there was at least one line break in the consumed data. Store the
+         // last line until the point where we stopped parsing.
+         nsScannerIterator startLastLine = currentExpatPosition;
+         startLastLine.advance(-((ptrdiff_t)lastLineLength));
+-        CopyUnicodeTo(startLastLine, currentExpatPosition, mLastLine);
++        if (!CopyUnicodeTo(startLastLine, currentExpatPosition, mLastLine)) {
++          return (mInternalState = NS_ERROR_OUT_OF_MEMORY);
++        }
+       }
+       else {
+         // There was no line break in the consumed data, append the consumed
+         // data.
+-        AppendUnicodeTo(oldExpatPosition, currentExpatPosition, mLastLine);
++        if (!AppendUnicodeTo(oldExpatPosition,
++                             currentExpatPosition,
++                             mLastLine)) {
++          return (mInternalState = NS_ERROR_OUT_OF_MEMORY);
++        }
+       }
+     }
+ 
+     mExpatBuffered += length - consumed;
+ 
+     if (BlockedOrInterrupted()) {
+       PR_LOG(GetExpatDriverLog(), PR_LOG_DEBUG,
+              ("Blocked or interrupted parser (probably for loading linked "
+diff --git a/parser/htmlparser/nsParser.cpp b/parser/htmlparser/nsParser.cpp
+--- a/parser/htmlparser/nsParser.cpp
++++ b/parser/htmlparser/nsParser.cpp
+@@ -1508,17 +1508,19 @@ nsParser::ResumeParse(bool allowIteratio
+                 DidBuildModel(mStreamStatus);
+                 return NS_OK;
+               }
+             } else {
+               CParserContext* theContext = PopContext();
+               if (theContext) {
+                 theIterationIsOk = allowIteration && theContextIsStringBased;
+                 if (theContext->mCopyUnused) {
+-                  theContext->mScanner->CopyUnusedData(mUnusedInput);
++                  if (!theContext->mScanner->CopyUnusedData(mUnusedInput)) {
++                    mInternalState = NS_ERROR_OUT_OF_MEMORY;
++                  }
+                 }
+ 
+                 delete theContext;
+               }
+ 
+               result = mInternalState;
+               aIsFinalChunk = mParserContext &&
+                               mParserContext->mStreamListenerState == eOnStop;
+diff --git a/parser/htmlparser/nsScanner.cpp b/parser/htmlparser/nsScanner.cpp
+--- a/parser/htmlparser/nsScanner.cpp
++++ b/parser/htmlparser/nsScanner.cpp
+@@ -379,17 +379,19 @@ nsresult nsScanner::Peek(nsAString& aStr
+   if (mCountRemaining < uint32_t(aNumChars + aOffset)) {
+     end = mEndPosition;
+   }
+   else {
+     end = start;
+     end.advance(aNumChars);
+   }
+ 
+-  CopyUnicodeTo(start, end, aStr);
++  if (!CopyUnicodeTo(start, end, aStr)) {
++    return NS_ERROR_OUT_OF_MEMORY;
++  }
+ 
+   return NS_OK;
+ }
+ 
+ 
+ /**
+  *  Skip whitespace on scanner input stream
+  *  
+@@ -542,17 +544,19 @@ nsresult nsScanner::ReadTagIdentifier(ns
+ 
+     if (!found) {
+       ++current;
+     }
+   }
+ 
+   // Don't bother appending nothing.
+   if (current != mCurrentPosition) {
+-    AppendUnicodeTo(mCurrentPosition, current, aString);
++    if (!AppendUnicodeTo(mCurrentPosition, current, aString)) {
++      return NS_ERROR_OUT_OF_MEMORY;
++    }
+   }
+ 
+   SetPosition(current);  
+   if (current == end) {
+     result = kEOF;
+   }
+ 
+   //DoErrTest(aString);
+@@ -597,26 +601,30 @@ nsresult nsScanner::ReadEntityIdentifier
+         default:
+           found = ('a'<=theChar && theChar<='z') ||
+                   ('A'<=theChar && theChar<='Z') ||
+                   ('0'<=theChar && theChar<='9');
+           break;
+       }
+ 
+       if(!found) {
+-        AppendUnicodeTo(mCurrentPosition, current, aString);
++        if (!AppendUnicodeTo(mCurrentPosition, current, aString)) {
++          return NS_ERROR_OUT_OF_MEMORY;
++        }
+         break;
+       }
+     }
+     ++current;
+   }
+   
+   SetPosition(current);
+   if (current == end) {
+-    AppendUnicodeTo(origin, current, aString);
++    if (!AppendUnicodeTo(origin, current, aString)) {
++      return NS_ERROR_OUT_OF_MEMORY;
++    }
+     return kEOF;
+   }
+ 
+   //DoErrTest(aString);
+ 
+   return result;
+ }
+ 
+@@ -646,26 +654,30 @@ nsresult nsScanner::ReadNumber(nsString&
+   while(current != end) {
+     theChar=*current;
+     if(theChar) {
+       done = (theChar < '0' || theChar > '9') && 
+              ((aBase == 16)? (theChar < 'A' || theChar > 'F') &&
+                              (theChar < 'a' || theChar > 'f')
+                              :true);
+       if(done) {
+-        AppendUnicodeTo(origin, current, aString);
++        if (!AppendUnicodeTo(origin, current, aString)) {
++          return NS_ERROR_OUT_OF_MEMORY;
++        }
+         break;
+       }
+     }
+     ++current;
+   }
+ 
+   SetPosition(current);
+   if (current == end) {
+-    AppendUnicodeTo(origin, current, aString);
++    if (!AppendUnicodeTo(origin, current, aString)) {
++      return NS_ERROR_OUT_OF_MEMORY;
++    }
+     return kEOF;
+   }
+ 
+   //DoErrTest(aString);
+ 
+   return result;
+ }
+ 
+@@ -712,37 +724,43 @@ nsresult nsScanner::ReadWhitespace(nsSca
+           char16_t thePrevChar = theChar;
+           theChar = (++current != end) ? *current : '\0';
+           if ((thePrevChar == '\r' && theChar == '\n') ||
+               (thePrevChar == '\n' && theChar == '\r')) {
+             theChar = (++current != end) ? *current : '\0'; // CRLF == LFCR => LF
+             haveCR = true;
+           } else if (thePrevChar == '\r') {
+             // Lone CR becomes CRLF; callers should know to remove extra CRs
+-            AppendUnicodeTo(origin, current, aString);
++            if (!AppendUnicodeTo(origin, current, aString)) {
++              return NS_ERROR_OUT_OF_MEMORY;
++            }
+             aString.writable().Append(char16_t('\n'));
+             origin = current;
+             haveCR = true;
+           }
+         }
+         break;
+       case ' ' :
+       case '\t':
+         theChar = (++current != end) ? *current : '\0';
+         break;
+       default:
+         done = true;
+-        AppendUnicodeTo(origin, current, aString);
++        if (!AppendUnicodeTo(origin, current, aString)) {
++          return NS_ERROR_OUT_OF_MEMORY;
++        }
+         break;
+     }
+   }
+ 
+   SetPosition(current);
+   if (current == end) {
+-    AppendUnicodeTo(origin, current, aString);
++    if (!AppendUnicodeTo(origin, current, aString)) {
++      return NS_ERROR_OUT_OF_MEMORY;
++    }
+     result = kEOF;
+   }
+ 
+   aHaveCR = haveCR;
+   return result;
+ }
+ 
+ //XXXbz callers of this have to manage their lone '\r' themselves if they want
+@@ -846,34 +864,38 @@ nsresult nsScanner::ReadUntil(nsAString&
+     if(!(theChar & aEndCondition.mFilter)) {
+       // They were. Do a thorough check.
+ 
+       setcurrent = setstart;
+       while (*setcurrent) {
+         if (*setcurrent == theChar) {
+           if(addTerminal)
+             ++current;
+-          AppendUnicodeTo(origin, current, aString);
++          if (!AppendUnicodeTo(origin, current, aString)) {
++            return NS_ERROR_OUT_OF_MEMORY;
++          }
+           SetPosition(current);
+ 
+           //DoErrTest(aString);
+ 
+           return NS_OK;
+         }
+         ++setcurrent;
+       }
+     }
+     
+     ++current;
+   }
+ 
+   // If we are here, we didn't find any terminator in the string and
+   // current = mEndPosition
+   SetPosition(current);
+-  AppendUnicodeTo(origin, current, aString);
++  if (!AppendUnicodeTo(origin, current, aString)) {
++    return NS_ERROR_OUT_OF_MEMORY;
++  }
+   return kEOF;
+ }
+ 
+ nsresult nsScanner::ReadUntil(nsScannerSharedSubstring& aString,
+                               const nsReadEndCondition& aEndCondition,
+                               bool addTerminal)
+ {  
+   if (!mSlidingBuffer) {
+@@ -906,34 +928,38 @@ nsresult nsScanner::ReadUntil(nsScannerS
+     if(!(theChar & aEndCondition.mFilter)) {
+       // They were. Do a thorough check.
+ 
+       setcurrent = setstart;
+       while (*setcurrent) {
+         if (*setcurrent == theChar) {
+           if(addTerminal)
+             ++current;
+-          AppendUnicodeTo(origin, current, aString);
++          if (!AppendUnicodeTo(origin, current, aString)) {
++            return NS_ERROR_OUT_OF_MEMORY;
++          }
+           SetPosition(current);
+ 
+           //DoErrTest(aString);
+ 
+           return NS_OK;
+         }
+         ++setcurrent;
+       }
+     }
+     
+     ++current;
+   }
+ 
+   // If we are here, we didn't find any terminator in the string and
+   // current = mEndPosition
+   SetPosition(current);
+-  AppendUnicodeTo(origin, current, aString);
++  if (!AppendUnicodeTo(origin, current, aString)) {
++    return NS_ERROR_OUT_OF_MEMORY;
++  }
+   return kEOF;
+ }
+ 
+ nsresult nsScanner::ReadUntil(nsScannerIterator& aStart, 
+                               nsScannerIterator& aEnd,
+                               const nsReadEndCondition &aEndCondition,
+                               bool addTerminal)
+ {
+@@ -1025,26 +1051,30 @@ nsresult nsScanner::ReadUntil(nsAString&
+     if (theChar == '\0') {
+       ReplaceCharacter(current, sInvalid);
+       theChar = sInvalid;
+     }
+ 
+     if (aTerminalChar == theChar) {
+       if(addTerminal)
+         ++current;
+-      AppendUnicodeTo(origin, current, aString);
++      if (!AppendUnicodeTo(origin, current, aString)) {
++        return NS_ERROR_OUT_OF_MEMORY;
++      }
+       SetPosition(current);
+       return NS_OK;
+     }
+     ++current;
+   }
+ 
+   // If we are here, we didn't find any terminator in the string and
+   // current = mEndPosition
+-  AppendUnicodeTo(origin, current, aString);
++  if (!AppendUnicodeTo(origin, current, aString)) {
++    return NS_ERROR_OUT_OF_MEMORY;
++  }
+   SetPosition(current);
+   return kEOF;
+ 
+ }
+ 
+ void nsScanner::BindSubstring(nsScannerSubstring& aSubstring, const nsScannerIterator& aStart, const nsScannerIterator& aEnd)
+ {
+   aSubstring.Rebind(*mSlidingBuffer, aStart, aEnd);
+@@ -1142,29 +1172,29 @@ bool nsScanner::AppendToBuffer(nsScanner
+ }
+ 
+ /**
+  *  call this to copy bytes out of the scanner that have not yet been consumed
+  *  by the tokenization process.
+  *  
+  *  @update  gess 5/12/98
+  *  @param   aCopyBuffer is where the scanner buffer will be copied to
+- *  @return  nada
++ *  @return  true if OK or false on OOM
+  */
+-void nsScanner::CopyUnusedData(nsString& aCopyBuffer) {
++bool nsScanner::CopyUnusedData(nsString& aCopyBuffer) {
+   if (!mSlidingBuffer) {
+     aCopyBuffer.Truncate();
+-    return;
++    return true;
+   }
+ 
+   nsScannerIterator start, end;
+   start = mCurrentPosition;
+   end = mEndPosition;
+ 
+-  CopyUnicodeTo(start, end, aCopyBuffer);
++  return CopyUnicodeTo(start, end, aCopyBuffer);
+ }
+ 
+ /**
+  *  Retrieve the name of the file that the scanner is reading from.
+  *  In some cases, it's just a given name, because the scanner isn't
+  *  really reading from a file.
+  *  
+  *  @update  gess 5/12/98
+diff --git a/parser/htmlparser/nsScanner.h b/parser/htmlparser/nsScanner.h
+--- a/parser/htmlparser/nsScanner.h
++++ b/parser/htmlparser/nsScanner.h
+@@ -204,19 +204,19 @@ class nsScanner {
+                       nsIRequest *aRequest);
+ 
+       /**
+        *  Call this to copy bytes out of the scanner that have not yet been consumed
+        *  by the tokenization process.
+        *  
+        *  @update  gess 5/12/98
+        *  @param   aCopyBuffer is where the scanner buffer will be copied to
+-       *  @return  nada
++       *  @return  true if OK or false on OOM
+        */
+-      void CopyUnusedData(nsString& aCopyBuffer);
++      bool CopyUnusedData(nsString& aCopyBuffer);
+ 
+       /**
+        *  Retrieve the name of the file that the scanner is reading from.
+        *  In some cases, it's just a given name, because the scanner isn't
+        *  really reading from a file.
+        *  
+        *  @update  gess 5/12/98
+        *  @return  
+diff --git a/parser/htmlparser/nsScannerString.cpp b/parser/htmlparser/nsScannerString.cpp
+--- a/parser/htmlparser/nsScannerString.cpp
++++ b/parser/htmlparser/nsScannerString.cpp
+@@ -461,61 +461,63 @@ copy_multifragment_string( nsScannerIter
+         sink_traits::write(result, source_traits::read(first), distance);
+         NS_ASSERTION(distance > 0, "|copy_multifragment_string| will never terminate");
+         source_traits::advance(first, distance);
+       }
+ 
+     return result;
+   }
+ 
+-void
++bool
+ CopyUnicodeTo( const nsScannerIterator& aSrcStart,
+                const nsScannerIterator& aSrcEnd,
+                nsAString& aDest )
+   {
+     nsAString::iterator writer;
+     if (!aDest.SetLength(Distance(aSrcStart, aSrcEnd), mozilla::fallible)) {
+       aDest.Truncate();
+-      return; // out of memory
++      return false; // out of memory
+     }
+     aDest.BeginWriting(writer);
+     nsScannerIterator fromBegin(aSrcStart);
+     
+     copy_multifragment_string(fromBegin, aSrcEnd, writer);
++    return true;
+   }
+ 
+-void
++bool
+ AppendUnicodeTo( const nsScannerIterator& aSrcStart,
+                  const nsScannerIterator& aSrcEnd,
+                  nsScannerSharedSubstring& aDest )
+   {
+     // Check whether we can just create a dependent string.
+     if (aDest.str().IsEmpty()) {
+       // We can just make |aDest| point to the buffer.
+       // This will take care of copying if the buffer spans fragments.
+       aDest.Rebind(aSrcStart, aSrcEnd);
+-    } else {
+-      // The dest string is not empty, so it can't be a dependent substring.
+-      AppendUnicodeTo(aSrcStart, aSrcEnd, aDest.writable());
++      return true;
+     }
++    // The dest string is not empty, so it can't be a dependent substring.
++    return AppendUnicodeTo(aSrcStart, aSrcEnd, aDest.writable());
+   }
+ 
+-void
++bool
+ AppendUnicodeTo( const nsScannerIterator& aSrcStart,
+                  const nsScannerIterator& aSrcEnd,
+                  nsAString& aDest )
+   {
+     nsAString::iterator writer;
+     uint32_t oldLength = aDest.Length();
+     if (!aDest.SetLength(oldLength + Distance(aSrcStart, aSrcEnd), mozilla::fallible))
+-      return; // out of memory
++      return false; // out of memory
+     aDest.BeginWriting(writer).advance(oldLength);
+     nsScannerIterator fromBegin(aSrcStart);
+     
+     copy_multifragment_string(fromBegin, aSrcEnd, writer);
++    return true;
+   }
+ 
+ bool
+ FindCharInReadable( char16_t aChar,
+                     nsScannerIterator& aSearchStart,
+                     const nsScannerIterator& aSearchEnd )
+   {
+     while ( aSearchStart != aSearchEnd )
+diff --git a/parser/htmlparser/nsScannerString.h b/parser/htmlparser/nsScannerString.h
+--- a/parser/htmlparser/nsScannerString.h
++++ b/parser/htmlparser/nsScannerString.h
+@@ -539,43 +539,43 @@ nsScannerBufferList::Position::operator=
+ inline
+ size_t
+ Distance( const nsScannerIterator& aStart, const nsScannerIterator& aEnd )
+   {
+     typedef nsScannerBufferList::Position Position;
+     return Position::Distance(Position(aStart), Position(aEnd));
+   }
+ 
+-void
++bool
+ CopyUnicodeTo( const nsScannerIterator& aSrcStart,
+                const nsScannerIterator& aSrcEnd,
+                nsAString& aDest );
+ 
+ inline
+-void
++bool
+ CopyUnicodeTo( const nsScannerSubstring& aSrc, nsAString& aDest )
+   {
+     nsScannerIterator begin, end;
+-    CopyUnicodeTo(aSrc.BeginReading(begin), aSrc.EndReading(end), aDest);
++    return CopyUnicodeTo(aSrc.BeginReading(begin), aSrc.EndReading(end), aDest);
+   }
+ 
+-void
++bool
+ AppendUnicodeTo( const nsScannerIterator& aSrcStart,
+                  const nsScannerIterator& aSrcEnd,
+                  nsAString& aDest );
+ 
+ inline
+-void
++bool
+ AppendUnicodeTo( const nsScannerSubstring& aSrc, nsAString& aDest )
+   {
+     nsScannerIterator begin, end;
+-    AppendUnicodeTo(aSrc.BeginReading(begin), aSrc.EndReading(end), aDest);
++    return AppendUnicodeTo(aSrc.BeginReading(begin), aSrc.EndReading(end), aDest);
+   }
+ 
+-void
++bool
+ AppendUnicodeTo( const nsScannerIterator& aSrcStart,
+                  const nsScannerIterator& aSrcEnd,
+                  nsScannerSharedSubstring& aDest );
+ 
+ bool
+ FindCharInReadable( char16_t aChar,
+                     nsScannerIterator& aStart,
+                     const nsScannerIterator& aEnd );
+
diff --git a/gnu/packages/patches/icecat-bug-1248851.patch b/gnu/packages/patches/icecat-bug-1248851.patch
new file mode 100644
index 0000000000..ea4d6831b5
--- /dev/null
+++ b/gnu/packages/patches/icecat-bug-1248851.patch
@@ -0,0 +1,37 @@
+Copied from upstream:
+https://hg.mozilla.org/releases/mozilla-esr38/raw-rev/8c1d40e45a72
+
+# HG changeset patch
+# User Xidorn Quan <quanxunzhen@gmail.com>
+# Date 1456199544 -28800
+# Node ID 8c1d40e45a72c6432e879137a0afa519dc6c9841
+# Parent  1dd0ca8e70bd77b6fd93f36cc4e9c2cebfe8ba0a
+Bug 1248851 - r=sicking, a=ritu
+
+diff --git a/dom/indexedDB/ActorsParent.cpp b/dom/indexedDB/ActorsParent.cpp
+--- a/dom/indexedDB/ActorsParent.cpp
++++ b/dom/indexedDB/ActorsParent.cpp
+@@ -14823,22 +14823,19 @@ ObjectStoreAddOrPutRequestOp::DoDatabase
+     }
+ 
+     snappy::RawCompress(uncompressed, uncompressedLength, compressed,
+                         &compressedLength);
+ 
+     uint8_t* dataBuffer = reinterpret_cast<uint8_t*>(compressed);
+     size_t dataBufferLength = compressedLength;
+ 
+-    // If this call succeeds, | compressed | is now owned by the statement, and
+-    // we are no longer responsible for it.
+     rv = stmt->BindAdoptedBlobByName(NS_LITERAL_CSTRING("data"), dataBuffer,
+                                      dataBufferLength);
+     if (NS_WARN_IF(NS_FAILED(rv))) {
+-      moz_free(compressed);
+       return rv;
+     }
+   }
+ 
+   nsCOMPtr<nsIFile> fileDirectory;
+   nsCOMPtr<nsIFile> journalDirectory;
+ 
+   if (mFileManager) {
+
diff --git a/gnu/packages/patches/icecat-update-graphite2-pt2.patch b/gnu/packages/patches/icecat-update-graphite2-pt2.patch
new file mode 100644
index 0000000000..8acde75d6c
--- /dev/null
+++ b/gnu/packages/patches/icecat-update-graphite2-pt2.patch
@@ -0,0 +1,861 @@
+Copied from upstream:
+https://hg.mozilla.org/releases/mozilla-esr38/raw-rev/ec9cff7bb543
+
+# HG changeset patch
+# User Jonathan Kew <jkew@mozilla.com>
+# Date 1456760339 0
+# Node ID ec9cff7bb5439b2b4c1249ff9376d07a80172c27
+# Parent  6f4d5130238790fa5810c76ffeb9eccc65efa8c9
+Bug 1248876 - Update graphite2 to upstream release 1.3.6. r=jrmuizel a=sledru
+
+diff --git a/gfx/graphite2/README.mozilla b/gfx/graphite2/README.mozilla
+--- a/gfx/graphite2/README.mozilla
++++ b/gfx/graphite2/README.mozilla
+@@ -1,7 +1,3 @@
+-This directory contains the Graphite2 library release 1.3.5 from
+-https://github.com/silnrsi/graphite/releases/download/1.3.5/graphite2-minimal-1.3.5.tgz
++This directory contains the Graphite2 library release 1.3.6 from
++https://github.com/silnrsi/graphite/releases/download/1.3.6/graphite-minimal-1.3.6.tgz
+ See gfx/graphite2/moz-gr-update.sh for update procedure.
+-
+-Also includes two post-1.3.5 fixes:
+-a8b3ac2aed0eb132cd80efe7de88f8153e73c829
+-e569e28d83491fedb31b9220493f3c07f6ec6d80
+diff --git a/gfx/graphite2/include/graphite2/Font.h b/gfx/graphite2/include/graphite2/Font.h
+--- a/gfx/graphite2/include/graphite2/Font.h
++++ b/gfx/graphite2/include/graphite2/Font.h
+@@ -25,17 +25,17 @@
+     either version 2 of the License or (at your option) any later version.
+ */
+ #pragma once
+ 
+ #include "graphite2/Types.h"
+ 
+ #define GR2_VERSION_MAJOR   1
+ #define GR2_VERSION_MINOR   3
+-#define GR2_VERSION_BUGFIX  5
++#define GR2_VERSION_BUGFIX  6
+ 
+ #ifdef __cplusplus
+ extern "C"
+ {
+ #endif
+ 
+ typedef struct gr_face          gr_face;
+ typedef struct gr_font          gr_font;
+diff --git a/gfx/graphite2/moz-gr-update.sh b/gfx/graphite2/moz-gr-update.sh
+--- a/gfx/graphite2/moz-gr-update.sh
++++ b/gfx/graphite2/moz-gr-update.sh
+@@ -14,17 +14,17 @@
+ RELEASE=$1
+ 
+ if [ "x$RELEASE" == "x" ]
+ then
+     echo "Must provide the version number to be used."
+     exit 1
+ fi
+ 
+-TARBALL="https://github.com/silnrsi/graphite/releases/download/$RELEASE/graphite2-minimal-$RELEASE.tgz"
++TARBALL="https://github.com/silnrsi/graphite/releases/download/$RELEASE/graphite-minimal-$RELEASE.tgz"
+ 
+ foo=`basename $0`
+ TMPFILE=`mktemp -t ${foo}` || exit 1
+ 
+ curl -L "$TARBALL" -o "$TMPFILE"
+ tar -x -z -C gfx/graphite2/ --strip-components 1 -f "$TMPFILE" || exit 1
+ rm "$TMPFILE"
+ 
+diff --git a/gfx/graphite2/src/CmapCache.cpp b/gfx/graphite2/src/CmapCache.cpp
+--- a/gfx/graphite2/src/CmapCache.cpp
++++ b/gfx/graphite2/src/CmapCache.cpp
+@@ -33,43 +33,43 @@ of the License or (at your option) any l
+ 
+ 
+ using namespace graphite2;
+ 
+ const void * bmp_subtable(const Face::Table & cmap)
+ {
+     const void * stbl;
+     if (!cmap.size()) return 0;
+-    if (TtfUtil::CheckCmapSubtable4(stbl = TtfUtil::FindCmapSubtable(cmap, 3, 1, cmap.size()), cmap.size())
+-     || TtfUtil::CheckCmapSubtable4(stbl = TtfUtil::FindCmapSubtable(cmap, 0, 3, cmap.size()), cmap.size())
+-     || TtfUtil::CheckCmapSubtable4(stbl = TtfUtil::FindCmapSubtable(cmap, 0, 2, cmap.size()), cmap.size())
+-     || TtfUtil::CheckCmapSubtable4(stbl = TtfUtil::FindCmapSubtable(cmap, 0, 1, cmap.size()), cmap.size())
+-     || TtfUtil::CheckCmapSubtable4(stbl = TtfUtil::FindCmapSubtable(cmap, 0, 0, cmap.size()), cmap.size()))
++    if (TtfUtil::CheckCmapSubtable4(stbl = TtfUtil::FindCmapSubtable(cmap, 3, 1, cmap.size()), cmap + cmap.size())
++     || TtfUtil::CheckCmapSubtable4(stbl = TtfUtil::FindCmapSubtable(cmap, 0, 3, cmap.size()), cmap + cmap.size())
++     || TtfUtil::CheckCmapSubtable4(stbl = TtfUtil::FindCmapSubtable(cmap, 0, 2, cmap.size()), cmap + cmap.size())
++     || TtfUtil::CheckCmapSubtable4(stbl = TtfUtil::FindCmapSubtable(cmap, 0, 1, cmap.size()), cmap + cmap.size())
++     || TtfUtil::CheckCmapSubtable4(stbl = TtfUtil::FindCmapSubtable(cmap, 0, 0, cmap.size()), cmap + cmap.size()))
+         return stbl;
+     return 0;
+ }
+ 
+ const void * smp_subtable(const Face::Table & cmap)
+ {
+     const void * stbl;
+     if (!cmap.size()) return 0;
+-    if (TtfUtil::CheckCmapSubtable12(stbl = TtfUtil::FindCmapSubtable(cmap, 3, 10, cmap.size()), cmap.size())
+-     || TtfUtil::CheckCmapSubtable12(stbl = TtfUtil::FindCmapSubtable(cmap, 0, 4, cmap.size()), cmap.size()))
++    if (TtfUtil::CheckCmapSubtable12(stbl = TtfUtil::FindCmapSubtable(cmap, 3, 10, cmap.size()), cmap + cmap.size())
++     || TtfUtil::CheckCmapSubtable12(stbl = TtfUtil::FindCmapSubtable(cmap, 0, 4, cmap.size()), cmap + cmap.size()))
+         return stbl;
+     return 0;
+ }
+ 
+ template <unsigned int (*NextCodePoint)(const void *, unsigned int, int *),
+           uint16 (*LookupCodePoint)(const void *, unsigned int, int)>
+ bool cache_subtable(uint16 * blocks[], const void * cst, const unsigned int limit)
+ {
+     int rangeKey = 0;
+     uint32          codePoint = NextCodePoint(cst, 0, &rangeKey),
+                     prevCodePoint = 0;
+-    while (codePoint != limit)
++    while (codePoint < limit)
+     {
+         unsigned int block = codePoint >> 8;
+         if (!blocks[block])
+         {
+             blocks[block] = grzeroalloc<uint16>(0x100);
+             if (!blocks[block])
+                 return false;
+         }
+diff --git a/gfx/graphite2/src/Code.cpp b/gfx/graphite2/src/Code.cpp
+--- a/gfx/graphite2/src/Code.cpp
++++ b/gfx/graphite2/src/Code.cpp
+@@ -79,18 +79,19 @@ struct context
+ 
+ 
+ class Machine::Code::decoder
+ {
+ public:
+     struct limits;
+     struct analysis
+     {
++        static const int NUMCONTEXTS = 256;
+         uint8     slotref;
+-        context   contexts[256];
++        context   contexts[NUMCONTEXTS];
+         byte      max_ref;
+         
+         analysis() : slotref(0), max_ref(0) {};
+         void set_ref(int index, bool incinsert=false) throw();
+         void set_noref(int index) throw();
+         void set_changed(int index) throw();
+ 
+     };
+@@ -363,29 +364,33 @@ opcode Machine::Code::decoder::fetch_opc
+             break;
+         case ATTR_SET :
+         case ATTR_ADD :
+         case ATTR_SUB :
+         case ATTR_SET_SLOT :
+             if (--_stack_depth < 0)
+                 failure(underfull_stack);
+             valid_upto(gr_slatMax, bc[0]);
++            if (attrCode(bc[0]) == gr_slatUserDefn)     // use IATTR for user attributes
++                failure(out_of_range_data);
+             test_context();
+             break;
+         case IATTR_SET_SLOT :
+             if (--_stack_depth < 0)
+                 failure(underfull_stack);
+             if (valid_upto(gr_slatMax, bc[0]))
+                 valid_upto(_max.attrid[bc[0]], bc[1]);
+             test_context();
+             break;
+         case PUSH_SLOT_ATTR :
+             ++_stack_depth;
+             valid_upto(gr_slatMax, bc[0]);
+             valid_upto(_rule_length, _pre_context + int8(bc[1]));
++            if (attrCode(bc[0]) == gr_slatUserDefn)     // use IATTR for user attributes
++                failure(out_of_range_data);
+             break;
+         case PUSH_GLYPH_ATTR_OBS :
+             ++_stack_depth;
+             valid_upto(_max.glyf_attrs, bc[0]);
+             valid_upto(_rule_length, _pre_context + int8(bc[1]));
+             break;
+         case PUSH_GLYPH_METRIC :
+             ++_stack_depth;
+@@ -656,24 +661,24 @@ bool Machine::Code::decoder::validate_op
+         return false;
+     }
+     return true;
+ }
+ 
+ 
+ bool Machine::Code::decoder::valid_upto(const uint16 limit, const uint16 x) const throw()
+ {
+-    const bool t = x < limit;
++    const bool t = (limit != 0) && (x < limit);
+     if (!t) failure(out_of_range_data);
+     return t;
+ }
+ 
+ bool Machine::Code::decoder::test_context() const throw()
+ {
+-    if (_pre_context >= _rule_length)
++    if (_pre_context >= _rule_length || _analysis.slotref >= analysis::NUMCONTEXTS - 1)
+     {
+         failure(out_of_range_data);
+         return false;
+     }
+     return true;
+ }
+ 
+ inline 
+@@ -681,34 +686,34 @@ void Machine::Code::failure(const status
+     release_buffers();
+     _status = s;
+ }
+ 
+ 
+ inline
+ void Machine::Code::decoder::analysis::set_ref(int index, bool incinsert) throw() {
+     if (incinsert && contexts[slotref].flags.inserted) --index;
+-    if (index + slotref < 0) return;
++    if (index + slotref < 0 || index + slotref >= NUMCONTEXTS) return;
+     contexts[index + slotref].flags.referenced = true;
+     if ((index > 0 || !contexts[index + slotref].flags.inserted) && index + slotref > max_ref) max_ref = index + slotref;
+ }
+ 
+ 
+ inline
+ void Machine::Code::decoder::analysis::set_noref(int index) throw() {
+     if (contexts[slotref].flags.inserted) --index;
+-    if (index + slotref < 0) return;
++    if (index + slotref < 0 || index + slotref >= NUMCONTEXTS) return;
+     if ((index > 0 || !contexts[index + slotref].flags.inserted) && index + slotref > max_ref) max_ref = index + slotref;
+ }
+ 
+ 
+ inline
+ void Machine::Code::decoder::analysis::set_changed(int index) throw() {
+     if (contexts[slotref].flags.inserted) --index;
+-    if (index + slotref < 0) return;
++    if (index + slotref < 0 || index + slotref >= NUMCONTEXTS) return;
+     contexts[index + slotref].flags.changed = true;
+     if ((index > 0 || !contexts[index + slotref].flags.inserted) && index + slotref > max_ref) max_ref = index + slotref;
+ }
+ 
+ 
+ void Machine::Code::release_buffers() throw()
+ {
+     if (_own)
+diff --git a/gfx/graphite2/src/GlyphCache.cpp b/gfx/graphite2/src/GlyphCache.cpp
+--- a/gfx/graphite2/src/GlyphCache.cpp
++++ b/gfx/graphite2/src/GlyphCache.cpp
+@@ -260,17 +260,17 @@ GlyphCache::Loader::Loader(const Face & 
+         _head = Face::Table();
+         return;
+     }
+ 
+     if (!dumb_font)
+     {
+         if ((m_pGlat = Face::Table(face, Tag::Glat, 0x00030000)) == NULL
+             || (m_pGloc = Face::Table(face, Tag::Gloc)) == NULL
+-            || m_pGloc.size() < 6)
++            || m_pGloc.size() < 8)
+         {
+             _head = Face::Table();
+             return;
+         }
+         const byte    * p = m_pGloc;
+         int       version = be::read<uint32>(p);
+         const uint16    flags = be::read<uint16>(p);
+         _num_attrs = be::read<uint16>(p);
+diff --git a/gfx/graphite2/src/Pass.cpp b/gfx/graphite2/src/Pass.cpp
+--- a/gfx/graphite2/src/Pass.cpp
++++ b/gfx/graphite2/src/Pass.cpp
+@@ -233,17 +233,17 @@ bool Pass::readRules(const byte * rule_m
+     m_codes = new Code [m_numRules*2];
+     const size_t prog_pool_sz = vm::Machine::Code::estimateCodeDataOut(ac_end - ac_data + rc_end - rc_data);
+     m_progs = gralloc<byte>(prog_pool_sz);
+     byte * prog_pool_free = m_progs,
+          * prog_pool_end  = m_progs + prog_pool_sz;
+     if (e.test(!(m_rules && m_codes && m_progs), E_OUTOFMEM)) return face.error(e);
+ 
+     Rule * r = m_rules + m_numRules - 1;
+-    for (size_t n = m_numRules; n; --n, --r, ac_end = ac_begin, rc_end = rc_begin)
++    for (size_t n = m_numRules; r >= m_rules; --n, --r, ac_end = ac_begin, rc_end = rc_begin)
+     {
+         face.error_context((face.error_context() & 0xFFFF00) + EC_ARULE + ((n - 1) << 24));
+         r->preContext = *--precontext;
+         r->sort       = be::peek<uint16>(--sort_key);
+ #ifndef NDEBUG
+         r->rule_idx   = n - 1;
+ #endif
+         if (r->sort > 63 || r->preContext >= r->sort || r->preContext > m_maxPreCtxt || r->preContext < m_minPreCtxt)
+@@ -405,16 +405,17 @@ bool Pass::runGraphite(vm::Machine & m, 
+         json::closer rules_array_closer(fsm.dbgout);
+ #endif
+ 
+         m.slotMap().highwater(currHigh);
+         int lc = m_iMaxLoop;
+         do
+         {
+             findNDoRule(s, m, fsm);
++            if (m.status() != Machine::finished) return false;
+             if (s && (s == m.slotMap().highwater() || m.slotMap().highpassed() || --lc == 0)) {
+                 if (!lc)
+                     s = m.slotMap().highwater();
+                 lc = m_iMaxLoop;
+                 if (s)
+                     m.slotMap().highwater(s->next());
+             }
+         } while (s);
+@@ -495,17 +496,22 @@ void Pass::findNDoRule(Slot * & slot, Ma
+ {
+     assert(slot);
+ 
+     if (runFSM(fsm, slot))
+     {
+         // Search for the first rule which passes the constraint
+         const RuleEntry *        r = fsm.rules.begin(),
+                         * const re = fsm.rules.end();
+-        while (r != re && !testConstraint(*r->rule, m)) ++r;
++        while (r != re && !testConstraint(*r->rule, m))
++        {
++            ++r;
++            if (m.status() != Machine::finished)
++                return;
++        }
+ 
+ #if !defined GRAPHITE2_NTRACING
+         if (fsm.dbgout)
+         {
+             if (fsm.rules.size() != 0)
+             {
+                 *fsm.dbgout << json::item << json::object;
+                 dumpRuleEventConsidered(fsm, *r);
+@@ -530,16 +536,17 @@ void Pass::findNDoRule(Slot * & slot, Ma
+             }
+         }
+         else
+ #endif
+         {
+             if (r != re)
+             {
+                 const int adv = doAction(r->rule->action, slot, m);
++                if (m.status() != Machine::finished) return;
+                 if (r->rule->action->deletes()) fsm.slots.collectGarbage(slot);
+                 adjustSlot(adv, slot, fsm.slots);
+                 return;
+             }
+         }
+     }
+ 
+     slot = slot->next();
+diff --git a/gfx/graphite2/src/Segment.cpp b/gfx/graphite2/src/Segment.cpp
+--- a/gfx/graphite2/src/Segment.cpp
++++ b/gfx/graphite2/src/Segment.cpp
+@@ -205,18 +205,23 @@ Slot *Segment::newSlot()
+ void Segment::freeSlot(Slot *aSlot)
+ {
+     if (m_last == aSlot) m_last = aSlot->prev();
+     if (m_first == aSlot) m_first = aSlot->next();
+     if (aSlot->attachedTo())
+         aSlot->attachedTo()->removeChild(aSlot);
+     while (aSlot->firstChild())
+     {
+-        aSlot->firstChild()->attachTo(NULL);
+-        aSlot->removeChild(aSlot->firstChild());
++        if (aSlot->firstChild()->attachedTo() == aSlot)
++        {
++            aSlot->firstChild()->attachTo(NULL);
++            aSlot->removeChild(aSlot->firstChild());
++        }
++        else
++            aSlot->firstChild(NULL);
+     }
+     // reset the slot incase it is reused
+     ::new (aSlot) Slot(aSlot->userAttrs());
+     memset(aSlot->userAttrs(), 0, m_silf->numUser() * sizeof(int16));
+     // Update generation counter for debug
+ #if !defined GRAPHITE2_NTRACING
+     if (m_face->logger())
+         ++aSlot->userAttrs()[m_silf->numUser()];
+diff --git a/gfx/graphite2/src/Slot.cpp b/gfx/graphite2/src/Slot.cpp
+--- a/gfx/graphite2/src/Slot.cpp
++++ b/gfx/graphite2/src/Slot.cpp
+@@ -192,16 +192,18 @@ int32 Slot::clusterMetric(const Segment 
+ #define SLOTGETCOLATTR(x) { SlotCollision *c = seg->collisionInfo(this); return c ? int(c-> x) : 0; }
+ 
+ int Slot::getAttr(const Segment *seg, attrCode ind, uint8 subindex) const
+ {
+     if (ind == gr_slatUserDefnV1)
+     {
+         ind = gr_slatUserDefn;
+         subindex = 0;
++        if (seg->numAttrs() == 0)
++            return 0;
+     }
+     else if (ind >= gr_slatJStretch && ind < gr_slatJStretch + 20 && ind != gr_slatJWidth)
+     {
+         int indx = ind - gr_slatJStretch;
+         return getJustify(seg, indx / 5, indx % 5);
+     }
+ 
+     switch (ind)
+@@ -269,16 +271,18 @@ int Slot::getAttr(const Segment *seg, at
+         break; }
+ 
+ void Slot::setAttr(Segment *seg, attrCode ind, uint8 subindex, int16 value, const SlotMap & map)
+ {
+     if (ind == gr_slatUserDefnV1)
+     {
+         ind = gr_slatUserDefn;
+         subindex = 0;
++        if (seg->numAttrs() == 0)
++            return;
+     }
+     else if (ind >= gr_slatJStretch && ind < gr_slatJStretch + 20 && ind != gr_slatJWidth)
+     {
+         int indx = ind - gr_slatJStretch;
+         return setJustify(seg, indx / 5, indx % 5, value);
+     }
+ 
+     switch (ind)
+@@ -416,32 +420,32 @@ bool Slot::sibling(Slot *ap)
+ }
+ 
+ bool Slot::removeChild(Slot *ap)
+ {
+     if (this == ap || !m_child) return false;
+     else if (ap == m_child)
+     {
+         Slot *nSibling = m_child->nextSibling();
+-        m_child->sibling(NULL);
++        m_child->removeSibling(nSibling);
+         m_child = nSibling;
+         return true;
+     }
+     else
+         return m_child->removeSibling(ap);
+     return true;
+ }
+ 
+ bool Slot::removeSibling(Slot *ap)
+ {
+     if (this == ap || !m_sibling) return false;
+     else if (ap == m_sibling)
+     {
+         m_sibling = m_sibling->nextSibling();
+-        ap->sibling(NULL);
++        if (m_sibling) ap->removeSibling(m_sibling);
+         return true;
+     }
+     else
+         return m_sibling->removeSibling(ap);
+     return true;
+ }
+ 
+ void Slot::setGlyph(Segment *seg, uint16 glyphid, const GlyphFace * theGlyph)
+diff --git a/gfx/graphite2/src/TtfUtil.cpp b/gfx/graphite2/src/TtfUtil.cpp
+--- a/gfx/graphite2/src/TtfUtil.cpp
++++ b/gfx/graphite2/src/TtfUtil.cpp
+@@ -884,18 +884,19 @@ const void * FindCmapSubtable(const void
+     }
+ 
+     return 0;
+ }
+ 
+ /*----------------------------------------------------------------------------------------------
+     Check the Microsoft Unicode subtable for expected values
+ ----------------------------------------------------------------------------------------------*/
+-bool CheckCmapSubtable4(const void * pCmapSubtable4, size_t table_len /*, unsigned int maxgid*/)
++bool CheckCmapSubtable4(const void * pCmapSubtable4, const void * pCmapEnd /*, unsigned int maxgid*/)
+ {
++    size_t table_len = (const byte *)pCmapEnd - (const byte *)pCmapSubtable4;
+     if (!pCmapSubtable4) return false;
+     const Sfnt::CmapSubTable * pTable = reinterpret_cast<const Sfnt::CmapSubTable *>(pCmapSubtable4);
+     // Bob H say some freeware TT fonts have version 1 (eg, CALIGULA.TTF) 
+     // so don't check subtable version. 21 Mar 2002 spec changes version to language.
+     if (be::swap(pTable->format) != 4) return false;
+     const Sfnt::CmapSubTableFormat4 * pTable4 = reinterpret_cast<const Sfnt::CmapSubTableFormat4 *>(pCmapSubtable4);
+     uint16 length = be::swap(pTable4->length);
+     if (length > table_len)
+@@ -1044,17 +1045,17 @@ unsigned int CmapSubtable4NextCodepoint(
+             *pRangeKey = nRange - 1;
+         return 0xFFFF;
+     }
+ 
+     int iRange = (pRangeKey) ? *pRangeKey : 0;
+     // Just in case we have a bad key:
+     while (iRange > 0 && be::peek<uint16>(pStartCode + iRange) > nUnicodePrev)
+         iRange--;
+-    while (be::peek<uint16>(pTable->end_code + iRange) < nUnicodePrev)
++    while (iRange < nRange - 1 && be::peek<uint16>(pTable->end_code + iRange) < nUnicodePrev)
+         iRange++;
+ 
+     // Now iRange is the range containing nUnicodePrev.
+     unsigned int nStartCode = be::peek<uint16>(pStartCode + iRange);
+     unsigned int nEndCode = be::peek<uint16>(pTable->end_code + iRange);
+ 
+     if (nStartCode > nUnicodePrev)
+         // Oops, nUnicodePrev is not in the cmap! Adjust so we get a reasonable
+@@ -1069,36 +1070,37 @@ unsigned int CmapSubtable4NextCodepoint(
+         return nUnicodePrev + 1;
+     }
+ 
+     // Otherwise the next codepoint is the first one in the next range.
+     // There is guaranteed to be a next range because there must be one that
+     // ends with 0xFFFF.
+     if (pRangeKey)
+         *pRangeKey = iRange + 1;
+-    return be::peek<uint16>(pStartCode + iRange + 1);
++    return (iRange + 1 >= nRange) ? 0xFFFF : be::peek<uint16>(pStartCode + iRange + 1);
+ }
+ 
+ /*----------------------------------------------------------------------------------------------
+     Check the Microsoft UCS-4 subtable for expected values.
+ ----------------------------------------------------------------------------------------------*/
+-bool CheckCmapSubtable12(const void *pCmapSubtable12, size_t table_len /*, unsigned int maxgid*/)
++bool CheckCmapSubtable12(const void *pCmapSubtable12, const void *pCmapEnd /*, unsigned int maxgid*/)
+ {
++    size_t table_len = (const byte *)pCmapEnd - (const byte *)pCmapSubtable12;
+     if (!pCmapSubtable12)  return false;
+     const Sfnt::CmapSubTable * pTable = reinterpret_cast<const Sfnt::CmapSubTable *>(pCmapSubtable12);
+     if (be::swap(pTable->format) != 12)
+         return false;
+     const Sfnt::CmapSubTableFormat12 * pTable12 = reinterpret_cast<const Sfnt::CmapSubTableFormat12 *>(pCmapSubtable12);
+     uint32 length = be::swap(pTable12->length);
+     if (length > table_len)
+         return false;
+     if (length < sizeof(Sfnt::CmapSubTableFormat12))
+         return false;
+     uint32 num_groups = be::swap(pTable12->num_groups);
+-    if (length != (sizeof(Sfnt::CmapSubTableFormat12) + (num_groups - 1) * sizeof(uint32) * 3))
++    if (num_groups > 0x10000000 || length != (sizeof(Sfnt::CmapSubTableFormat12) + (num_groups - 1) * sizeof(uint32) * 3))
+         return false;
+ #if 0
+     for (unsigned int i = 0; i < num_groups; ++i)
+     {
+         if (be::swap(pTable12->group[i].end_char_code)  - be::swap(pTable12->group[i].start_char_code) + be::swap(pTable12->group[i].start_glyph_id) > maxgid)
+             return false;
+         if (i > 0 && be::swap(pTable12->group[i].start_char_code) <= be::swap(pTable12->group[i-1].end_char_code))
+             return false;
+@@ -1161,17 +1163,17 @@ unsigned int CmapSubtable12NextCodepoint
+             *pRangeKey = nRange;
+         return 0x10FFFF;
+     }
+ 
+     int iRange = (pRangeKey) ? *pRangeKey : 0;
+     // Just in case we have a bad key:
+     while (iRange > 0 && be::swap(pTable->group[iRange].start_char_code) > nUnicodePrev)
+         iRange--;
+-    while (be::swap(pTable->group[iRange].end_char_code) < nUnicodePrev)
++    while (iRange < nRange - 1 && be::swap(pTable->group[iRange].end_char_code) < nUnicodePrev)
+         iRange++;
+ 
+     // Now iRange is the range containing nUnicodePrev.
+ 
+     unsigned int nStartCode = be::swap(pTable->group[iRange].start_char_code);
+     unsigned int nEndCode = be::swap(pTable->group[iRange].end_char_code);
+ 
+     if (nStartCode > nUnicodePrev)
+diff --git a/gfx/graphite2/src/call_machine.cpp b/gfx/graphite2/src/call_machine.cpp
+--- a/gfx/graphite2/src/call_machine.cpp
++++ b/gfx/graphite2/src/call_machine.cpp
+@@ -67,32 +67,34 @@ using namespace vm;
+ struct regbank  {
+     slotref         is;
+     slotref *       map;
+     SlotMap       & smap;
+     slotref * const map_base;
+     const instr * & ip;
+     uint8           direction;
+     int8            flags;
++    Machine::status_t & status;
+ };
+ 
+ typedef bool        (* ip_t)(registers);
+ 
+ // Pull in the opcode definitions
+ // We pull these into a private namespace so these otherwise common names dont
+ // pollute the toplevel namespace.
+ namespace {
+ #define smap    reg.smap
+ #define seg     smap.segment
+ #define is      reg.is
+ #define ip      reg.ip
+ #define map     reg.map
+ #define mapb    reg.map_base
+ #define flags   reg.flags
+ #define dir     reg.direction
++#define status  reg.status
+ 
+ #include "inc/opcodes.h"
+ 
+ #undef smap
+ #undef seg
+ #undef is
+ #undef ip
+ #undef map
+@@ -108,17 +110,17 @@ Machine::stack_t  Machine::run(const ins
+ {
+     assert(program != 0);
+ 
+     // Declare virtual machine registers
+     const instr   * ip = program-1;
+     const byte    * dp = data;
+     stack_t       * sp = _stack + Machine::STACK_GUARD,
+             * const sb = sp;
+-    regbank         reg = {*map, map, _map, _map.begin()+_map.context(), ip, _map.dir(), 0};
++    regbank         reg = {*map, map, _map, _map.begin()+_map.context(), ip, _map.dir(), 0, _status};
+ 
+     // Run the program        
+     while ((reinterpret_cast<ip_t>(*++ip))(dp, sp, sb, reg)) {}
+     const stack_t ret = sp == _stack+STACK_GUARD+1 ? *sp-- : 0;
+ 
+     check_final_stack(sp);
+     map = reg.map;
+     *map = reg.is;
+diff --git a/gfx/graphite2/src/direct_machine.cpp b/gfx/graphite2/src/direct_machine.cpp
+--- a/gfx/graphite2/src/direct_machine.cpp
++++ b/gfx/graphite2/src/direct_machine.cpp
+@@ -57,36 +57,37 @@ using namespace vm;
+ namespace {
+ 
+ const void * direct_run(const bool          get_table_mode,
+                         const instr       * program,
+                         const byte        * data,
+                         Machine::stack_t  * stack,
+                         slotref         * & __map,
+                         uint8                _dir,
++                        Machine::status_t & status,
+                         SlotMap           * __smap=0)
+ {
+     // We need to define and return to opcode table from within this function 
+     // other inorder to take the addresses of the instruction bodies.
+     #include "inc/opcode_table.h"
+     if (get_table_mode)
+         return opcode_table;
+ 
+     // Declare virtual machine registers
+-    const instr       * ip = program;
+-    const byte        * dp = data;
+-    Machine::stack_t  * sp = stack + Machine::STACK_GUARD,
+-                * const sb = sp;
+-    SlotMap         & smap = *__smap;
+-    Segment          & seg = smap.segment;
+-    slotref             is = *__map,
+-                     * map = __map,
+-              * const mapb = smap.begin()+smap.context();
+-    uint8            dir = _dir;
+-    int8             flags = 0;
++    const instr           * ip = program;
++    const byte            * dp = data;
++    Machine::stack_t      * sp = stack + Machine::STACK_GUARD,
++                    * const sb = sp;
++    SlotMap             & smap = *__smap;
++    Segment              & seg = smap.segment;
++    slotref                 is = *__map,
++                         * map = __map,
++                  * const mapb = smap.begin()+smap.context();
++    uint8                  dir = _dir;
++    int8                 flags = 0;
+     
+     // start the program
+     goto **ip;
+ 
+     // Pull in the opcode definitions
+     #include "inc/opcodes.h"
+     
+     end:
+@@ -95,25 +96,26 @@ const void * direct_run(const bool      
+     return sp;
+ }
+ 
+ }
+ 
+ const opcode_t * Machine::getOpcodeTable() throw()
+ {
+     slotref * dummy;
+-    return static_cast<const opcode_t *>(direct_run(true, 0, 0, 0, dummy, 0));
++    Machine::status_t dumstat = Machine::finished;
++    return static_cast<const opcode_t *>(direct_run(true, 0, 0, 0, dummy, 0, dumstat));
+ }
+ 
+ 
+ Machine::stack_t  Machine::run(const instr   * program,
+                                const byte    * data,
+                                slotref     * & is)
+ {
+     assert(program != 0);
+     
+     const stack_t *sp = static_cast<const stack_t *>(
+-                direct_run(false, program, data, _stack, is, _map.dir(), &_map));
++                direct_run(false, program, data, _stack, is, _map.dir(), _status, &_map));
+     const stack_t ret = sp == _stack+STACK_GUARD+1 ? *sp-- : 0;
+     check_final_stack(sp);
+     return ret;
+ }
+ 
+diff --git a/gfx/graphite2/src/inc/Code.h b/gfx/graphite2/src/inc/Code.h
+--- a/gfx/graphite2/src/inc/Code.h
++++ b/gfx/graphite2/src/inc/Code.h
+@@ -109,17 +109,17 @@ public:
+     int32 run(Machine &m, slotref * & map) const;
+     
+     CLASS_NEW_DELETE;
+ };
+ 
+ inline
+ size_t  Machine::Code::estimateCodeDataOut(size_t n_bc)
+ {
+-    return n_bc * (sizeof(instr)+sizeof(byte));
++    return (n_bc + 1) * (sizeof(instr)+sizeof(byte));
+ }
+ 
+ 
+ inline Machine::Code::Code() throw()
+ : _code(0), _data(0), _data_size(0), _instr_count(0), _max_ref(0),
+   _status(loaded), _constraint(false), _modify(false), _delete(false),
+   _own(false)
+ {
+diff --git a/gfx/graphite2/src/inc/Machine.h b/gfx/graphite2/src/inc/Machine.h
+--- a/gfx/graphite2/src/inc/Machine.h
++++ b/gfx/graphite2/src/inc/Machine.h
+@@ -135,17 +135,18 @@ public:
+ 
+     class Code;
+ 
+     enum status_t {
+         finished = 0,
+         stack_underflow,
+         stack_not_empty,
+         stack_overflow,
+-        slot_offset_out_bounds
++        slot_offset_out_bounds,
++        died_early
+     };
+ 
+     Machine(SlotMap &) throw();
+     static const opcode_t *   getOpcodeTable() throw();
+ 
+     CLASS_NEW_DELETE;
+ 
+     SlotMap   & slotMap() const throw();
+diff --git a/gfx/graphite2/src/inc/TtfUtil.h b/gfx/graphite2/src/inc/TtfUtil.h
+--- a/gfx/graphite2/src/inc/TtfUtil.h
++++ b/gfx/graphite2/src/inc/TtfUtil.h
+@@ -132,21 +132,21 @@ public:
+     int GetLangsForNames(const void * pName, int nPlatformId, int nEncodingId,
+         int *nameIdList, int cNameIds, short *langIdList);
+     void SwapWString(void * pWStr, size_t nSize = 0); // throw (std::invalid_argument);
+ #endif
+ 
+     ////////////////////////////////// cmap lookup tools 
+     const void * FindCmapSubtable(const void * pCmap, int nPlatformId = 3, 
+         int nEncodingId = 1, size_t length = 0);
+-    bool CheckCmapSubtable4(const void * pCmap31, size_t table_len /*, unsigned int maxgid*/);
++    bool CheckCmapSubtable4(const void * pCmap31, const void * pCmapEnd /*, unsigned int maxgid*/);
+     gid16 CmapSubtable4Lookup(const void * pCmapSubtabel4, unsigned int nUnicodeId, int rangeKey = 0);
+     unsigned int CmapSubtable4NextCodepoint(const void *pCmap31, unsigned int nUnicodeId,
+         int * pRangeKey = 0);
+-    bool CheckCmapSubtable12(const void *pCmap310, size_t table_len /*, unsigned int maxgid*/);
++    bool CheckCmapSubtable12(const void *pCmap310, const void * pCmapEnd /*, unsigned int maxgid*/);
+     gid16 CmapSubtable12Lookup(const void * pCmap310, unsigned int uUnicodeId, int rangeKey = 0);
+     unsigned int CmapSubtable12NextCodepoint(const void *pCmap310, unsigned int nUnicodeId,
+         int * pRangeKey = 0);
+ 
+     ///////////////////////////////// horizontal metric data for a glyph
+     bool HorMetrics(gid16 nGlyphId, const void * pHmtx, size_t lHmtxSize, 
+         const void * pHhea, int & nLsb, unsigned int & nAdvWid);
+ 
+diff --git a/gfx/graphite2/src/inc/opcodes.h b/gfx/graphite2/src/inc/opcodes.h
+--- a/gfx/graphite2/src/inc/opcodes.h
++++ b/gfx/graphite2/src/inc/opcodes.h
+@@ -71,17 +71,17 @@ of the License or (at your option) any l
+ #define use_params(n)       dp += n
+ 
+ #define declare_params(n)   const byte * param = dp; \
+                             use_params(n);
+ 
+ #define push(n)             { *++sp = n; }
+ #define pop()               (*sp--)
+ #define slotat(x)           (map[(x)])
+-#define DIE                 { is=seg.last(); EXIT(1); }
++#define DIE                 { is=seg.last(); status = Machine::died_early; EXIT(1); }
+ #define POSITIONED          1
+ 
+ STARTOP(nop)
+     do {} while (0);
+ ENDOP
+ 
+ STARTOP(push_byte)
+     declare_params(1);
+@@ -387,30 +387,30 @@ STARTOP(attr_set)
+ ENDOP
+ 
+ STARTOP(attr_add)
+     declare_params(1);
+     const attrCode      slat = attrCode(uint8(*param));
+     const          int  val  = int(pop());
+     if ((slat == gr_slatPosX || slat == gr_slatPosY) && (flags & POSITIONED) == 0)
+     {
+-        seg.positionSlots(0, *smap.begin(), *(smap.end()-1), dir);
++        seg.positionSlots(0, *smap.begin(), *(smap.end()-1), seg.currdir());
+         flags |= POSITIONED;
+     }
+     int res = is->getAttr(&seg, slat, 0);
+     is->setAttr(&seg, slat, 0, val + res, smap);
+ ENDOP
+ 
+ STARTOP(attr_sub)
+     declare_params(1);
+     const attrCode      slat = attrCode(uint8(*param));
+     const          int  val  = int(pop());
+     if ((slat == gr_slatPosX || slat == gr_slatPosY) && (flags & POSITIONED) == 0)
+     {
+-        seg.positionSlots(0, *smap.begin(), *(smap.end()-1), dir);
++        seg.positionSlots(0, *smap.begin(), *(smap.end()-1), seg.currdir());
+         flags |= POSITIONED;
+     }
+     int res = is->getAttr(&seg, slat, 0);
+     is->setAttr(&seg, slat, 0, res - val, smap);
+ ENDOP
+ 
+ STARTOP(attr_set_slot)
+     declare_params(1);
+@@ -429,17 +429,17 @@ STARTOP(iattr_set_slot)
+ ENDOP
+ 
+ STARTOP(push_slot_attr)
+     declare_params(2);
+     const attrCode      slat     = attrCode(uint8(param[0]));
+     const int           slot_ref = int8(param[1]);
+     if ((slat == gr_slatPosX || slat == gr_slatPosY) && (flags & POSITIONED) == 0)
+     {
+-        seg.positionSlots(0, *smap.begin(), *(smap.end()-1), dir);
++        seg.positionSlots(0, *smap.begin(), *(smap.end()-1), seg.currdir());
+         flags |= POSITIONED;
+     }
+     slotref slot = slotat(slot_ref);
+     if (slot)
+     {
+         int res = slot->getAttr(&seg, slat, 0);
+         push(res);
+     }
+@@ -505,17 +505,17 @@ ENDOP
+ 
+ STARTOP(push_islot_attr)
+     declare_params(3);
+     const attrCode  slat     = attrCode(uint8(param[0]));
+     const int           slot_ref = int8(param[1]),
+                         idx      = uint8(param[2]);
+     if ((slat == gr_slatPosX || slat == gr_slatPosY) && (flags & POSITIONED) == 0)
+     {
+-        seg.positionSlots(0, *smap.begin(), *(smap.end()-1), dir);
++        seg.positionSlots(0, *smap.begin(), *(smap.end()-1), seg.currdir());
+         flags |= POSITIONED;
+     }
+     slotref slot = slotat(slot_ref);
+     if (slot)
+     {
+         int res = slot->getAttr(&seg, slat, idx);
+         push(res);
+     }
+
diff --git a/gnu/packages/patches/ilmbase-fix-tests.patch b/gnu/packages/patches/ilmbase-fix-tests.patch
new file mode 100644
index 0000000000..fcaa37d201
--- /dev/null
+++ b/gnu/packages/patches/ilmbase-fix-tests.patch
@@ -0,0 +1,149 @@
+Fix FTBFS on i686-linux due to rounding issue (see references).
+
+Fixes Guix bug #22049 (see below).
+
+Copied from Debian.
+
+Source:
+https://sources.debian.net/src/ilmbase/2.2.0-11/debian/patches/testBoxAlgo.patch/
+https://sources.debian.net/src/ilmbase/2.2.0-11/debian/patches/testBox.patch/
+
+References:
+https://lists.nongnu.org/archive/html/openexr-devel/2015-12/msg00001.html
+https://debbugs.gnu.org/cgi/bugreport.cgi?bug=22049
+https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=815712
+https://anonscm.debian.org/cgit/pkg-phototools/ilmbase.git/commit/?id=ab28bb45cdad8adc32e345b777ab8e692b1d9a9c
+
+---
+
+Subject: testBoxAlgo: allow fuzzy match of b12 == b2
+From: Steven Chamberlain <steven@pyro.eu.org>
+Date: Wed, 24 Feb 2016 01:04:11 +0000
+
+Also fix a pre-existing typo.
+
+Index: ilmbase/ImathTest/testBoxAlgo.cpp
+===================================================================
+--- ilmbase.orig/ImathTest/testBoxAlgo.cpp
++++ ilmbase/ImathTest/testBoxAlgo.cpp
+@@ -886,10 +886,11 @@ boxMatrixTransform ()
+ 
+     assert (approximatelyEqual (b2.min, b4.min, e));
+     assert (approximatelyEqual (b2.max, b4.max, e));
+-    assert (approximatelyEqual (b3.max, b4.max, e));
++    assert (approximatelyEqual (b3.min, b4.min, e));
+     assert (approximatelyEqual (b3.max, b4.max, e));
+ 
+-    assert (b21 == b2);
++    assert (approximatelyEqual (b2.min, b21.min, e));
++    assert (approximatelyEqual (b2.max, b21.max, e));
+     assert (b31 == b3);
+ 
+     M[0][3] = 1;
+
+---
+
+Subject: testBox: allow fuzzy comparison of floats, doubles
+From: Steven Chamberlain <steven@pyro.eu.org>
+Date: Wed, 24 Feb 2016 01:10:11 +0000
+
+Allow for inexact values, as long as the error is smaller than the
+epsilon of the data type.
+
+On 32-bit x86, allow even greater discrepency at double
+precision, due to possible double-rounding.  See
+https://lists.nongnu.org/archive/html/openexr-devel/2015-12/msg00001.html
+
+Index: ilmbase/ImathTest/testBox.cpp
+===================================================================
+--- ilmbase.orig/ImathTest/testBox.cpp
++++ ilmbase/ImathTest/testBox.cpp
+@@ -47,6 +47,58 @@ using namespace IMATH_INTERNAL_NAMESPACE
+ 
+ namespace {
+ 
++template <class T>
++bool
++approximatelyEqual (const T &p1, const T &p2)
++{
++	/* int and short should be exact */
++	return (p1 == p2);
++}
++
++bool
++approximatelyEqual (const Vec2<float> &p1, const Vec2<float> &p2)
++{
++    float e = limits<float>::epsilon();
++    float m = 0;
++
++    for (int i = 0; i < 2; ++i)
++    {
++	m = max (m, abs (p1[i]));
++	m = max (m, abs (p2[i]));
++    }
++
++    for (int i = 0; i < 2; ++i)
++	if (!equalWithAbsError (p1[i], p2[i], m * e))
++	    return false;
++
++    return true;
++}
++
++bool
++approximatelyEqual (const Vec2<double> &p1, const Vec2<double> &p2)
++{
++#if defined(__i386__) || defined(_M_IX86)
++    /* double-rounding on 32-bit x86 may cause larger error:
++       use epsilon of float rather than double */
++    double e = limits<float>::epsilon();
++#else
++    double e = limits<double>::epsilon();
++#endif
++    double m = 0;
++
++    for (int i = 0; i < 2; ++i)
++    {
++	m = max (m, abs (p1[i]));
++	m = max (m, abs (p2[i]));
++    }
++
++    for (int i = 0; i < 2; ++i)
++	if (!equalWithAbsError (p1[i], p2[i], m * e))
++	    return false;
++
++    return true;
++}
++
+ //
+ // Test case generation utility - create a vector of IMATH_INTERNAL_NAMESPACE::Vec{2,3,4}
+ // with all permutations of integers 1..T::dimensions().
+@@ -250,7 +302,8 @@ testExtendByPoint(const char *type)
+                               
+         IMATH_INTERNAL_NAMESPACE::Box<T> b;
+         b.extendBy(p);
+-        assert(b.min == p && b.max == p);
++        assert (approximatelyEqual (b.min, p));
++        assert (approximatelyEqual (b.max, p));
+     }
+ 
+     //
+@@ -283,7 +336,8 @@ testExtendByPoint(const char *type)
+ 
+             b.extendBy(p);
+ 
+-            assert(b.min == min && b.max == max);
++            assert (approximatelyEqual (b.min, min));
++            assert (approximatelyEqual (b.max, max));
+         }
+     }
+ }
+@@ -358,7 +412,8 @@ testExtendByBox(const char *type)
+             }
+             b.extendBy(IMATH_INTERNAL_NAMESPACE::Box<T>(p0, p1));
+ 
+-            assert(b.min == min && b.max == max);
++            assert (approximatelyEqual (b.min, min));
++            assert (approximatelyEqual (b.max, max));
+         }
+     }
+ }
diff --git a/gnu/packages/patches/jasper-CVE-2016-1577.patch b/gnu/packages/patches/jasper-CVE-2016-1577.patch
new file mode 100644
index 0000000000..75bbd526af
--- /dev/null
+++ b/gnu/packages/patches/jasper-CVE-2016-1577.patch
@@ -0,0 +1,19 @@
+Description: CVE-2016-1577: Prevent double-free in jas_iccattrval_destroy()
+Origin: vendor, http://www.openwall.com/lists/oss-security/2016/03/03/12
+Bug-Ubuntu: https://launchpad.net/bugs/1547865
+Bug-Debian: https://bugs.debian.org/816625
+Forwarded: not-needed
+Author: Tyler Hicks <tyhicks@canonical.com>
+Reviewed-by: Salvatore Bonaccorso <carnil@debian.org>
+Last-Update: 2016-03-05
+
+--- a/src/libjasper/base/jas_icc.c
++++ b/src/libjasper/base/jas_icc.c
+@@ -300,6 +300,7 @@ jas_iccprof_t *jas_iccprof_load(jas_stre
+ 				if (jas_iccprof_setattr(prof, tagtabent->tag, attrval))
+ 					goto error;
+ 				jas_iccattrval_destroy(attrval);
++				attrval = 0;
+ 			} else {
+ #if 0
+ 				jas_eprintf("warning: skipping unknown tag type\n");
diff --git a/gnu/packages/patches/jasper-CVE-2016-2089.patch b/gnu/packages/patches/jasper-CVE-2016-2089.patch
new file mode 100644
index 0000000000..95d4b61111
--- /dev/null
+++ b/gnu/packages/patches/jasper-CVE-2016-2089.patch
@@ -0,0 +1,90 @@
+Description: CVE-2016-2089: matrix rows_ NULL pointer dereference in jas_matrix_clip()
+Origin: vendor
+Bug-RedHat: https://bugzilla.redhat.com/show_bug.cgi?id=1302636
+Bug-Debian: https://bugs.debian.org/812978
+Forwarded: not-needed
+Author: Tomas Hoger <thoger@redhat.com>
+Reviewed-by: Salvatore Bonaccorso <carnil@debian.org>
+Last-Update: 2016-03-05
+
+--- a/src/libjasper/base/jas_image.c
++++ b/src/libjasper/base/jas_image.c
+@@ -426,6 +426,10 @@ int jas_image_readcmpt(jas_image_t *imag
+ 		return -1;
+ 	}
+ 
++	if (!data->rows_) {
++		return -1;
++	}
++
+ 	if (jas_matrix_numrows(data) != height || jas_matrix_numcols(data) != width) {
+ 		if (jas_matrix_resize(data, height, width)) {
+ 			return -1;
+@@ -479,6 +483,10 @@ int jas_image_writecmpt(jas_image_t *ima
+ 		return -1;
+ 	}
+ 
++	if (!data->rows_) {
++		return -1;
++	}
++
+ 	if (jas_matrix_numrows(data) != height || jas_matrix_numcols(data) != width) {
+ 		return -1;
+ 	}
+--- a/src/libjasper/base/jas_seq.c
++++ b/src/libjasper/base/jas_seq.c
+@@ -262,6 +262,10 @@ void jas_matrix_divpow2(jas_matrix_t *ma
+ 	int rowstep;
+ 	jas_seqent_t *data;
+ 
++	if (!matrix->rows_) {
++		return;
++	}
++
+ 	rowstep = jas_matrix_rowstep(matrix);
+ 	for (i = matrix->numrows_, rowstart = matrix->rows_[0]; i > 0; --i,
+ 	  rowstart += rowstep) {
+@@ -282,6 +286,10 @@ void jas_matrix_clip(jas_matrix_t *matri
+ 	jas_seqent_t *data;
+ 	int rowstep;
+ 
++	if (!matrix->rows_) {
++		return;
++	}
++
+ 	rowstep = jas_matrix_rowstep(matrix);
+ 	for (i = matrix->numrows_, rowstart = matrix->rows_[0]; i > 0; --i,
+ 	  rowstart += rowstep) {
+@@ -306,6 +314,10 @@ void jas_matrix_asr(jas_matrix_t *matrix
+ 	int rowstep;
+ 	jas_seqent_t *data;
+ 
++	if (!matrix->rows_) {
++		return;
++	}
++
+ 	assert(n >= 0);
+ 	rowstep = jas_matrix_rowstep(matrix);
+ 	for (i = matrix->numrows_, rowstart = matrix->rows_[0]; i > 0; --i,
+@@ -325,6 +337,10 @@ void jas_matrix_asl(jas_matrix_t *matrix
+ 	int rowstep;
+ 	jas_seqent_t *data;
+ 
++	if (!matrix->rows_) {
++		return;
++	}
++
+ 	rowstep = jas_matrix_rowstep(matrix);
+ 	for (i = matrix->numrows_, rowstart = matrix->rows_[0]; i > 0; --i,
+ 	  rowstart += rowstep) {
+@@ -367,6 +383,10 @@ void jas_matrix_setall(jas_matrix_t *mat
+ 	int rowstep;
+ 	jas_seqent_t *data;
+ 
++	if (!matrix->rows_) {
++		return;
++	}
++
+ 	rowstep = jas_matrix_rowstep(matrix);
+ 	for (i = matrix->numrows_, rowstart = matrix->rows_[0]; i > 0; --i,
+ 	  rowstart += rowstep) {
diff --git a/gnu/packages/patches/jasper-CVE-2016-2116.patch b/gnu/packages/patches/jasper-CVE-2016-2116.patch
new file mode 100644
index 0000000000..cdb616fb6a
--- /dev/null
+++ b/gnu/packages/patches/jasper-CVE-2016-2116.patch
@@ -0,0 +1,19 @@
+Description: CVE-2016-2116: Prevent jas_stream_t memory leak in jas_iccprof_createfrombuf()
+Origin: vendor, http://www.openwall.com/lists/oss-security/2016/03/03/12
+Bug-Debian: https://bugs.debian.org/816626
+Forwarded: not-needed
+Author: Tyler Hicks <tyhicks@canoonical.com>
+Reviewed-by: Salvatore Bonaccorso <carnil@debian.org>
+Last-Update: 2016-03-05
+
+--- a/src/libjasper/base/jas_icc.c
++++ b/src/libjasper/base/jas_icc.c
+@@ -1693,6 +1693,8 @@ jas_iccprof_t *jas_iccprof_createfrombuf
+ 	jas_stream_close(in);
+ 	return prof;
+ error:
++	if (in)
++		jas_stream_close(in);
+ 	return 0;
+ }
+ 
diff --git a/gnu/packages/patches/libotr-test-auth-fix.patch b/gnu/packages/patches/libotr-test-auth-fix.patch
new file mode 100644
index 0000000000..23b8d8308d
--- /dev/null
+++ b/gnu/packages/patches/libotr-test-auth-fix.patch
@@ -0,0 +1,15 @@
+Initialize the context in 'test_auth_clear'.
+Fixes the test suite on mips64el.
+
+Patch by Mark H Weaver <mhw@netris.org>
+
+--- libotr-4.1.1/tests/unit/test_auth.c.orig	2015-12-25 12:39:45.000000000 -0500
++++ libotr-4.1.1/tests/unit/test_auth.c	2016-03-17 18:53:10.169999706 -0400
+@@ -67,6 +67,7 @@
+ 	OtrlAuthInfo *auth = &ctx.auth;
+ 
+ 	/* API call. */
++	otrl_auth_new(&ctx);
+ 	otrl_auth_clear(auth);
+ 
+ 	ok(auth->authstate == OTRL_AUTHSTATE_NONE &&
diff --git a/gnu/packages/patches/mupdf-buildsystem-fix.patch b/gnu/packages/patches/mupdf-buildsystem-fix.patch
deleted file mode 100644
index 0b17dda911..0000000000
--- a/gnu/packages/patches/mupdf-buildsystem-fix.patch
+++ /dev/null
@@ -1,69 +0,0 @@
-Since openjpeg doesn't seem to ship with a .pc file, provide an alternative.
-
---- a/ojp2_cppflags.sh	1970-01-01 01:00:00.000000000 +0100
-+++ b/ojp2_cppflags.sh	2014-09-13 22:56:38.842418777 +0200
-@@ -0,0 +1,7 @@
-+#!/bin/sh
-+
-+# Return the preprocessor flags to link against openjpeg.
-+
-+cpppath=$(echo ${NIX_STORE}/*-openjpeg-*/include/openjpeg-*)
-+
-+echo -I$cpppath
-
---- a/ojp2_ldflags.sh	1970-01-01 01:00:00.000000000 +0100
-+++ b/ojp2_ldflags.sh	2014-09-13 22:56:38.842418777 +0200
-@@ -0,0 +1,7 @@
-+#!/bin/sh
-+
-+# Return the linker flags to link against openjpeg.
-+
-+ldpath=$(echo ${NIX_STORE}/*-openjpeg-*/lib)
-+
-+echo -L$ldpath -lopenjp2
-
-Make use of the above alternatives, compile with gcc.
-
---- a/Makerules	2014-09-14 09:13:40.729149860 +0200
-+++ b/Makerules	2014-09-14 09:17:06.425156595 +0200
-@@ -75,12 +75,14 @@
- 
- SYS_FREETYPE_CFLAGS = $(shell pkg-config --cflags freetype2)
- SYS_FREETYPE_LIBS = $(shell pkg-config --libs freetype2)
--SYS_OPENJPEG_CFLAGS = $(shell pkg-config --cflags libopenjp2)
--SYS_OPENJPEG_LIBS = $(shell pkg-config --libs libopenjp2)
-+SYS_OPENJPEG_CFLAGS = $(shell ./ojp2_cppflags.sh)
-+SYS_OPENJPEG_LIBS = $(shell ./ojp2_ldflags.sh)
- SYS_JBIG2DEC_LIBS = -ljbig2dec
- SYS_JPEG_LIBS = -ljpeg
- SYS_ZLIB_LIBS = -lz
- 
-+CC = gcc
-+
- endif
- 
- # The following section is an example of how to simply do cross-compilation
-
-Remove the -x11 from the built binaries, since X11 is implied on GNU. (This
-might change when Wayland gets more popular)
-
---- a/Makefile	2014-06-10 17:09:28.000000000 +0200
-+++ b/Makefile	2014-09-14 09:57:10.381235299 +0200
-@@ -255,7 +255,7 @@
- 	$(LINK_CMD)
- 
- ifeq "$(HAVE_X11)" "yes"
--MUVIEW_X11 := $(OUT)/mupdf-x11
-+MUVIEW_X11 := $(OUT)/mupdf
- MUVIEW_X11_OBJ := $(addprefix $(OUT)/platform/x11/, x11_main.o x11_image.o pdfapp.o)
- $(MUVIEW_X11_OBJ) : $(FITZ_HDR) $(PDF_HDR)
- $(MUVIEW_X11) : $(MUPDF_LIB) $(THIRD_LIBS)
-@@ -263,7 +263,7 @@
- 	$(LINK_CMD) $(X11_LIBS)
- 
- ifeq "$(HAVE_CURL)" "yes"
--MUVIEW_X11_CURL := $(OUT)/mupdf-x11-curl
-+MUVIEW_X11_CURL := $(OUT)/mupdf-curl
- MUVIEW_X11_CURL_OBJ := $(addprefix $(OUT)/platform/x11/curl/, x11_main.o x11_image.o pdfapp.o curl_stream.o)
- $(MUVIEW_X11_CURL_OBJ) : $(FITZ_HDR) $(PDF_HDR)
- $(MUVIEW_X11_CURL) : $(MUPDF_LIB) $(THIRD_LIBS) $(CURL_LIB)
diff --git a/gnu/packages/patches/openssl-c-rehash-in.patch b/gnu/packages/patches/openssl-c-rehash-in.patch
new file mode 100644
index 0000000000..bd3d3178f1
--- /dev/null
+++ b/gnu/packages/patches/openssl-c-rehash-in.patch
@@ -0,0 +1,17 @@
+This patch removes the explicit reference to the 'perl' binary,
+such that OpenSSL does not retain a reference to Perl.
+
+The 'c_rehash' program is seldom used, but it is used nonetheless
+to create symbolic links to certificates, for instance in the 'nss-certs'
+package.
+
+--- openssl-1.0.2g/tools/c_rehash.in	2015-09-09 18:36:07.313316482 +0200
++++ openssl-1.0.2g/tools/c_rehash.in	2015-09-09 18:36:28.965458458 +0200
+@@ -1,4 +1,6 @@
+-#!/usr/local/bin/perl
++eval '(exit $?0)' && eval 'exec perl -wS "$0" ${1+"$@"}'
++  & eval 'exec perl -wS "$0" $argv:q'
++    if 0;
+ 
+ # Perl c_rehash script, scan all files in a directory
+ # and add symbolic links to their hash values.
diff --git a/gnu/packages/patches/perl-CVE-2016-2381.patch b/gnu/packages/patches/perl-CVE-2016-2381.patch
new file mode 100644
index 0000000000..99d1944a5d
--- /dev/null
+++ b/gnu/packages/patches/perl-CVE-2016-2381.patch
@@ -0,0 +1,116 @@
+Fix CVE-2016-2381 (ambiguous handling of duplicated environment variables).
+
+Copied from upstream:
+http://perl5.git.perl.org/perl.git/commit/ae37b791a73a9e78dedb89fb2429d2628cf58076
+
+References:
+https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-2381
+http://www.nntp.perl.org/group/perl.perl5.porters/2016/03/msg234747.html
+https://security-tracker.debian.org/tracker/CVE-2016-2381
+
+---
+
+From 1237ea93fb2475a5ae576d5ee1358a5bb4ebe426 Mon Sep 17 00:00:00 2001
+From: Tony Cook <tony@develop-help.com>
+Date: Wed, 27 Jan 2016 11:52:15 +1100
+Subject: remove duplicate environment variables from environ
+
+If we see duplicate environment variables while iterating over
+environ[]:
+
+a) make sure we use the same value in %ENV that getenv() returns.
+
+Previously on a duplicate, %ENV would have the last entry for the name
+from environ[], but a typical getenv() would return the first entry.
+
+Rather than assuming all getenv() implementations return the first entry
+explicitly call getenv() to ensure they agree.
+
+b) remove duplicate entries from environ
+
+Previously if there was a duplicate definition for a name in environ[]
+setting that name in %ENV could result in an unsafe value being passed
+to a child process, so ensure environ[] has no duplicates.
+
+Patch-Name: fixes/CVE-2016-2381_duplicate_env.diff
+---
+ perl.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++--
+ 1 file changed, 49 insertions(+), 2 deletions(-)
+
+diff --git a/perl.c b/perl.c
+index 67d32ce..26aeb91 100644
+--- a/perl.c
++++ b/perl.c
+@@ -4277,23 +4277,70 @@ S_init_postdump_symbols(pTHX_ int argc, char **argv, char **env)
+ 	}
+ 	if (env) {
+ 	  char *s, *old_var;
++          STRLEN nlen;
+ 	  SV *sv;
++          HV *dups = newHV();
++
+ 	  for (; *env; env++) {
+ 	    old_var = *env;
+ 
+ 	    if (!(s = strchr(old_var,'=')) || s == old_var)
+ 		continue;
++            nlen = s - old_var;
+ 
+ #if defined(MSDOS) && !defined(DJGPP)
+ 	    *s = '\0';
+ 	    (void)strupr(old_var);
+ 	    *s = '=';
+ #endif
+-	    sv = newSVpv(s+1, 0);
+-	    (void)hv_store(hv, old_var, s - old_var, sv, 0);
++            if (hv_exists(hv, old_var, nlen)) {
++                const char *name = savepvn(old_var, nlen);
++
++                /* make sure we use the same value as getenv(), otherwise code that
++                   uses getenv() (like setlocale()) might see a different value to %ENV
++                 */
++                sv = newSVpv(PerlEnv_getenv(name), 0);
++
++                /* keep a count of the dups of this name so we can de-dup environ later */
++                if (hv_exists(dups, name, nlen))
++                    ++SvIVX(*hv_fetch(dups, name, nlen, 0));
++                else
++                    (void)hv_store(dups, name, nlen, newSViv(1), 0);
++
++                Safefree(name);
++            }
++            else {
++                sv = newSVpv(s+1, 0);
++            }
++	    (void)hv_store(hv, old_var, nlen, sv, 0);
+ 	    if (env_is_not_environ)
+ 	        mg_set(sv);
+ 	  }
++          if (HvKEYS(dups)) {
++              /* environ has some duplicate definitions, remove them */
++              HE *entry;
++              hv_iterinit(dups);
++              while ((entry = hv_iternext_flags(dups, 0))) {
++                  STRLEN nlen;
++                  const char *name = HePV(entry, nlen);
++                  IV count = SvIV(HeVAL(entry));
++                  IV i;
++                  SV **valp = hv_fetch(hv, name, nlen, 0);
++
++                  assert(valp);
++
++                  /* try to remove any duplicate names, depending on the
++                   * implementation used in my_setenv() the iteration might
++                   * not be necessary, but let's be safe.
++                   */
++                  for (i = 0; i < count; ++i)
++                      my_setenv(name, 0);
++
++                  /* and set it back to the value we set $ENV{name} to */
++                  my_setenv(name, SvPV_nolen(*valp));
++              }
++          }
++          SvREFCNT_dec_NN(dups);
+       }
+ #endif /* USE_ENVIRON_ARRAY */
+ #endif /* !PERL_MICRO */
diff --git a/gnu/packages/patches/procmail-ambiguous-getline-debian.patch b/gnu/packages/patches/procmail-ambiguous-getline-debian.patch
new file mode 100644
index 0000000000..5dc91b1919
--- /dev/null
+++ b/gnu/packages/patches/procmail-ambiguous-getline-debian.patch
@@ -0,0 +1,61 @@
+Rename getline() to procmail_getline() to avoid namespace clash with
+POSIX getline(). Fixes FTBFS.
+
+Copied from Debian:
+http://sources.debian.net/src/procmail/3.22-24/debian/patches/24/
+
+References:
+http://bugs.debian.org/549426
+
+--- a/src/fields.c
++++ b/src/fields.c
+@@ -110,16 +110,16 @@
+ 		    /* try and append one valid field to rdheader from stdin */
+ int readhead P((void))
+ { int idlen;
+-  getline();
++  procmail_getline();
+   if((idlen=breakfield(buf,buffilled))<=0) /* not the start of a valid field */
+      return 0;
+   if(idlen==STRLEN(FROM)&&eqFrom_(buf))			/* it's a From_ line */
+    { if(rdheader)
+ 	return 0;			       /* the From_ line was a fake! */
+-     for(;buflast=='>';getline());	    /* gather continued >From_ lines */
++     for(;buflast=='>';procmail_getline());	    /* gather continued >From_ lines */
+    }
+   else
+-     for(;;getline())		      /* get the rest of the continued field */
++     for(;;procmail_getline())		      /* get the rest of the continued field */
+       { switch(buflast)			     /* will this line be continued? */
+ 	 { case ' ':case '\t':				  /* yep, it sure is */
+ 	      continue;
+--- a/src/formail.c
++++ b/src/formail.c
+@@ -819,7 +819,7 @@
+       { if(split)		       /* gobble up the next start separator */
+ 	 { buffilled=0;
+ #ifdef sMAILBOX_SEPARATOR
+-	   getline();buffilled=0;		 /* but only if it's defined */
++	   procmail_getline();buffilled=0;		 /* but only if it's defined */
+ #endif
+ 	   if(buflast!=EOF)					   /* if any */
+ 	      goto splitit;
+--- a/src/formisc.c
++++ b/src/formisc.c
+@@ -115,7 +115,7 @@
+   buf[buffilled++]=c;
+ }
+ 
+-int getline P((void))			   /* read a newline-terminated line */
++int procmail_getline P((void))			   /* read a newline-terminated line */
+ { if(buflast==EOF)			 /* at the end of our Latin already? */
+    { loadchar('\n');					  /* fake empty line */
+      return EOF;					  /* spread the word */
+--- a/src/formisc.h
++++ b/src/formisc.h
+@@ -17,4 +17,4 @@
+ char*
+  skipwords P((char*start));
+ int
+- getline P((void));
++ procmail_getline P((void));
diff --git a/gnu/packages/patches/python-rarfile-fix-tests.patch b/gnu/packages/patches/python-rarfile-fix-tests.patch
new file mode 100644
index 0000000000..8ae8894009
--- /dev/null
+++ b/gnu/packages/patches/python-rarfile-fix-tests.patch
@@ -0,0 +1,14 @@
+There is no test.sh, but there are test1.sh and test2.sh.
+
+diff --git a/test/Makefile b/test/Makefile
+index 027bc5f..5383db3 100644
+--- a/test/Makefile
++++ b/test/Makefile
+@@ -1,5 +1,6 @@
+ test:
+-	./test.sh
++	./test1.sh
++	./test2.sh
+ 
+ clean:
+ 	rm -rf __pycache__
diff --git a/gnu/packages/patches/scribus-qobject.patch b/gnu/packages/patches/scribus-qobject.patch
deleted file mode 100644
index 91be932f1b..0000000000
--- a/gnu/packages/patches/scribus-qobject.patch
+++ /dev/null
@@ -1,17 +0,0 @@
-See upstream bug report: http://bugs.scribus.net/view.php?id=13102
-
-scribus/sclayer.cpp | 1 +
- 1 file changed, 1 insertion(+)
-
-diff --git a/scribus/sclayer.cpp b/scribus/sclayer.cpp
-index 502112b..4da7bd5 100644
---- a/scribus/sclayer.cpp
-+++ b/scribus/sclayer.cpp
-@@ -9,6 +9,7 @@ for which a new license (GPL+exception) is in place.
- 

- #include <QHash>   //necessary to avoid msvc warnings induced by SCRIBUS_API on ScLayers + early instanciation of templates

- #include <QVector> //necessary to avoid msvc warnings induced by SCRIBUS_API on ScLayers + early instanciation of templates

-+#include <QObject>

- #include <QtAlgorithms>

- 

- ScLayer::ScLayer(void)

diff --git a/gnu/packages/patches/vorbis-tools-CVE-2015-6749.patch b/gnu/packages/patches/vorbis-tools-CVE-2015-6749.patch
new file mode 100644
index 0000000000..bcddcbfd70
--- /dev/null
+++ b/gnu/packages/patches/vorbis-tools-CVE-2015-6749.patch
@@ -0,0 +1,44 @@
+Upstream fix for CVE-2015-6749.
+https://trac.xiph.org/ticket/2212
+
+From 04815d3e1bfae3a6cdfb2c25358a5a72b61299f7 Mon Sep 17 00:00:00 2001
+From: Mark Harris <mark.hsj@gmail.com>
+Date: Sun, 30 Aug 2015 05:54:46 -0700
+Subject: [PATCH] oggenc: Fix large alloca on bad AIFF input
+
+Fixes #2212
+---
+ oggenc/audio.c | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/oggenc/audio.c b/oggenc/audio.c
+index 477da8c..4921fb9 100644
+--- a/oggenc/audio.c
++++ b/oggenc/audio.c
+@@ -245,8 +245,8 @@ static int aiff_permute_matrix[6][6] =
+ int aiff_open(FILE *in, oe_enc_opt *opt, unsigned char *buf, int buflen)
+ {
+     int aifc; /* AIFC or AIFF? */
+-    unsigned int len;
+-    unsigned char *buffer;
++    unsigned int len, readlen;
++    unsigned char buffer[22];
+     unsigned char buf2[8];
+     aiff_fmt format;
+     aifffile *aiff = malloc(sizeof(aifffile));
+@@ -269,9 +269,9 @@ int aiff_open(FILE *in, oe_enc_opt *opt, unsigned char *buf, int buflen)
+         return 0; /* Weird common chunk */
+     }
+ 
+-    buffer = alloca(len);
+-
+-    if(fread(buffer,1,len,in) < len)
++    readlen = len < sizeof(buffer) ? len : sizeof(buffer);
++    if(fread(buffer,1,readlen,in) < readlen ||
++       (len > readlen && !seek_forward(in, len-readlen)))
+     {
+         fprintf(stderr, _("Warning: Unexpected EOF in reading AIFF header\n"));
+         return 0;
+-- 
+2.5.0
+