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/4store-fix-buildsystem.patch56
-rw-r--r--gnu/packages/patches/doc++-include-directives.patch224
-rw-r--r--gnu/packages/patches/doc++-segfault-fix.patch169
-rw-r--r--gnu/packages/patches/gcc-cross-environment-variables.patch51
-rw-r--r--gnu/packages/patches/glib-tests-desktop.patch138
-rw-r--r--gnu/packages/patches/glib-tests-gapplication.patch28
-rw-r--r--gnu/packages/patches/glib-tests-homedir.patch59
-rw-r--r--gnu/packages/patches/glib-tests-prlimit.patch14
-rw-r--r--gnu/packages/patches/glib-tests-timer.patch11
-rw-r--r--gnu/packages/patches/gnupg-simple-query-ignore-status-messages.patch142
-rw-r--r--gnu/packages/patches/gtk2-theme-paths.patch41
-rw-r--r--gnu/packages/patches/hdf5-config-date.patch21
-rw-r--r--gnu/packages/patches/hypre-doc-tables.patch25
-rw-r--r--gnu/packages/patches/hypre-ldflags.patch9
-rw-r--r--gnu/packages/patches/icecat-CVE-2016-2805.patch75
-rw-r--r--gnu/packages/patches/icecat-CVE-2016-2807-pt1.patch35
-rw-r--r--gnu/packages/patches/icecat-CVE-2016-2807-pt2.patch69
-rw-r--r--gnu/packages/patches/icecat-CVE-2016-2807-pt3.patch33
-rw-r--r--gnu/packages/patches/icecat-CVE-2016-2807-pt4.patch37
-rw-r--r--gnu/packages/patches/icecat-CVE-2016-2807-pt5.patch35
-rw-r--r--gnu/packages/patches/icecat-CVE-2016-2808.patch389
-rw-r--r--gnu/packages/patches/icecat-CVE-2016-2814.patch35
-rw-r--r--gnu/packages/patches/icecat-re-enable-DHE-cipher-suites.patch24
-rw-r--r--gnu/packages/patches/icecat-update-bundled-graphite2.patch2488
-rw-r--r--gnu/packages/patches/imagemagick-test-segv.patch20
-rw-r--r--gnu/packages/patches/imlib2-CVE-2016-4024.patch52
-rw-r--r--gnu/packages/patches/inkscape-drop-wait-for-targets.patch68
-rw-r--r--gnu/packages/patches/libarchive-CVE-2016-1541.patch67
-rw-r--r--gnu/packages/patches/netcdf-config-date.patch47
-rw-r--r--gnu/packages/patches/ocaml-CVE-2015-8869.patch72
-rw-r--r--gnu/packages/patches/poppler-CVE-2015-8868.patch30
-rw-r--r--gnu/packages/patches/portmidi-modular-build.patch325
-rw-r--r--gnu/packages/patches/qemu-CVE-2015-8558.patch48
-rw-r--r--gnu/packages/patches/qemu-CVE-2015-8567.patch93
-rw-r--r--gnu/packages/patches/qemu-CVE-2015-8613.patch35
-rw-r--r--gnu/packages/patches/qemu-CVE-2015-8619.patch119
-rw-r--r--gnu/packages/patches/qemu-CVE-2015-8701.patch47
-rw-r--r--gnu/packages/patches/qemu-CVE-2015-8743.patch48
-rw-r--r--gnu/packages/patches/qemu-CVE-2016-1568.patch39
-rw-r--r--gnu/packages/patches/qemu-CVE-2016-1922.patch65
-rw-r--r--gnu/packages/patches/qemu-CVE-2016-1981.patch95
-rw-r--r--gnu/packages/patches/qemu-CVE-2016-2197.patch40
-rw-r--r--gnu/packages/patches/qemu-usb-ehci-oob-read.patch49
-rw-r--r--gnu/packages/patches/qemu-virtio-9p-use-accessor-to-get-thread-pool.patch34
-rw-r--r--gnu/packages/patches/totem-debug-format-fix.patch11
-rw-r--r--gnu/packages/patches/tvtime-gcc41.patch58
-rw-r--r--gnu/packages/patches/tvtime-pngoutput.patch15
-rw-r--r--gnu/packages/patches/tvtime-videodev2.patch15
-rw-r--r--gnu/packages/patches/tvtime-xmltv.patch28
-rw-r--r--gnu/packages/patches/wpa-supplicant-CVE-2016-4476.patch82
-rw-r--r--gnu/packages/patches/wpa-supplicant-CVE-2016-4477-pt1.patch51
-rw-r--r--gnu/packages/patches/wpa-supplicant-CVE-2016-4477-pt2.patch82
-rw-r--r--gnu/packages/patches/wpa-supplicant-CVE-2016-4477-pt3.patch62
-rw-r--r--gnu/packages/patches/wpa-supplicant-CVE-2016-4477-pt4.patch50
54 files changed, 1496 insertions, 4559 deletions
diff --git a/gnu/packages/patches/4store-fix-buildsystem.patch b/gnu/packages/patches/4store-fix-buildsystem.patch
new file mode 100644
index 0000000000..383baa9461
--- /dev/null
+++ b/gnu/packages/patches/4store-fix-buildsystem.patch
@@ -0,0 +1,56 @@
+This patch sets a fixed version to avoid needing Git and the .git/ folder.
+It also removes the creation of "/var/lib/4store", which is not available
+during the install phase in GNU Guix.
+
+Patch by Roel Janssen <roel@gnu.org>
+*** a/configure.ac	Wed Feb  4 19:05:24 2015
+--- b/configure.ac	Wed Mar 23 11:20:38 2016
+***************
+*** 2,13 ****
+  # Process this file with autoconf to produce a configure script.
+
+  AC_PREREQ([2.50])
+! AC_INIT([4store], m4_esyscmd([./version.sh .version]), [http://4store.org/support/], [4store])
+  AC_CONFIG_SRCDIR([src/backend/backend-intl.h])
+! AM_INIT_AUTOMAKE([1.7 std-options -Wall])
+  AC_CONFIG_HEADERS(4store-config.h)
+
+  # Checks for programs.
+  AC_PROG_LIBTOOL
+  AC_PROG_AWK
+  AC_PROG_CC
+--- 2,14 ----
+  # Process this file with autoconf to produce a configure script.
+
+  AC_PREREQ([2.50])
+! AC_INIT([4store], [1.1.6], [http://4store.org/support/], [4store])
+  AC_CONFIG_SRCDIR([src/backend/backend-intl.h])
+! AM_INIT_AUTOMAKE([1.7 std-options foreign -Wall])
+  AC_CONFIG_HEADERS(4store-config.h)
+
+  # Checks for programs.
++ AM_PROG_AR
+  AC_PROG_LIBTOOL
+  AC_PROG_AWK
+  AC_PROG_CC
+
+*** a/src/utilities/Makefile.am	Wed Feb  4 19:05:24 2015
+--- b/src/utilities/Makefile.am	Wed Mar 23 14:05:56 2016
+***************
+*** 13,20 ****
+  noinst_PROGRAMS = lex-file-verify 4s-rid
+
+  install-data-local: 
+! 	mkdir -p $(DESTDIR)@FS_STORE_ROOT@
+! 	chmod 1777 $(DESTDIR)@FS_STORE_ROOT@
+
+  4s_backend_destroy_SOURCES = backend-destroy.c
+  4s_backend_destroy_LDADD = ../common/lib4sintl.a
+--- 13,19 ----
+  noinst_PROGRAMS = lex-file-verify 4s-rid
+
+  install-data-local: 
+! 	echo "Please create the following directory: " $(DESTDIR)@FS_STORE_ROOT@
+
+  4s_backend_destroy_SOURCES = backend-destroy.c
+  4s_backend_destroy_LDADD = ../common/lib4sintl.a
diff --git a/gnu/packages/patches/doc++-include-directives.patch b/gnu/packages/patches/doc++-include-directives.patch
new file mode 100644
index 0000000000..a59a907c3b
--- /dev/null
+++ b/gnu/packages/patches/doc++-include-directives.patch
@@ -0,0 +1,224 @@
+Adapted from https://sourceforge.net/p/docpp/patches/1/
+
+--- doc++-3.4.10/src/comment.ll	2000-06-24 18:50:23.000000000 +0200
++++ doc++-3.4.10/src/comment.ll	2012-09-17 11:14:50.744922841 +0200
+@@ -24,7 +24,7 @@
+ 
+ #include <assert.h>
+ #include <ctype.h>
+-#include <iostream.h>
++#include <iostream>
+ #include <stdarg.h>
+ #include <stdio.h>
+ 
+--- doc++-3.4.10/src/cpp.ll	2002-05-09 08:11:14.000000000 +0200
++++ doc++-3.4.10/src/cpp.ll	2012-09-17 11:15:21.184333236 +0200
+@@ -26,7 +26,7 @@
+ 
+ #include <assert.h>
+ #include <ctype.h>
+-#include <iostream.h>
++#include <iostream>
+ #include <stdarg.h>
+ #include <stdio.h>
+ 
+--- doc++-3.4.10/src/datahashtable.h	2000-08-27 21:44:34.000000000 +0200
++++ doc++-3.4.10/src/datahashtable.h	2012-09-17 11:22:59.442589960 +0200
+@@ -26,11 +26,13 @@
+ #define _DATAHASHTABLE_H
+ 
+ #include <assert.h>
+-#include <iostream.h>
++#include <iostream>
+ #include <stdlib.h>
+ 
+ #include "McDArray.h"
+ 
++using namespace std;
++
+ /* This should be a private subclass of #DataHashTable#. However, since cfront
+    is not able to compile this constrution, we had move the class to global
+    scope.
+--- doc++-3.4.10/src/doc2dbsgml.ll	2002-05-09 08:11:14.000000000 +0200
++++ doc++-3.4.10/src/doc2dbsgml.ll	2012-09-17 11:20:49.077259414 +0200
+@@ -22,8 +22,8 @@
+ 
+ %{
+ #include <assert.h>
+-#include <fstream.h>
+-#include <iostream.h>
++#include <fstream>
++#include <iostream>
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <string.h>
+@@ -36,6 +36,8 @@
+ #undef	YY_INPUT
+ #define	YY_INPUT(buf, result, max_size) result = yyread(buf, max_size);
+ 
++using namespace std;
++
+ static Entry*	current;
+ static int	inPos;
+ static int	lastContext;
+--- doc++-3.4.10/src/doc2dbxml.ll	2002-05-09 08:11:14.000000000 +0200
++++ doc++-3.4.10/src/doc2dbxml.ll	2012-09-17 11:20:22.264831159 +0200
+@@ -25,8 +25,8 @@
+ 
+ %{
+ #include <assert.h>
+-#include <fstream.h>
+-#include <iostream.h>
++#include <fstream>
++#include <iostream>
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <string.h>
+@@ -39,6 +39,8 @@
+ #undef	YY_INPUT
+ #define	YY_INPUT(buf, result, max_size) result = yyread(buf, max_size);
+ 
++using namespace std;
++
+ static Entry*	current;
+ static int	inPos;
+ static int	lastContext;
+--- doc++-3.4.10/src/doc2html.ll	2000-07-17 23:17:24.000000000 +0200
++++ doc++-3.4.10/src/doc2html.ll	2012-09-17 11:22:40.354469631 +0200
+@@ -29,6 +29,8 @@
+ #include "doc.h"
+ #include "nametable.h"
+ 
++using namespace std;
++
+ extern NameTable	gifs;
+ 
+ #define YY_DECL int yylex()
+--- doc++-3.4.10/src/doc2tex.ll	2000-11-05 17:21:16.000000000 +0100
++++ doc++-3.4.10/src/doc2tex.ll	2012-09-17 11:23:22.210701715 +0200
+@@ -23,8 +23,8 @@
+ 
+ %{
+ #include <assert.h>
+-#include <fstream.h>
+-#include <iostream.h>
++#include <fstream>
++#include <iostream>
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <string.h>
+@@ -38,6 +38,8 @@
+ #undef	YY_INPUT
+ #define	YY_INPUT(buf, result, max_size) result = yyread(buf, max_size);
+ 
++using namespace std;
++
+ static Entry*	current;
+ static int	inPos;
+ static int	lastContext;
+--- doc++-3.4.10/src/doc.ll	2000-09-17 21:41:17.000000000 +0200
++++ doc++-3.4.10/src/doc.ll	2012-09-17 11:15:37.068009454 +0200
+@@ -23,8 +23,8 @@
+ 
+ %{
+ #include <assert.h>
+-#include <fstream.h>
+-#include <iostream.h>
++#include <fstream>
++#include <iostream>
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <string.h>
+--- doc++-3.4.10/src/equate.cc	2002-05-02 21:13:10.000000000 +0200
++++ doc++-3.4.10/src/equate.cc	2012-09-17 11:25:42.850669366 +0200
+@@ -23,9 +23,9 @@
+ 
+ #include "config.h"
+ 
+-#include <fstream.h>
++#include <fstream>
+ #include <getopt.h>
+-#include <iostream.h>
++#include <iostream>
+ #include <stdio.h>
+ #include <string.h>
+ 
+--- doc++-3.4.10/src/html.cc	2001-02-17 07:34:49.000000000 +0100
++++ doc++-3.4.10/src/html.cc	2012-09-17 11:24:07.978824681 +0200
+@@ -31,7 +31,7 @@
+ #include <direct.h>
+ #endif
+ #include <errno.h>
+-#include <iostream.h>
++#include <iostream>
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <string.h>
+--- doc++-3.4.10/src/java.ll	2001-11-25 18:04:12.000000000 +0100
++++ doc++-3.4.10/src/java.ll	2012-09-17 11:24:19.138834603 +0200
+@@ -26,7 +26,7 @@
+ 
+ #include <assert.h>
+ #include <ctype.h>
+-#include <iostream.h>
++#include <iostream>
+ #include <stdio.h>
+ 
+ #include "doc.h"
+--- doc++-3.4.10/src/main.cc	2002-05-09 08:11:14.000000000 +0200
++++ doc++-3.4.10/src/main.cc	2012-09-17 11:25:30.650719070 +0200
+@@ -25,7 +25,7 @@
+ #include "config.h"
+ 
+ #include <assert.h>
+-#include <fstream.h>
++#include <fstream>
+ #include <getopt.h>
+ #include <locale.h>
+ #include <stdio.h>
+--- doc++-3.4.10/src/nametable.cc	2000-04-08 23:11:54.000000000 +0200
++++ doc++-3.4.10/src/nametable.cc	2012-09-17 11:25:58.894591128 +0200
+@@ -22,7 +22,7 @@
+ */
+ 
+ #include <assert.h>
+-#include <iostream.h>
++#include <iostream>
+ #include <stdlib.h>
+ #include <string.h>
+ 
+--- doc++-3.4.10/src/nametable.h	2000-04-08 23:11:56.000000000 +0200
++++ doc++-3.4.10/src/nametable.h	2012-09-17 11:22:07.826207198 +0200
+@@ -25,7 +25,7 @@
+ #define	_NAME_TABLE_H
+ 
+ #include <assert.h>
+-#include <iostream.h>
++#include <iostream>
+ 
+ #include "datahashtable.h"
+ 
+--- doc++-3.4.10/src/php.ll	2001-02-16 23:34:47.000000000 +0100
++++ doc++-3.4.10/src/php.ll	2012-09-17 11:25:18.582759801 +0200
+@@ -23,7 +23,7 @@
+ %{
+ #include <assert.h>
+ #include <ctype.h>
+-#include <iostream.h>
++#include <iostream>
+ #include <stdio.h>
+ 
+ #include "doc.h"
+--- doc++-3.4.10/src/tex2gif.cc	2001-08-07 20:55:40.000000000 +0200
++++ doc++-3.4.10/src/tex2gif.cc	2012-09-17 11:26:06.698547836 +0200
+@@ -21,8 +21,8 @@
+   Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+ 
+-#include <iostream.h>
+-#include <fstream.h>
++#include <iostream>
++#include <fstream>
+ #include <stdio.h>
+ #include <string.h>
+ 
diff --git a/gnu/packages/patches/doc++-segfault-fix.patch b/gnu/packages/patches/doc++-segfault-fix.patch
new file mode 100644
index 0000000000..bad34c814e
--- /dev/null
+++ b/gnu/packages/patches/doc++-segfault-fix.patch
@@ -0,0 +1,169 @@
+Adapted from https://sources.debian.net/data/main/d/doc%2B%2B/3.4.10-3.4/debian/patches/segfault_fix.patch
+
+--- doc++-3.4.10/src/McDArray.h	2000-07-30 12:40:48.000000000 +0200
++++ doc++-3.4.10/src/McDArray.h	2005-05-10 15:02:06.000000000 +0200
+@@ -80,9 +80,14 @@
+     McDArray(const McDArray& old) : memFactor(old.memFactor),
+ 	thesize(old.thesize), themax(old.themax)
+ 	{
+-	data = (T*)malloc(themax * sizeof(T));
+-	if(thesize)
+-	    memcpy(data, old.data, thesize * sizeof(T));
++	if (themax)
++	    {
++	    data = (T*)malloc(themax * sizeof(T));
++	    if(thesize)
++		memcpy(data, old.data, thesize * sizeof(T));
++	    }
++	else
++	    data = 0;
+ 	assert(isConsistent());
+ 	}
+ 
+--- doc++-3.4.10/src/McDirectory.cc	2000-03-14 22:17:36.000000000 +0100
++++ doc++-3.4.10/src/McDirectory.cc	2005-05-10 15:02:18.000000000 +0200
+@@ -23,12 +23,13 @@
+ */
+ 
+ #include "McDirectory.h"
+-#include "McSorter.h"
+ #include "McString.h"
+ #include "doc.h"
+ 
+ #include <stdio.h>
+ 
++#include <algorithm>
++
+ #ifdef WIN32
+ #include <windows.h>
+ #ifdef __BORLANDC__
+@@ -62,7 +63,7 @@
+     FindClose(searchHandle);
+     StringCompare comp;
+     if(list.size())
+-	sort((char **)list, list.size(), comp, 0);
++	std::sort((char **)list, (char **)list + list.size(), comp);
+     return 0;
+ }
+ 
+@@ -107,7 +108,7 @@
+     closedir(dir);
+     StringCompare comp;
+     if(list.size())
+-	sort((char **)list, list.size(), comp, 0);
++	std::sort((char **)list, (char **)list + list.size(), comp);
+     return list.size();
+ }
+ 
+--- doc++-3.4.10/src/McDirectory.h	2000-06-28 21:54:58.000000000 +0200
++++ doc++-3.4.10/src/McDirectory.h	2005-05-10 15:02:18.000000000 +0200
+@@ -59,9 +59,9 @@
+     class StringCompare
+ 	{
+ 	public:
+-	    int operator()(const char *t1, const char *t2)
++	    bool operator()(const char *t1, const char *t2)
+ 		{
+-		return strcmp(t1, t2);
++		return strcmp(t1, t2) < 0;
+ 		}
+ 	};
+ };
+--- doc++-3.4.10/src/html.cc	2001-02-17 07:34:49.000000000 +0100
++++ doc++-3.4.10/src/html.cc	2005-05-10 15:02:18.000000000 +0200
+@@ -38,9 +38,10 @@
+ #include <sys/stat.h>
+ #include <sys/types.h>
+ 
++#include <algorithm>
++
+ #include "McDirectory.h"
+ #include "McHashTable.h"
+-#include "McSorter.h"
+ #include "classgraph.h"
+ #include "doc.h"
+ #include "gifs.h"
+@@ -314,9 +315,11 @@
+ 	virtual void writeMember(Entry *e, bool links, bool withSub = true);
+ 	class EntryCompare {
+ 	    public:
+-		int operator()(const MemberWriterListEntry& l1, const MemberWriterListEntry& l2)
++		bool operator()(const MemberWriterListEntry& l1, const MemberWriterListEntry& l2)
+ 		    {
+-		    return strcmp(l1.entry->fullName.c_str(), l2.entry->fullName.c_str());
++		    const char *s1 = l1.entry->fullName.c_str();
++		    const char *s2 = l2.entry->fullName.c_str();
++		    return strcmp(s1, s2) < 0;
+ 		    }
+ 	};
+     public:
+@@ -324,7 +327,7 @@
+ 	    {
+ 	    EntryCompare comp;
+ 	    if(list.size())
+-		::sort((MemberWriterListEntry *)list, list.size(), comp, 0);
++		std::sort((MemberWriterListEntry *)list, (MemberWriterListEntry *)list + list.size(), comp);
+ 	    }
+ 	virtual void startList(FILE *f, char *heading, bool withLinks);
+ 	virtual void addMember(Entry *e, bool links, bool withSub = true)
+@@ -376,7 +379,7 @@
+ 	    int lp;
+ 
+ 	    if(list.size() > 1)
+-		::sort((TOCListEntry *)list, list.size(), comp, 0);
++		std::sort((TOCListEntry *)list, (TOCListEntry *)list + list.size(), comp);
+ 
+ 	    // Sort subsections
+ 	    for(lp = 0; lp < list.size(); lp++)
+@@ -385,9 +388,9 @@
+ 	    }
+ 	class EntryCompare {
+ 	    public:
+-		int operator()(TOCListEntry& l1, TOCListEntry& l2)
++		bool operator()(const TOCListEntry& l1, const TOCListEntry& l2)
+ 		    {
+-		    return strcmp(l1.name, l2.name);
++		    return strcmp(l1.name, l2.name) < 0;
+ 		    }
+ 	};
+ 	void addEntry(Entry *entry, TOClist *tl);
+@@ -487,7 +490,7 @@
+ 
+     for(i = 0; i < list.size(); i++)
+ 	if(list[i].tl)
+-	    free(list[i].tl);
++	    delete list[i].tl;
+ }
+ 
+ class HIERlist;
+@@ -509,7 +512,7 @@
+ 	    int i;
+ 
+ 	    if(list.size() > 1)
+-		::sort((HIERListEntry *)list, list.size(), comp, 0);
++		std::sort((HIERListEntry *)list, (HIERListEntry *)list + list.size(), comp);
+ 
+ 	    // Sort subentries
+ 	    for(i = 0; i < list.size(); i++)
+@@ -519,9 +522,9 @@
+ 	class EntryCompare
+ 	    {
+ 	    public:
+-		int operator()(HIERListEntry& l1, HIERListEntry& l2)
++		bool operator()(const HIERListEntry& l1, const HIERListEntry& l2)
+ 		    {
+-		    return strcmp(l1.name, l2.name);
++		    return strcmp(l1.name, l2.name) < 0;
+ 		    }
+ 	    };
+ 	void addEntry(Entry *entry, HIERlist *hl);
+--- doc++-3.4.10/src/readfiles.ll	2001-11-25 18:04:48.000000000 +0100
++++ doc++-3.4.10/src/readfiles.ll	2005-05-10 15:02:18.000000000 +0200
+@@ -28,7 +28,6 @@
+ #include <sys/types.h>
+ 
+ #include "McDirectory.h"
+-#include "McSorter.h"
+ #include "McString.h"
+ #include "doc.h"
+ #include "nametable.h"
diff --git a/gnu/packages/patches/gcc-cross-environment-variables.patch b/gnu/packages/patches/gcc-cross-environment-variables.patch
index 0bd0be5984..ec4378e2d2 100644
--- a/gnu/packages/patches/gcc-cross-environment-variables.patch
+++ b/gnu/packages/patches/gcc-cross-environment-variables.patch
@@ -1,9 +1,23 @@
 Search path environment variables for cross-compilers.  See the discussion
 at <http://gcc.gnu.org/ml/gcc/2013-02/msg00124.html>.
 
---- gcc-4.7.2/gcc/incpath.c	2012-01-27 00:34:58.000000000 +0100
-+++ gcc-4.7.2/gcc/incpath.c	2013-02-12 10:11:27.000000000 +0100
-@@ -452,7 +452,7 @@ register_include_chains (cpp_reader *pfi
+Note: Touch 'C_INCLUDE_PATH' et al. rather than 'CPATH', as discussed
+at <http://bugs.gnu.org/22186>.
+
+--- a/gcc/incpath.c
++++ b/gcc/incpath.c
+@@ -461,8 +461,8 @@ register_include_chains (cpp_reader *pfile, const char *sysroot,
+ 			 int stdinc, int cxx_stdinc, int verbose)
+ {
+   static const char *const lang_env_vars[] =
+-    { "C_INCLUDE_PATH", "CPLUS_INCLUDE_PATH",
+-      "OBJC_INCLUDE_PATH", "OBJCPLUS_INCLUDE_PATH" };
++    { "CROSS_C_INCLUDE_PATH", "CROSS_CPLUS_INCLUDE_PATH",
++      "CROSS_OBJC_INCLUDE_PATH", "CROSS_OBJCPLUS_INCLUDE_PATH" };
+   cpp_options *cpp_opts = cpp_get_options (pfile);
+   size_t idx = (cpp_opts->objc ? 2: 0);
+ 
+@@ -473,7 +473,7 @@ register_include_chains (cpp_reader *pfile, const char *sysroot,
  
    /* CPATH and language-dependent environment variables may add to the
       include chain.  */
@@ -12,20 +26,22 @@ at <http://gcc.gnu.org/ml/gcc/2013-02/msg00124.html>.
    add_env_var_paths (lang_env_vars[idx], SYSTEM);
  
    target_c_incpath.extra_pre_includes (sysroot, iprefix, stdinc);
-
---- gcc-4.7.2/gcc/system.h	2012-02-17 00:16:28.000000000 +0100
-+++ gcc-4.7.2/gcc/system.h	2013-02-12 10:22:17.000000000 +0100
-@@ -1023,4 +1023,6 @@ helper_const_non_const_cast (const char
- #define DEBUG_VARIABLE
- #endif
+diff --git a/gcc/system.h b/gcc/system.h
+index 42bc509..af3b9ad 100644
+--- a/gcc/system.h
++++ b/gcc/system.h
+@@ -1063,4 +1063,6 @@ helper_const_non_const_cast (const char *p)
+ /* Get definitions of HOST_WIDE_INT and HOST_WIDEST_INT.  */
+ #include "hwint.h"
  
 +#define LIBRARY_PATH_ENV "CROSS_LIBRARY_PATH"
 +
  #endif /* ! GCC_SYSTEM_H */
-
---- gcc-4.7.2/gcc/tlink.c	2012-02-11 09:50:23.000000000 +0100
-+++ gcc-4.7.2/gcc/tlink.c	2013-05-23 22:06:19.000000000 +0200
-@@ -461,7 +461,7 @@ recompile_files (void)
+diff --git a/gcc/tlink.c b/gcc/tlink.c
+index bc358b8..ad6242f 100644
+--- a/gcc/tlink.c
++++ b/gcc/tlink.c
+@@ -458,7 +458,7 @@ recompile_files (void)
    file *f;
  
    putenv (xstrdup ("COMPILER_PATH="));
@@ -34,10 +50,11 @@ at <http://gcc.gnu.org/ml/gcc/2013-02/msg00124.html>.
  
    while ((f = file_pop ()) != NULL)
      {
-
---- gcc-4.7.3/gcc/gcc.c	2013-03-08 08:25:09.000000000 +0100
-+++ gcc-4.7.3/gcc/gcc.c	2013-05-24 08:58:16.000000000 +0200
-@@ -3726,7 +3726,7 @@ process_command (unsigned int decoded_op
+diff --git a/gcc/gcc.c b/gcc/gcc.c
+index adbf0c4..70448c6 100644
+--- a/gcc/gcc.c
++++ b/gcc/gcc.c
+@@ -3853,7 +3853,7 @@ process_command (unsigned int decoded_options_count,
      }
  
    temp = getenv (LIBRARY_PATH_ENV);
diff --git a/gnu/packages/patches/glib-tests-desktop.patch b/gnu/packages/patches/glib-tests-desktop.patch
deleted file mode 100644
index 642234ebbc..0000000000
--- a/gnu/packages/patches/glib-tests-desktop.patch
+++ /dev/null
@@ -1,138 +0,0 @@
-Some GLib tests expect desktop things, such as an xterm, a MIME
-database, the `update-desktop-database' program, which we don't provide.
-
---- glib-2.37.1/gio/tests/appinfo.c	2013-06-07 23:44:44.000000000 +0200
-+++ glib-2.37.1/gio/tests/appinfo.c	2013-06-07 23:44:56.000000000 +0200
-@@ -497,16 +497,10 @@ main (int argc, char *argv[])
- 
-   g_test_add_func ("/appinfo/basic", test_basic);
-   g_test_add_func ("/appinfo/text", test_text);
--  g_test_add_func ("/appinfo/launch", test_launch);
-   g_test_add_func ("/appinfo/show-in", test_show_in);
-   g_test_add_func ("/appinfo/commandline", test_commandline);
--  g_test_add_func ("/appinfo/launch-context", test_launch_context);
--  g_test_add_func ("/appinfo/launch-context-signals", test_launch_context_signals);
-   g_test_add_func ("/appinfo/tryexec", test_tryexec);
--  g_test_add_func ("/appinfo/associations", test_associations);
-   g_test_add_func ("/appinfo/environment", test_environment);
--  g_test_add_func ("/appinfo/startup-wm-class", test_startup_wm_class);
--  g_test_add_func ("/appinfo/supported-types", test_supported_types);
-   g_test_add_func ("/appinfo/from-keyfile", test_from_keyfile);
- 
-   return g_test_run ();
-
---- glib-2.40.0/gio/tests/contenttype.c	2013-01-16 21:22:29.000000000 +0100
-+++ glib-2.40.0/gio/tests/contenttype.c	2013-01-16 21:22:33.000000000 +0100
-@@ -207,15 +207,6 @@ main (int argc, char *argv[])
- {
-   g_test_init (&argc, &argv, NULL);
- 
--  g_test_add_func ("/contenttype/guess", test_guess);
--  g_test_add_func ("/contenttype/unknown", test_unknown);
--  g_test_add_func ("/contenttype/subtype", test_subtype);
--  g_test_add_func ("/contenttype/list", test_list);
--  g_test_add_func ("/contenttype/executable", test_executable);
--  g_test_add_func ("/contenttype/description", test_description);
--  g_test_add_func ("/contenttype/icon", test_icon);
--  g_test_add_func ("/contenttype/symbolic-icon", test_symbolic_icon);
--  g_test_add_func ("/contenttype/tree", test_tree);
- 
-   return g_test_run ();
- }
-
-
---- glib-2.40.0/gio/tests/desktop-app-info.c	2014-03-19 22:50:45.000000000 -0500
-+++ glib-2.40.0/gio/tests/desktop-app-info.c	2014-06-30 14:27:52.543358331 -0500
-@@ -708,6 +708,8 @@
-   g_setenv ("XDG_DATA_HOME", basedir, TRUE);
-   cleanup_subdirs (basedir);
- 
-+  result = g_test_run ();
-+  return result;
-   g_test_add_func ("/desktop-app-info/delete", test_delete);
-   g_test_add_func ("/desktop-app-info/default", test_default);
-   g_test_add_func ("/desktop-app-info/fallback", test_fallback);
-
-
------------------------------
-The hunk below removes tests that depend on `gdbus-testserver.py',
-because that script depends on python-gobject.  The second hunk
-disables a test that expects /etc/machine-id in the build environment.
- 
---- glib-2.46.0/gio/tests/Makefile.in	2015-10-14 14:11:00.928809504 +0200
-+++ glib-2.46.0/gio/tests/Makefile.in	2015-10-14 14:12:13.157291092 +0200
-@@ -186,20 +186,13 @@ check_PROGRAMS = $(am__EXEEXT_16)
- @HAVE_DBUS_DAEMON_TRUE@@OS_UNIX_TRUE@	gdbus-auth				\
- @HAVE_DBUS_DAEMON_TRUE@@OS_UNIX_TRUE@	gdbus-bz627724				\
- @HAVE_DBUS_DAEMON_TRUE@@OS_UNIX_TRUE@	gdbus-close-pending			\
--@HAVE_DBUS_DAEMON_TRUE@@OS_UNIX_TRUE@	gdbus-connection			\
--@HAVE_DBUS_DAEMON_TRUE@@OS_UNIX_TRUE@	gdbus-connection-loss			\
--@HAVE_DBUS_DAEMON_TRUE@@OS_UNIX_TRUE@	gdbus-connection-slow			\
- @HAVE_DBUS_DAEMON_TRUE@@OS_UNIX_TRUE@	gdbus-error				\
- @HAVE_DBUS_DAEMON_TRUE@@OS_UNIX_TRUE@	gdbus-exit-on-close			\
- @HAVE_DBUS_DAEMON_TRUE@@OS_UNIX_TRUE@	gdbus-export				\
--@HAVE_DBUS_DAEMON_TRUE@@OS_UNIX_TRUE@	gdbus-introspection			\
- @HAVE_DBUS_DAEMON_TRUE@@OS_UNIX_TRUE@	gdbus-names				\
--@HAVE_DBUS_DAEMON_TRUE@@OS_UNIX_TRUE@	gdbus-proxy				\
- @HAVE_DBUS_DAEMON_TRUE@@OS_UNIX_TRUE@	gdbus-proxy-threads			\
--@HAVE_DBUS_DAEMON_TRUE@@OS_UNIX_TRUE@	gdbus-proxy-well-known-name		\
- @HAVE_DBUS_DAEMON_TRUE@@OS_UNIX_TRUE@	gdbus-test-codegen			\
- @HAVE_DBUS_DAEMON_TRUE@@OS_UNIX_TRUE@	gdbus-test-codegen-old			\
--@HAVE_DBUS_DAEMON_TRUE@@OS_UNIX_TRUE@	gdbus-threading				\
- @HAVE_DBUS_DAEMON_TRUE@@OS_UNIX_TRUE@	gmenumodel				\
- @HAVE_DBUS_DAEMON_TRUE@@OS_UNIX_TRUE@	gnotification				\
- @HAVE_DBUS_DAEMON_TRUE@@OS_UNIX_TRUE@	$(NULL)
-@@ -321,8 +314,7 @@ libresourceplugin_la_LINK = $(LIBTOOL) $
- am__EXEEXT_1 =
- @OS_UNIX_TRUE@am__EXEEXT_2 = contenttype$(EXEEXT) file$(EXEEXT) \
- @OS_UNIX_TRUE@	gdbus-peer-object-manager$(EXEEXT) \
--@OS_UNIX_TRUE@	gdbus-unix-addresses$(EXEEXT) \
- @OS_UNIX_TRUE@	live-g-file$(EXEEXT) socket-address$(EXEEXT) \
- @OS_UNIX_TRUE@	stream-rw_all$(EXEEXT) unix-fd$(EXEEXT) \
- @OS_UNIX_TRUE@	unix-streams$(EXEEXT) $(am__EXEEXT_1) \
-  
-
-The test below depends on the availability /etc/passwd to dbus-daemon.
-
---- glib-2.40.0/gio/tests/gdbus-auth.c	2014-02-03 11:40:41.000000000 -0600
-+++ glib-2.40.0/gio/tests/gdbus-auth.c	2014-06-30 15:08:43.719421893 -0500
-@@ -286,6 +286,8 @@
- {
-   gint ret;
- 
-+  g_test_init (&argc, &argv, NULL);
-+  return g_test_run();
-   setlocale (LC_ALL, "C");
- 
-   temp_dbus_keyrings_setup ();
-
-
-The test dbus-appinfo is dropped as it hangs indefinitely since 2.37.5, see
-   https://launchpad.net/ubuntu/+source/glib2.0/2.37.5-1ubuntu1
-
---- glib-2.40.0/gio/tests/dbus-appinfo.c	2014-02-03 11:40:41.000000000 -0600
-+++ glib-2.40.0/gio/tests/dbus-appinfo.c	2014-06-30 14:44:08.215383632 -0500
-@@ -278,7 +278,7 @@
- {
-   g_test_init (&argc, &argv, NULL);
- 
--  g_test_add_func ("/appinfo/dbusappinfo", test_dbus_appinfo);
-+  return g_test_run();
- 
-   return session_bus_run ();
- }
-
-
-The test below fails for unknown reasons (!).
-
---- glib-2.39.1/gio/tests/gsettings.c.orig	2014-01-20 00:45:04.000000000 +0100
-+++ glib-2.39.1/gio/tests/gsettings.c	2014-01-20 00:45:10.000000000 +0100
-@@ -2489,7 +2489,6 @@ main (int argc, char *argv[])
-   g_test_add_func ("/gsettings/range/subprocess/high", test_range_high);
-   g_test_add_func ("/gsettings/range/subprocess/low", test_range_low);
-   g_test_add_func ("/gsettings/list-items", test_list_items);
--  g_test_add_func ("/gsettings/list-schemas", test_list_schemas);
-   g_test_add_func ("/gsettings/mapped", test_get_mapped);
-   g_test_add_func ("/gsettings/get-range", test_get_range);
-   g_test_add_func ("/gsettings/schema-source", test_schema_source);
-
diff --git a/gnu/packages/patches/glib-tests-gapplication.patch b/gnu/packages/patches/glib-tests-gapplication.patch
deleted file mode 100644
index 1845fcb9b8..0000000000
--- a/gnu/packages/patches/glib-tests-gapplication.patch
+++ /dev/null
@@ -1,28 +0,0 @@
-This test has proven to be unreliable, often leading to things like this
-in gapplication.log:
-
-  PASS: gapplication 3 /gapplication/properties
-  Failed to register: The connection is closed
-  **
-  GLib-GIO:ERROR:gapplication.c:564:test_quit: assertion failed: (activated)
-  ok 4 /gapplication/app-id
-  PASS: gapplication 4 /gapplication/app-id
-  ../../tap-test: line 5: 24133 Aborted                 $1 -k --tap
-  # GLib-GIO:ERROR:gapplication.c:564:test_quit: assertion failed: (activated)
-  cleaning up pid 24154
-  ERROR: gapplication - missing test plan
-  ERROR: gapplication - exited with status 134 (terminated by signal 6?)
-
-See <https://bugs.debian.org/756273> and <http://bugs.gnu.org/18445>.
-
-
---- glib-2.40.2/gio/tests/gapplication.c	2014-12-03 22:34:44.566667649 +0100
-+++ glib-2.40.2/gio/tests/gapplication.c	2014-12-03 22:34:45.346674179 +0100
-@@ -685,7 +685,6 @@ main (int argc, char **argv)
- /*  g_test_add_func ("/gapplication/non-unique", test_nonunique); */
-   g_test_add_func ("/gapplication/properties", properties);
-   g_test_add_func ("/gapplication/app-id", appid);
--  g_test_add_func ("/gapplication/quit", test_quit);
-   g_test_add_func ("/gapplication/local-actions", test_local_actions);
- /*  g_test_add_func ("/gapplication/remote-actions", test_remote_actions); */
-   g_test_add_func ("/gapplication/local-command-line", test_local_command_line);
diff --git a/gnu/packages/patches/glib-tests-homedir.patch b/gnu/packages/patches/glib-tests-homedir.patch
deleted file mode 100644
index 0a2bcf1a23..0000000000
--- a/gnu/packages/patches/glib-tests-homedir.patch
+++ /dev/null
@@ -1,59 +0,0 @@
-`g_get_home_dir' looks at /etc/passwd first, which fails in chroot builds.
-The gdbus tests use it to lookup .dbus-keyrings, so they cannot run in our
-chroot build environment.  Thus, disable them.
-
---- glib-2.34.3/gio/tests/gdbus-connection-flush.c	2013-01-16 17:29:46.000000000 +0100
-+++ glib-2.34.3/gio/tests/gdbus-connection-flush.c	2013-01-16 17:29:47.000000000 +0100
-@@ -373,10 +373,6 @@ main (int   argc,
-   g_type_init ();
-   g_test_init (&argc, &argv, NULL);
- 
--  g_test_add ("/gdbus/connection/flush/busy", Fixture, NULL,
--              setup, test_flush_busy, teardown);
--  g_test_add ("/gdbus/connection/flush/idle", Fixture, NULL,
--              setup, test_flush_idle, teardown);
- 
-   ret = g_test_run();
-
---- glib-2.38.0.orig/gio/tests/gdbus-peer.c     2013-08-08 12:00:40.000000000 +0200
-+++ glib-2.38.0/gio/tests/gdbus-peer.c  2013-09-30 19:36:40.000000000 +0200
-@@ -1746,11 +1746,6 @@
-
-   g_test_add_func ("/gdbus/peer-to-peer", test_peer);
-   g_test_add_func ("/gdbus/delayed-message-processing", delayed_message_processing);
--  g_test_add_func ("/gdbus/nonce-tcp", test_nonce_tcp);
--
--  g_test_add_func ("/gdbus/tcp-anonymous", test_tcp_anonymous);
--  g_test_add_func ("/gdbus/credentials", test_credentials);
--  g_test_add_func ("/gdbus/codegen-peer-to-peer", codegen_test_peer);
-
-   ret = g_test_run();
- 
---- glib-2.37.1/gio/tests/gdbus-exit-on-close.c	2013-06-07 23:41:34.000000000 +0200
-+++ glib-2.37.1/gio/tests/gdbus-exit-on-close.c	2013-06-07 23:41:40.000000000 +0200
-@@ -211,6 +211,7 @@ main (int   argc,
- 
-   g_test_init (&argc, &argv, NULL);
- 
-+  return g_test_run();
-   for (i = 0; cases[i].name != NULL; i++)
-     {
-       gchar *name;
-@@ -224,5 +225,4 @@ main (int   argc,
-       g_free (name);
-     }
- 
--  return g_test_run();
- }
-
---- glib-2.34.3/gio/tests/gdbus-non-socket.c	2013-01-16 18:13:25.000000000 +0100
-+++ glib-2.34.3/gio/tests/gdbus-non-socket.c	2013-01-16 18:13:27.000000000 +0100
-@@ -294,7 +294,6 @@ main (int   argc,
-   g_type_init ();
-   g_test_init (&argc, &argv, NULL);
- 
--  g_test_add_func ("/gdbus/non-socket", test_non_socket);
- 
-   ret = g_test_run();
- 
-
diff --git a/gnu/packages/patches/glib-tests-prlimit.patch b/gnu/packages/patches/glib-tests-prlimit.patch
deleted file mode 100644
index f2b2a61bee..0000000000
--- a/gnu/packages/patches/glib-tests-prlimit.patch
+++ /dev/null
@@ -1,14 +0,0 @@
-prlimit(2) returns ENOSYS on Linux 2.6.32-5-xen-amd64 as found on
-hydra.gnu.org, and strace(1) doesn't recognize it.
-
---- glib-2.34.3/glib/tests/thread.c	2012-11-20 15:27:12.000000000 +0100
-+++ glib-2.34.3/glib/tests/thread.c	2013-03-27 14:48:31.000000000 +0100
-@@ -130,7 +130,7 @@ test_thread3 (void)
- static void
- test_thread4 (void)
- {
--#ifdef HAVE_PRLIMIT
-+#if 0
-   struct rlimit ol, nl;
-   GThread *thread;
-   GError *error;
diff --git a/gnu/packages/patches/glib-tests-timer.patch b/gnu/packages/patches/glib-tests-timer.patch
index 1ac364fcc1..e37425c0c8 100644
--- a/gnu/packages/patches/glib-tests-timer.patch
+++ b/gnu/packages/patches/glib-tests-timer.patch
@@ -2,9 +2,6 @@
   fail depending on the elapsed microseconds.  Improve rounding by adding a
   fractional bit.
 
-* The /timer/stop test fails if compiler optimizations are enabled, which they
-  are by default.  Disable that test.
-
 --- glib-2.40.0/glib/tests/timer.c	2014-03-05 08:05:42.000000000 -0600
 +++ glib-2.40.0/glib/tests/timer.c	2014-07-10 16:33:12.746862822 -0500
 @@ -35,7 +35,7 @@
@@ -16,11 +13,3 @@
  
    g_timer_destroy (timer);
  }
-@@ -204,7 +204,6 @@
-   g_test_init (&argc, &argv, NULL);
- 
-   g_test_add_func ("/timer/basic", test_timer_basic);
--  g_test_add_func ("/timer/stop", test_timer_stop);
-   g_test_add_func ("/timer/continue", test_timer_continue);
-   g_test_add_func ("/timer/reset", test_timer_reset);
-   g_test_add_func ("/timeval/add", test_timeval_add);
diff --git a/gnu/packages/patches/gnupg-simple-query-ignore-status-messages.patch b/gnu/packages/patches/gnupg-simple-query-ignore-status-messages.patch
deleted file mode 100644
index 153f71c38f..0000000000
--- a/gnu/packages/patches/gnupg-simple-query-ignore-status-messages.patch
+++ /dev/null
@@ -1,142 +0,0 @@
-Copied from upstream:
-http://git.gnupg.org/cgi-bin/gitweb.cgi?p=gnupg.git;a=commitdiff;h=acac103ba5772ae738ce5409d17feab80596cde6
-
-Fixes: https://debbugs.gnu.org/22558
-Upstream bug: https://bugs.gnupg.org/gnupg/issue2229
-
-From acac103ba5772ae738ce5409d17feab80596cde6 Mon Sep 17 00:00:00 2001
-From: "Neal H. Walfield" <neal@g10code.com>
-Date: Fri, 12 Feb 2016 22:12:21 +0100
-Subject: [PATCH] common: Change simple_query to ignore status messages.
-
-* common/simple-pwquery.c (simple_query): Ignore status messages.
-
---
-Signed-off-by: Neal H. Walfield <neal@g10code.com>
-GnuPG-bug-id: 2229
----
- common/simple-pwquery.c | 95 ++++++++++++++++++++++++++++++++++---------------
- 1 file changed, 67 insertions(+), 28 deletions(-)
-
-diff --git a/common/simple-pwquery.c b/common/simple-pwquery.c
-index 90d04c0..b2d666c 100644
---- a/common/simple-pwquery.c
-+++ b/common/simple-pwquery.c
-@@ -618,6 +618,7 @@ simple_query (const char *query)
-   int fd = -1;
-   int nread;
-   char response[500];
-+  int have = 0;
-   int rc;
- 
-   rc = agent_open (&fd);
-@@ -628,40 +629,78 @@ simple_query (const char *query)
-   if (rc)
-     goto leave;
- 
--  /* get response */
--  nread = readline (fd, response, 499);
--  if (nread < 0)
--    {
--      rc = -nread;
--      goto leave;
--    }
--  if (nread < 3)
-+  while (1)
-     {
--      rc = SPWQ_PROTOCOL_ERROR;
--      goto leave;
--    }
-+      if (! have || ! strchr (response, '\n'))
-+        /* get response */
-+        {
-+          nread = readline (fd, &response[have],
-+                            sizeof (response) - 1 /* NUL */ - have);
-+          if (nread < 0)
-+            {
-+              rc = -nread;
-+              goto leave;
-+            }
-+          have += nread;
-+          if (have < 3)
-+            {
-+              rc = SPWQ_PROTOCOL_ERROR;
-+              goto leave;
-+            }
-+          response[have] = 0;
-+        }
- 
--  if (response[0] == 'O' && response[1] == 'K')
--    /* OK, do nothing.  */;
--  else if ((nread > 7 && !memcmp (response, "ERR 111", 7)
--            && (response[7] == ' ' || response[7] == '\n') )
--           || ((nread > 4 && !memcmp (response, "ERR ", 4)
--                && (strtoul (response+4, NULL, 0) & 0xffff) == 99)) )
--    {
--      /* 111 is the old Assuan code for canceled which might still
--         be in use by old installations. 99 is GPG_ERR_CANCELED as
--         used by modern gpg-agents; 0xffff is used to mask out the
--         error source.  */
-+      if (response[0] == 'O' && response[1] == 'K')
-+        /* OK, do nothing.  */;
-+      else if ((nread > 7 && !memcmp (response, "ERR 111", 7)
-+                && (response[7] == ' ' || response[7] == '\n') )
-+               || ((nread > 4 && !memcmp (response, "ERR ", 4)
-+                    && (strtoul (response+4, NULL, 0) & 0xffff) == 99)) )
-+        {
-+          /* 111 is the old Assuan code for canceled which might still
-+             be in use by old installations. 99 is GPG_ERR_CANCELED as
-+             used by modern gpg-agents; 0xffff is used to mask out the
-+             error source.  */
- #ifdef SPWQ_USE_LOGGING
--      log_info (_("canceled by user\n") );
-+          log_info (_("canceled by user\n") );
- #endif
--    }
--  else
--    {
-+        }
-+      else if (response[0] == 'S' && response[1] == ' ')
-+        {
-+          char *nextline;
-+          int consumed;
-+
-+          nextline = strchr (response, '\n');
-+          if (! nextline)
-+            /* Point to the NUL.  */
-+            nextline = &response[have];
-+          else
-+            /* Move past the \n.  */
-+            nextline ++;
-+
-+          consumed = (size_t) nextline - (size_t) response;
-+
-+          /* Skip any additional newlines.  */
-+          while (consumed < have && response[consumed] == '\n')
-+            consumed ++;
-+
-+          have -= consumed;
-+
-+          if (have)
-+            memmove (response, &response[consumed], have + 1);
-+
-+          continue;
-+        }
-+      else
-+        {
- #ifdef SPWQ_USE_LOGGING
--      log_error (_("problem with the agent\n"));
-+          log_error (_("problem with the agent (unexpected response \"%s\"\n"),
-+                     response);
- #endif
--      rc = SPWQ_ERR_RESPONSE;
-+          rc = SPWQ_ERR_RESPONSE;
-+        }
-+
-+      break;
-     }
- 
-  leave:
--- 
-2.6.3
-
diff --git a/gnu/packages/patches/gtk2-theme-paths.patch b/gnu/packages/patches/gtk2-theme-paths.patch
new file mode 100644
index 0000000000..6c1351e516
--- /dev/null
+++ b/gnu/packages/patches/gtk2-theme-paths.patch
@@ -0,0 +1,41 @@
+From: Jookia <166291@gmail.com>
+Subject: [PATCHv2] gtk: Patch GTK+ to look for themes in profiles.
+To: guix-devel@gnu.org
+Date: Sun, 13 Mar 2016 15:17:37 +1100
+Url: https://lists.gnu.org/archive/html/guix-devel/2016-03/msg00492.html
+
+diff -Naur gtk+-2.24.28.new/gtk/gtkrc.c gtk+-2.24.28/gtk/gtkrc.c
+--- gtk+-2.24.28.new/gtk/gtkrc.c	2016-03-13 10:31:14.413644362 +1100
++++ gtk+-2.24.28/gtk/gtkrc.c	2016-03-13 12:51:34.723398423 +1100
+@@ -808,6 +808,8 @@
+   gchar *path = NULL;
+   const gchar *home_dir;
+   gchar *subpath;
++  const gchar * const *xdg_data_dirs;
++  gint i;
+ 
+   if (type)
+     subpath = g_strconcat ("gtk-2.0-", type,
+@@ -830,6 +832,22 @@
+     }
+ 
+   if (!path)
++    {
++      xdg_data_dirs = g_get_system_data_dirs ();
++      for (i = 0; xdg_data_dirs[i]; i++)
++        {
++          path = g_build_filename (xdg_data_dirs[i], "themes", name, subpath, NULL);
++          if (g_file_test (path, G_FILE_TEST_EXISTS))
++            break;
++          else
++            {
++              g_free (path);
++              path = NULL;
++            }
++        }
++    }
++
++  if (!path)
+     {
+       gchar *theme_dir = gtk_rc_get_theme_dir ();
+       path = g_build_filename (theme_dir, name, subpath, NULL);
diff --git a/gnu/packages/patches/hdf5-config-date.patch b/gnu/packages/patches/hdf5-config-date.patch
new file mode 100644
index 0000000000..c105435dc2
--- /dev/null
+++ b/gnu/packages/patches/hdf5-config-date.patch
@@ -0,0 +1,21 @@
+Honor SOURCE_DATE_EPOCH when exporting configuration date.
+Autoconf-level patch submitted upstream on Wed Apr 13 17:03:23 UTC 2016
+
+--- a/configure
++++ b/configure
+@@ -27737,7 +28573,14 @@
+ 
+ 
+ ## Configuration date
+- CONFIG_DATE="`date`"
++ CONFIG_DATE="`date -u`"
++if test -n "$SOURCE_DATE_EPOCH"; then
++  CONFIG_DATE=`date -u -d "@$SOURCE_DATE_EPOCH" 2>/dev/null \
++               || date -u -r "$SOURCE_DATE_EPOCH" 2>/dev/null`
++  if test -z "$CONFIG_DATE"; then
++    as_fn_error $? "malformed SOURCE_DATE_EPOCH" "$LINENO" 5
++  fi
++fi
+ 
+ ## User doing the configuration
+  CONFIG_USER="`whoami`@`hostname`"
diff --git a/gnu/packages/patches/hypre-doc-tables.patch b/gnu/packages/patches/hypre-doc-tables.patch
new file mode 100644
index 0000000000..6a852ee78e
--- /dev/null
+++ b/gnu/packages/patches/hypre-doc-tables.patch
@@ -0,0 +1,25 @@
+Fixes doc++'s treatment of tabular within a parameter block.
+
+From commit 883925f8a at http://github.com/LLNL/hypre
+
+--- hypre-2.10.1/src/parcsr_ls/HYPRE_parcsr_ls.h	2015-12-04 22:12:19.000000000 -0600
++++ hypre-2.10.1/src/parcsr_ls/HYPRE_parcsr_ls.h	2016-03-16 09:02:58.547501336 -0500
+@@ -1154,8 +1154,6 @@
+  * Set the symmetry parameter for the
+  * ParaSails preconditioner.
+  *
+- * @param solver [IN] Preconditioner object for which to set symmetry parameter.
+- * @param sym [IN] Value of the symmetry parameter:
+  * \begin{tabular}{|c|l|} \hline 
+  * value & meaning \\ \hline 
+  * 0 & nonsymmetric and/or indefinite problem, and nonsymmetric preconditioner\\
+@@ -1163,6 +1161,9 @@
+  * 2 & nonsymmetric, definite problem, and SPD (factored) preconditioner \\
+  * \hline
+  * \end{tabular}
++ * 
++ * @param solver [IN] Preconditioner object for which to set symmetry parameter.
++ * @param sym [IN] Value of the symmetry parameter:
+  **/
+ HYPRE_Int HYPRE_ParaSailsSetSym(HYPRE_Solver solver,
+                                 HYPRE_Int    sym);
diff --git a/gnu/packages/patches/hypre-ldflags.patch b/gnu/packages/patches/hypre-ldflags.patch
new file mode 100644
index 0000000000..a94fafa463
--- /dev/null
+++ b/gnu/packages/patches/hypre-ldflags.patch
@@ -0,0 +1,9 @@
+--- hypre-2.10.1/src/lib/Makefile.orig	2016-03-11 16:04:03.740259228 -0600
++++ hypre-2.10.1/src/lib/Makefile	2016-03-11 16:04:57.296260190 -0600
+@@ -107,5 +107,5 @@
+ 
+ libHYPRE.so: ${FILES_HYPRE}
+ 	@echo  "Building $@ ... "
+-	${BUILD_CC_SHARED} -o ${SONAME} ${FILES_HYPRE} ${SOLIBS} ${SHARED_SET_SONAME}${SONAME} ${SHARED_OPTIONS}
++	${BUILD_CC_SHARED} ${LDFLAGS} -o ${SONAME} ${FILES_HYPRE} ${SOLIBS} ${SHARED_SET_SONAME}${SONAME} ${SHARED_OPTIONS}
+ 	ln -s ${SONAME} $@
diff --git a/gnu/packages/patches/icecat-CVE-2016-2805.patch b/gnu/packages/patches/icecat-CVE-2016-2805.patch
deleted file mode 100644
index 5e4150f00c..0000000000
--- a/gnu/packages/patches/icecat-CVE-2016-2805.patch
+++ /dev/null
@@ -1,75 +0,0 @@
-Copied from https://hg.mozilla.org/releases/mozilla-esr38/raw-rev/bf34b97757b3
-
-# HG changeset patch
-# User Jon Coppeard <jcoppeard@mozilla.com>
-# Date 1453890675 0
-# Node ID bf34b97757b334af1f9f53b9b59e0b6902e7ed6f
-# Parent  228ca3f46cabaf3f388f6c6640690772aa13c1a5
-Bug 1241731 - Handle incomplete buffer in DiscardTransferables r=sfink a=abillings a=sylvestre
-
-diff --git a/js/src/jit-test/tests/gc/bug-1241731.js b/js/src/jit-test/tests/gc/bug-1241731.js
-new file mode 100644
---- /dev/null
-+++ b/js/src/jit-test/tests/gc/bug-1241731.js
-@@ -0,0 +1,4 @@
-+if (!('oomTest' in this))
-+    quit();
-+
-+oomTest(() => serialize(0, [{}]));
-diff --git a/js/src/vm/StructuredClone.cpp b/js/src/vm/StructuredClone.cpp
---- a/js/src/vm/StructuredClone.cpp
-+++ b/js/src/vm/StructuredClone.cpp
-@@ -379,39 +379,50 @@ ReadStructuredClone(JSContext* cx, uint6
- 
- // If the given buffer contains Transferables, free them. Note that custom
- // Transferables will use the JSStructuredCloneCallbacks::freeTransfer() to
- // delete their transferables.
- static void
- Discard(uint64_t* buffer, size_t nbytes, const JSStructuredCloneCallbacks* cb, void* cbClosure)
- {
-     MOZ_ASSERT(nbytes % sizeof(uint64_t) == 0);
--    if (nbytes < sizeof(uint64_t))
-+    uint64_t* end = buffer + nbytes / sizeof(uint64_t);
-+    uint64_t* point = buffer;
-+    if (point == end)
-         return; // Empty buffer
- 
--    uint64_t* point = buffer;
-     uint32_t tag, data;
-     SCInput::getPair(point++, &tag, &data);
-     if (tag != SCTAG_TRANSFER_MAP_HEADER)
-         return;
- 
-     if (TransferableMapHeader(data) == SCTAG_TM_TRANSFERRED)
-         return;
- 
-     // freeTransfer should not GC
-     JS::AutoSuppressGCAnalysis nogc;
- 
-+    if (point == end)
-+        return;
-+
-     uint64_t numTransferables = LittleEndian::readUint64(point++);
-     while (numTransferables--) {
-+        if (point == end)
-+            return;
-+
-         uint32_t ownership;
-         SCInput::getPair(point++, &tag, &ownership);
-         MOZ_ASSERT(tag >= SCTAG_TRANSFER_MAP_PENDING_ENTRY);
-+        if (point == end)
-+            return;
- 
-         void* content;
-         SCInput::getPtr(point++, &content);
-+        if (point == end)
-+            return;
- 
-         uint64_t extraData = LittleEndian::readUint64(point++);
- 
-         if (ownership < JS::SCTAG_TMO_FIRST_OWNED)
-             continue;
- 
-         if (ownership == JS::SCTAG_TMO_ALLOC_DATA) {
-             js_free(content);
-
diff --git a/gnu/packages/patches/icecat-CVE-2016-2807-pt1.patch b/gnu/packages/patches/icecat-CVE-2016-2807-pt1.patch
deleted file mode 100644
index 0a6bee378b..0000000000
--- a/gnu/packages/patches/icecat-CVE-2016-2807-pt1.patch
+++ /dev/null
@@ -1,35 +0,0 @@
-Copied from https://hg.mozilla.org/releases/mozilla-esr38/raw-rev/e7c23c08bf84
-
-# HG changeset patch
-# User Randell Jesup <rjesup@jesup.org>
-# Date 1458543433 14400
-# Node ID e7c23c08bf84a02d9154f31e0c5d121a45884a69
-# Parent  a6de1f453712edabff597879398606708c191098
-Bug 1254876: assert windows recording is shut down r=pkerr a=ritu
-
-MozReview-Commit-ID: JRqxBb5TgrE
-
-diff --git a/media/webrtc/trunk/webrtc/modules/audio_device/win/audio_device_core_win.cc b/media/webrtc/trunk/webrtc/modules/audio_device/win/audio_device_core_win.cc
---- a/media/webrtc/trunk/webrtc/modules/audio_device/win/audio_device_core_win.cc
-+++ b/media/webrtc/trunk/webrtc/modules/audio_device/win/audio_device_core_win.cc
-@@ -567,16 +567,19 @@ AudioDeviceWindowsCore::AudioDeviceWindo
- // ----------------------------------------------------------------------------
- 
- AudioDeviceWindowsCore::~AudioDeviceWindowsCore()
- {
-     WEBRTC_TRACE(kTraceMemory, kTraceAudioDevice, _id, "%s destroyed", __FUNCTION__);
- 
-     Terminate();
- 
-+    // Recording thread should be shut down before this!
-+    assert(_hRecThread == NULL);
-+
-     // The IMMDeviceEnumerator is created during construction. Must release
-     // it here and not in Terminate() since we don't recreate it in Init().
-     SAFE_RELEASE(_ptrEnumerator);
- 
-     _ptrAudioBuffer = NULL;
- 
-     if (NULL != _hRenderSamplesReadyEvent)
-     {
-
diff --git a/gnu/packages/patches/icecat-CVE-2016-2807-pt2.patch b/gnu/packages/patches/icecat-CVE-2016-2807-pt2.patch
deleted file mode 100644
index f4b4c0d4eb..0000000000
--- a/gnu/packages/patches/icecat-CVE-2016-2807-pt2.patch
+++ /dev/null
@@ -1,69 +0,0 @@
-Copied from https://hg.mozilla.org/releases/mozilla-esr38/raw-rev/3d2b62083a6a
-
-# HG changeset patch
-# User Shu-yu Guo <shu@rfrn.org>
-# Date 1459741387 -7200
-# Node ID 3d2b62083a6a4fb43cb330d77142f9dce0959a23
-# Parent  9d4364f6b55c6ee65c13c491292c3abe1ee2c993
-Bug 1254164 - Make aliasedBodyLevelLexicalBegin a uint32. r=Waldo, a=ritu
-
-diff --git a/js/src/jit-test/tests/parser/bug-1254164.js b/js/src/jit-test/tests/parser/bug-1254164.js
-new file mode 100644
---- /dev/null
-+++ b/js/src/jit-test/tests/parser/bug-1254164.js
-@@ -0,0 +1,6 @@
-+// |jit-test| slow;
-+
-+var s = '';
-+for (var i = 0; i < 70000; i++)
-+    s += 'function x' + i + '() { x' + i + '(); }\n';
-+eval("(function() { " + s + " })();");
-diff --git a/js/src/jsscript.cpp b/js/src/jsscript.cpp
---- a/js/src/jsscript.cpp
-+++ b/js/src/jsscript.cpp
-@@ -111,17 +111,20 @@ Bindings::initWithTemporaryStorage(Exclu
-     // JITs when interpreting/compiling aliasedvar ops.)
- 
-     // Since unaliased variables are, by definition, only accessed by local
-     // operations and never through the scope chain, only give shapes to
-     // aliased variables. While the debugger may observe any scope object at
-     // any time, such accesses are mediated by DebugScopeProxy (see
-     // DebugScopeProxy::handleUnaliasedAccess).
-     uint32_t nslots = CallObject::RESERVED_SLOTS;
--    uint32_t aliasedBodyLevelLexicalBegin = UINT16_MAX;
-+
-+    // Unless there are aliased body-level lexical bindings at all, set the
-+    // begin index to an impossible slot number.
-+    uint32_t aliasedBodyLevelLexicalBegin = LOCALNO_LIMIT;
-     for (BindingIter bi(self); bi; bi++) {
-         if (bi->aliased()) {
-             // Per ES6, lexical bindings cannot be accessed until
-             // initialized. Remember the first aliased slot that is a
-             // body-level lexical, so that they may be initialized to sentinel
-             // magic values.
-             if (numBodyLevelLexicals > 0 &&
-                 nslots < aliasedBodyLevelLexicalBegin &&
-diff --git a/js/src/jsscript.h b/js/src/jsscript.h
---- a/js/src/jsscript.h
-+++ b/js/src/jsscript.h
-@@ -201,18 +201,18 @@ class Bindings
-     friend class BindingIter;
-     friend class AliasedFormalIter;
- 
-     RelocatablePtrShape callObjShape_;
-     uintptr_t bindingArrayAndFlag_;
-     uint16_t numArgs_;
-     uint16_t numBlockScoped_;
-     uint16_t numBodyLevelLexicals_;
--    uint16_t aliasedBodyLevelLexicalBegin_;
-     uint16_t numUnaliasedBodyLevelLexicals_;
-+    uint32_t aliasedBodyLevelLexicalBegin_;
-     uint32_t numVars_;
-     uint32_t numUnaliasedVars_;
- 
- #if JS_BITS_PER_WORD == 32
-     // Bindings is allocated inline inside JSScript, which needs to be
-     // gc::Cell aligned.
-     uint32_t padding_;
- #endif
-
diff --git a/gnu/packages/patches/icecat-CVE-2016-2807-pt3.patch b/gnu/packages/patches/icecat-CVE-2016-2807-pt3.patch
deleted file mode 100644
index a5a4212c28..0000000000
--- a/gnu/packages/patches/icecat-CVE-2016-2807-pt3.patch
+++ /dev/null
@@ -1,33 +0,0 @@
-Copied from https://hg.mozilla.org/releases/mozilla-esr38/raw-rev/88f1eb2c3f4b
-
-# HG changeset patch
-# User Timothy Nikkel <tnikkel@gmail.com>
-# Date 1457637807 21600
-# Node ID 88f1eb2c3f4b4b57365ed88223cf8adc2bec4610
-# Parent  bf34b97757b334af1f9f53b9b59e0b6902e7ed6f
-Bug 1187420. r=drc r=jmuizelaar a=sylvestre
-
-MozReview-Commit-ID: Hh0Khqfj8Bf
-
-diff --git a/media/libjpeg/jstdhuff.c b/media/libjpeg/jstdhuff.c
---- a/media/libjpeg/jstdhuff.c
-+++ b/media/libjpeg/jstdhuff.c
-@@ -36,16 +36,17 @@ add_huff_table (j_common_ptr cinfo,
-    */
-   nsymbols = 0;
-   for (len = 1; len <= 16; len++)
-     nsymbols += bits[len];
-   if (nsymbols < 1 || nsymbols > 256)
-     ERREXIT(cinfo, JERR_BAD_HUFF_TABLE);
- 
-   MEMCOPY((*htblptr)->huffval, val, nsymbols * sizeof(UINT8));
-+  MEMZERO(&((*htblptr)->huffval[nsymbols]), (256 - nsymbols) * sizeof(UINT8));
- 
-   /* Initialize sent_table FALSE so table will be written to JPEG file. */
-   (*htblptr)->sent_table = FALSE;
- }
- 
- 
- LOCAL(void)
- std_huff_tables (j_common_ptr cinfo)
-
diff --git a/gnu/packages/patches/icecat-CVE-2016-2807-pt4.patch b/gnu/packages/patches/icecat-CVE-2016-2807-pt4.patch
deleted file mode 100644
index 5eff4fe99c..0000000000
--- a/gnu/packages/patches/icecat-CVE-2016-2807-pt4.patch
+++ /dev/null
@@ -1,37 +0,0 @@
-Copied from https://hg.mozilla.org/releases/mozilla-esr38/raw-rev/5c312182da90
-
-# HG changeset patch
-# User Jan de Mooij <jdemooij@mozilla.com>
-# Date 1458828581 -3600
-# Node ID 5c312182da9020504103aa329360abaffa7e232d
-# Parent  fa4efccde9b7efde8763a178a6cf422b6d37a0e9
-Bug 1254622 - Relookup group->newScript in CreateThisForFunctionWithGroup. r=bhackett a=sylvestre
-
-MozReview-Commit-ID: KXd7kB70f1Z
-
-diff --git a/js/src/jsobj.cpp b/js/src/jsobj.cpp
---- a/js/src/jsobj.cpp
-+++ b/js/src/jsobj.cpp
-@@ -1574,18 +1574,19 @@ CreateThisForFunctionWithGroup(JSContext
-         // Not enough objects with this group have been created yet, so make a
-         // plain object and register it with the group. Use the maximum number
-         // of fixed slots, as is also required by the TypeNewScript.
-         gc::AllocKind allocKind = GuessObjectGCKind(NativeObject::MAX_FIXED_SLOTS);
-         PlainObject* res = NewObjectWithGroup<PlainObject>(cx, group, parent, allocKind, newKind);
-         if (!res)
-             return nullptr;
- 
--        if (newKind != SingletonObject)
--            newScript->registerNewObject(res);
-+        // Make sure group->newScript is still there.
-+        if (newKind != SingletonObject && group->newScript())
-+            group->newScript()->registerNewObject(res);
- 
-         return res;
-     }
- 
-     gc::AllocKind allocKind = NewObjectGCKind(&PlainObject::class_);
- 
-     if (newKind == SingletonObject) {
-         Rooted<TaggedProto> protoRoot(cx, group->proto());
-
diff --git a/gnu/packages/patches/icecat-CVE-2016-2807-pt5.patch b/gnu/packages/patches/icecat-CVE-2016-2807-pt5.patch
deleted file mode 100644
index 00718ebaac..0000000000
--- a/gnu/packages/patches/icecat-CVE-2016-2807-pt5.patch
+++ /dev/null
@@ -1,35 +0,0 @@
-Copied from https://hg.mozilla.org/releases/mozilla-esr38/raw-rev/3fdd280fa099
-
-# HG changeset patch
-# User Carsten "Tomcat" Book <cbook@mozilla.com>
-# Date 1461123938 -7200
-# Node ID 3fdd280fa099b6453ce9fd9905af883bc2ebce24
-# Parent  52dfdd37150d62f708dc5bf61dd28f3967596788
-Bug 1252707 - a=sylvestre
-
-diff --git a/js/src/vm/Shape.cpp b/js/src/vm/Shape.cpp
---- a/js/src/vm/Shape.cpp
-+++ b/js/src/vm/Shape.cpp
-@@ -382,18 +382,20 @@ NativeObject::getChildPropertyOnDictiona
- 
-     if (obj->inDictionaryMode()) {
-         MOZ_ASSERT(parent == obj->lastProperty());
-         RootedGeneric<StackShape*> childRoot(cx, &child);
-         shape = childRoot->isAccessorShape() ? NewGCAccessorShape(cx) : NewGCShape(cx);
-         if (!shape)
-             return nullptr;
-         if (childRoot->hasSlot() && childRoot->slot() >= obj->lastProperty()->base()->slotSpan()) {
--            if (!obj->setSlotSpan(cx, childRoot->slot() + 1))
-+            if (!obj->setSlotSpan(cx, childRoot->slot() + 1)) {
-+                new (shape) Shape(obj->lastProperty()->base()->unowned(), 0);
-                 return nullptr;
-+            }
-         }
-         shape->initDictionaryShape(*childRoot, obj->numFixedSlots(), &obj->shape_);
-     }
- 
-     return shape;
- }
- 
- /* static */ Shape*
-
diff --git a/gnu/packages/patches/icecat-CVE-2016-2808.patch b/gnu/packages/patches/icecat-CVE-2016-2808.patch
deleted file mode 100644
index ae190b8b4c..0000000000
--- a/gnu/packages/patches/icecat-CVE-2016-2808.patch
+++ /dev/null
@@ -1,389 +0,0 @@
-Copied from https://hg.mozilla.org/releases/mozilla-esr38/raw-rev/71f611fd27c7
-
-# HG changeset patch
-# User Jeff Walden <jwalden@mit.edu>
-# Date 1458941573 25200
-# Node ID 71f611fd27c7d6cb7d6dab9895c2922948042543
-# Parent  861f6b83ce1deade2a976cabe059776ad51ce370
-Bug 1246061.  r=luke, r=froydnj, a=sylvestre
-
-diff --git a/js/public/HashTable.h b/js/public/HashTable.h
---- a/js/public/HashTable.h
-+++ b/js/public/HashTable.h
-@@ -8,16 +8,17 @@
- #define js_HashTable_h
- 
- #include "mozilla/Alignment.h"
- #include "mozilla/Assertions.h"
- #include "mozilla/Attributes.h"
- #include "mozilla/Casting.h"
- #include "mozilla/MemoryReporting.h"
- #include "mozilla/Move.h"
-+#include "mozilla/Opaque.h"
- #include "mozilla/PodOperations.h"
- #include "mozilla/ReentrancyGuard.h"
- #include "mozilla/TemplateLib.h"
- #include "mozilla/TypeTraits.h"
- 
- #include "js/Utility.h"
- 
- namespace js {
-@@ -27,16 +28,18 @@ template <class> struct DefaultHasher;
- template <class, class> class HashMapEntry;
- namespace detail {
-     template <class T> class HashTableEntry;
-     template <class T, class HashPolicy, class AllocPolicy> class HashTable;
- }
- 
- /*****************************************************************************/
- 
-+using Generation = mozilla::Opaque<uint64_t>;
-+
- // A JS-friendly, STL-like container providing a hash-based map from keys to
- // values. In particular, HashMap calls constructors and destructors of all
- // objects added so non-PODs may be used safely.
- //
- // Key/Value requirements:
- //  - movable, destructible, assignable
- // HashPolicy requirements:
- //  - see Hash Policy section below
-@@ -200,17 +203,19 @@ class HashMap
-         return impl.sizeOfExcludingThis(mallocSizeOf);
-     }
-     size_t sizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const {
-         return mallocSizeOf(this) + impl.sizeOfExcludingThis(mallocSizeOf);
-     }
- 
-     // If |generation()| is the same before and after a HashMap operation,
-     // pointers into the table remain valid.
--    uint32_t generation() const                       { return impl.generation(); }
-+    Generation generation() const {
-+        return impl.generation();
-+    }
- 
-     /************************************************** Shorthand operations */
- 
-     bool has(const Lookup& l) const {
-         return impl.lookup(l).found();
-     }
- 
-     // Overwrite existing value with v. Return false on oom.
-@@ -431,17 +436,19 @@ class HashSet
-         return impl.sizeOfExcludingThis(mallocSizeOf);
-     }
-     size_t sizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const {
-         return mallocSizeOf(this) + impl.sizeOfExcludingThis(mallocSizeOf);
-     }
- 
-     // If |generation()| is the same before and after a HashSet operation,
-     // pointers into the table remain valid.
--    uint32_t generation() const                       { return impl.generation(); }
-+    Generation generation() const {
-+        return impl.generation();
-+    }
- 
-     /************************************************** Shorthand operations */
- 
-     bool has(const Lookup& l) const {
-         return impl.lookup(l).found();
-     }
- 
-     // Add |u| if it is not present already. Return false on oom.
-@@ -766,17 +773,17 @@ class HashTable : private AllocPolicy
-     // table operations unless |generation()| is tested.
-     class Ptr
-     {
-         friend class HashTable;
- 
-         Entry* entry_;
- #ifdef JS_DEBUG
-         const HashTable* table_;
--        uint32_t generation;
-+        Generation generation;
- #endif
- 
-       protected:
-         Ptr(Entry& entry, const HashTable& tableArg)
-           : entry_(&entry)
- #ifdef JS_DEBUG
-           , table_(&tableArg)
-           , generation(tableArg.generation())
-@@ -873,17 +880,17 @@ class HashTable : private AllocPolicy
-             while (cur < end && !cur->isLive())
-                 ++cur;
-         }
- 
-         Entry* cur, *end;
- #ifdef JS_DEBUG
-         const HashTable* table_;
-         uint64_t mutationCount;
--        uint32_t generation;
-+        Generation generation;
-         bool validEntry;
- #endif
- 
-       public:
-         Range()
-           : cur(nullptr)
-           , end(nullptr)
- #ifdef JS_DEBUG
-@@ -1012,18 +1019,18 @@ class HashTable : private AllocPolicy
-     // HashTable is not copyable or assignable
-     HashTable(const HashTable&) = delete;
-     void operator=(const HashTable&) = delete;
- 
-   private:
-     static const size_t CAP_BITS = 24;
- 
-   public:
--    Entry*      table;                 // entry storage
--    uint32_t    gen;                    // entry storage generation number
-+    uint64_t    gen;                    // entry storage generation number
-+    Entry*      table;                  // entry storage
-     uint32_t    entryCount;             // number of entries in table
-     uint32_t    removedCount:CAP_BITS;  // removed entry sentinels in table
-     uint32_t    hashShift:8;            // multiplicative hash shift
- 
- #ifdef JS_DEBUG
-     uint64_t     mutationCount;
-     mutable bool mEntered;
-     mutable struct Stats
-@@ -1097,18 +1104,18 @@ class HashTable : private AllocPolicy
-         for (Entry* e = oldTable, *end = e + capacity; e < end; ++e)
-             e->destroyIfLive();
-         alloc.free_(oldTable);
-     }
- 
-   public:
-     explicit HashTable(AllocPolicy ap)
-       : AllocPolicy(ap)
-+      , gen(0)
-       , table(nullptr)
--      , gen(0)
-       , entryCount(0)
-       , removedCount(0)
-       , hashShift(sHashBits)
- #ifdef JS_DEBUG
-       , mutationCount(0)
-       , mEntered(false)
- #endif
-     {}
-@@ -1524,20 +1531,20 @@ class HashTable : private AllocPolicy
-     }
- 
-     uint32_t capacity() const
-     {
-         MOZ_ASSERT(table);
-         return JS_BIT(sHashBits - hashShift);
-     }
- 
--    uint32_t generation() const
-+    Generation generation() const
-     {
-         MOZ_ASSERT(table);
--        return gen;
-+        return Generation(gen);
-     }
- 
-     size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const
-     {
-         return mallocSizeOf(table);
-     }
- 
-     size_t sizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const
-diff --git a/js/src/jsapi.h b/js/src/jsapi.h
---- a/js/src/jsapi.h
-+++ b/js/src/jsapi.h
-@@ -270,20 +270,16 @@ class AutoHashMapRooter : protected Auto
- 
-     size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const {
-         return map.sizeOfExcludingThis(mallocSizeOf);
-     }
-     size_t sizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const {
-         return map.sizeOfIncludingThis(mallocSizeOf);
-     }
- 
--    uint32_t generation() const {
--        return map.generation();
--    }
--
-     /************************************************** Shorthand operations */
- 
-     bool has(const Lookup& l) const {
-         return map.has(l);
-     }
- 
-     template<typename KeyInput, typename ValueInput>
-     bool put(const KeyInput& k, const ValueInput& v) {
-@@ -385,20 +381,16 @@ class AutoHashSetRooter : protected Auto
- 
-     size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const {
-         return set.sizeOfExcludingThis(mallocSizeOf);
-     }
-     size_t sizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const {
-         return set.sizeOfIncludingThis(mallocSizeOf);
-     }
- 
--    uint32_t generation() const {
--        return set.generation();
--    }
--
-     /************************************************** Shorthand operations */
- 
-     bool has(const Lookup& l) const {
-         return set.has(l);
-     }
- 
-     bool put(const T& t) {
-         return set.put(t);
-diff --git a/js/src/jscntxt.h b/js/src/jscntxt.h
---- a/js/src/jscntxt.h
-+++ b/js/src/jscntxt.h
-@@ -30,21 +30,21 @@ class DebugModeOSRVolatileJitFrameIterat
- }
- 
- typedef HashSet<JSObject*> ObjectSet;
- typedef HashSet<Shape*> ShapeSet;
- 
- /* Detects cycles when traversing an object graph. */
- class AutoCycleDetector
- {
-+    Generation hashsetGenerationAtInit;
-     JSContext* cx;
-     RootedObject obj;
-+    ObjectSet::AddPtr hashsetAddPointer;
-     bool cyclic;
--    uint32_t hashsetGenerationAtInit;
--    ObjectSet::AddPtr hashsetAddPointer;
-     MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
- 
-   public:
-     AutoCycleDetector(JSContext* cx, HandleObject objArg
-                       MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
-       : cx(cx), obj(cx, objArg), cyclic(true)
-     {
-         MOZ_GUARD_OBJECT_NOTIFIER_INIT;
-diff --git a/js/src/jswatchpoint.cpp b/js/src/jswatchpoint.cpp
---- a/js/src/jswatchpoint.cpp
-+++ b/js/src/jswatchpoint.cpp
-@@ -22,25 +22,25 @@ DefaultHasher<WatchKey>::hash(const Look
- {
-     return DefaultHasher<JSObject*>::hash(key.object.get()) ^ HashId(key.id.get());
- }
- 
- namespace {
- 
- class AutoEntryHolder {
-     typedef WatchpointMap::Map Map;
-+    Generation gen;
-     Map& map;
-     Map::Ptr p;
--    uint32_t gen;
-     RootedObject obj;
-     RootedId id;
- 
-   public:
-     AutoEntryHolder(JSContext* cx, Map& map, Map::Ptr p)
--      : map(map), p(p), gen(map.generation()), obj(cx, p->key().object), id(cx, p->key().id)
-+      : gen(map.generation()), map(map), p(p), obj(cx, p->key().object), id(cx, p->key().id)
-     {
-         MOZ_ASSERT(!p->value().held);
-         p->value().held = true;
-     }
- 
-     ~AutoEntryHolder() {
-         if (gen != map.generation())
-             p = map.lookup(WatchKey(obj, id));
-diff --git a/js/src/shell/jsheaptools.cpp b/js/src/shell/jsheaptools.cpp
---- a/js/src/shell/jsheaptools.cpp
-+++ b/js/src/shell/jsheaptools.cpp
-@@ -267,17 +267,17 @@ HeapReverser::traverseEdge(void* cell, J
-     Map::AddPtr a = map.lookupForAdd(cell);
-     if (!a) {
-         /*
-          * We've never visited this cell before. Add it to the map (thus
-          * marking it as visited), and put it on the work stack, to be
-          * visited from the main loop.
-          */
-         Node n(kind);
--        uint32_t generation = map.generation();
-+        Generation generation = map.generation();
-         if (!map.add(a, cell, Move(n)) ||
-             !work.append(Child(cell, kind)))
-             return false;
-         /* If the map has been resized, re-check the pointer. */
-         if (map.generation() != generation)
-             a = map.lookupForAdd(cell);
-     }
- 
-diff --git a/mfbt/Opaque.h b/mfbt/Opaque.h
-new file mode 100644
---- /dev/null
-+++ b/mfbt/Opaque.h
-@@ -0,0 +1,44 @@
-+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
-+/* 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/. */
-+
-+/* An opaque integral type supporting only comparison operators. */
-+
-+#ifndef mozilla_Opaque_h
-+#define mozilla_Opaque_h
-+
-+#include "mozilla/TypeTraits.h"
-+
-+namespace mozilla {
-+
-+/**
-+ * Opaque<T> is a replacement for integral T in cases where only comparisons
-+ * must be supported, and it's desirable to prevent accidental dependency on
-+ * exact values.
-+ */
-+template<typename T>
-+class Opaque final
-+{
-+  static_assert(mozilla::IsIntegral<T>::value,
-+                "mozilla::Opaque only supports integral types");
-+
-+  T mValue;
-+
-+public:
-+  Opaque() {}
-+  explicit Opaque(T aValue) : mValue(aValue) {}
-+
-+  bool operator==(const Opaque& aOther) const {
-+    return mValue == aOther.mValue;
-+  }
-+
-+  bool operator!=(const Opaque& aOther) const {
-+    return !(*this == aOther);
-+  }
-+};
-+
-+} // namespace mozilla
-+
-+#endif /* mozilla_Opaque_h */
-diff --git a/mfbt/moz.build b/mfbt/moz.build
---- a/mfbt/moz.build
-+++ b/mfbt/moz.build
-@@ -48,16 +48,17 @@ EXPORTS.mozilla = [
-     'MathAlgorithms.h',
-     'Maybe.h',
-     'MaybeOneOf.h',
-     'MemoryChecking.h',
-     'MemoryReporting.h',
-     'Move.h',
-     'NullPtr.h',
-     'NumericLimits.h',
-+    'Opaque.h',
-     'Pair.h',
-     'PodOperations.h',
-     'Poison.h',
-     'Range.h',
-     'RangedPtr.h',
-     'RefCountType.h',
-     'ReentrancyGuard.h',
-     'RefPtr.h',
-
diff --git a/gnu/packages/patches/icecat-CVE-2016-2814.patch b/gnu/packages/patches/icecat-CVE-2016-2814.patch
deleted file mode 100644
index 5f197f25e6..0000000000
--- a/gnu/packages/patches/icecat-CVE-2016-2814.patch
+++ /dev/null
@@ -1,35 +0,0 @@
-
-# HG changeset patch
-# User Jean-Yves Avenard <jyavenard@mozilla.com>
-# Date 1460655260 25200
-# Node ID a13c0bc84d6eb132f4199f563fbe228d2d3b3a51
-# Parent  88f1eb2c3f4b4b57365ed88223cf8adc2bec4610
-Bug 1254721: Ensure consistency between Cenc offsets and sizes table. r=gerald a=sylvestre
-
-MozReview-Commit-ID: E1KbKIIBR87
-
-diff --git a/media/libstagefright/frameworks/av/media/libstagefright/SampleTable.cpp b/media/libstagefright/frameworks/av/media/libstagefright/SampleTable.cpp
---- a/media/libstagefright/frameworks/av/media/libstagefright/SampleTable.cpp
-+++ b/media/libstagefright/frameworks/av/media/libstagefright/SampleTable.cpp
-@@ -612,18 +612,18 @@ status_t
- SampleTable::parseSampleCencInfo() {
-     if ((!mCencDefaultSize && !mCencInfoCount) || mCencOffsets.isEmpty()) {
-         // We don't have all the cenc information we need yet. Quietly fail and
-         // hope we get the data we need later in the track header.
-         ALOGV("Got half of cenc saio/saiz pair. Deferring parse until we get the other half.");
-         return OK;
-     }
- 
--    if (!mCencSizes.isEmpty() && mCencOffsets.size() > 1 &&
--        mCencSizes.size() != mCencOffsets.size()) {
-+    if ((mCencOffsets.size() > 1 && mCencOffsets.size() < mCencInfoCount) ||
-+        (!mCencDefaultSize && mCencSizes.size() < mCencInfoCount)) {
-         return ERROR_MALFORMED;
-     }
- 
-     if (mCencInfoCount > kMAX_ALLOCATION / sizeof(SampleCencInfo)) {
-         // Avoid future OOM.
-         return ERROR_MALFORMED;
-     }
- 
-
diff --git a/gnu/packages/patches/icecat-re-enable-DHE-cipher-suites.patch b/gnu/packages/patches/icecat-re-enable-DHE-cipher-suites.patch
deleted file mode 100644
index 5c869bf510..0000000000
--- a/gnu/packages/patches/icecat-re-enable-DHE-cipher-suites.patch
+++ /dev/null
@@ -1,24 +0,0 @@
-Re-enable the DHE (Ephemeral Diffie-Hellman) cipher suites, which IceCat
-38.6.0 disabled by default to avoid the Logjam attack.  This issue was
-fixed in NSS version 3.19.1 by limiting the lower strength of supported
-DHE keys to use 1023 bit primes, so we can enable these cipher suites
-safely.  The DHE cipher suites are needed to allow IceCat to connect to
-many sites, including https://gnupg.org/.
-
-Patch by Mark H Weaver <mhw@netris.org>
-
---- icecat-38.6.0/browser/app/profile/icecat.js.orig	1969-12-31 19:00:00.000000000 -0500
-+++ icecat-38.6.0/browser/app/profile/icecat.js	2016-02-06 00:48:23.826170154 -0500
-@@ -2061,12 +2061,6 @@
- pref("security.ssl3.rsa_des_ede3_sha", false);
- pref("security.ssl3.ecdhe_ecdsa_rc4_128_sha", false);
- pref("security.ssl3.ecdhe_rsa_rc4_128_sha", false);
--// https://directory.fsf.org/wiki/Disable_DHE
--// Avoid logjam attack
--pref("security.ssl3.dhe_rsa_aes_128_sha", false);
--pref("security.ssl3.dhe_rsa_aes_256_sha", false);
--pref("security.ssl3.dhe_dss_aes_128_sha", false);
--pref("security.ssl3.dhe_rsa_des_ede3_sha", false);
- //Optional
- //Perfect forward secrecy
- // pref("security.ssl3.rsa_aes_256_sha", false);
diff --git a/gnu/packages/patches/icecat-update-bundled-graphite2.patch b/gnu/packages/patches/icecat-update-bundled-graphite2.patch
deleted file mode 100644
index c3ab920335..0000000000
--- a/gnu/packages/patches/icecat-update-bundled-graphite2.patch
+++ /dev/null
@@ -1,2488 +0,0 @@
-
-# HG changeset patch
-# User Jonathan Kew <jkew@mozilla.com>
-# Date 1460660890 -3600
-# Node ID 7330633d20ffb33941e41ea0666c4099b6e6d317
-# Parent  5c312182da9020504103aa329360abaffa7e232d
-Bug 1262846 (patch for ESR trees) - Update Graphite2 library to 1.3.8. 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,3 +1,3 @@
--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
-+This directory contains the Graphite2 library release 1.3.8 from
-+https://github.com/silnrsi/graphite/releases/download/1.3.8/graphite2-minimal-1.3.8.tgz
- See gfx/graphite2/moz-gr-update.sh for update procedure.
-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  6
-+#define GR2_VERSION_BUGFIX  8
- 
- #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/graphite-minimal-$RELEASE.tgz"
-+TARBALL="https://github.com/silnrsi/graphite/releases/download/$RELEASE/graphite2-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/CachedFace.cpp b/gfx/graphite2/src/CachedFace.cpp
---- a/gfx/graphite2/src/CachedFace.cpp
-+++ b/gfx/graphite2/src/CachedFace.cpp
-@@ -64,20 +64,20 @@ bool CachedFace::runGraphite(Segment *se
-         return false;
- 
-     assert(m_cacheStore);
-     // find where the segment can be broken
-     Slot * subSegStartSlot = seg->first();
-     Slot * subSegEndSlot = subSegStartSlot;
-     uint16 cmapGlyphs[eMaxSpliceSize];
-     int subSegStart = 0;
--    for (unsigned int i = 0; i < seg->charInfoCount(); ++i)
-+    for (unsigned int i = 0; i < seg->charInfoCount() && subSegEndSlot; ++i)
-     {
-         const unsigned int length = i - subSegStart + 1;
--        if (length < eMaxSpliceSize)
-+        if (length < eMaxSpliceSize && subSegEndSlot->gid() < m_cacheStore->maxCmapGid())
-             cmapGlyphs[length-1] = subSegEndSlot->gid();
-         else return false;
-         const bool spaceOnly = m_cacheStore->isSpaceGlyph(subSegEndSlot->gid());
-         // at this stage the character to slot mapping is still 1 to 1
-         const int   breakWeight = seg->charinfo(i)->breakWeight(),
-                     nextBreakWeight = (i + 1 < seg->charInfoCount())?
-                             seg->charinfo(i+1)->breakWeight() : 0;
-         const uint8 f = seg->charinfo(i)->flags();
-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
-@@ -61,93 +61,88 @@ inline bool is_return(const instr i) {
-     const instr pop_ret  = *opmap[POP_RET].impl,
-                 ret_zero = *opmap[RET_ZERO].impl,
-                 ret_true = *opmap[RET_TRUE].impl;
-     return i == pop_ret || i == ret_zero || i == ret_true;
- }
- 
- struct context
- {
--    context(uint8 ref=0) : codeRef(ref) {flags.changed=false; flags.referenced=false; flags.inserted=false;}
-+    context(uint8 ref=0) : codeRef(ref) {flags.changed=false; flags.referenced=false;}
-     struct { 
-         uint8   changed:1,
--                referenced:1,
--                inserted:1;
-+                referenced:1;
-     } flags;
-     uint8       codeRef;
- };
- 
- } // end namespace
- 
- 
- class Machine::Code::decoder
- {
- public:
-     struct limits;
--    struct analysis
--    {
--        static const int NUMCONTEXTS = 256;
--        uint8     slotref;
--        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();
--
--    };
-+    static const int NUMCONTEXTS = 256;
-     
-     decoder(limits & lims, Code &code, enum passtype pt) throw();
-     
-     bool        load(const byte * bc_begin, const byte * bc_end);
-     void        apply_analysis(instr * const code, instr * code_end);
--    byte        max_ref() { return _analysis.max_ref; }
--    int         pre_context() const { return _pre_context; }
-+    byte        max_ref() { return _max_ref; }
-+    int         out_index() const { return _out_index; }
-     
- private:
-+    void        set_ref(int index) throw();
-+    void        set_noref(int index) throw();
-+    void        set_changed(int index) throw();
-     opcode      fetch_opcode(const byte * bc);
-     void        analyse_opcode(const opcode, const int8 * const dp) throw();
-     bool        emit_opcode(opcode opc, const byte * & bc);
--    bool        validate_opcode(const opcode opc, const byte * const bc);
-+    bool        validate_opcode(const byte opc, const byte * const bc);
-     bool        valid_upto(const uint16 limit, const uint16 x) const throw();
-     bool        test_context() const throw();
-+    bool        test_ref(int8 index) const throw();
-     void        failure(const status_t s) const throw() { _code.failure(s); }
-     
-     Code              & _code;
--    int                 _pre_context;
--    uint16              _rule_length;
-+    int                 _out_index;
-+    uint16              _out_length;
-     instr             * _instr;
-     byte              * _data;
-     limits            & _max;
--    analysis            _analysis;
-     enum passtype       _passtype;
-     int                 _stack_depth;
-     bool                _in_ctxt_item;
-+    int16               _slotref;
-+    context             _contexts[NUMCONTEXTS];
-+    byte                _max_ref;
- };
- 
- 
- struct Machine::Code::decoder::limits
- {
-   const byte       * bytecode;
-   const uint8        pre_context;
-   const uint16       rule_length,
-                      classes,
-                      glyf_attrs,
-                      features;
-   const byte         attrid[gr_slatMax];
- };
-    
- inline Machine::Code::decoder::decoder(limits & lims, Code &code, enum passtype pt) throw()
- : _code(code),
--  _pre_context(code._constraint ? 0 : lims.pre_context), 
--  _rule_length(code._constraint ? 1 : lims.rule_length), 
-+  _out_index(code._constraint ? 0 : lims.pre_context), 
-+  _out_length(code._constraint ? 1 : lims.rule_length), 
-   _instr(code._code), _data(code._data), _max(lims), _passtype(pt),
-   _stack_depth(0),
--  _in_ctxt_item(false)
-+  _in_ctxt_item(false),
-+  _slotref(0),
-+  _max_ref(0)
- { }
-     
- 
- 
- Machine::Code::Code(bool is_constraint, const byte * bytecode_begin, const byte * const bytecode_end,
-            uint8 pre_context, uint16 rule_length, const Silf & silf, const Face & face,
-            enum passtype pt, byte * * const _out)
-  :  _code(0), _data(0), _data_size(0), _instr_count(0), _max_ref(0), _status(loaded),
-@@ -163,17 +158,17 @@ Machine::Code::Code(bool is_constraint, 
-       return;
-     }
-     assert(bytecode_end > bytecode_begin);
-     const opcode_t *    op_to_fn = Machine::getOpcodeTable();
-     
-     // Allocate code and data target buffers, these sizes are a worst case
-     // estimate.  Once we know their real sizes the we'll shrink them.
-     if (_out)   _code = reinterpret_cast<instr *>(*_out);
--    else        _code = static_cast<instr *>(malloc(estimateCodeDataOut(bytecode_end-bytecode_begin)));
-+    else        _code = static_cast<instr *>(malloc(estimateCodeDataOut(bytecode_end-bytecode_begin, 1, is_constraint ? 0 : rule_length)));
-     _data = reinterpret_cast<byte *>(_code + (bytecode_end - bytecode_begin));
-     
-     if (!_code || !_data) {
-         failure(alloc_failed);
-         return;
-     }
-     
-     decoder::limits lims = {
-@@ -266,23 +261,23 @@ bool Machine::Code::decoder::load(const 
-     return bool(_code);
- }
- 
- // Validation check and fixups.
- //
- 
- opcode Machine::Code::decoder::fetch_opcode(const byte * bc)
- {
--    const opcode opc = opcode(*bc++);
-+    const byte opc = *bc++;
- 
-     // Do some basic sanity checks based on what we know about the opcode
-     if (!validate_opcode(opc, bc))  return MAX_OPCODE;
- 
-     // And check it's arguments as far as possible
--    switch (opc)
-+    switch (opcode(opc))
-     {
-         case NOP :
-             break;
-         case PUSH_BYTE :
-         case PUSH_BYTEU :
-         case PUSH_SHORT :
-         case PUSH_SHORTU :
-         case PUSH_LONG :
-@@ -319,47 +314,57 @@ opcode Machine::Code::decoder::fetch_opc
-         case COND :
-             _stack_depth -= 2;
-             if (_stack_depth <= 0)
-                 failure(underfull_stack);
-             break;
-         case NEXT :
-         case NEXT_N :           // runtime checked
-         case COPY_NEXT :
--            test_context();
--            ++_pre_context;
-+            ++_out_index;
-+            if (_out_index < -1 || _out_index > _out_length || _slotref > _max.rule_length)
-+                failure(out_of_range_data);
-             break;
-         case PUT_GLYPH_8BIT_OBS :
-             valid_upto(_max.classes, bc[0]);
-             test_context();
-             break;
-         case PUT_SUBS_8BIT_OBS :
--            valid_upto(_rule_length, _pre_context + int8(bc[0]));
-+            test_ref(int8(bc[0]));
-             valid_upto(_max.classes, bc[1]);
-             valid_upto(_max.classes, bc[2]);
-             test_context();
-             break;
-         case PUT_COPY :
--            valid_upto(_rule_length, _pre_context + int8(bc[0]));
-+            test_ref(int8(bc[0]));
-             test_context();
-             break;
-         case INSERT :
-             if (_passtype >= PASS_TYPE_POSITIONING)
-                 failure(invalid_opcode);
--            else
--                --_pre_context;
-+            ++_out_length;
-+            if (_out_index < 0) ++_out_index;
-+            if (_out_index < -1 || _out_index >= _out_length)
-+                failure(out_of_range_data);
-             break;
-         case DELETE :
-             if (_passtype >= PASS_TYPE_POSITIONING)
-                 failure(invalid_opcode);
--            test_context();
-+            if (_out_index < _max.pre_context)
-+                failure(out_of_range_data);
-+            --_out_index;
-+            --_out_length;
-+            if (_out_index < -1 || _out_index > _out_length)
-+                failure(out_of_range_data);
-             break;
-         case ASSOC :
-+            if (bc[0] == 0)
-+                failure(out_of_range_data);
-             for (uint8 num = bc[0]; num; --num)
--                valid_upto(_rule_length, _pre_context + int8(bc[num]));
-+                test_ref(int8(bc[num]));
-             test_context();
-             break;
-         case CNTXT_ITEM :
-             valid_upto(_max.rule_length, _max.pre_context + int8(bc[0]));
-             if (bc + 2 + bc[1] >= _max.bytecode)    failure(jump_past_end);
-             if (_in_ctxt_item)                      failure(nested_context_item);
-             break;
-         case ATTR_SET :
-@@ -378,52 +383,43 @@ opcode Machine::Code::decoder::fetch_opc
-                 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]));
-+            test_ref(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 :
-+        case PUSH_ATT_TO_GATTR_OBS :
-             ++_stack_depth;
-             valid_upto(_max.glyf_attrs, bc[0]);
--            valid_upto(_rule_length, _pre_context + int8(bc[1]));
-+            test_ref(int8(bc[1]));
-             break;
-+        case PUSH_ATT_TO_GLYPH_METRIC :
-         case PUSH_GLYPH_METRIC :
-             ++_stack_depth;
-             valid_upto(kgmetDescent, bc[0]);
--            valid_upto(_rule_length, _pre_context + int8(bc[1]));
-+            test_ref(int8(bc[1]));
-             // level: dp[2] no check necessary
-             break;
-         case PUSH_FEAT :
-             ++_stack_depth;
-             valid_upto(_max.features, bc[0]);
--            valid_upto(_rule_length, _pre_context + int8(bc[1]));
--            break;
--        case PUSH_ATT_TO_GATTR_OBS :
--            ++_stack_depth;
--            valid_upto(_max.glyf_attrs, bc[0]);
--            valid_upto(_rule_length, _pre_context + int8(bc[1]));
--            break;
--        case PUSH_ATT_TO_GLYPH_METRIC :
--            ++_stack_depth;
--            valid_upto(kgmetDescent, bc[0]);
--            valid_upto(_rule_length, _pre_context + int8(bc[1]));
--            // level: dp[2] no check necessary
-+            test_ref(int8(bc[1]));
-             break;
-         case PUSH_ISLOT_ATTR :
-             ++_stack_depth;
-             if (valid_upto(gr_slatMax, bc[0]))
-             {
--                valid_upto(_rule_length, _pre_context + int8(bc[1]));
-+                test_ref(int8(bc[1]));
-                 valid_upto(_max.attrid[bc[0]], bc[2]);
-             }
-             break;
-         case PUSH_IGLYPH_ATTR :// not implemented
-             ++_stack_depth;
-             break;
-         case POP_RET :
-             if (--_stack_depth < 0)
-@@ -442,118 +438,107 @@ opcode Machine::Code::decoder::fetch_opc
-                 valid_upto(_max.attrid[bc[0]], bc[1]);
-             test_context();
-             break;
-         case PUSH_PROC_STATE :  // dummy: dp[0] no check necessary
-         case PUSH_VERSION :
-             ++_stack_depth;
-             break;
-         case PUT_SUBS :
--            valid_upto(_rule_length, _pre_context + int8(bc[0]));
-+            test_ref(int8(bc[0]));
-             valid_upto(_max.classes, uint16(bc[1]<< 8) | bc[2]);
-             valid_upto(_max.classes, uint16(bc[3]<< 8) | bc[4]);
-             test_context();
-             break;
-         case PUT_SUBS2 :        // not implemented
-         case PUT_SUBS3 :        // not implemented
-             break;
-         case PUT_GLYPH :
-             valid_upto(_max.classes, uint16(bc[0]<< 8) | bc[1]);
-             test_context();
-             break;
-         case PUSH_GLYPH_ATTR :
-         case PUSH_ATT_TO_GLYPH_ATTR :
-             ++_stack_depth;
-             valid_upto(_max.glyf_attrs, uint16(bc[0]<< 8) | bc[1]);
--            valid_upto(_rule_length, _pre_context + int8(bc[2]));
-+            test_ref(int8(bc[2]));
-+            break;
-+        case SET_FEAT :
-+            valid_upto(_max.features, bc[0]);
-+            test_ref(int8(bc[1]));
-             break;
-         default:
-             failure(invalid_opcode);
-             break;
-     }
- 
--    return bool(_code) ? opc : MAX_OPCODE;
-+    return bool(_code) ? opcode(opc) : MAX_OPCODE;
- }
- 
- 
- void Machine::Code::decoder::analyse_opcode(const opcode opc, const int8  * arg) throw()
- {
--  if (_code._constraint) return;
--  
-   switch (opc)
-   {
-     case DELETE :
-       _code._delete = true;
-       break;
-+    case ASSOC :
-+      set_changed(0);
-+//      for (uint8 num = arg[0]; num; --num)
-+//        _analysis.set_noref(num);
-+      break;
-     case PUT_GLYPH_8BIT_OBS :
-     case PUT_GLYPH :
-       _code._modify = true;
--      _analysis.set_changed(0);
-+      set_changed(0);
-       break;
-     case ATTR_SET :
-     case ATTR_ADD :
-+    case ATTR_SUB :
-     case ATTR_SET_SLOT :
-     case IATTR_SET_SLOT :
-     case IATTR_SET :
-     case IATTR_ADD :
-     case IATTR_SUB :
--      _analysis.set_noref(0);
-+      set_noref(0);
-       break;
-     case NEXT :
-     case COPY_NEXT :
--      if (!_analysis.contexts[_analysis.slotref].flags.inserted)
--        ++_analysis.slotref;
--      _analysis.contexts[_analysis.slotref] = context(_code._instr_count+1);
-+      ++_slotref;
-+      _contexts[_slotref] = context(_code._instr_count+1);
-       // if (_analysis.slotref > _analysis.max_ref) _analysis.max_ref = _analysis.slotref;
-       break;
-     case INSERT :
--      _analysis.contexts[_analysis.slotref].flags.inserted = true;
-+      if (_slotref >= 0) --_slotref;
-       _code._modify = true;
-       break;
-     case PUT_SUBS_8BIT_OBS :    // slotref on 1st parameter
-     case PUT_SUBS : 
-       _code._modify = true;
--      _analysis.set_changed(0);
-+      set_changed(0);
-       GR_FALLTHROUGH;
-       // no break
-     case PUT_COPY :
--    {
--      if (arg[0] != 0) { _analysis.set_changed(0); _code._modify = true; }
--      if (arg[0] <= 0 && -arg[0] <= _analysis.slotref - _analysis.contexts[_analysis.slotref].flags.inserted)
--        _analysis.set_ref(arg[0], true);
--      else if (arg[0] > 0)
--        _analysis.set_ref(arg[0], true);
-+      if (arg[0] != 0) { set_changed(0); _code._modify = true; }
-+      set_ref(arg[0]);
-       break;
--    }
--    case PUSH_ATT_TO_GATTR_OBS : // slotref on 2nd parameter
--        if (_code._constraint) return;
--        GR_FALLTHROUGH;
--        // no break
-     case PUSH_GLYPH_ATTR_OBS :
-     case PUSH_SLOT_ATTR :
-     case PUSH_GLYPH_METRIC :
-+    case PUSH_ATT_TO_GATTR_OBS :
-     case PUSH_ATT_TO_GLYPH_METRIC :
-     case PUSH_ISLOT_ATTR :
-     case PUSH_FEAT :
--      if (arg[1] <= 0 && -arg[1] <= _analysis.slotref - _analysis.contexts[_analysis.slotref].flags.inserted)
--        _analysis.set_ref(arg[1], true);
--      else if (arg[1] > 0)
--        _analysis.set_ref(arg[1], true);
-+    case SET_FEAT :
-+      set_ref(arg[1]);
-       break;
-     case PUSH_ATT_TO_GLYPH_ATTR :
--        if (_code._constraint) return;
--        GR_FALLTHROUGH;
--        // no break
-     case PUSH_GLYPH_ATTR :
--      if (arg[2] <= 0 && -arg[2] <= _analysis.slotref - _analysis.contexts[_analysis.slotref].flags.inserted)
--        _analysis.set_ref(arg[2], true);
--      else if (arg[2] > 0)
--        _analysis.set_ref(arg[2], true);
--      break;
--    case ASSOC :                // slotrefs in varargs
-+      set_ref(arg[2]);
-       break;
-     default:
-         break;
-   }
- }
- 
- 
- bool Machine::Code::decoder::emit_opcode(opcode opc, const byte * & bc)
-@@ -579,81 +564,89 @@ bool Machine::Code::decoder::emit_opcode
-         _data            += param_sz;
-         _code._data_size += param_sz;
-     }
-     
-     // recursively decode a context item so we can split the skip into 
-     // instruction and data portions.
-     if (opc == CNTXT_ITEM)
-     {
--        assert(_pre_context == 0);
-+        assert(_out_index == 0);
-         _in_ctxt_item = true;
--        _pre_context = _max.pre_context + int8(_data[-2]);
--        _rule_length = _max.rule_length;
-+        _out_index = _max.pre_context + int8(_data[-2]);
-+        _slotref = int8(_data[-2]);
-+        _out_length = _max.rule_length;
- 
-         const size_t ctxt_start = _code._instr_count;
-         byte & instr_skip = _data[-1];
-         byte & data_skip  = *_data++;
-         ++_code._data_size;
-         const byte *curr_end = _max.bytecode;
- 
-         if (load(bc, bc + instr_skip))
-         {
-             bc += instr_skip;
-             data_skip  = instr_skip - (_code._instr_count - ctxt_start);
-             instr_skip = _code._instr_count - ctxt_start;
-             _max.bytecode = curr_end;
- 
--            _rule_length = 1;
--            _pre_context = 0;
-+            _out_length = 1;
-+            _out_index = 0;
-+            _slotref = 0;
-             _in_ctxt_item = false;
-         }
-         else
-         {
--            _pre_context = 0;
-+            _out_index = 0;
-+            _slotref = 0;
-             return false;
-         }
-     }
-     
-     return bool(_code);
- }
- 
- 
- void Machine::Code::decoder::apply_analysis(instr * const code, instr * code_end)
- {
-     // insert TEMP_COPY commands for slots that need them (that change and are referenced later)
-     int tempcount = 0;
-     if (_code._constraint) return;
- 
-     const instr temp_copy = Machine::getOpcodeTable()[TEMP_COPY].impl[0];
--    for (const context * c = _analysis.contexts, * const ce = c + _analysis.slotref; c != ce; ++c)
-+    for (const context * c = _contexts, * const ce = c + _slotref; c < ce; ++c)
-     {
-         if (!c->flags.referenced || !c->flags.changed) continue;
-         
-         instr * const tip = code + c->codeRef + tempcount;        
-         memmove(tip+1, tip, (code_end - tip) * sizeof(instr));
-         *tip = temp_copy;
-         ++code_end;
-         ++tempcount;
-         _code._delete = true;
-     }
-     
-     _code._instr_count = code_end - code;
- }
- 
- 
- inline
--bool Machine::Code::decoder::validate_opcode(const opcode opc, const byte * const bc)
-+bool Machine::Code::decoder::validate_opcode(const byte opc, const byte * const bc)
- {
-     if (opc >= MAX_OPCODE)
-     {
-         failure(invalid_opcode);
-         return false;
-     }
-     const opcode_t & op = Machine::getOpcodeTable()[opc];
-+    if (op.impl[_code._constraint] == 0)
-+    {
-+        failure(unimplemented_opcode_used);
-+        return false;
-+    }
-     if (op.param_sz == VARARGS && bc >= _max.bytecode)
-     {
-         failure(arguments_exhausted);
-         return false;
-     }
-     const size_t param_sz = op.param_sz == VARARGS ? bc[0] + 1 : op.param_sz;
-     if (bc - 1 + param_sz >= _max.bytecode)
-     {
-@@ -666,56 +659,69 @@ bool Machine::Code::decoder::validate_op
- 
- bool Machine::Code::decoder::valid_upto(const uint16 limit, const uint16 x) const throw()
- {
-     const bool t = (limit != 0) && (x < limit);
-     if (!t) failure(out_of_range_data);
-     return t;
- }
- 
-+inline
-+bool Machine::Code::decoder::test_ref(int8 index) const throw()
-+{
-+    if (_code._constraint && !_in_ctxt_item)
-+    {
-+        if (index > 0 || -index > _max.pre_context)
-+        {
-+            failure(out_of_range_data);
-+            return false;
-+        }
-+    }
-+    else
-+        return valid_upto(_max.rule_length, _slotref + _max.pre_context + index);
-+    return true;
-+}
-+
- bool Machine::Code::decoder::test_context() const throw()
- {
--    if (_pre_context >= _rule_length || _analysis.slotref >= analysis::NUMCONTEXTS - 1)
-+    if (_out_index >= _out_length || _out_index < 0 || _slotref >= NUMCONTEXTS - 1)
-     {
-         failure(out_of_range_data);
-         return false;
-     }
-     return true;
- }
- 
- inline 
- void Machine::Code::failure(const status_t s) throw() {
-     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 || 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;
-+void Machine::Code::decoder::set_ref(int index) throw() {
-+    if (index + _slotref < 0 || index + _slotref >= NUMCONTEXTS) return;
-+    _contexts[index + _slotref].flags.referenced = true;
-+    if (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 || index + slotref >= NUMCONTEXTS) return;
--    if ((index > 0 || !contexts[index + slotref].flags.inserted) && index + slotref > max_ref) max_ref = index + slotref;
-+void Machine::Code::decoder::set_noref(int index) throw() {
-+    if (index + _slotref < 0 || index + _slotref >= NUMCONTEXTS) return;
-+    if (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 || 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::decoder::set_changed(int index) throw() {
-+    if (index + _slotref < 0 || index + _slotref >= NUMCONTEXTS) return;
-+    _contexts[index + _slotref].flags.changed= true;
-+    if (index + _slotref > _max_ref) _max_ref = index + _slotref;
- }
- 
- 
- void Machine::Code::release_buffers() throw()
- {
-     if (_own)
-         free(_code);
-     _code = 0;
-diff --git a/gfx/graphite2/src/Collider.cpp b/gfx/graphite2/src/Collider.cpp
---- a/gfx/graphite2/src/Collider.cpp
-+++ b/gfx/graphite2/src/Collider.cpp
-@@ -21,17 +21,17 @@
- 
- Alternatively, the contents of this file may be used under the terms of the
- Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public
- License, as published by the Free Software Foundation, either version 2
- of the License or (at your option) any later version.
- */
- #include <algorithm>
- #include <limits>
--#include <math.h>
-+#include <cmath>
- #include <string>
- #include <functional>
- #include "inc/Collider.h"
- #include "inc/Segment.h"
- #include "inc/Slot.h"
- #include "inc/GlyphCache.h"
- #include "inc/Sparse.h"
- 
-@@ -824,43 +824,43 @@ bool KernCollider::initSlot(Segment *seg
-     if (margin < 10) margin = 10;
- 
-     _limit = limit;
-     _offsetPrev = offsetPrev; // kern from a previous pass
-     
-     // Calculate the height of the glyph and how many horizontal slices to use.
-     if (_maxy >= 1e37f)
-     {
--        _maxy = ymax;
--        _miny = ymin;
-         _sliceWidth = margin / 1.5f;
-+        _maxy = ymax + margin;
-+        _miny = ymin - margin;
-         numSlices = int((_maxy - _miny + 2) / (_sliceWidth / 1.5f) + 1.f);  // +2 helps with rounding errors
-         _edges.clear();
-         _edges.insert(_edges.begin(), numSlices, (dir & 1) ? 1e38f : -1e38f);
-         _xbound = (dir & 1) ? (float)1e38f : (float)-1e38f;
-     }
-     else if (_maxy != ymax || _miny != ymin)
-     {
-         if (_miny != ymin)
-         {
--            numSlices = int((ymin - _miny) / _sliceWidth - 1);
-+            numSlices = int((ymin - margin - _miny) / _sliceWidth - 1);
-             _miny += numSlices * _sliceWidth;
-             if (numSlices < 0)
-                 _edges.insert(_edges.begin(), -numSlices, (dir & 1) ? 1e38f : -1e38f);
-             else if ((unsigned)numSlices < _edges.size())    // this shouldn't fire since we always grow the range
-             {
-                 Vector<float>::iterator e = _edges.begin();
-                 while (numSlices--)
-                     ++e;
-                 _edges.erase(_edges.begin(), e);
-             }
-         }
-         if (_maxy != ymax)
-         {
--            numSlices = int((ymax - _miny) / _sliceWidth + 1);
-+            numSlices = int((ymax + margin - _miny) / _sliceWidth + 1);
-             _maxy = numSlices * _sliceWidth + _miny;
-             if (numSlices > (int)_edges.size())
-                 _edges.insert(_edges.end(), numSlices - _edges.size(), (dir & 1) ? 1e38f : -1e38f);
-             else if (numSlices < (int)_edges.size())   // this shouldn't fire since we always grow the range
-             {
-                 while ((int)_edges.size() > numSlices)
-                     _edges.pop_back();
-             }
-@@ -930,53 +930,60 @@ bool KernCollider::initSlot(Segment *seg
- // Return false if we know there is no collision, true if we think there might be one.
- bool KernCollider::mergeSlot(Segment *seg, Slot *slot, const Position &currShift, float currSpace, int dir, GR_MAYBE_UNUSED json * const dbgout)
- {
-     int rtl = (dir & 1) * 2 - 1;
-     if (!seg->getFace()->glyphs().check(slot->gid()))
-         return false;
-     const Rect &bb = seg->theGlyphBBoxTemporary(slot->gid());
-     const float sx = slot->origin().x + currShift.x;
--    float x = sx + (rtl > 0 ? bb.tr.x : bb.bl.x);
-+    float x = (sx + (rtl > 0 ? bb.tr.x : bb.bl.x)) * rtl;
-     // this isn't going to reduce _mingap so skip
--    if ((rtl > 0 && x < _xbound - _mingap - currSpace) || (rtl <= 0 && x > _xbound + _mingap + currSpace))
-+    if (x < rtl * (_xbound - _mingap - currSpace))
-         return false;
- 
-     const float sy = slot->origin().y + currShift.y;
--    int smin = max(0, int((bb.bl.y + (1 - _miny + sy)) / _sliceWidth + 1));
--    int smax = min((int)_edges.size() - 1, int((bb.tr.y + (1 - _miny + sy)) / _sliceWidth + 1));
-+    int smin = max(1, int((bb.bl.y + (1 - _miny + sy)) / _sliceWidth + 1)) - 1;
-+    int smax = min((int)_edges.size() - 2, int((bb.tr.y + (1 - _miny + sy)) / _sliceWidth + 1)) + 1;
-+    if (smin > smax)
-+        return false;
-     bool collides = false;
-+    float below = smin > 0 ? _edges[smin-1] * rtl : 1e38f;
-+    float here = _edges[smin] * rtl;
-+    float above = smin < (int)_edges.size() - 1 ? _edges[smin+1] * rtl : 1e38f;
- 
-     for (int i = smin; i <= smax; ++i)
-     {
-         float t;
-         float y = (float)(_miny - 1 + (i + .5f) * _sliceWidth);  // vertical center of slice
--        if (x * rtl > _edges[i] * rtl - _mingap - currSpace)
-+        if (    (x > here - _mingap - currSpace)
-+             || (x > below - _mingap - currSpace)
-+             || (x > above - _mingap - currSpace))
-         {
-             // 2 * currSpace to account for the space that is already separating them and the space we want to add
--            float m = get_edge(seg, slot, currShift, y, _sliceWidth, rtl > 0) + 2 * rtl * currSpace;
--            t = rtl * (_edges[i] - m);
-+            float m = get_edge(seg, slot, currShift, y, _sliceWidth, rtl > 0) * rtl + 2 * currSpace;
-             // Check slices above and below (if any).
--            if (i < (int)_edges.size() - 1) t = min(t, rtl * (_edges[i+1] - m));
--            if (i > 0) t = min(t, rtl * (_edges[i-1] - m));
-+            t = min(min(here, below), above) - m;
-             // _mingap is positive to shrink
-             if (t < _mingap)
-             {
-                 _mingap = t;
-                 collides = true;
-             }
- #if !defined GRAPHITE2_NTRACING
-             // Debugging - remember the closest neighboring edge for this slice.
--            if (rtl * m > rtl * _nearEdges[i])
-+            if (m > rtl * _nearEdges[i])
-             {
-                 _slotNear[i] = slot;
--                _nearEdges[i] = m;
-+                _nearEdges[i] = m * rtl;
-             }
- #endif
-         }
-+        below = here; here = above;
-+        above = i < (int)_edges.size() - 2 ? _edges[i+2] * rtl : 1e38f;
-     }
-     return collides;   // note that true is not a necessarily reliable value
-     
- }   // end of KernCollider::mergeSlot
- 
- 
- // Return the amount to kern by.
- Position KernCollider::resolve(GR_MAYBE_UNUSED Segment *seg, GR_MAYBE_UNUSED Slot *slot,
-diff --git a/gfx/graphite2/src/Face.cpp b/gfx/graphite2/src/Face.cpp
---- a/gfx/graphite2/src/Face.cpp
-+++ b/gfx/graphite2/src/Face.cpp
-@@ -178,17 +178,18 @@ bool Face::runGraphite(Segment *seg, con
-     if ((seg->dir() & 3) == 3 && aSilf->bidiPass() == 0xFF)
-         seg->doMirror(aSilf->aMirror());
-     bool res = aSilf->runGraphite(seg, 0, aSilf->positionPass(), true);
-     if (res)
-     {
-         seg->associateChars(0, seg->charInfoCount());
-         if (aSilf->flags() & 0x20)
-             res &= seg->initCollisions();
--        res &= aSilf->runGraphite(seg, aSilf->positionPass(), aSilf->numPasses(), false);
-+        if (res)
-+            res &= aSilf->runGraphite(seg, aSilf->positionPass(), aSilf->numPasses(), false);
-     }
- 
- #if !defined GRAPHITE2_NTRACING
-     if (dbgout)
- {
-         seg->positionSlots(0, 0, 0, aSilf->dir());
-         *dbgout             << json::item
-                             << json::close // Close up the passes array
-@@ -226,17 +227,17 @@ const Silf *Face::chooseSilf(uint32 scri
-         return m_silfs;
- }
- 
- uint16 Face::findPseudo(uint32 uid) const
- {
-     return (m_numSilf) ? m_silfs[0].findPseudo(uid) : 0;
- }
- 
--uint16 Face::getGlyphMetric(uint16 gid, uint8 metric) const
-+int32 Face::getGlyphMetric(uint16 gid, uint8 metric) const
- {
-     switch (metrics(metric))
-     {
-         case kgmetAscent : return m_ascent;
-         case kgmetDescent : return m_descent;
-         default: 
-             if (gid >= glyphs().numGlyphs()) return 0;
-             return glyphs().glyph(gid)->getMetric(metric);
-@@ -277,17 +278,17 @@ Face::Table::Table(const Face & face, co
- : _f(&face), _compressed(false)
- {
-     size_t sz = 0;
-     _p = static_cast<const byte *>((*_f->m_ops.get_table)(_f->m_appFaceHandle, n, &sz));
-     _sz = uint32(sz);
- 
-     if (!TtfUtil::CheckTable(n, _p, _sz))
-     {
--        this->~Table();     // Make sure we release the table buffer even if the table filed it's checks
-+        releaseBuffers();     // Make sure we release the table buffer even if the table failed it's checks
-         return;
-     }
- 
-     if (be::peek<uint32>(_p) >= version)
-         decompress();
- }
- 
- void Face::Table::releaseBuffers()
-@@ -324,17 +325,18 @@ Error Face::Table::decompress()
-     switch(compression(hdr >> 27))
-     {
-     case NONE: return e;
- 
-     case LZ4:
-     {
-         uncompressed_size  = hdr & 0x07ffffff;
-         uncompressed_table = gralloc<byte>(uncompressed_size);
--        if (!e.test(!uncompressed_table, E_OUTOFMEM))
-+        if (!e.test(!uncompressed_table || uncompressed_size < 4, E_OUTOFMEM))
-+            memset(uncompressed_table, 0, 4);   // make sure version number is initialised
-             // coverity[forward_null : FALSE] - uncompressed_table has been checked so can't be null
-             // coverity[checked_return : FALSE] - we test e later
-             e.test(lz4::decompress(p, _sz - 2*sizeof(uint32), uncompressed_table, uncompressed_size) != signed(uncompressed_size), E_SHRINKERFAILED);
-         break;
-     }
- 
-     default:
-         e.error(E_BADSCHEME);
-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
-@@ -111,18 +111,20 @@ private:
-                     _num_glyphs_attributes,
-                     _num_attrs;                    // number of glyph attributes per glyph
- };
- 
- 
- 
- GlyphCache::GlyphCache(const Face & face, const uint32 face_options)
- : _glyph_loader(new Loader(face, bool(face_options & gr_face_dumbRendering))),
--  _glyphs(_glyph_loader && *_glyph_loader ? grzeroalloc<const GlyphFace *>(_glyph_loader->num_glyphs()) : 0),
--  _boxes(_glyph_loader && _glyph_loader->has_boxes() ? grzeroalloc<GlyphBox *>(_glyph_loader->num_glyphs()) : 0),
-+  _glyphs(_glyph_loader && *_glyph_loader && _glyph_loader->num_glyphs()
-+        ? grzeroalloc<const GlyphFace *>(_glyph_loader->num_glyphs()) : 0),
-+  _boxes(_glyph_loader && _glyph_loader->has_boxes() && _glyph_loader->num_glyphs()
-+        ? grzeroalloc<GlyphBox *>(_glyph_loader->num_glyphs()) : 0),
-   _num_glyphs(_glyphs ? _glyph_loader->num_glyphs() : 0),
-   _num_attrs(_glyphs ? _glyph_loader->num_attrs() : 0),
-   _upem(_glyphs ? _glyph_loader->units_per_em() : 0)
- {
-     if ((face_options & gr_face_preloadGlyphs) && _glyph_loader && _glyphs)
-     {
-         int numsubs = 0;
-         GlyphFace * const glyphs = new GlyphFace [_num_glyphs];
-@@ -139,17 +141,17 @@ GlyphCache::GlyphCache(const Face & face
-         for (uint16 gid = 1; loaded && gid != _num_glyphs; ++gid)
-             _glyphs[gid] = loaded = _glyph_loader->read_glyph(gid, glyphs[gid], &numsubs);
- 
-         if (!loaded)
-         {
-             _glyphs[0] = 0;
-             delete [] glyphs;
-         }
--        else if (numsubs > 0)
-+        else if (numsubs > 0 && _boxes)
-         {
-             GlyphBox * boxes = (GlyphBox *)gralloc<char>(_num_glyphs * sizeof(GlyphBox) + numsubs * 8 * sizeof(float));
-             GlyphBox * currbox = boxes;
- 
-             for (uint16 gid = 0; currbox && gid != _num_glyphs; ++gid)
-             {
-                 _boxes[gid] = currbox;
-                 currbox = _glyph_loader->read_box(gid, currbox, *_glyphs[gid]);
-@@ -204,16 +206,18 @@ GlyphCache::~GlyphCache()
-             free(_boxes[0]);
-         free(_boxes);
-     }
-     delete _glyph_loader;
- }
- 
- const GlyphFace *GlyphCache::glyph(unsigned short glyphid) const      //result may be changed by subsequent call with a different glyphid
- { 
-+    if (glyphid >= numGlyphs())
-+        return _glyphs[0];
-     const GlyphFace * & p = _glyphs[glyphid];
-     if (p == 0 && _glyph_loader)
-     {
-         int numsubs = 0;
-         GlyphFace * g = new GlyphFace();
-         if (g)  p = _glyph_loader->read_glyph(glyphid, *g, &numsubs);
-         if (!p)
-         {
-@@ -280,26 +284,27 @@ GlyphCache::Loader::Loader(const Face & 
-         _long_fmt              = flags & 1;
-         int tmpnumgattrs       = (m_pGloc.size()
-                                    - (p - m_pGloc)
-                                    - sizeof(uint16)*(flags & 0x2 ? _num_attrs : 0))
-                                        / (_long_fmt ? sizeof(uint32) : sizeof(uint16)) - 1;
- 
-         if (version >= 0x00020000 || tmpnumgattrs < 0 || tmpnumgattrs > 65535
-             || _num_attrs == 0 || _num_attrs > 0x3000  // is this hard limit appropriate?
--            || _num_glyphs_graphics > tmpnumgattrs)
-+            || _num_glyphs_graphics > tmpnumgattrs
-+            || m_pGlat.size() < 4)
-         {
-             _head = Face::Table();
-             return;
-         }
- 
-         _num_glyphs_attributes = static_cast<unsigned short>(tmpnumgattrs);
-         p = m_pGlat;
-         version = be::read<uint32>(p);
--        if (version >= 0x00040000)       // reject Glat tables that are too new
-+        if (version >= 0x00040000 || (version >= 0x00030000 && m_pGlat.size() < 8))       // reject Glat tables that are too new
-         {
-             _head = Face::Table();
-             return;
-         }
-         else if (version >= 0x00030000)
-         {
-             unsigned int glatflags = be::read<uint32>(p);
-             _has_boxes = glatflags & 1;
-@@ -381,22 +386,24 @@ const GlyphFace * GlyphCache::Loader::re
-         }
-         else
-         {
-             be::skip<uint16>(gloc, glyphid);
-             glocs = be::read<uint16>(gloc);
-             gloce = be::peek<uint16>(gloc);
-         }
- 
--        if (glocs >= m_pGlat.size() || gloce > m_pGlat.size())
-+        if (glocs >= m_pGlat.size() - 1 || gloce > m_pGlat.size())
-             return 0;
- 
-         const uint32 glat_version = be::peek<uint32>(m_pGlat);
--        if (glat_version == 0x00030000)
-+        if (glat_version >= 0x00030000)
-         {
-+            if (glocs >= gloce)
-+                return 0;
-             const byte * p = m_pGlat + glocs;
-             uint16 bmap = be::read<uint16>(p);
-             int num = bit_set_count((uint32)bmap);
-             if (numsubs) *numsubs += num;
-             glocs += 6 + 8 * num;
-             if (glocs > gloce)
-                 return 0;
-         }
-@@ -449,29 +456,31 @@ GlyphBox * GlyphCache::Loader::read_box(
-     }
-     else
-     {
-         be::skip<uint16>(gloc, gid);
-         glocs = be::read<uint16>(gloc);
-         gloce = be::peek<uint16>(gloc);
-     }
- 
--    if (glocs >= m_pGlat.size() || gloce > m_pGlat.size())
-+    if (gloce > m_pGlat.size() || glocs + 6 >= gloce)
-         return 0;
- 
-     const byte * p = m_pGlat + glocs;
-     uint16 bmap = be::read<uint16>(p);
-     int num = bit_set_count((uint32)bmap);
- 
-     Rect bbox = glyph.theBBox();
-     Rect diamax(Position(bbox.bl.x + bbox.bl.y, bbox.bl.x - bbox.tr.y),
-                 Position(bbox.tr.x + bbox.tr.y, bbox.tr.x - bbox.bl.y));
-     Rect diabound = readbox(diamax, p[0], p[2], p[1], p[3]);
-     ::new (curr) GlyphBox(num, bmap, &diabound);
-     be::skip<uint8>(p, 4);
-+    if (glocs + 6 + num * 8 >= gloce)
-+        return 0;
- 
-     for (int i = 0; i < num * 2; ++i)
-     {
-         Rect box = readbox((i & 1) ? diamax : bbox, p[0], p[2], p[1], p[3]);
-         curr->addSubBox(i >> 1, i & 1, &box);
-         be::skip<uint8>(p, 4);
-     } 
-     return (GlyphBox *)((char *)(curr) + sizeof(GlyphBox) + 2 * num * sizeof(Rect));
-diff --git a/gfx/graphite2/src/GlyphFace.cpp b/gfx/graphite2/src/GlyphFace.cpp
---- a/gfx/graphite2/src/GlyphFace.cpp
-+++ b/gfx/graphite2/src/GlyphFace.cpp
-@@ -24,25 +24,25 @@ Mozilla Public License (http://mozilla.o
- License, as published by the Free Software Foundation, either version 2
- of the License or (at your option) any later version.
- */
- #include "inc/GlyphFace.h"
- 
- 
- using namespace graphite2;
- 
--uint16 GlyphFace::getMetric(uint8 metric) const
-+int32 GlyphFace::getMetric(uint8 metric) const
- {
-     switch (metrics(metric))
-     {
--        case kgmetLsb       : return static_cast<uint16>(m_bbox.bl.x);
--        case kgmetRsb       : return static_cast<uint16>(m_advance.x - m_bbox.tr.x);
--        case kgmetBbTop     : return static_cast<uint16>(m_bbox.tr.y);
--        case kgmetBbBottom  : return static_cast<uint16>(m_bbox.bl.y);
--        case kgmetBbLeft    : return static_cast<uint16>(m_bbox.bl.x);
--        case kgmetBbRight   : return static_cast<uint16>(m_bbox.tr.x);
--        case kgmetBbHeight  : return static_cast<uint16>(m_bbox.tr.y - m_bbox.bl.y);
--        case kgmetBbWidth   : return static_cast<uint16>(m_bbox.tr.x - m_bbox.bl.x);
--        case kgmetAdvWidth  : return static_cast<uint16>(m_advance.x);
--        case kgmetAdvHeight : return static_cast<uint16>(m_advance.y);
-+        case kgmetLsb       : return m_bbox.bl.x;
-+        case kgmetRsb       : return m_advance.x - m_bbox.tr.x;
-+        case kgmetBbTop     : return m_bbox.tr.y;
-+        case kgmetBbBottom  : return m_bbox.bl.y;
-+        case kgmetBbLeft    : return m_bbox.bl.x;
-+        case kgmetBbRight   : return m_bbox.tr.x;
-+        case kgmetBbHeight  : return m_bbox.tr.y - m_bbox.bl.y;
-+        case kgmetBbWidth   : return m_bbox.tr.x - m_bbox.bl.x;
-+        case kgmetAdvWidth  : return m_advance.x;
-+        case kgmetAdvHeight : return m_advance.y;
-         default : return 0;
-     }
- }
-diff --git a/gfx/graphite2/src/Justifier.cpp b/gfx/graphite2/src/Justifier.cpp
---- a/gfx/graphite2/src/Justifier.cpp
-+++ b/gfx/graphite2/src/Justifier.cpp
-@@ -95,62 +95,63 @@ float Segment::justify(Slot *pSlot, cons
- 
-     end = pLast->nextSibling();
-     pFirst = pFirst->nextSibling();
- 
-     int icount = 0;
-     int numLevels = silf()->numJustLevels();
-     if (!numLevels)
-     {
--        for (s = pSlot; s != end; s = s->next())
-+        for (s = pSlot; s && s != end; s = s->nextSibling())
-         {
-             CharInfo *c = charinfo(s->before());
-             if (isWhitespace(c->unicodeChar()))
-             {
-                 s->setJustify(this, 0, 3, 1);
-                 s->setJustify(this, 0, 2, 1);
-                 s->setJustify(this, 0, 0, -1);
-                 ++icount;
-             }
-         }
-         if (!icount)
-         {
--            for (s = pSlot; s != end; s = s->nextSibling())
-+            for (s = pSlot; s && s != end; s = s->nextSibling())
-             {
-                 s->setJustify(this, 0, 3, 1);
-                 s->setJustify(this, 0, 2, 1);
-                 s->setJustify(this, 0, 0, -1);
-             }
-         }
-         ++numLevels;
-     }
- 
-     Vector<JustifyTotal> stats(numLevels);
--    for (s = pFirst; s != end; s = s->nextSibling())
-+    for (s = pFirst; s && s != end; s = s->nextSibling())
-     {
-         float w = s->origin().x / scale + s->advance() - base;
-         if (w > currWidth) currWidth = w;
-         for (int j = 0; j < numLevels; ++j)
-             stats[j].accumulate(s, this, j);
-         s->just(0);
-     }
- 
-     for (int i = (width < 0.0f) ? -1 : numLevels - 1; i >= 0; --i)
-     {
-         float diff;
-         float error = 0.;
-         float diffpw;
-         int tWeight = stats[i].weight();
-+        if (tWeight == 0) continue;
- 
-         do {
-             error = 0.;
-             diff = width - currWidth;
-             diffpw = diff / tWeight;
-             tWeight = 0;
--            for (s = pFirst; s != end; s = s->nextSibling()) // don't include final glyph
-+            for (s = pFirst; s && s != end; s = s->nextSibling()) // don't include final glyph
-             {
-                 int w = s->getJustify(this, i, 3);
-                 float pref = diffpw * w + error;
-                 int step = s->getJustify(this, i, 2);
-                 if (!step) step = 1;        // handle lazy font developers
-                 if (pref > 0)
-                 {
-                     float max = uint16(s->getJustify(this, i, 0));
-diff --git a/gfx/graphite2/src/NameTable.cpp b/gfx/graphite2/src/NameTable.cpp
---- a/gfx/graphite2/src/NameTable.cpp
-+++ b/gfx/graphite2/src/NameTable.cpp
-@@ -42,25 +42,26 @@ NameTable::NameTable(const void* data, s
-     memcpy(pdata, data, length);
-     m_table = reinterpret_cast<const TtfUtil::Sfnt::FontNames*>(pdata);
- 
-     if ((length > sizeof(TtfUtil::Sfnt::FontNames)) &&
-         (length > sizeof(TtfUtil::Sfnt::FontNames) +
-          sizeof(TtfUtil::Sfnt::NameRecord) * ( be::swap<uint16>(m_table->count) - 1)))
-     {
-         uint16 offset = be::swap<uint16>(m_table->string_offset);
--        m_nameData = reinterpret_cast<const uint8*>(pdata) + offset;
--        setPlatformEncoding(platformId, encodingID);
--        m_nameDataLength = length - offset;
-+        if (offset < length)
-+        {
-+            m_nameData = reinterpret_cast<const uint8*>(pdata) + offset;
-+            setPlatformEncoding(platformId, encodingID);
-+            m_nameDataLength = length - offset;
-+            return;
-+        }
-     }
--    else
--    {
--        free(const_cast<TtfUtil::Sfnt::FontNames*>(m_table));
--        m_table = NULL;
--    }
-+    free(const_cast<TtfUtil::Sfnt::FontNames*>(m_table));
-+    m_table = NULL;
- }
- 
- uint16 NameTable::setPlatformEncoding(uint16 platformId, uint16 encodingID)
- {
-     if (!m_nameData) return 0;
-     uint16 i = 0;
-     uint16 count = be::swap<uint16>(m_table->count);
-     for (; i < count; i++)
-@@ -139,28 +140,36 @@ void* NameTable::getName(uint16& languag
-     uint16 offset = be::swap<uint16>(nameRecord.offset);
-     if(offset + utf16Length > m_nameDataLength)
-     {
-         languageId = 0;
-         length = 0;
-         return NULL;
-     }
-     utf16Length >>= 1; // in utf16 units
--    utf16::codeunit_t * utf16Name = gralloc<utf16::codeunit_t>(utf16Length);
-+    utf16::codeunit_t * utf16Name = gralloc<utf16::codeunit_t>(utf16Length + 1);
-     if (!utf16Name)
-     {
-         languageId = 0;
-         length = 0;
-         return NULL;
-     }
-     const uint8* pName = m_nameData + offset;
-     for (size_t i = 0; i < utf16Length; i++)
-     {
-         utf16Name[i] = be::read<uint16>(pName);
-     }
-+    utf16Name[utf16Length] = 0;
-+    if (!utf16::validate(utf16Name, utf16Name + utf16Length))
-+    {
-+        free(utf16Name);
-+        languageId = 0;
-+        length = 0;
-+        return NULL;
-+    }
-     switch (enc)
-     {
-     case gr_utf8:
-     {
-         utf8::codeunit_t* uniBuffer = gralloc<utf8::codeunit_t>(3 * utf16Length + 1);
-         if (!uniBuffer)
-         {
-             free(utf16Name);
-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
-@@ -96,17 +96,17 @@ bool Pass::readPass(const byte * const p
-     const byte * p              = pass_start,
-                * const pass_end = p + pass_length;
-     size_t numRanges;
- 
-     if (e.test(pass_length < 40, E_BADPASSLENGTH)) return face.error(e); 
-     // Read in basic values
-     const byte flags = be::read<byte>(p);
-     if (e.test((flags & 0x1f) && 
--            (pt < PASS_TYPE_POSITIONING || !m_silf->aCollision() || !face.glyphs().hasBoxes()),
-+            (pt < PASS_TYPE_POSITIONING || !m_silf->aCollision() || !face.glyphs().hasBoxes() || !(m_silf->flags() & 0x20)),
-             E_BADCOLLISIONPASS))
-         return face.error(e);
-     m_numCollRuns = flags & 0x7;
-     m_kernColls   = (flags >> 3) & 0x3;
-     m_isReverseDir = (flags >> 5) & 0x1;
-     m_iMaxLoop = be::read<byte>(p);
-     if (m_iMaxLoop < 1) m_iMaxLoop = 1;
-     be::skip<byte>(p,2); // skip maxContext & maxBackup
-@@ -226,17 +226,21 @@ bool Pass::readRules(const byte * rule_m
-     // Load rules.
-     const byte * ac_begin = 0, * rc_begin = 0,
-                * ac_end = ac_data + be::peek<uint16>(o_action),
-                * rc_end = rc_data + be::peek<uint16>(o_constraint);
- 
-     // Allocate pools
-     m_rules = new Rule [m_numRules];
-     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);
-+    int totalSlots = 0;
-+    const uint16 *tsort = sort_key;
-+    for (int i = 0; i < m_numRules; ++i)
-+        totalSlots += be::peek<uint16>(--tsort);
-+    const size_t prog_pool_sz = vm::Machine::Code::estimateCodeDataOut(ac_end - ac_data + rc_end - rc_data, 2 * m_numRules, totalSlots);
-     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; r >= m_rules; --n, --r, ac_end = ac_begin, rc_end = rc_begin)
-     {
-@@ -249,17 +253,17 @@ bool Pass::readRules(const byte * rule_m
-         if (r->sort > 63 || r->preContext >= r->sort || r->preContext > m_maxPreCtxt || r->preContext < m_minPreCtxt)
-             return false;
-         ac_begin      = ac_data + be::peek<uint16>(--o_action);
-         --o_constraint;
-         rc_begin      = be::peek<uint16>(o_constraint) ? rc_data + be::peek<uint16>(o_constraint) : rc_end;
- 
-         if (ac_begin > ac_end || ac_begin > ac_data_end || ac_end > ac_data_end
-                 || rc_begin > rc_end || rc_begin > rc_data_end || rc_end > rc_data_end
--                || vm::Machine::Code::estimateCodeDataOut(ac_end - ac_begin + rc_end - rc_begin) > size_t(prog_pool_end - prog_pool_free))
-+                || vm::Machine::Code::estimateCodeDataOut(ac_end - ac_begin + rc_end - rc_begin, 2, r->sort) > size_t(prog_pool_end - prog_pool_free))
-             return false;
-         r->action     = new (m_codes+n*2-2) vm::Machine::Code(false, ac_begin, ac_end, r->preContext, r->sort, *m_silf, face, pt, &prog_pool_free);
-         r->constraint = new (m_codes+n*2-1) vm::Machine::Code(true,  rc_begin, rc_end, r->preContext, r->sort, *m_silf, face, pt, &prog_pool_free);
- 
-         if (e.test(!r->action || !r->constraint, E_OUTOFMEM)
-                 || e.test(r->action->status() != Code::loaded, r->action->status() + E_CODEFAILURE)
-                 || e.test(r->constraint->status() != Code::loaded, r->constraint->status() + E_CODEFAILURE)
-                 || e.test(!r->constraint->immutable(), E_MUTABLECCODE))
-@@ -330,17 +334,17 @@ bool Pass::readStates(const byte * start
- 
-     // load state transition table.
-     for (uint16 * t = m_transitions,
-                 * const t_end = t + m_numTransition*m_numColumns; t != t_end; ++t)
-     {
-         *t = be::read<uint16>(states);
-         if (e.test(*t >= m_numStates, E_BADSTATE))
-         {
--            face.error_context((face.error_context() & 0xFFFF00) + EC_ATRANS + (((t - m_transitions) / m_numColumns) << 24));
-+            face.error_context((face.error_context() & 0xFFFF00) + EC_ATRANS + (((t - m_transitions) / m_numColumns) << 8));
-             return face.error(e);
-         }
-     }
- 
-     State * s = m_states,
-           * const success_begin = m_states + m_numStates - m_numSuccess;
-     const RuleEntry * rule_map_end = m_ruleMap + be::peek<uint16>(o_rule_map + m_numSuccess*sizeof(uint16));
-     for (size_t n = m_numStates; n; --n, ++s)
-@@ -351,17 +355,18 @@ bool Pass::readStates(const byte * start
-         if (e.test(begin >= rule_map_end || end > rule_map_end || begin > end, E_BADRULEMAPPING))
-         {
-             face.error_context((face.error_context() & 0xFFFF00) + EC_ARULEMAP + (n << 24));
-             return face.error(e);
-         }
-         s->rules = begin;
-         s->rules_end = (end - begin <= FiniteStateMachine::MAX_RULES)? end :
-             begin + FiniteStateMachine::MAX_RULES;
--        qsort(begin, end - begin, sizeof(RuleEntry), &cmpRuleEntry);
-+        if (begin)      // keep UBSan happy can't call qsort with null begin
-+            qsort(begin, end - begin, sizeof(RuleEntry), &cmpRuleEntry);
-     }
- 
-     return true;
- }
- 
- bool Pass::readRanges(const byte * ranges, size_t num_ranges, Error &e)
- {
-     m_cols = gralloc<uint16>(m_numGlyphs);
-@@ -449,19 +454,19 @@ bool Pass::runFSM(FiniteStateMachine& fs
-     if (fsm.slots.context() < m_minPreCtxt)
-         return false;
- 
-     uint16 state = m_startStates[m_maxPreCtxt - fsm.slots.context()];
-     uint8  free_slots = SlotMap::MAX_SLOTS;
-     do
-     {
-         fsm.slots.pushSlot(slot);
--        if (--free_slots == 0
--         || slot->gid() >= m_numGlyphs
-+        if (slot->gid() >= m_numGlyphs
-          || m_cols[slot->gid()] == 0xffffU
-+         || --free_slots == 0
-          || state >= m_numTransition)
-             return free_slots != 0;
- 
-         const uint16 * transitions = m_transitions + state*m_numColumns;
-         state = transitions[m_cols[slot->gid()]];
-         if (state >= m_successStart)
-             fsm.rules.accumulate_rules(m_states[state]);
- 
-@@ -627,37 +632,40 @@ bool Pass::testPassConstraint(Machine & 
- }
- 
- 
- bool Pass::testConstraint(const Rule & r, Machine & m) const
- {
-     const uint16 curr_context = m.slotMap().context();
-     if (unsigned(r.sort - r.preContext) > m.slotMap().size() - curr_context
-         || curr_context - r.preContext < 0) return false;
-+
-+    vm::slotref * map = m.slotMap().begin() + curr_context - r.preContext;
-+    if (map[r.sort - 1] == 0)
-+        return false;
-+
-     if (!*r.constraint) return true;
-     assert(r.constraint->constraint());
--
--    vm::slotref * map = m.slotMap().begin() + curr_context - r.preContext;
-     for (int n = r.sort; n && map; --n, ++map)
-     {
-         if (!*map) continue;
-         const int32 ret = r.constraint->run(m, map);
-         if (!ret || m.status() != Machine::finished)
-             return false;
-     }
- 
-     return true;
- }
- 
- 
- void SlotMap::collectGarbage(Slot * &aSlot)
- {
-     for(Slot **s = begin(), *const *const se = end() - 1; s != se; ++s) {
-         Slot *& slot = *s;
--        if(slot->isDeleted() || slot->isCopied())
-+        if(slot && (slot->isDeleted() || slot->isCopied()))
-         {
-             if (slot == aSlot)
-                 aSlot = slot->prev() ? slot->prev() : slot->next();
-             segment.freeSlot(slot);
-         }
-     }
- }
- 
-@@ -848,17 +856,16 @@ bool Pass::collisionShift(Segment *seg, 
-             }
-         }
-     }
-     return true;
- }
- 
- bool Pass::collisionKern(Segment *seg, int dir, json * const dbgout) const
- {
--    KernCollider kerncoll(dbgout);
-     Slot *start = seg->first();
-     float ymin = 1e38f;
-     float ymax = -1e38f;
-     const GlyphCache &gc = seg->getFace()->glyphs();
- 
-     // phase 3 : handle kerning of clusters
- #if !defined GRAPHITE2_NTRACING
-     if (dbgout)
-@@ -871,17 +878,17 @@ bool Pass::collisionKern(Segment *seg, i
-             return false;
-         const SlotCollision * c = seg->collisionInfo(s);
-         const Rect &bbox = seg->theGlyphBBoxTemporary(s->gid());
-         float y = s->origin().y + c->shift().y;
-         ymax = max(y + bbox.tr.y, ymax);
-         ymin = min(y + bbox.bl.y, ymin);
-         if (start && (c->flags() & (SlotCollision::COLL_KERN | SlotCollision::COLL_FIX))
-                         == (SlotCollision::COLL_KERN | SlotCollision::COLL_FIX))
--            resolveKern(seg, s, start, kerncoll, dir, ymin, ymax, dbgout);
-+            resolveKern(seg, s, start, dir, ymin, ymax, dbgout);
-         if (c->flags() & SlotCollision::COLL_END)
-             start = NULL;
-         if (c->flags() & SlotCollision::COLL_START)
-             start = s;
-     }
- 
- #if !defined GRAPHITE2_NTRACING
-     if (dbgout)
-@@ -1010,17 +1017,17 @@ bool Pass::resolveCollisions(Segment *se
-     if (isCol)
-     { cFix->setFlags(cFix->flags() | SlotCollision::COLL_ISCOL | SlotCollision::COLL_KNOWN); }
-     else
-     { cFix->setFlags((cFix->flags() & ~SlotCollision::COLL_ISCOL) | SlotCollision::COLL_KNOWN); }
-     hasCol |= isCol;
-     return true;
- }
- 
--float Pass::resolveKern(Segment *seg, Slot *slotFix, GR_MAYBE_UNUSED Slot *start, KernCollider &coll, int dir,
-+float Pass::resolveKern(Segment *seg, Slot *slotFix, GR_MAYBE_UNUSED Slot *start, int dir,
-     float &ymin, float &ymax, json *const dbgout) const
- {
-     Slot *nbor; // neighboring slot
-     float currSpace = 0.;
-     bool collides = false;
-     unsigned int space_count = 0;
-     Slot *base = slotFix;
-     while (base->attachedTo())
-@@ -1030,16 +1037,17 @@ float Pass::resolveKern(Segment *seg, Sl
- 
-     if (base != slotFix)
-     {
-         cFix->setFlags(cFix->flags() | SlotCollision::COLL_KERN | SlotCollision::COLL_FIX);
-         return 0;
-     }
-     bool seenEnd = (cFix->flags() & SlotCollision::COLL_END) != 0;
-     bool isInit = false;
-+    KernCollider coll(dbgout);
- 
-     for (nbor = slotFix->next(); nbor; nbor = nbor->next())
-     {
-         if (nbor->isChildOf(base))
-             continue;
-         if (!gc.check(nbor->gid()))
-             return 0.;
-         const Rect &bb = seg->theGlyphBBoxTemporary(nbor->gid());
-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
-@@ -419,16 +419,19 @@ Position Segment::positionSlots(const Fo
-         reverseSlots();
-         temp = iStart;
-         iStart = iEnd;
-         iEnd = temp;
-     }
-     if (!iStart)    iStart = m_first;
-     if (!iEnd)      iEnd   = m_last;
- 
-+    if (!iStart || !iEnd)   // only true for empty segments
-+        return currpos;
-+
-     if (isRtl)
-     {
-         for (Slot * s = iEnd, * const end = iStart->prev(); s && s != end; s = s->prev())
-         {
-             if (s->isBase())
-                 currpos = s->finalise(this, font, currpos, bbox, 0, clusterMin = currpos.x, isRtl, isFinal);
-         }
-     }
-@@ -526,11 +529,14 @@ void Segment::doMirror(uint16 aMirror)
- }
- 
- bool Segment::initCollisions()
- {
-     m_collisions = grzeroalloc<SlotCollision>(slotCount());
-     if (!m_collisions) return false;
- 
-     for (Slot *p = m_first; p; p = p->next())
--        ::new (collisionInfo(p)) SlotCollision(this, p);
-+        if (p->index() < slotCount())
-+            ::new (collisionInfo(p)) SlotCollision(this, p);
-+        else
-+            return false;
-     return true;
- }
-diff --git a/gfx/graphite2/src/Silf.cpp b/gfx/graphite2/src/Silf.cpp
---- a/gfx/graphite2/src/Silf.cpp
-+++ b/gfx/graphite2/src/Silf.cpp
-@@ -350,20 +350,20 @@ uint16 Silf::getClassGlyph(uint16 cid, u
-     }
-     return 0;
- }
- 
- 
- bool Silf::runGraphite(Segment *seg, uint8 firstPass, uint8 lastPass, int dobidi) const
- {
-     assert(seg != 0);
--    SlotMap            map(*seg, m_dir);
-+    unsigned int       maxSize = seg->slotCount() * MAX_SEG_GROWTH_FACTOR;
-+    SlotMap            map(*seg, m_dir, maxSize);
-     FiniteStateMachine fsm(map, seg->getFace()->logger());
-     vm::Machine        m(map);
--    unsigned int       initSize = seg->slotCount();
-     uint8              lbidi = m_bPass;
- #if !defined GRAPHITE2_NTRACING
-     json * const dbgout = seg->getFace()->logger();
- #endif
- 
-     if (lastPass == 0)
-     {
-         if (firstPass == lastPass && lbidi == 0xFF)
-@@ -419,13 +419,13 @@ bool Silf::runGraphite(Segment *seg, uin
- 
-         // test whether to reorder, prepare for positioning
-         bool reverse = (lbidi == 0xFF) && (seg->currdir() != ((m_dir & 1) ^ m_passes[i].reverseDir()));
-         if ((i >= 32 || (seg->passBits() & (1 << i)) == 0 || m_passes[i].collisionLoops())
-                 && !m_passes[i].runGraphite(m, fsm, reverse))
-             return false;
-         // only subsitution passes can change segment length, cached subsegments are short for their text
-         if (m.status() != vm::Machine::finished
--            || (seg->slotCount() && seg->slotCount() * MAX_SEG_GROWTH_FACTOR < initSize))
-+            || (seg->slotCount() && seg->slotCount() > maxSize))
-             return false;
-     }
-     return true;
- }
-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
-@@ -80,20 +80,20 @@ void Slot::set(const Slot & orig, int ch
- 
- void Slot::update(int /*numGrSlots*/, int numCharInfo, Position &relpos)
- {
-     m_before += numCharInfo;
-     m_after += numCharInfo;
-     m_position = m_position + relpos;
- }
- 
--Position Slot::finalise(const Segment *seg, const Font *font, Position & base, Rect & bbox, uint8 attrLevel, float & clusterMin, bool rtl, bool isFinal)
-+Position Slot::finalise(const Segment *seg, const Font *font, Position & base, Rect & bbox, uint8 attrLevel, float & clusterMin, bool rtl, bool isFinal, int depth)
- {
-     SlotCollision *coll = NULL;
--    if (attrLevel && m_attLevel > attrLevel) return Position(0, 0);
-+    if (depth > 100 || (attrLevel && m_attLevel > attrLevel)) return Position(0, 0);
-     float scale = font ? font->scale() : 1.0f;
-     Position shift(m_shift.x * (rtl * -2 + 1) + m_just, m_shift.y);
-     float tAdvance = m_advance.x + m_just;
-     if (isFinal && (coll = seg->collisionInfo(this)))
-     {
-         const Position &collshift = coll->offset();
-         if (!(coll->flags() & SlotCollision::COLL_KERN) || rtl)
-             shift = shift + collshift;
-@@ -128,23 +128,23 @@ Position Slot::finalise(const Segment *s
-     if (glyphFace)
-     {
-         Rect ourBbox = glyphFace->theBBox() * scale + m_position;
-         bbox = bbox.widen(ourBbox);
-     }
- 
-     if (m_child && m_child != this && m_child->attachedTo() == this)
-     {
--        Position tRes = m_child->finalise(seg, font, m_position, bbox, attrLevel, clusterMin, rtl, isFinal);
-+        Position tRes = m_child->finalise(seg, font, m_position, bbox, attrLevel, clusterMin, rtl, isFinal, depth + 1);
-         if ((!m_parent || m_advance.x >= 0.5f) && tRes.x > res.x) res = tRes;
-     }
- 
-     if (m_parent && m_sibling && m_sibling != this && m_sibling->attachedTo() == m_parent)
-     {
--        Position tRes = m_sibling->finalise(seg, font, base, bbox, attrLevel, clusterMin, rtl, isFinal);
-+        Position tRes = m_sibling->finalise(seg, font, base, bbox, attrLevel, clusterMin, rtl, isFinal, depth + 1);
-         if (tRes.x > res.x) res = tRes;
-     }
-     
-     if (!m_parent && clusterMin < base.x)
-     {
-         Position adj = Position(m_position.x - clusterMin, 0.);
-         res += adj;
-         m_position += adj;
-@@ -160,35 +160,35 @@ int32 Slot::clusterMetric(const Segment 
-         return 0;
-     Rect bbox = seg->theGlyphBBoxTemporary(glyph());
-     float clusterMin = 0.;
-     Position res = finalise(seg, NULL, base, bbox, attrLevel, clusterMin, rtl, false);
- 
-     switch (metrics(metric))
-     {
-     case kgmetLsb :
--        return static_cast<uint32>(bbox.bl.x);
-+        return bbox.bl.x;
-     case kgmetRsb :
--        return static_cast<uint32>(res.x - bbox.tr.x);
-+        return res.x - bbox.tr.x;
-     case kgmetBbTop :
--        return static_cast<uint32>(bbox.tr.y);
-+        return bbox.tr.y;
-     case kgmetBbBottom :
--        return static_cast<uint32>(bbox.bl.y);
-+        return bbox.bl.y;
-     case kgmetBbLeft :
--        return static_cast<uint32>(bbox.bl.x);
-+        return bbox.bl.x;
-     case kgmetBbRight :
--        return static_cast<uint32>(bbox.tr.x);
-+        return bbox.tr.x;
-     case kgmetBbWidth :
--        return static_cast<uint32>(bbox.tr.x - bbox.bl.x);
-+        return bbox.tr.x - bbox.bl.x;
-     case kgmetBbHeight :
--        return static_cast<uint32>(bbox.tr.y - bbox.bl.y);
-+        return bbox.tr.y - bbox.bl.y;
-     case kgmetAdvWidth :
--        return static_cast<uint32>(res.x);
-+        return res.x;
-     case kgmetAdvHeight :
--        return static_cast<uint32>(res.y);
-+        return res.y;
-     default :
-         return 0;
-     }
- }
- 
- #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
-@@ -290,19 +290,32 @@ void Slot::setAttr(Segment *seg, attrCod
-     case gr_slatAdvX :  m_advance.x = value; break;
-     case gr_slatAdvY :  m_advance.y = value; break;
-     case gr_slatAttTo :
-     {
-         const uint16 idx = uint16(value);
-         if (idx < map.size() && map[idx])
-         {
-             Slot *other = map[idx];
--            if (other == this || other == m_parent) break;
--            if (m_parent) m_parent->removeChild(this);
--            if (!other->isChildOf(this) && other->child(this))
-+            if (other == this || other == m_parent || other->isCopied()) break;
-+            if (m_parent) { m_parent->removeChild(this); attachTo(NULL); }
-+            Slot *pOther = other;
-+            int count = 0;
-+            bool foundOther = false;
-+            while (pOther)
-+            {
-+                ++count;
-+                if (pOther == this) foundOther = true;
-+                pOther = pOther->attachedTo();
-+            }
-+            for (pOther = m_child; pOther; pOther = pOther->m_child)
-+                ++count;
-+            for (pOther = m_sibling; pOther; pOther = pOther->m_sibling)
-+                ++count;
-+            if (count < 100 && !foundOther && other->child(this))
-             {
-                 attachTo(other);
-                 if ((map.dir() != 0) ^ (idx > subindex))
-                     m_with = Position(advance(), 0);
-                 else        // normal match to previous root
-                     m_attach = Position(other->advance(), 0);
-             }
-         }
-@@ -416,41 +429,34 @@ bool Slot::sibling(Slot *ap)
-         m_sibling = ap;
-     else
-         return m_sibling->sibling(ap);
-     return true;
- }
- 
- bool Slot::removeChild(Slot *ap)
- {
--    if (this == ap || !m_child) return false;
-+    if (this == ap || !m_child || !ap) return false;
-     else if (ap == m_child)
-     {
-         Slot *nSibling = m_child->nextSibling();
--        m_child->removeSibling(nSibling);
-+        m_child->nextSibling(NULL);
-         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)
-+    for (Slot *p = m_child; p; p = p->m_sibling)
-     {
--        m_sibling = m_sibling->nextSibling();
--        if (m_sibling) ap->removeSibling(m_sibling);
--        return true;
-+        if (p->m_sibling && p->m_sibling == ap)
-+        {
-+            p->m_sibling = p->m_sibling->m_sibling;
-+            ap->nextSibling(NULL);
-+            return true;
-+        }
-     }
--    else
--        return m_sibling->removeSibling(ap);
--    return true;
-+    return false;
- }
- 
- void Slot::setGlyph(Segment *seg, uint16 glyphid, const GlyphFace * theGlyph)
- {
-     m_glyphid = glyphid;
-     m_bidiCls = -1;
-     if (!theGlyph)
-     {
-@@ -475,21 +481,23 @@ void Slot::setGlyph(Segment *seg, uint16
-     if (seg->silf()->aPassBits())
-     {
-         seg->mergePassBits(theGlyph->attrs()[seg->silf()->aPassBits()]);
-         if (seg->silf()->numPasses() > 16)
-             seg->mergePassBits(theGlyph->attrs()[seg->silf()->aPassBits()+1] << 16);
-     }
- }
- 
--void Slot::floodShift(Position adj)
-+void Slot::floodShift(Position adj, int depth)
- {
-+    if (depth > 100)
-+        return;
-     m_position += adj;
--    if (m_child) m_child->floodShift(adj);
--    if (m_sibling) m_sibling->floodShift(adj);
-+    if (m_child) m_child->floodShift(adj, depth + 1);
-+    if (m_sibling) m_sibling->floodShift(adj, depth + 1);
- }
- 
- void SlotJustify::LoadSlot(const Slot *s, const Segment *seg)
- {
-     for (int i = seg->silf()->numJustLevels() - 1; i >= 0; --i)
-     {
-         Justinfo *justs = seg->silf()->justAttrs() + i;
-         int16 *v = values + i * NUMJUSTPARAMS;
-@@ -514,15 +522,14 @@ Slot * Slot::nextInCluster(const Slot *s
-             return base->nextSibling();
-         s = base;
-     }
-     return NULL;
- }
- 
- bool Slot::isChildOf(const Slot *base) const
- {
--    if (m_parent == base)
--        return true;
--    else if (!m_parent)
--        return false;
--    else
--        return m_parent->isChildOf(base);
-+    for (Slot *p = m_parent; p; p = p->m_parent)
-+        if (p == base)
-+            return true;
-+    return false;
- }
-+
-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
-@@ -891,25 +891,27 @@ const void * FindCmapSubtable(const void
- ----------------------------------------------------------------------------------------------*/
- 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;
-+    if (table_len < sizeof(*pTable) || be::swap(pTable->format) != 4) return false;
-     const Sfnt::CmapSubTableFormat4 * pTable4 = reinterpret_cast<const Sfnt::CmapSubTableFormat4 *>(pCmapSubtable4);
-+    if (table_len < sizeof(*pTable4))
-+        return false;
-     uint16 length = be::swap(pTable4->length);
-     if (length > table_len)
-         return false;
-     if (length < sizeof(Sfnt::CmapSubTableFormat4))
-         return false;
-     uint16 nRanges = be::swap(pTable4->seg_count_x2) >> 1;
--    if (length < sizeof(Sfnt::CmapSubTableFormat4) + 4 * nRanges * sizeof(uint16))
-+    if (!nRanges || length < sizeof(Sfnt::CmapSubTableFormat4) + 4 * nRanges * sizeof(uint16))
-         return false;
-     // check last range is properly terminated
-     uint16 chEnd = be::peek<uint16>(pTable4->end_code + nRanges - 1);
-     if (chEnd != 0xFFFF)
-         return false;
- #if 0
-     int lastend = -1;
-     for (int i = 0; i < nRanges; ++i)
-@@ -999,17 +1001,17 @@ gid16 CmapSubtable4Lookup(const void * p
-         uint16 idRangeOffset = be::peek<uint16>(pMid += nSeg);
- 
-         if (idRangeOffset == 0)
-             return (uint16)(idDelta + nUnicodeId); // must use modulus 2^16
- 
-         // Look up value in glyphIdArray
-         const ptrdiff_t offset = (nUnicodeId - chStart) + (idRangeOffset >> 1) +
-                 (pMid - reinterpret_cast<const uint16 *>(pTable));
--        if (offset * 2 >= be::swap<uint16>(pTable->length))
-+        if (offset * 2 + 1 >= be::swap<uint16>(pTable->length))
-             return 0;
-         gid16 nGlyphId = be::peek<uint16>(reinterpret_cast<const uint16 *>(pTable)+offset);
-         // If this value is 0, return 0. Else add the idDelta
-         return nGlyphId ? nGlyphId + idDelta : 0;
-     }
- 
-     return 0;
- }
-@@ -1081,19 +1083,21 @@ unsigned int CmapSubtable4NextCodepoint(
- /*----------------------------------------------------------------------------------------------
-     Check the Microsoft UCS-4 subtable for expected values.
- ----------------------------------------------------------------------------------------------*/
- 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)
-+    if (table_len < sizeof(*pTable) || be::swap(pTable->format) != 12)
-         return false;
-     const Sfnt::CmapSubTableFormat12 * pTable12 = reinterpret_cast<const Sfnt::CmapSubTableFormat12 *>(pCmapSubtable12);
-+    if (table_len < sizeof(*pTable12))
-+        return false;
-     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 (num_groups > 0x10000000 || length != (sizeof(Sfnt::CmapSubTableFormat12) + (num_groups - 1) * sizeof(uint32) * 3))
-         return false;
-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
-@@ -81,17 +81,17 @@ private:
-                 _modify,
-                 _delete;
-     mutable bool _own;
- 
-     void release_buffers() throw ();
-     void failure(const status_t) throw();
- 
- public:
--    static size_t estimateCodeDataOut(size_t num_bytecodes);
-+    static size_t estimateCodeDataOut(size_t num_bytecodes, int nRules, int nSlots);
- 
-     Code() throw();
-     Code(bool is_constraint, const byte * bytecode_begin, const byte * const bytecode_end,
-          uint8 pre_context, uint16 rule_length, const Silf &, const Face &,
-          enum passtype pt, byte * * const _out = 0);
-     Code(const Machine::Code &) throw();
-     ~Code() throw();
-     
-@@ -107,19 +107,21 @@ public:
-     void          externalProgramMoved(ptrdiff_t) throw();
- 
-     int32 run(Machine &m, slotref * & map) const;
-     
-     CLASS_NEW_DELETE;
- };
- 
- inline
--size_t  Machine::Code::estimateCodeDataOut(size_t n_bc)
-+size_t  Machine::Code::estimateCodeDataOut(size_t n_bc, int nRules, int nSlots)
- {
--    return (n_bc + 1) * (sizeof(instr)+sizeof(byte));
-+    // max is: all codes are instructions + 1 for each rule + max tempcopies
-+    // allocate space for separate maximal code and data then merge them later
-+    return (n_bc + nRules + nSlots) * sizeof(instr) + n_bc * 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/Face.h b/gfx/graphite2/src/inc/Face.h
---- a/gfx/graphite2/src/inc/Face.h
-+++ b/gfx/graphite2/src/inc/Face.h
-@@ -82,17 +82,17 @@ public:
-     uint16              languageForLocale(const char * locale) const;
- 
-     // Features
-     uint16              numFeatures() const;
-     const FeatureRef  * featureById(uint32 id) const;
-     const FeatureRef  * feature(uint16 index) const;
- 
-     // Glyph related
--    uint16 getGlyphMetric(uint16 gid, uint8 metric) const;
-+    int32  getGlyphMetric(uint16 gid, uint8 metric) const;
-     uint16 findPseudo(uint32 uid) const;
- 
-     // Errors
-     unsigned int        error() const { return m_error; }
-     bool                error(Error e) { m_error = e.error(); return false; }
-     unsigned int        error_context() const { return m_error; }
-     void                error_context(unsigned int errcntxt) { m_errcntxt = errcntxt; }
- 
-diff --git a/gfx/graphite2/src/inc/GlyphFace.h b/gfx/graphite2/src/inc/GlyphFace.h
---- a/gfx/graphite2/src/inc/GlyphFace.h
-+++ b/gfx/graphite2/src/inc/GlyphFace.h
-@@ -46,17 +46,17 @@ class GlyphFace
- public:
-     GlyphFace();
-     template<typename I>
-     GlyphFace(const Rect & bbox, const Position & adv, I first, const I last);
- 
-     const Position    & theAdvance() const;
-     const Rect        & theBBox() const { return m_bbox; }
-     const sparse      & attrs() const { return m_attrs; }
--    uint16              getMetric(uint8 metric) const;
-+    int32               getMetric(uint8 metric) const;
- 
-     CLASS_NEW_DELETE;
- private:
-     Rect     m_bbox;        // bounding box metrics in design units
-     Position m_advance;     // Advance width and height in design units
-     sparse   m_attrs;
- };
- 
-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
-@@ -179,17 +179,17 @@ inline SlotMap& Machine::slotMap() const
-     return _map;
- }
- 
- inline Machine::status_t Machine::status() const throw()
- {
-     return _status;
- }
- 
--inline void Machine::check_final_stack(const int32 * const sp)
-+inline void Machine::check_final_stack(const stack_t * const sp)
- {
-     stack_t const * const base  = _stack + STACK_GUARD,
-                   * const limit = base + STACK_MAX;
-     if      (sp <  base)    _status = stack_underflow;       // This should be impossible now.
-     else if (sp >= limit)   _status = stack_overflow;        // So should this.
-     else if (sp != base)    _status = stack_not_empty;
- }
- 
-diff --git a/gfx/graphite2/src/inc/Pass.h b/gfx/graphite2/src/inc/Pass.h
---- a/gfx/graphite2/src/inc/Pass.h
-+++ b/gfx/graphite2/src/inc/Pass.h
-@@ -76,17 +76,17 @@ private:
-     void    dumpRuleEventConsidered(const FiniteStateMachine & fsm, const RuleEntry & re) const;
-     void    dumpRuleEventOutput(const FiniteStateMachine & fsm, vm::Machine & m, const Rule & r, Slot * os) const;
-     void    adjustSlot(int delta, Slot * & slot_out, SlotMap &) const;
-     bool    collisionShift(Segment *seg, int dir, json * const dbgout) const;
-     bool    collisionKern(Segment *seg, int dir, json * const dbgout) const;
-     bool    collisionFinish(Segment *seg, GR_MAYBE_UNUSED json * const dbgout) const;
-     bool    resolveCollisions(Segment *seg, Slot *slot, Slot *start, ShiftCollider &coll, bool isRev,
-                      int dir, bool &moved, bool &hasCol, json * const dbgout) const;
--    float   resolveKern(Segment *seg, Slot *slot, Slot *start, KernCollider &coll, int dir,
-+    float   resolveKern(Segment *seg, Slot *slot, Slot *start, int dir,
-                      float &ymin, float &ymax, json *const dbgout) const;
- 
-     const Silf        * m_silf;
-     uint16            * m_cols;
-     Rule              * m_rules; // rules
-     RuleEntry         * m_ruleMap;
-     uint16            * m_startStates; // prectxt length
-     uint16            * m_transitions;
-diff --git a/gfx/graphite2/src/inc/Rule.h b/gfx/graphite2/src/inc/Rule.h
---- a/gfx/graphite2/src/inc/Rule.h
-+++ b/gfx/graphite2/src/inc/Rule.h
-@@ -97,17 +97,17 @@ bool State::empty() const
-     return rules_end == rules;
- }
- 
- 
- class SlotMap
- {
- public:
-   enum {MAX_SLOTS=64};
--  SlotMap(Segment & seg, uint8 direction);
-+  SlotMap(Segment & seg, uint8 direction, int maxSize);
-   
-   Slot       * * begin();
-   Slot       * * end();
-   size_t         size() const;
-   unsigned short context() const;
-   void           reset(Slot &, unsigned short);
-   
-   Slot * const & operator[](int n) const;
-@@ -116,23 +116,25 @@ public:
-   void           collectGarbage(Slot *& aSlot);
- 
-   Slot         * highwater() { return m_highwater; }
-   void           highwater(Slot *s) { m_highwater = s; m_highpassed = false; }
-   bool           highpassed() const { return m_highpassed; }
-   void           highpassed(bool v) { m_highpassed = v; }
- 
-   uint8          dir() const { return m_dir; }
-+  int            decMax() { return --m_maxSize; }
- 
-   Segment &    segment;
- private:
-   Slot         * m_slot_map[MAX_SLOTS+1];
-   unsigned short m_size;
-   unsigned short m_precontext;
-   Slot         * m_highwater;
-+  int            m_maxSize;
-   uint8          m_dir;
-   bool           m_highpassed;
- };
- 
- 
- class FiniteStateMachine
- {
- public:
-@@ -237,18 +239,19 @@ void FiniteStateMachine::Rules::accumula
-       return;
-     }
-   }
-   while (rre != rrend && out != lrend) { *out++ = *rre++; }
-   m_end = out;
- }
- 
- inline
--SlotMap::SlotMap(Segment & seg, uint8 direction)
--: segment(seg), m_size(0), m_precontext(0), m_highwater(0), m_dir(direction), m_highpassed(false)
-+SlotMap::SlotMap(Segment & seg, uint8 direction, int maxSize)
-+: segment(seg), m_size(0), m_precontext(0), m_highwater(0),
-+    m_maxSize(maxSize), m_dir(direction), m_highpassed(false)
- {
-     m_slot_map[0] = 0;
- }
- 
- inline
- Slot * * SlotMap::begin()
- {
-   return &m_slot_map[1]; // allow map to go 1 before slot_map when inserting
-diff --git a/gfx/graphite2/src/inc/Segment.h b/gfx/graphite2/src/inc/Segment.h
---- a/gfx/graphite2/src/inc/Segment.h
-+++ b/gfx/graphite2/src/inc/Segment.h
-@@ -35,17 +35,17 @@ of the License or (at your option) any l
- #include "inc/FeatureVal.h"
- #include "inc/GlyphCache.h"
- #include "inc/GlyphFace.h"
- #include "inc/Slot.h"
- #include "inc/Position.h"
- #include "inc/List.h"
- #include "inc/Collider.h"
- 
--#define MAX_SEG_GROWTH_FACTOR  256
-+#define MAX_SEG_GROWTH_FACTOR  64
- 
- namespace graphite2 {
- 
- typedef Vector<Features>        FeatureList;
- typedef Vector<Slot *>          SlotRope;
- typedef Vector<int16 *>         AttributeRope;
- typedef Vector<SlotJustify *>   JustifyRope;
- 
-@@ -154,17 +154,17 @@ public:
-     int8 getSlotBidiClass(Slot *s) const;
-     void doMirror(uint16 aMirror);
-     Slot *addLineEnd(Slot *nSlot);
-     void delLineEnd(Slot *s);
-     bool hasJustification() const { return m_justifies.size() != 0; }
-     void reverseSlots();
- 
-     bool isWhitespace(const int cid) const;
--    bool hasCollisionInfo() const { return (m_flags & SEG_HASCOLLISIONS); }
-+    bool hasCollisionInfo() const { return (m_flags & SEG_HASCOLLISIONS) && m_collisions; }
-     SlotCollision *collisionInfo(const Slot *s) const { return m_collisions ? m_collisions + s->index() : 0; }
-     CLASS_NEW_DELETE
- 
- public:       //only used by: GrSegment* makeAndInitialize(const GrFont *font, const GrFace *face, uint32 script, const FeaturesHandle& pFeats/*must not be IsNull*/, encform enc, const void* pStart, size_t nChars, int dir);
-     bool read_text(const Face *face, const Features* pFeats/*must not be NULL*/, gr_encform enc, const void*pStart, size_t nChars);
-     void finalise(const Font *font, bool reverse=false);
-     float justify(Slot *pSlot, const Font *font, float width, enum justFlags flags, Slot *pFirst, Slot *pLast);
-     bool initCollisions();
-diff --git a/gfx/graphite2/src/inc/Slot.h b/gfx/graphite2/src/inc/Slot.h
---- a/gfx/graphite2/src/inc/Slot.h
-+++ b/gfx/graphite2/src/inc/Slot.h
-@@ -92,17 +92,17 @@ public:
-     void adjKern(const Position &pos) { m_shift = m_shift + pos; m_advance = m_advance + pos; }
-     void origin(const Position &pos) { m_position = pos + m_shift; }
-     void originate(int ind) { m_original = ind; }
-     int original() const { return m_original; }
-     void before(int ind) { m_before = ind; }
-     void after(int ind) { m_after = ind; }
-     bool isBase() const { return (!m_parent); }
-     void update(int numSlots, int numCharInfo, Position &relpos);
--    Position finalise(const Segment* seg, const Font* font, Position & base, Rect & bbox, uint8 attrLevel, float & clusterMin, bool rtl, bool isFinal);
-+    Position finalise(const Segment* seg, const Font* font, Position & base, Rect & bbox, uint8 attrLevel, float & clusterMin, bool rtl, bool isFinal, int depth = 0);
-     bool isDeleted() const { return (m_flags & DELETED) ? true : false; }
-     void markDeleted(bool state) { if (state) m_flags |= DELETED; else m_flags &= ~DELETED; }
-     bool isCopied() const { return (m_flags & COPIED) ? true : false; }
-     void markCopied(bool state) { if (state) m_flags |= COPIED; else m_flags &= ~COPIED; }
-     bool isPositioned() const { return (m_flags & POSITIONED) ? true : false; }
-     void markPositioned(bool state) { if (state) m_flags |= POSITIONED; else m_flags &= ~POSITIONED; }
-     bool isInsertBefore() const { return !(m_flags & INSERTED); }
-     uint8 getBidiLevel() const { return m_bidiLevel; }
-@@ -123,20 +123,19 @@ public:
-     Position attachOffset() const { return m_attach - m_with; }
-     Slot* firstChild() const { return m_child; }
-     void firstChild(Slot *ap) { m_child = ap; }
-     bool child(Slot *ap);
-     Slot* nextSibling() const { return m_sibling; }
-     void nextSibling(Slot *ap) { m_sibling = ap; }
-     bool sibling(Slot *ap);
-     bool removeChild(Slot *ap);
--    bool removeSibling(Slot *ap);
-     int32 clusterMetric(const Segment* seg, uint8 metric, uint8 attrLevel, bool rtl);
-     void positionShift(Position a) { m_position += a; }
--    void floodShift(Position adj);
-+    void floodShift(Position adj, int depth = 0);
-     float just() const { return m_just; }
-     void just(float j) { m_just = j; }
-     Slot *nextInCluster(const Slot *s) const;
-     bool isChildOf(const Slot *base) const;
- 
-     CLASS_NEW_DELETE
- 
- private:
-diff --git a/gfx/graphite2/src/inc/UtfCodec.h b/gfx/graphite2/src/inc/UtfCodec.h
---- a/gfx/graphite2/src/inc/UtfCodec.h
-+++ b/gfx/graphite2/src/inc/UtfCodec.h
-@@ -35,16 +35,17 @@ typedef uint32  uchar_t;
- 
- template <int N>
- struct _utf_codec
- {
-     typedef uchar_t codeunit_t;
- 
-     static void     put(codeunit_t * cp, const uchar_t , int8 & len) throw();
-     static uchar_t  get(const codeunit_t * cp, int8 & len) throw();
-+    static bool     validate(const codeunit_t * s, const codeunit_t * e) throw();
- };
- 
- 
- template <>
- struct _utf_codec<32>
- {
- private:
-     static const uchar_t    limit = 0x110000;
-@@ -58,16 +59,22 @@ public:
-     }
- 
-     inline
-     static uchar_t get(const codeunit_t * cp, int8 & l) throw()
-     {
-         if (cp[0] < limit)  { l = 1;  return cp[0]; }
-         else                { l = -1; return 0xFFFD; }
-     }
-+
-+    inline
-+    static bool validate(codeunit_t * s, codeunit_t * e) throw()
-+    {
-+        return e > s;
-+    }
- };
- 
- 
- template <>
- struct _utf_codec<16>
- {
- private:
-     static const int32  lead_offset      = 0xD800 - (0x10000 >> 10);
-@@ -88,22 +95,31 @@ public:
-     }
- 
-     inline
-     static uchar_t get(const codeunit_t * cp, int8 & l) throw()
-     {
-         const uint32    uh = cp[0];
-         l = 1;
- 
--        if (0xD800 > uh || uh > 0xDFFF) { return uh; }
-+        if (uh < 0xD800|| uh > 0xDFFF) { return uh; }
-         const uint32 ul = cp[1];
--        if (uh > 0xDBFF || 0xDC00 > ul || ul > 0xDFFF) { l = -1; return 0xFFFD; }
-+        if (uh > 0xDBFF || ul < 0xDC00 || ul > 0xDFFF) { l = -1; return 0xFFFD; }
-         ++l;
-         return (uh<<10) + ul + surrogate_offset;
-     }
-+
-+    inline
-+    static bool validate(codeunit_t * s, codeunit_t * e) throw()
-+    {
-+        const ptrdiff_t n = e-s;
-+        if (n <= 0) return n == 0;
-+        const uint32 u = *(s+(n-1)); // Get the last codepoint
-+        return (u < 0xD800 || u > 0xDBFF);
-+    }
- };
- 
- 
- template <>
- struct _utf_codec<8>
- {
- private:
-     static const int8 sz_lut[16];
-@@ -143,16 +159,34 @@ public:
- 
-         if (l != seq_sz || toolong)
-         {
-             l = -l;
-             return 0xFFFD;
-         }
-         return u;
-     }
-+
-+    inline
-+    static bool validate(codeunit_t * s, codeunit_t * e) throw()
-+    {
-+        const ptrdiff_t n = e-s;
-+        if (n <= 0) return n == 0;
-+        s += (n-1);
-+        if (*s < 0x80) return true;
-+        if (*s >= 0xC0) return false;
-+        if (n == 1) return true;
-+        if (*--s < 0x80) return true;
-+        if (*s >= 0xe0) return false;
-+        if (n == 2 || *s >= 0xC0) return true;
-+        if (*--s < 0x80) return true;
-+        if (*s >= 0xF0) return false;
-+        return true;
-+    }
-+
- };
- 
- 
- template <typename C>
- class _utf_iterator
- {
-     typedef _utf_codec<sizeof(C)*8> codec;
- 
-@@ -195,16 +229,21 @@ public:
- 
- template <typename C>
- struct utf
- {
-     typedef typename _utf_codec<sizeof(C)*8>::codeunit_t codeunit_t;
- 
-     typedef _utf_iterator<C>        iterator;
-     typedef _utf_iterator<const C>  const_iterator;
-+
-+    inline
-+    static bool validate(codeunit_t * s, codeunit_t * e) throw() {
-+        return _utf_codec<sizeof(C)*8>::validate(s,e);
-+    }
- };
- 
- 
- typedef utf<uint32> utf32;
- typedef utf<uint16> utf16;
- typedef utf<uint8>  utf8;
- 
- } // namespace graphite2
-diff --git a/gfx/graphite2/src/inc/opcode_table.h b/gfx/graphite2/src/inc/opcode_table.h
---- a/gfx/graphite2/src/inc/opcode_table.h
-+++ b/gfx/graphite2/src/inc/opcode_table.h
-@@ -113,13 +113,13 @@ static const opcode_t opcode_table[] =
-     {{NILOP,NILOP},                                 0, "PUT_SUBS3"},
-     {{do_(put_glyph), NILOP},                       2, "PUT_GLYPH"},                // output_class output_class
-     {{do2(push_glyph_attr)},                        3, "PUSH_GLYPH_ATTR"},          // gattrnum gattrnum slot
-     {{do2(push_att_to_glyph_attr)},                 3, "PUSH_ATT_TO_GLYPH_ATTR"},   // gattrnum gattrnum slot
-     {{do2(bor)},                                    0, "BITOR"},
-     {{do2(band)},                                   0, "BITAND"},
-     {{do2(bnot)},                                   0, "BITNOT"},   // 0x40
-     {{do2(setbits)},                                4, "BITSET"},
--    {{do2(set_feat)},                               2, "SET_FEAT"},
-+    {{do_(set_feat), NILOP},                        2, "SET_FEAT"},                 // featidx slot
-     // private opcodes for internal use only, comes after all other on disk opcodes.
-     {{do_(temp_copy), NILOP},                       0, "TEMP_COPY"}
- };
- 
-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
-@@ -62,17 +62,18 @@ of the License or (at your option) any l
- //        ip        = The current instruction pointer
- //        endPos    = Position of advance of last cluster
- //        dir       = writing system directionality of the font
-      
- 
- // #define NOT_IMPLEMENTED     assert(false)
- #define NOT_IMPLEMENTED
- 
--#define binop(op)           const int32 a = pop(); *sp = int32(*sp) op a
-+#define binop(op)           const uint32 a = pop(); *sp = uint32(*sp) op a
-+#define sbinop(op)          const int32 a = pop(); *sp = int32(*sp) op a
- #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)])
-@@ -125,17 +126,17 @@ STARTOP(sub)
- ENDOP
- 
- STARTOP(mul)
-     binop(*);
- ENDOP
- 
- STARTOP(div_)
-     if (*sp == 0) DIE;
--    binop(/);
-+    sbinop(/);
- ENDOP
- 
- STARTOP(min_)
-     const int32 a = pop(), b = *sp;
-     if (a < b) *sp = a;
- ENDOP
- 
- STARTOP(max_)
-@@ -176,29 +177,29 @@ STARTOP(equal)
-     binop(==);
- ENDOP
- 
- STARTOP(not_eq_)
-     binop(!=);
- ENDOP
- 
- STARTOP(less)
--    binop(<);
-+    sbinop(<);
- ENDOP
- 
- STARTOP(gtr)
--    binop(>);
-+    sbinop(>);
- ENDOP
- 
- STARTOP(less_eq)
--    binop(<=);
-+    sbinop(<=);
- ENDOP
- 
- STARTOP(gtr_eq)
--    binop(>=);
-+    sbinop(>=);
- ENDOP
- 
- STARTOP(next)
-     if (map - &smap[0] >= int(smap.size())) DIE
-     if (is)
-     {
-         if (is == smap.highwater())
-             smap.highpassed(true);
-@@ -237,17 +238,17 @@ STARTOP(put_subs_8bit_obs)
-         index = seg.findClassIndex(input_class, slot->gid());
-         is->setGlyph(&seg, seg.getClassGlyph(output_class, index));
-     }
- ENDOP
- 
- STARTOP(put_copy)
-     declare_params(1);
-     const int  slot_ref = int8(*param);
--    if (is)
-+    if (is && !is->isDeleted())
-     {
-         slotref ref = slotat(slot_ref);
-         if (ref && ref != is)
-         {
-             int16 *tempUserAttrs = is->userAttrs();
-             if (is->attachedTo() || is->firstChild()) DIE
-             Slot *prev = is->prev();
-             Slot *next = is->next();
-@@ -262,16 +263,17 @@ STARTOP(put_copy)
-                 is->attachedTo()->child(is);
-         }
-         is->markCopied(false);
-         is->markDeleted(false);
-     }
- ENDOP
- 
- STARTOP(insert)
-+    if (smap.decMax() <= 0) DIE;
-     Slot *newSlot = seg.newSlot();
-     if (!newSlot) DIE;
-     Slot *iss = is;
-     while (iss && iss->isDeleted()) iss = iss->next();
-     if (!iss)
-     {
-         if (seg.last())
-         {
-@@ -550,31 +552,31 @@ ENDOP
- 
- STARTOP(iattr_add)
-     declare_params(2);
-     const attrCode      slat = attrCode(uint8(param[0]));
-     const size_t        idx  = uint8(param[1]);
-     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, idx);
-     is->setAttr(&seg, slat, idx, val + res, smap);
- ENDOP
- 
- STARTOP(iattr_sub)
-     declare_params(2);
-     const attrCode      slat = attrCode(uint8(param[0]));
-     const size_t        idx  = uint8(param[1]);
-     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, idx);
-     is->setAttr(&seg, slat, idx, res - val, smap);
- ENDOP
- 
- STARTOP(push_proc_state)
-     use_params(1);
-
diff --git a/gnu/packages/patches/imagemagick-test-segv.patch b/gnu/packages/patches/imagemagick-test-segv.patch
deleted file mode 100644
index 6626e54828..0000000000
--- a/gnu/packages/patches/imagemagick-test-segv.patch
+++ /dev/null
@@ -1,20 +0,0 @@
-This patch works around a segmentation fault in 'Magick++/tests/color' when
-running 'Magick++/tests/tests.tap'.  Here we get an exception early on, which
-is supposedly harmless:
-
-  Caught exception: color: UnableToOpenConfigureFile `colors.xml' @ warning/configure.c/GetConfigureOptions/706
-
-However, when the stack unwinders run, 'UnregisterDOTImage' gets called even
-though 'RegisterDOTImage' hadn't been called yet; thus, 'graphic_context' in
-coders/dot.c is NULL, leading to the segfault.
-
---- ImageMagick-6.9.2-1/coders/dot.c	2015-09-16 17:32:42.900323334 +0200
-+++ ImageMagick-6.9.2-1/coders/dot.c	2015-09-16 17:32:48.312367636 +0200
-@@ -240,6 +240,7 @@ ModuleExport void UnregisterDOTImage(voi
-   (void) UnregisterMagickInfo("GV");
-   (void) UnregisterMagickInfo("DOT");
- #if defined(MAGICKCORE_GVC_DELEGATE)
-+  if (graphic_context != NULL)
-   gvFreeContext(graphic_context);
- #endif
- }
diff --git a/gnu/packages/patches/imlib2-CVE-2016-4024.patch b/gnu/packages/patches/imlib2-CVE-2016-4024.patch
deleted file mode 100644
index c4f1f21b28..0000000000
--- a/gnu/packages/patches/imlib2-CVE-2016-4024.patch
+++ /dev/null
@@ -1,52 +0,0 @@
-Fix CVE-2016-4024 (integer overflow in lib/image.h).
-
-https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-4024
-
-Upstream source:
-https://git.enlightenment.org/legacy/imlib2.git/commit/?id=7eba2e4c8ac0e20838947f10f29d0efe1add8227
-
-From 7eba2e4c8ac0e20838947f10f29d0efe1add8227 Mon Sep 17 00:00:00 2001
-From: "Yuriy M. Kaminskiy" <yumkam@gmail.com>
-Date: Wed, 6 Apr 2016 03:34:01 +0300
-Subject: Fix integer overflow resulting in insufficient heap allocation
-
-IMAGE_DIMENSIONS_OK ensures that image width and height are less then
-46340, so that maximum number of pixels is ~2**31.
-
-Unfortunately, there are a lot of code that allocates image data with
-something like
-
-   malloc(w * h * sizeof(DATA32));
-
-Obviously, on 32-bit machines this results in integer overflow,
-insufficient heap allocation, with [massive] out-of-bounds heap
-overwrite.
-Either X_MAX should be reduced to 32767, or (w)*(h) should be checked to
-not exceed ULONG_MAX/sizeof(DATA32).
-
-Security implications:
-*) for 32-bit machines: insufficient heap allocation and heap overwrite
-in many image loaders, with escalation potential to remote code
-execution;
-*) for 64-bit machines: it seems, no impact.
----
- src/lib/image.h | 3 ++-
- 1 file changed, 2 insertions(+), 1 deletion(-)
-
-diff --git a/src/lib/image.h b/src/lib/image.h
-index e9eb678..5fae6ed 100644
---- a/src/lib/image.h
-+++ b/src/lib/image.h
-@@ -188,7 +188,8 @@ void                __imlib_SaveImage(ImlibImage * im, const char *file,
- 
- /* The maximum pixmap dimension is 65535. */
- /* However, for now, use 46340 (46340^2 < 2^31) to avoid buffer overflow issues. */
--#define X_MAX_DIM 46340
-+/* Reduced further to 32767, so that (w * h * sizeof(DATA32)) won't exceed ULONG_MAX */
-+#define X_MAX_DIM 32767
- 
- #define IMAGE_DIMENSIONS_OK(w, h) \
-    ( ((w) > 0) && ((h) > 0) && ((w) < X_MAX_DIM) && ((h) < X_MAX_DIM) )
--- 
-cgit v0.12
-
diff --git a/gnu/packages/patches/inkscape-drop-wait-for-targets.patch b/gnu/packages/patches/inkscape-drop-wait-for-targets.patch
new file mode 100644
index 0000000000..3dbe6641e2
--- /dev/null
+++ b/gnu/packages/patches/inkscape-drop-wait-for-targets.patch
@@ -0,0 +1,68 @@
+Copied from Fedora.
+
+http://pkgs.fedoraproject.org/cgit/rpms/inkscape.git/plain/inkscape-0.91-drop-wait-for-targets.patch?id=eb5340800b563d6b05aa5f11a2f24f2cc0d8c80e
+
+=== modified file 'src/ui/clipboard.cpp'
+--- src/ui/clipboard.cpp	2016-04-02 15:15:43 +0000
++++ src/ui/clipboard.cpp	2016-04-07 16:30:32 +0000
+@@ -146,8 +146,6 @@
+     void _setClipboardColor(guint32);
+     void _userWarn(SPDesktop *, char const *);
+ 
+-    void _inkscape_wait_for_targets(std::list<Glib::ustring> &);
+-
+     // private properites
+     SPDocument *_clipboardSPDoc; ///< Document that stores the clipboard until someone requests it
+     Inkscape::XML::Node *_defs; ///< Reference to the clipboard document's defs node
+@@ -1302,9 +1300,7 @@
+  */
+ Glib::ustring ClipboardManagerImpl::_getBestTarget()
+ {
+-    // GTKmm's wait_for_targets() is broken, see the comment in _inkscape_wait_for_targets()
+-    std::list<Glib::ustring> targets; // = _clipboard->wait_for_targets();
+-    _inkscape_wait_for_targets(targets);
++    std::list<Glib::ustring> targets = _clipboard->wait_for_targets();
+ 
+     // clipboard target debugging snippet
+     /*
+@@ -1456,39 +1452,6 @@
+     desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, msg);
+ }
+ 
+-
+-// GTKMM's clipboard::wait_for_targets is buggy and might return bogus, see
+-//
+-// https://bugs.launchpad.net/inkscape/+bug/296778
+-// http://mail.gnome.org/archives/gtk-devel-list/2009-June/msg00062.html
+-//
+-// for details. Until this has been fixed upstream we will use our own implementation
+-// of this method, as copied from /gtkmm-2.16.0/gtk/gtkmm/clipboard.cc.
+-void ClipboardManagerImpl::_inkscape_wait_for_targets(std::list<Glib::ustring> &listTargets)
+-{
+-    //Get a newly-allocated array of atoms:
+-    GdkAtom* targets = NULL;
+-    gint n_targets = 0;
+-    gboolean test = gtk_clipboard_wait_for_targets( gtk_clipboard_get(GDK_SELECTION_CLIPBOARD), &targets, &n_targets );
+-    if (!test || (targets == NULL)) {
+-        return;
+-    }
+-
+-    //Add the targets to the C++ container:
+-    for (int i = 0; i < n_targets; i++)
+-    {
+-        //Convert the atom to a string:
+-        gchar* const atom_name = gdk_atom_name(targets[i]);
+-
+-        Glib::ustring target;
+-        if (atom_name) {
+-            target = Glib::ScopedPtr<char>(atom_name).get(); //This frees the gchar*.
+-        }
+-
+-        listTargets.push_back(target);
+-    }
+-}
+-
+ /* #######################################
+           ClipboardManager class
+    ####################################### */
+
diff --git a/gnu/packages/patches/libarchive-CVE-2016-1541.patch b/gnu/packages/patches/libarchive-CVE-2016-1541.patch
new file mode 100644
index 0000000000..6ac8773244
--- /dev/null
+++ b/gnu/packages/patches/libarchive-CVE-2016-1541.patch
@@ -0,0 +1,67 @@
+Fix CVE-2016-1541 (buffer overflow zip_read_mac_metadata)
+
+Taken from upstream source repository:
+https://github.com/libarchive/libarchive/commit/d0331e8e5b05b475f20b1f3101fe1ad772d7e7e7
+
+When reading OS X metadata entries in Zip archives that were stored
+without compression, libarchive would use the uncompressed entry size
+to allocate a buffer but would use the compressed entry size to limit
+the amount of data copied into that buffer.  Since the compressed
+and uncompressed sizes are provided by data in the archive itself,
+an attacker could manipulate these values to write data beyond
+the end of the allocated buffer.
+
+This fix provides three new checks to guard against such
+manipulation and to make libarchive generally more robust when
+handling this type of entry:
+ 1. If an OS X metadata entry is stored without compression,
+    abort the entire archive if the compressed and uncompressed
+    data sizes do not match.
+ 2. When sanity-checking the size of an OS X metadata entry,
+    abort this entry if either the compressed or uncompressed
+    size is larger than 4MB.
+ 3. When copying data into the allocated buffer, check the copy
+    size against both the compressed entry size and uncompressed
+    entry size.
+---
+ libarchive/archive_read_support_format_zip.c | 13 +++++++++++++
+ 1 file changed, 13 insertions(+)
+
+diff --git a/libarchive/archive_read_support_format_zip.c b/libarchive/archive_read_support_format_zip.c
+index 0f8262c..0a0be96 100644
+--- a/libarchive/archive_read_support_format_zip.c
++++ b/libarchive/archive_read_support_format_zip.c
+@@ -2778,6 +2778,11 @@ zip_read_mac_metadata(struct archive_read *a, struct archive_entry *entry,
+ 
+ 	switch(rsrc->compression) {
+ 	case 0:  /* No compression. */
++		if (rsrc->uncompressed_size != rsrc->compressed_size) {
++			archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
++			    "Malformed OS X metadata entry: inconsistent size");
++			return (ARCHIVE_FATAL);
++		}
+ #ifdef HAVE_ZLIB_H
+ 	case 8: /* Deflate compression. */
+ #endif
+@@ -2798,6 +2803,12 @@ zip_read_mac_metadata(struct archive_read *a, struct archive_entry *entry,
+ 		    (intmax_t)rsrc->uncompressed_size);
+ 		return (ARCHIVE_WARN);
+ 	}
++	if (rsrc->compressed_size > (4 * 1024 * 1024)) {
++		archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
++		    "Mac metadata is too large: %jd > 4M bytes",
++		    (intmax_t)rsrc->compressed_size);
++		return (ARCHIVE_WARN);
++	}
+ 
+ 	metadata = malloc((size_t)rsrc->uncompressed_size);
+ 	if (metadata == NULL) {
+@@ -2836,6 +2847,8 @@ zip_read_mac_metadata(struct archive_read *a, struct archive_entry *entry,
+ 			bytes_avail = remaining_bytes;
+ 		switch(rsrc->compression) {
+ 		case 0:  /* No compression. */
++			if ((size_t)bytes_avail > metadata_bytes)
++				bytes_avail = metadata_bytes;
+ 			memcpy(mp, p, bytes_avail);
+ 			bytes_used = (size_t)bytes_avail;
+ 			metadata_bytes -= bytes_used;
diff --git a/gnu/packages/patches/netcdf-config-date.patch b/gnu/packages/patches/netcdf-config-date.patch
new file mode 100644
index 0000000000..5054612e95
--- /dev/null
+++ b/gnu/packages/patches/netcdf-config-date.patch
@@ -0,0 +1,47 @@
+Honor SOURCE_DATE_EPOCH when exporting configuration date.
+Autoconf-level patch submitted upstream on Fri Apr 15 23:07:42 UTC 2016
+
+--- a/configure
++++ b/configure
+@@ -2866,7 +2866,17 @@
+ 
+ 
+ # Configuration Date
+- CONFIG_DATE="`date`"
++ CONFIG_DATE="`date -u`"
++if test -n "$SOURCE_DATE_EPOCH"; then
++  CONFIG_DATE=`date -u -d "@$SOURCE_DATE_EPOCH" 2>/dev/null \
++               || date -u -r "$SOURCE_DATE_EPOCH" 2>/dev/null`
++  if test -z "$CONFIG_DATE"; then
++    as_fn_error $? "malformed SOURCE_DATE_EPOCH" "$LINENO" 5
++  fi
++fi
++cat >>confdefs.h <<_ACEOF
++#define CONFIG_DATE "$CONFIG_DATE"
++_ACEOF
+ 
+ # Find out about the host we're building on.
+ ac_aux_dir=
+--- a/libdispatch/derror.c
++++ b/libdispatch/derror.c
+@@ -13,7 +13,7 @@
+ #endif
+ 
+ /* Tell the user the version of netCDF. */
+-static const char nc_libvers[] = PACKAGE_VERSION " of "__DATE__" "__TIME__" $";
++static const char nc_libvers[] = PACKAGE_VERSION " of "CONFIG_DATE" $";
+ 
+ /**
+ \defgroup lib_version Library Version
+--- a/config.h.in
++++ b/config.h.in
+@@ -393,6 +393,9 @@
+ /* Define to the version of this package. */
+ #undef PACKAGE_VERSION
+ 
++/* Define to the configuration date */
++#undef CONFIG_DATE
++
+ /* The size of `double', as computed by sizeof. */
+ #undef SIZEOF_DOUBLE
+ 
diff --git a/gnu/packages/patches/ocaml-CVE-2015-8869.patch b/gnu/packages/patches/ocaml-CVE-2015-8869.patch
new file mode 100644
index 0000000000..0a4cb34d25
--- /dev/null
+++ b/gnu/packages/patches/ocaml-CVE-2015-8869.patch
@@ -0,0 +1,72 @@
+Adapted from upstream commit 659615c7b100a89eafe6253e7a5b9d84d0e8df74,
+this patch omits the upstream changes to 'Changes' and 'VERSION'.
+
+http://seclists.org/oss-sec/2016/q2/170
+https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-8869
+https://github.com/ocaml/ocaml/commit/659615c7b100a89eafe6253e7a5b9d84d0e8df74
+---
+ byterun/alloc.c  | 4 ++--
+ byterun/intern.c | 2 +-
+ byterun/str.c    | 4 ++--
+ 3 files changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/byterun/alloc.c b/byterun/alloc.c
+index 96a21bf..0db9947 100644
+--- a/byterun/alloc.c
++++ b/byterun/alloc.c
+@@ -153,7 +153,7 @@ CAMLexport int caml_convert_flag_list(value list, int *flags)
+ /* [size] is a [value] representing number of words (fields) */
+ CAMLprim value caml_alloc_dummy(value size)
+ {
+-  mlsize_t wosize = Int_val(size);
++  mlsize_t wosize = Long_val(size);
+ 
+   if (wosize == 0) return Atom(0);
+   return caml_alloc (wosize, 0);
+@@ -169,7 +169,7 @@ CAMLprim value caml_alloc_dummy_function(value size,value arity)
+ /* [size] is a [value] representing number of floats. */
+ CAMLprim value caml_alloc_dummy_float (value size)
+ {
+-  mlsize_t wosize = Int_val(size) * Double_wosize;
++  mlsize_t wosize = Long_val(size) * Double_wosize;
+ 
+   if (wosize == 0) return Atom(0);
+   return caml_alloc (wosize, 0);
+diff --git a/byterun/intern.c b/byterun/intern.c
+index 89d13d1..7b8d049 100644
+--- a/byterun/intern.c
++++ b/byterun/intern.c
+@@ -291,7 +291,7 @@ static void intern_rec(value *dest)
+   case OFreshOID:
+     /* Refresh the object ID */
+     /* but do not do it for predefined exception slots */
+-    if (Int_val(Field((value)dest, 1)) >= 0)
++    if (Long_val(Field((value)dest, 1)) >= 0)
+       caml_set_oo_id((value)dest);
+     /* Pop item and iterate */
+     sp--;
+diff --git a/byterun/str.c b/byterun/str.c
+index 5ad4e29..885772f 100644
+--- a/byterun/str.c
++++ b/byterun/str.c
+@@ -266,7 +266,7 @@ CAMLprim value caml_string_greaterequal(value s1, value s2)
+ CAMLprim value caml_blit_string(value s1, value ofs1, value s2, value ofs2,
+                                 value n)
+ {
+-  memmove(&Byte(s2, Long_val(ofs2)), &Byte(s1, Long_val(ofs1)), Int_val(n));
++  memmove(&Byte(s2, Long_val(ofs2)), &Byte(s1, Long_val(ofs1)), Long_val(n));
+   return Val_unit;
+ }
+ 
+@@ -278,7 +278,7 @@ CAMLprim value caml_fill_string(value s, value offset, value len, value init)
+ 
+ CAMLprim value caml_bitvect_test(value bv, value n)
+ {
+-  int pos = Int_val(n);
++  intnat pos = Long_val(n);
+   return Val_int(Byte_u(bv, pos >> 3) & (1 << (pos & 7)));
+ }
+ 
+-- 
+2.7.4
+
diff --git a/gnu/packages/patches/poppler-CVE-2015-8868.patch b/gnu/packages/patches/poppler-CVE-2015-8868.patch
deleted file mode 100644
index ac78d32ffa..0000000000
--- a/gnu/packages/patches/poppler-CVE-2015-8868.patch
+++ /dev/null
@@ -1,30 +0,0 @@
-Fixes CVE-2015-8868 (heap overflow).
-
-Upstream source:
-https://cgit.freedesktop.org/poppler/poppler/commit/?id=b3425dd3261679958cd56c0f71995c15d2124433
-
-From b3425dd3261679958cd56c0f71995c15d2124433 Mon Sep 17 00:00:00 2001
-From: Albert Astals Cid <aacid@kde.org>
-Date: Tue, 22 Dec 2015 22:50:33 +0100
-Subject: Do not crash on invalid files
-
-Bug #93476
-
-diff --git a/poppler/Function.cc b/poppler/Function.cc
-index 67283df..ee5afc1 100644
---- a/poppler/Function.cc
-+++ b/poppler/Function.cc
-@@ -577,6 +577,10 @@ ExponentialFunction::ExponentialFunction(Object *funcObj, Dict *dict) {
-       goto err2;
-     }
-     n = obj1.arrayGetLength();
-+    if (unlikely(n > funcMaxOutputs)) {
-+      error(errSyntaxError, -1, "Function's C0 array is wrong length");
-+      n = funcMaxOutputs;
-+    }
-     for (i = 0; i < n; ++i) {
-       obj1.arrayGet(i, &obj2);
-       if (!obj2.isNum()) {
--- 
-cgit v0.10.2
-
diff --git a/gnu/packages/patches/portmidi-modular-build.patch b/gnu/packages/patches/portmidi-modular-build.patch
new file mode 100644
index 0000000000..25e64ae317
--- /dev/null
+++ b/gnu/packages/patches/portmidi-modular-build.patch
@@ -0,0 +1,325 @@
+We took this patch from Gentoo to break apart the portmidi build, so that we
+can disable the Java parts and cleanly disable the tests which fail to link
+(possibly because they are linked before “-lportmidi” is available).  The
+patch was downloaded from here:
+
+https://gitweb.gentoo.org/repo/gentoo.git/plain/media-libs/portmidi/files/portmidi-217-cmake.patch?id=56bd759df1d0c750a065b8c845e93d5dfa6b549d
+
+--- portmidi/CMakeLists.txt
++++ portmidi/CMakeLists.txt
+@@ -9,12 +9,11 @@
+   set(CMAKE_BUILD_TYPE Release CACHE STRING 
+       "Semicolon-separate list of supported configuration types")
+   # set default directories but don't override cached values...
+-  set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CACHEFILE_DIR}/${CMAKE_BUILD_TYPE}
++  set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+       CACHE STRING "libraries go here")
+-  set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CACHEFILE_DIR}/${CMAKE_BUILD_TYPE}
++  set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+       CACHE STRING "libraries go here")
+-  set(CMAKE_RUNTIME_OUTPUT_DIRECTORY 
+-      ${CMAKE_CACHEFILE_DIR}/${CMAKE_BUILD_TYPE}
++  set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+       CACHE STRING "executables go here")
+ 
+ else(UNIX)
+@@ -68,10 +67,20 @@
+ include_directories(pm_common porttime)
+ add_subdirectory(pm_common)
+ 
+-add_subdirectory(pm_test)
++option(PORTMIDI_ENABLE_JAVA "Enable Java bindings support" ON)
++option(PORTMIDI_ENABLE_STATIC "Build and install static libraries" OFF)
++option(PORTMIDI_ENABLE_TEST "Build test programs" ON)
++
++if(PORTMIDI_ENABLE_TEST)
++  add_subdirectory(pm_test)
++endif(PORTMIDI_ENABLE_TEST)
+ 
+ add_subdirectory(pm_dylib)
+ 
+ # Cannot figure out how to make an xcode Java application with CMake
+-add_subdirectory(pm_java)
++if(PORTMIDI_ENABLE_JAVA)
++  set(JAR_INSTALL_DIR share/java
++      CACHE STRING "Define directory name for jar installation")
++  add_subdirectory(pm_java)
++endif(PORTMIDI_ENABLE_JAVA)
+ 
+--- portmidi/pm_common/CMakeLists.txt
++++ portmidi/pm_common/CMakeLists.txt
+@@ -44,9 +44,6 @@
+ 
+ # first include the appropriate system-dependent file:
+ if(UNIX)
+-  # add the -g switch for Linux and Mac OS X (not used in Win32)
+-  set (CMAKE_C_FLAGS_DEBUG "-g ${CMAKE_C_FLAGS_DEBUG}" 
+-       CACHE STRING "enable extra checks for debugging" FORCE)
+   if(APPLE)
+     set(MACSRC pmmacosxcm pmmac readbinaryplist finddefault)
+     prepend_path(LIBSRC ../pm_mac/ ${MACSRC})
+@@ -62,19 +59,23 @@
+                              ${COREMIDI_LIB} ${CORESERVICES_LIB}
+         CACHE INTERNAL "")
+ 
+-    set(JAVAVM_LIB "${FRAMEWORK_PATH}/JavaVM.framework")
+-    set(JAVA_INCLUDE_PATHS ${JAVAVM_LIB}/Headers)
++    if(PORTMIDI_ENABLE_JAVA)
++      set(JAVAVM_LIB "${FRAMEWORK_PATH}/JavaVM.framework")
++      set(JAVA_INCLUDE_PATHS ${JAVAVM_LIB}/Headers)
++    endif(PORTMIDI_ENABLE_JAVA)
+     message(STATUS "SYSROOT: " ${CMAKE_OSX_SYSROOT})
+   else(APPLE)
+     # LINUX settings...
+-    include(FindJNI)
+-    message(STATUS "JAVA_JVM_LIB_PATH is " ${JAVA_JVM_LIB_PATH})
+-    message(STATUS "JAVA_INCLUDE_PATH is " ${JAVA_INCLUDE_PATH})
+-    message(STATUS "JAVA_INCLUDE_PATH2 is " ${JAVA_INCLUDE_PATH2})
+-    message(STATUS "JAVA_JVM_LIBRARY is " ${JAVA_JVM_LIBRARY})
+-    set(JAVA_INCLUDE_PATHS ${JAVA_INCLUDE_PATH} ${JAVA_INCLUDE_PATH2})
+-    # libjvm.so is found relative to JAVA_INCLUDE_PATH:
+-    set(JAVAVM_LIB ${JAVA_JVM_LIBRARY}/libjvm.so)
++    if(PORTMIDI_ENABLE_JAVA)
++      include(FindJNI)
++      message(STATUS "JAVA_JVM_LIB_PATH is " ${JAVA_JVM_LIB_PATH})
++      message(STATUS "JAVA_INCLUDE_PATH is " ${JAVA_INCLUDE_PATH})
++      message(STATUS "JAVA_INCLUDE_PATH2 is " ${JAVA_INCLUDE_PATH2})
++      message(STATUS "JAVA_JVM_LIBRARY is " ${JAVA_JVM_LIBRARY})
++      set(JAVA_INCLUDE_PATHS ${JAVA_INCLUDE_PATH} ${JAVA_INCLUDE_PATH2})
++      # libjvm.so is found relative to JAVA_INCLUDE_PATH:
++      set(JAVAVM_LIB ${JAVA_JVM_LIBRARY}/libjvm.so)
++    endif(PORTMIDI_ENABLE_JAVA)
+ 
+     set(LINUXSRC pmlinuxalsa pmlinux finddefault)
+     prepend_path(LIBSRC ../pm_linux/ ${LINUXSRC})
+@@ -88,10 +89,12 @@
+     # /MD is multithread DLL, /MT is multithread. Change to static:
+     include(../pm_win/static.cmake)
+     
+-    include(FindJNI)
++    if(PORTMIDI_ENABLE_JAVA)
++      include(FindJNI)
+ 
+-    set(JAVA_INCLUDE_PATHS ${JAVA_INCLUDE_PATH} ${JAVA_INCLUDE_PATH2})
+-    # message(STATUS "JAVA_INCLUDE_PATHS: " ${JAVA_INCLUDE_PATHS})
++      set(JAVA_INCLUDE_PATHS ${JAVA_INCLUDE_PATH} ${JAVA_INCLUDE_PATH2})
++      # message(STATUS "JAVA_INCLUDE_PATHS: " ${JAVA_INCLUDE_PATHS})
++    endif(PORTMIDI_ENABLE_JAVA)
+ 
+     set(WINSRC pmwin pmwinmm)
+     prepend_path(LIBSRC ../pm_win/ ${WINSRC})
+@@ -99,29 +102,43 @@
+     set(PM_NEEDED_LIBS winmm.lib)
+   endif(WIN32)
+ endif(UNIX)
+-set(JNI_EXTRA_LIBS ${PM_NEEDED_LIBS} ${JAVA_JVM_LIBRARY})
++
++if(PORTMIDI_ENABLE_JAVA)
++  set(JNI_EXTRA_LIBS ${PM_NEEDED_LIBS} ${JAVA_JVM_LIBRARY})
++endif(PORTMIDI_ENABLE_JAVA)
+ 
+ # this completes the list of library sources by adding shared code
+ list(APPEND LIBSRC pmutil portmidi)
+ 
+ # now add the shared files to make the complete list of library sources
+-add_library(portmidi-static ${LIBSRC})
+-set_target_properties(portmidi-static PROPERTIES OUTPUT_NAME "portmidi_s")
+-target_link_libraries(portmidi-static ${PM_NEEDED_LIBS})
+-
+-# define the jni library
+-include_directories(${JAVA_INCLUDE_PATHS})
+-
+-set(JNISRC ${LIBSRC} ../pm_java/pmjni/pmjni.c)
+-add_library(pmjni SHARED ${JNISRC})
+-target_link_libraries(pmjni ${JNI_EXTRA_LIBS})
+-set_target_properties(pmjni PROPERTIES EXECUTABLE_EXTENSION "jnilib")
++if(PORTMIDI_ENABLE_STATIC)
++  add_library(portmidi-static ${LIBSRC})
++  set_target_properties(portmidi-static PROPERTIES OUTPUT_NAME "portmidi")
++  target_link_libraries(portmidi-static ${PM_NEEDED_LIBS})
++endif(PORTMIDI_ENABLE_STATIC)
++
++if(PORTMIDI_ENABLE_JAVA)
++  # define the jni library
++  include_directories(${JAVA_INCLUDE_PATHS})
++
++  set(JNISRC ${LIBSRC} ../pm_java/pmjni/pmjni.c)
++  add_library(pmjni SHARED ${JNISRC})
++  target_link_libraries(pmjni ${JNI_EXTRA_LIBS})
++  set_target_properties(pmjni PROPERTIES EXECUTABLE_EXTENSION "jnilib")
++endif(PORTMIDI_ENABLE_JAVA)
+ 
+ # install the libraries (Linux and Mac OS X command line)
+ if(UNIX)
+-  INSTALL(TARGETS portmidi-static pmjni
+-    LIBRARY DESTINATION /usr/local/lib
+-    ARCHIVE DESTINATION /usr/local/lib)
++  if(PORTMIDI_ENABLE_STATIC)
++    INSTALL(TARGETS portmidi-static
++      LIBRARY DESTINATION lib${LIB_SUFFIX}
++      ARCHIVE DESTINATION lib${LIB_SUFFIX})
++  endif(PORTMIDI_ENABLE_STATIC)
++  if(PORTMIDI_ENABLE_JAVA)
++    INSTALL(TARGETS pmjni
++      LIBRARY DESTINATION lib${LIB_SUFFIX}
++      ARCHIVE DESTINATION lib${LIB_SUFFIX})
++  endif(PORTMIDI_ENABLE_JAVA)
+ # .h files installed by pm_dylib/CMakeLists.txt, so don't need them here
+ #  INSTALL(FILES portmidi.h ../porttime/porttime.h
+ #    DESTINATION /usr/local/include)
+--- portmidi/pm_dylib/CMakeLists.txt
++++ portmidi/pm_dylib/CMakeLists.txt
+@@ -39,9 +39,6 @@
+ 
+ # first include the appropriate system-dependent file:
+ if(UNIX)
+-  # add the -g switch for Linux and Mac OS X (not used in Win32)
+-  set (CMAKE_C_FLAGS_DEBUG "-g ${CMAKE_C_FLAGS_DEBUG}" 
+-       CACHE STRING "enable extra checks for debugging" FORCE)
+   if(APPLE)
+     set(MACSRC pmmacosxcm pmmac readbinaryplist finddefault)
+     prepend_path(LIBSRC ../pm_mac/ ${MACSRC})
+@@ -63,7 +60,8 @@
+     message(STATUS "SYSROOT: " ${CMAKE_OSX_SYSROOT})
+   else(APPLE)
+     # LINUX settings...
+-    include(FindJNI)
++    if(PORTMIDI_ENABLE_JAVA)
++      include(FindJNI)
+     # message(STATUS "JAVA_JVM_LIB_PATH is " ${JAVA_JVM_LIB_PATH})
+     # message(STATUS "JAVA_INCLUDE_PATH is " ${JAVA_INCLUDE_PATH})
+     # note: should use JAVA_JVM_LIB_PATH, but it is not set properly
+@@ -75,11 +73,8 @@
+     # JAVA_INCLUDE_PATH2; if no, then we need to make both JAVA_INCLUDE_PATH
+     # and JAVA_INCLUDE_PATH2 set by user (will need clear documentation
+     # because JAVA_INCLUDE_PATH2 is pretty obscure)
+-    set(JAVA_INCLUDE_PATH  ${JAVA_INCLUDE_PATH-UNKNOWN}
+-        CACHE STRING "where to find Java SDK include directory")
+-    set(JAVA_INCLUDE_PATHS ${JAVA_INCLUDE_PATH} ${JAVA_INCLUDE_PATH}/linux)
+-    # libjvm.so is found relative to JAVA_INCLUDE_PATH:
+-    set(JAVAVM_LIB ${JAVA_INCLUDE_PATH}/../jre/lib/i386/client/libjvm.so)
++      set(JAVAVM_LIB ${JAVA_JVM_LIBRARY})
++    endif(PORTMIDI_ENABLE_JAVA)
+ 
+     set(LINUXSRC pmlinuxalsa pmlinux finddefault)
+     prepend_path(LIBSRC ../pm_linux/ ${LINUXSRC})
+@@ -91,13 +86,15 @@
+   if(WIN32)
+     # /MDd is multithread debug DLL, /MTd is multithread debug
+     # /MD is multithread DLL, /MT is multithread 
+-    
+-    include(FindJNI)
+-    # note: should use JAVA_JVM_LIB_PATH, but it is not set properly
+-    set(JAVAVM_LIB ${JAVA_INCLUDE_PATH}/../lib/jvm.lib)
+ 
+-    set(JAVA_INCLUDE_PATHS ${JAVA_INCLUDE_PATH} ${JAVA_INCLUDE_PATH2})
+-    # message(STATUS "JAVA_INCLUDE_PATHS: " ${JAVA_INCLUDE_PATHS})
++    if(PORTMIDI_ENABLE_JAVA)
++      include(FindJNI)
++      # note: should use JAVA_JVM_LIB_PATH, but it is not set properly
++      set(JAVAVM_LIB ${JAVA_INCLUDE_PATH}/../lib/jvm.lib)
++
++      set(JAVA_INCLUDE_PATHS ${JAVA_INCLUDE_PATH} ${JAVA_INCLUDE_PATH2})
++      # message(STATUS "JAVA_INCLUDE_PATHS: " ${JAVA_INCLUDE_PATHS})
++    endif(PORTMIDI_ENABLE_JAVA)
+ 
+     set(WINSRC pmwin pmwinmm)
+     prepend_path(LIBSRC ../pm_win/ ${WINSRC})
+@@ -106,7 +103,10 @@
+     # message(STATUS "JAVAVM_LIB: " ${JAVAVM_LIB})
+   endif(WIN32)
+ endif(UNIX)
++
++if(PORTMIDI_ENABLE_JAVA)
+ set(JNI_EXTRA_LIBS ${PM_NEEDED_LIBS} ${JAVAVM_LIB})
++endif(PORTMIDI_ENABLE_JAVA)
+ 
+ # this completes the list of library sources by adding shared code
+ set(SHARED_FILES pmutil portmidi)
+@@ -120,8 +120,8 @@
+ # install the libraries (Linux and Mac OS X command line)
+ if(UNIX)
+   INSTALL(TARGETS portmidi-dynamic
+-    LIBRARY DESTINATION /usr/local/lib
+-    ARCHIVE DESTINATION /usr/local/lib)
++    LIBRARY DESTINATION lib${LIB_SUFFIX}
++    ARCHIVE DESTINATION lib${LIB_SUFFIX})
+   INSTALL(FILES ../pm_common/portmidi.h ../porttime/porttime.h
+-    DESTINATION /usr/local/include)
++    DESTINATION include)
+ endif(UNIX)
+--- portmidi/pm_java/CMakeLists.txt
++++ portmidi/pm_java/CMakeLists.txt
+@@ -5,43 +5,24 @@
+     # java not dealt with in CMake -- see pm_mac/pm_mac.xcodeproj
+   else(APPLE)
+     # linux
+-    set(JPORTMIDICLASS JPortMidi.class JPortMidiException.class
+-    		       JPortMidiApi.class)
+-    set(PMDEFAULTSCLASS PmDefaultsFrame.class PmDefaults.class)
+-    prepend_path(JPORTMIDICLASS2 jportmidi/ ${JPORTMIDICLASS})
+-    prepend_path(PMDEFAULTSCLASS2 pmdefaults/ ${PMDEFAULTSCLASS})
+-    set(PMDEFAULTS_ALL_CLASSES ${JPORTMIDICLASS2} ${PMDEFAULTSCLASS2})
+-    # message(STATUS "PMDEFAULTS_ALL_CLASSES is " ${PMDEFAULTS_ALL_CLASSES})
+-    add_custom_command(OUTPUT pmdefaults/PmDefaultsFrame.class
+-        COMMAND javac -classpath . pmdefaults/PmDefaultsFrame.java
+-	MAIN_DEPENDENCY pmdefaults/PmDefaultsFrame.java
+-	DEPENDS pmdefaults/PmDefaults.java
+-	WORKING_DIRECTORY pm_java)
+-    add_custom_command(OUTPUT pmdefaults/PmDefaults.class
+-        COMMAND javac -classpath . pmdefaults/PmDefaults.java
+-	MAIN_DEPENDENCY pmdefaults/PmDefaults.java
+-	DEPENDS pmdefaults/PmDefaultsFrame.java
+-	WORKING_DIRECTORY pm_java)
+-    add_custom_command(OUTPUT ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/pmdefaults.jar
+-        COMMAND	cp pmdefaults/portmusic_logo.png .
+-        COMMAND	jar cmf pmdefaults/manifest.txt pmdefaults.jar
+-		pmdefaults/*.class portmusic_logo.png jportmidi/*.class
+-  	COMMAND chmod +x pmdefaults/pmdefaults
+-	COMMAND cp pmdefaults/pmdefaults ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}
+-	COMMAND mv pmdefaults.jar ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}
+-	COMMAND rm portmusic_logo.png
+-	MAIN_DEPENDENCY pmdefaults/PmDefaults.class
+-	DEPENDS ${PMDEFAULTS_ALL_CLASSES}
+-	WORKING_DIRECTORY pm_java)
+-    add_custom_target(pmdefaults_target ALL 
+-        DEPENDS ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/pmdefaults.jar)
+-    # message(STATUS "add_custom_target: pmdefaults.jar")
++	set(JAVA_CLASSES jportmidi pmdefaults)
++	add_custom_command(OUTPUT ${JAVA_CLASSES}
++		COMMAND javac -d ${CMAKE_CURRENT_BINARY_DIR} jportmidi/*.java pmdefaults/*.java
++		WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
++	add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/pmdefaults.jar
++		DEPENDS ${JAVA_CLASSES}
++		COMMAND jar cmf pmdefaults/manifest.txt ${CMAKE_CURRENT_BINARY_DIR}/pmdefaults.jar
++		-C pmdefaults portmusic_logo.png -C ${CMAKE_CURRENT_BINARY_DIR} jportmidi
++		-C ${CMAKE_CURRENT_BINARY_DIR} pmdefaults
++		WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
++	add_custom_target(pmdefaults.jar ALL
++		DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/pmdefaults.jar)
+ 
+     # install the libraries (Linux only)
+-    INSTALL(FILES ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/pmdefaults.jar
+-      DESTINATION /usr/share/java)
+-    INSTALL(PROGRAMS ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/pmdefaults
+-      DESTINATION /usr/local/bin)
++    INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/pmdefaults.jar
++      DESTINATION ${JAR_INSTALL_DIR})
++    INSTALL(PROGRAMS ${CMAKE_CURRENT_SOURCE_DIR}/pmdefaults/pmdefaults
++      DESTINATION bin)
+   endif(APPLE)
+ endif(UNIX)
+ # In windows, use pm_java/make.bat
+--- portmidi/pm_test/CMakeLists.txt
++++ portmidi/pm_test/CMakeLists.txt
+@@ -12,8 +12,8 @@
+ 
+ macro(make_a_test name)
+   add_executable(${name} ${name}.c)
+-  target_link_libraries(${name} portmidi-static ${PM_NEEDED_LIBS})
+-  add_dependencies(${name} portmidi-static)
++  target_link_libraries(${name} portmidi ${PM_NEEDED_LIBS})
++  add_dependencies(${name} portmidi)
+ endmacro(make_a_test)
+ 
+ make_a_test(test)
diff --git a/gnu/packages/patches/qemu-CVE-2015-8558.patch b/gnu/packages/patches/qemu-CVE-2015-8558.patch
deleted file mode 100644
index f755d735cb..0000000000
--- a/gnu/packages/patches/qemu-CVE-2015-8558.patch
+++ /dev/null
@@ -1,48 +0,0 @@
-From 156a2e4dbffa85997636a7a39ef12da6f1b40254 Mon Sep 17 00:00:00 2001
-From: Gerd Hoffmann <kraxel@redhat.com>
-Date: Mon, 14 Dec 2015 09:21:23 +0100
-Subject: [PATCH] ehci: make idt processing more robust
-
-Make ehci_process_itd return an error in case we didn't do any actual
-iso transfer because we've found no active transaction.  That'll avoid
-ehci happily run in circles forever if the guest builds a loop out of
-idts.
-
-This is CVE-2015-8558.
-
-Cc: qemu-stable@nongnu.org
-Reported-by: Qinghao Tang <luodalongde@gmail.com>
-Tested-by: P J P <ppandit@redhat.com>
-Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
----
- hw/usb/hcd-ehci.c | 5 +++--
- 1 file changed, 3 insertions(+), 2 deletions(-)
-
-diff --git a/hw/usb/hcd-ehci.c b/hw/usb/hcd-ehci.c
-index 4e2161b..d07f228 100644
---- a/hw/usb/hcd-ehci.c
-+++ b/hw/usb/hcd-ehci.c
-@@ -1389,7 +1389,7 @@ static int ehci_process_itd(EHCIState *ehci,
- {
-     USBDevice *dev;
-     USBEndpoint *ep;
--    uint32_t i, len, pid, dir, devaddr, endp;
-+    uint32_t i, len, pid, dir, devaddr, endp, xfers = 0;
-     uint32_t pg, off, ptr1, ptr2, max, mult;
- 
-     ehci->periodic_sched_active = PERIODIC_ACTIVE;
-@@ -1479,9 +1479,10 @@ static int ehci_process_itd(EHCIState *ehci,
-                 ehci_raise_irq(ehci, USBSTS_INT);
-             }
-             itd->transact[i] &= ~ITD_XACT_ACTIVE;
-+            xfers++;
-         }
-     }
--    return 0;
-+    return xfers ? 0 : -1;
- }
- 
- 
--- 
-2.6.3
-
diff --git a/gnu/packages/patches/qemu-CVE-2015-8567.patch b/gnu/packages/patches/qemu-CVE-2015-8567.patch
deleted file mode 100644
index 0cfd8e9627..0000000000
--- a/gnu/packages/patches/qemu-CVE-2015-8567.patch
+++ /dev/null
@@ -1,93 +0,0 @@
-From aa4a3dce1c88ed51b616806b8214b7c8428b7470 Mon Sep 17 00:00:00 2001
-From: P J P <ppandit@redhat.com>
-Date: Tue, 15 Dec 2015 12:27:54 +0530
-Subject: [PATCH] net: vmxnet3: avoid memory leakage in activate_device
-
-Vmxnet3 device emulator does not check if the device is active
-before activating it, also it did not free the transmit & receive
-buffers while deactivating the device, thus resulting in memory
-leakage on the host. This patch fixes both these issues to avoid
-host memory leakage.
-
-Reported-by: Qinghao Tang <luodalongde@gmail.com>
-Reviewed-by: Dmitry Fleytman <dmitry@daynix.com>
-Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
-Cc: qemu-stable@nongnu.org
-Signed-off-by: Jason Wang <jasowang@redhat.com>
----
- hw/net/vmxnet3.c | 24 ++++++++++++++++--------
- 1 file changed, 16 insertions(+), 8 deletions(-)
-
-diff --git a/hw/net/vmxnet3.c b/hw/net/vmxnet3.c
-index a5dd79a..9c1adfc 100644
---- a/hw/net/vmxnet3.c
-+++ b/hw/net/vmxnet3.c
-@@ -1194,8 +1194,13 @@ static void vmxnet3_reset_mac(VMXNET3State *s)
- 
- static void vmxnet3_deactivate_device(VMXNET3State *s)
- {
--    VMW_CBPRN("Deactivating vmxnet3...");
--    s->device_active = false;
-+    if (s->device_active) {
-+        VMW_CBPRN("Deactivating vmxnet3...");
-+        vmxnet_tx_pkt_reset(s->tx_pkt);
-+        vmxnet_tx_pkt_uninit(s->tx_pkt);
-+        vmxnet_rx_pkt_uninit(s->rx_pkt);
-+        s->device_active = false;
-+    }
- }
- 
- static void vmxnet3_reset(VMXNET3State *s)
-@@ -1204,7 +1209,6 @@ static void vmxnet3_reset(VMXNET3State *s)
- 
-     vmxnet3_deactivate_device(s);
-     vmxnet3_reset_interrupt_states(s);
--    vmxnet_tx_pkt_reset(s->tx_pkt);
-     s->drv_shmem = 0;
-     s->tx_sop = true;
-     s->skip_current_tx_pkt = false;
-@@ -1431,6 +1435,12 @@ static void vmxnet3_activate_device(VMXNET3State *s)
-         return;
-     }
- 
-+    /* Verify if device is active */
-+    if (s->device_active) {
-+        VMW_CFPRN("Vmxnet3 device is active");
-+        return;
-+    }
-+
-     vmxnet3_adjust_by_guest_type(s);
-     vmxnet3_update_features(s);
-     vmxnet3_update_pm_state(s);
-@@ -1627,7 +1637,7 @@ static void vmxnet3_handle_command(VMXNET3State *s, uint64_t cmd)
-         break;
- 
-     case VMXNET3_CMD_QUIESCE_DEV:
--        VMW_CBPRN("Set: VMXNET3_CMD_QUIESCE_DEV - pause the device");
-+        VMW_CBPRN("Set: VMXNET3_CMD_QUIESCE_DEV - deactivate the device");
-         vmxnet3_deactivate_device(s);
-         break;
- 
-@@ -1741,7 +1751,7 @@ vmxnet3_io_bar1_write(void *opaque,
-          * shared address only after we get the high part
-          */
-         if (val == 0) {
--            s->device_active = false;
-+            vmxnet3_deactivate_device(s);
-         }
-         s->temp_shared_guest_driver_memory = val;
-         s->drv_shmem = 0;
-@@ -2021,9 +2031,7 @@ static bool vmxnet3_peer_has_vnet_hdr(VMXNET3State *s)
- static void vmxnet3_net_uninit(VMXNET3State *s)
- {
-     g_free(s->mcast_list);
--    vmxnet_tx_pkt_reset(s->tx_pkt);
--    vmxnet_tx_pkt_uninit(s->tx_pkt);
--    vmxnet_rx_pkt_uninit(s->rx_pkt);
-+    vmxnet3_deactivate_device(s);
-     qemu_del_nic(s->nic);
- }
- 
--- 
-2.6.3
-
diff --git a/gnu/packages/patches/qemu-CVE-2015-8613.patch b/gnu/packages/patches/qemu-CVE-2015-8613.patch
deleted file mode 100644
index 3bcc6ab8d6..0000000000
--- a/gnu/packages/patches/qemu-CVE-2015-8613.patch
+++ /dev/null
@@ -1,35 +0,0 @@
-From 36fef36b91f7ec0435215860f1458b5342ce2811 Mon Sep 17 00:00:00 2001
-From: P J P <ppandit@redhat.com>
-Date: Mon, 21 Dec 2015 15:13:13 +0530
-Subject: [PATCH] scsi: initialise info object with appropriate size
-
-While processing controller 'CTRL_GET_INFO' command, the routine
-'megasas_ctrl_get_info' overflows the '&info' object size. Use its
-appropriate size to null initialise it.
-
-Reported-by: Qinghao Tang <luodalongde@gmail.com>
-Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
-Message-Id: <alpine.LFD.2.20.1512211501420.22471@wniryva>
-Cc: qemu-stable@nongnu.org
-Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
-Signed-off-by: P J P <ppandit@redhat.com>
----
- hw/scsi/megasas.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/hw/scsi/megasas.c b/hw/scsi/megasas.c
-index d7dc667..576f56c 100644
---- a/hw/scsi/megasas.c
-+++ b/hw/scsi/megasas.c
-@@ -718,7 +718,7 @@ static int megasas_ctrl_get_info(MegasasState *s, MegasasCmd *cmd)
-     BusChild *kid;
-     int num_pd_disks = 0;
- 
--    memset(&info, 0x0, cmd->iov_size);
-+    memset(&info, 0x0, dcmd_size);
-     if (cmd->iov_size < dcmd_size) {
-         trace_megasas_dcmd_invalid_xfer_len(cmd->index, cmd->iov_size,
-                                             dcmd_size);
--- 
-2.6.3
-
diff --git a/gnu/packages/patches/qemu-CVE-2015-8619.patch b/gnu/packages/patches/qemu-CVE-2015-8619.patch
deleted file mode 100644
index 5961343d1e..0000000000
--- a/gnu/packages/patches/qemu-CVE-2015-8619.patch
+++ /dev/null
@@ -1,119 +0,0 @@
-From: Wolfgang Bumiller <w.bumiller@proxmox.com>
-Date: Wed, 13 Jan 2016 09:09:58 +0100
-Subject: [PATCH] hmp: fix sendkey out of bounds write (CVE-2015-8619)
-
-When processing 'sendkey' command, hmp_sendkey routine null
-terminates the 'keyname_buf' array. This results in an OOB
-write issue, if 'keyname_len' was to fall outside of
-'keyname_buf' array.
-
-Since the keyname's length is known the keyname_buf can be
-removed altogether by adding a length parameter to
-index_from_key() and using it for the error output as well.
-
-Reported-by: Ling Liu <liuling-it@360.cn>
-Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
-Message-Id: <20160113080958.GA18934@olga>
-[Comparison with "<" dumbed down, test for junk after strtoul()
-tweaked]
-Signed-off-by: Markus Armbruster <armbru@redhat.com>
-
-(cherry picked from commit 64ffbe04eaafebf4045a3ace52a360c14959d196)
----
- hmp.c                | 18 ++++++++----------
- include/ui/console.h |  2 +-
- ui/input-legacy.c    |  5 +++--
- 3 files changed, 12 insertions(+), 13 deletions(-)
-
-diff --git a/hmp.c b/hmp.c
-index 2140605..1904203 100644
---- a/hmp.c
-+++ b/hmp.c
-@@ -1734,21 +1734,18 @@ void hmp_sendkey(Monitor *mon, const QDict *qdict)
-     int has_hold_time = qdict_haskey(qdict, "hold-time");
-     int hold_time = qdict_get_try_int(qdict, "hold-time", -1);
-     Error *err = NULL;
--    char keyname_buf[16];
-     char *separator;
-     int keyname_len;
- 
-     while (1) {
-         separator = strchr(keys, '-');
-         keyname_len = separator ? separator - keys : strlen(keys);
--        pstrcpy(keyname_buf, sizeof(keyname_buf), keys);
- 
-         /* Be compatible with old interface, convert user inputted "<" */
--        if (!strncmp(keyname_buf, "<", 1) && keyname_len == 1) {
--            pstrcpy(keyname_buf, sizeof(keyname_buf), "less");
-+        if (keys[0] == '<' && keyname_len == 1) {
-+            keys = "less";
-             keyname_len = 4;
-         }
--        keyname_buf[keyname_len] = 0;
- 
-         keylist = g_malloc0(sizeof(*keylist));
-         keylist->value = g_malloc0(sizeof(*keylist->value));
-@@ -1761,16 +1758,17 @@ void hmp_sendkey(Monitor *mon, const QDict *qdict)
-         }
-         tmp = keylist;
- 
--        if (strstart(keyname_buf, "0x", NULL)) {
-+        if (strstart(keys, "0x", NULL)) {
-             char *endp;
--            int value = strtoul(keyname_buf, &endp, 0);
--            if (*endp != '\0') {
-+            int value = strtoul(keys, &endp, 0);
-+            assert(endp <= keys + keyname_len);
-+            if (endp != keys + keyname_len) {
-                 goto err_out;
-             }
-             keylist->value->type = KEY_VALUE_KIND_NUMBER;
-             keylist->value->u.number = value;
-         } else {
--            int idx = index_from_key(keyname_buf);
-+            int idx = index_from_key(keys, keyname_len);
-             if (idx == Q_KEY_CODE_MAX) {
-                 goto err_out;
-             }
-@@ -1792,7 +1790,7 @@ out:
-     return;
- 
- err_out:
--    monitor_printf(mon, "invalid parameter: %s\n", keyname_buf);
-+    monitor_printf(mon, "invalid parameter: %.*s\n", keyname_len, keys);
-     goto out;
- }
- 
-diff --git a/include/ui/console.h b/include/ui/console.h
-index c249db4..5739bdd 100644
---- a/include/ui/console.h
-+++ b/include/ui/console.h
-@@ -433,7 +433,7 @@ static inline int vnc_display_pw_expire(const char *id, time_t expires)
- void curses_display_init(DisplayState *ds, int full_screen);
- 
- /* input.c */
--int index_from_key(const char *key);
-+int index_from_key(const char *key, size_t key_length);
- 
- /* gtk.c */
- void early_gtk_display_init(int opengl);
-diff --git a/ui/input-legacy.c b/ui/input-legacy.c
-index e0a39f0..3f28bbc 100644
---- a/ui/input-legacy.c
-+++ b/ui/input-legacy.c
-@@ -57,12 +57,13 @@ struct QEMUPutLEDEntry {
- static QTAILQ_HEAD(, QEMUPutLEDEntry) led_handlers =
-     QTAILQ_HEAD_INITIALIZER(led_handlers);
- 
--int index_from_key(const char *key)
-+int index_from_key(const char *key, size_t key_length)
- {
-     int i;
- 
-     for (i = 0; QKeyCode_lookup[i] != NULL; i++) {
--        if (!strcmp(key, QKeyCode_lookup[i])) {
-+        if (!strncmp(key, QKeyCode_lookup[i], key_length) &&
-+            !QKeyCode_lookup[i][key_length]) {
-             break;
-         }
-     }
diff --git a/gnu/packages/patches/qemu-CVE-2015-8701.patch b/gnu/packages/patches/qemu-CVE-2015-8701.patch
deleted file mode 100644
index c7ab7b68b0..0000000000
--- a/gnu/packages/patches/qemu-CVE-2015-8701.patch
+++ /dev/null
@@ -1,47 +0,0 @@
-From 007cd223de527b5f41278f2d886c1a4beb3e67aa Mon Sep 17 00:00:00 2001
-From: Prasad J Pandit <pjp@fedoraproject.org>
-Date: Mon, 28 Dec 2015 16:24:08 +0530
-Subject: [PATCH] net: rocker: fix an incorrect array bounds check
-
-While processing transmit(tx) descriptors in 'tx_consume' routine
-the switch emulator suffers from an off-by-one error, if a
-descriptor was to have more than allowed(ROCKER_TX_FRAGS_MAX=16)
-fragments. Fix an incorrect bounds check to avoid it.
-
-Reported-by: Qinghao Tang <luodalongde@gmail.com>
-Cc: qemu-stable@nongnu.org
-Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
-Signed-off-by: Jason Wang <jasowang@redhat.com>
----
- hw/net/rocker/rocker.c | 8 ++++----
- 1 file changed, 4 insertions(+), 4 deletions(-)
-
-diff --git a/hw/net/rocker/rocker.c b/hw/net/rocker/rocker.c
-index c57f1a6..2e77e50 100644
---- a/hw/net/rocker/rocker.c
-+++ b/hw/net/rocker/rocker.c
-@@ -232,6 +232,9 @@ static int tx_consume(Rocker *r, DescInfo *info)
-         frag_addr = rocker_tlv_get_le64(tlvs[ROCKER_TLV_TX_FRAG_ATTR_ADDR]);
-         frag_len = rocker_tlv_get_le16(tlvs[ROCKER_TLV_TX_FRAG_ATTR_LEN]);
- 
-+        if (iovcnt >= ROCKER_TX_FRAGS_MAX) {
-+            goto err_too_many_frags;
-+        }
-         iov[iovcnt].iov_len = frag_len;
-         iov[iovcnt].iov_base = g_malloc(frag_len);
-         if (!iov[iovcnt].iov_base) {
-@@ -244,10 +247,7 @@ static int tx_consume(Rocker *r, DescInfo *info)
-             err = -ROCKER_ENXIO;
-             goto err_bad_io;
-         }
--
--        if (++iovcnt > ROCKER_TX_FRAGS_MAX) {
--            goto err_too_many_frags;
--        }
-+        iovcnt++;
-     }
- 
-     if (iovcnt) {
--- 
-2.6.3
-
diff --git a/gnu/packages/patches/qemu-CVE-2015-8743.patch b/gnu/packages/patches/qemu-CVE-2015-8743.patch
deleted file mode 100644
index 4a9d0e2f2d..0000000000
--- a/gnu/packages/patches/qemu-CVE-2015-8743.patch
+++ /dev/null
@@ -1,48 +0,0 @@
-From aa7f9966dfdff500bbbf1956d9e115b1fa8987a6 Mon Sep 17 00:00:00 2001
-From: Prasad J Pandit <pjp@fedoraproject.org>
-Date: Thu, 31 Dec 2015 17:05:27 +0530
-Subject: [PATCH] net: ne2000: fix bounds check in ioport operations
-
-While doing ioport r/w operations, ne2000 device emulation suffers
-from OOB r/w errors. Update respective array bounds check to avoid
-OOB access.
-
-Reported-by: Ling Liu <liuling-it@360.cn>
-Cc: qemu-stable@nongnu.org
-Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
-Signed-off-by: Jason Wang <jasowang@redhat.com>
----
- hw/net/ne2000.c | 10 ++++++----
- 1 file changed, 6 insertions(+), 4 deletions(-)
-
-diff --git a/hw/net/ne2000.c b/hw/net/ne2000.c
-index 010f9ef..a3dffff 100644
---- a/hw/net/ne2000.c
-+++ b/hw/net/ne2000.c
-@@ -467,8 +467,9 @@ static inline void ne2000_mem_writel(NE2000State *s, uint32_t addr,
-                                      uint32_t val)
- {
-     addr &= ~1; /* XXX: check exact behaviour if not even */
--    if (addr < 32 ||
--        (addr >= NE2000_PMEM_START && addr < NE2000_MEM_SIZE)) {
-+    if (addr < 32
-+        || (addr >= NE2000_PMEM_START
-+            && addr + sizeof(uint32_t) <= NE2000_MEM_SIZE)) {
-         stl_le_p(s->mem + addr, val);
-     }
- }
-@@ -497,8 +498,9 @@ static inline uint32_t ne2000_mem_readw(NE2000State *s, uint32_t addr)
- static inline uint32_t ne2000_mem_readl(NE2000State *s, uint32_t addr)
- {
-     addr &= ~1; /* XXX: check exact behaviour if not even */
--    if (addr < 32 ||
--        (addr >= NE2000_PMEM_START && addr < NE2000_MEM_SIZE)) {
-+    if (addr < 32
-+        || (addr >= NE2000_PMEM_START
-+            && addr + sizeof(uint32_t) <= NE2000_MEM_SIZE)) {
-         return ldl_le_p(s->mem + addr);
-     } else {
-         return 0xffffffff;
--- 
-2.6.3
-
diff --git a/gnu/packages/patches/qemu-CVE-2016-1568.patch b/gnu/packages/patches/qemu-CVE-2016-1568.patch
deleted file mode 100644
index 53863704cd..0000000000
--- a/gnu/packages/patches/qemu-CVE-2016-1568.patch
+++ /dev/null
@@ -1,39 +0,0 @@
-From 4ab0359a8ae182a7ac5c99609667273167703fab Mon Sep 17 00:00:00 2001
-From: Prasad J Pandit <pjp@fedoraproject.org>
-Date: Mon, 11 Jan 2016 14:10:42 -0500
-Subject: [PATCH] ide: ahci: reset ncq object to unused on error
-
-When processing NCQ commands, AHCI device emulation prepares a
-NCQ transfer object; To which an aio control block(aiocb) object
-is assigned in 'execute_ncq_command'. In case, when the NCQ
-command is invalid, the 'aiocb' object is not assigned, and NCQ
-transfer object is left as 'used'. This leads to a use after
-free kind of error in 'bdrv_aio_cancel_async' via 'ahci_reset_port'.
-Reset NCQ transfer object to 'unused' to avoid it.
-
-[Maintainer edit: s/ACHI/AHCI/ in the commit message. --js]
-
-Reported-by: Qinghao Tang <luodalongde@gmail.com>
-Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
-Reviewed-by: John Snow <jsnow@redhat.com>
-Message-id: 1452282511-4116-1-git-send-email-ppandit@redhat.com
-Signed-off-by: John Snow <jsnow@redhat.com>
----
- hw/ide/ahci.c | 1 +
- 1 file changed, 1 insertion(+)
-
-diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c
-index dd1912e..17f1cbd 100644
---- a/hw/ide/ahci.c
-+++ b/hw/ide/ahci.c
-@@ -910,6 +910,7 @@ static void ncq_err(NCQTransferState *ncq_tfs)
-     ide_state->error = ABRT_ERR;
-     ide_state->status = READY_STAT | ERR_STAT;
-     ncq_tfs->drive->port_regs.scr_err |= (1 << ncq_tfs->tag);
-+    ncq_tfs->used = 0;
- }
- 
- static void ncq_finish(NCQTransferState *ncq_tfs)
--- 
-2.6.3
-
diff --git a/gnu/packages/patches/qemu-CVE-2016-1922.patch b/gnu/packages/patches/qemu-CVE-2016-1922.patch
deleted file mode 100644
index 36d9bd2591..0000000000
--- a/gnu/packages/patches/qemu-CVE-2016-1922.patch
+++ /dev/null
@@ -1,65 +0,0 @@
-From 4c1396cb576c9b14425558b73de1584c7a9735d7 Mon Sep 17 00:00:00 2001
-From: P J P <ppandit@redhat.com>
-Date: Fri, 18 Dec 2015 11:35:07 +0530
-Subject: [PATCH] i386: avoid null pointer dereference
-
-    Hello,
-
-A null pointer dereference issue was reported by Mr Ling Liu, CC'd here. It
-occurs while doing I/O port write operations via hmp interface. In that,
-'current_cpu' remains null as it is not called from cpu_exec loop, which
-results in the said issue.
-
-Below is a proposed (tested)patch to fix this issue; Does it look okay?
-
-===
-From ae88a4947fab9a148cd794f8ad2d812e7f5a1d0f Mon Sep 17 00:00:00 2001
-From: Prasad J Pandit <pjp@fedoraproject.org>
-Date: Fri, 18 Dec 2015 11:16:07 +0530
-Subject: [PATCH] i386: avoid null pointer dereference
-
-When I/O port write operation is called from hmp interface,
-'current_cpu' remains null, as it is not called from cpu_exec()
-loop. This leads to a null pointer dereference in vapic_write
-routine. Add check to avoid it.
-
-Reported-by: Ling Liu <liuling-it@360.cn>
-Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
-Message-Id: <alpine.LFD.2.20.1512181129320.9805@wniryva>
-Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
-Signed-off-by: P J P <ppandit@redhat.com>
----
- hw/i386/kvmvapic.c | 15 ++++++++++-----
- 1 file changed, 10 insertions(+), 5 deletions(-)
-
-diff --git a/hw/i386/kvmvapic.c b/hw/i386/kvmvapic.c
-index c6d34b2..f0922da 100644
---- a/hw/i386/kvmvapic.c
-+++ b/hw/i386/kvmvapic.c
-@@ -634,13 +634,18 @@ static int vapic_prepare(VAPICROMState *s)
- static void vapic_write(void *opaque, hwaddr addr, uint64_t data,
-                         unsigned int size)
- {
--    CPUState *cs = current_cpu;
--    X86CPU *cpu = X86_CPU(cs);
--    CPUX86State *env = &cpu->env;
--    hwaddr rom_paddr;
-     VAPICROMState *s = opaque;
-+    X86CPU *cpu;
-+    CPUX86State *env;
-+    hwaddr rom_paddr;
- 
--    cpu_synchronize_state(cs);
-+    if (!current_cpu) {
-+        return;
-+    }
-+
-+    cpu_synchronize_state(current_cpu);
-+    cpu = X86_CPU(current_cpu);
-+    env = &cpu->env;
- 
-     /*
-      * The VAPIC supports two PIO-based hypercalls, both via port 0x7E.
--- 
-2.6.3
-
diff --git a/gnu/packages/patches/qemu-CVE-2016-1981.patch b/gnu/packages/patches/qemu-CVE-2016-1981.patch
deleted file mode 100644
index 03e7b333c9..0000000000
--- a/gnu/packages/patches/qemu-CVE-2016-1981.patch
+++ /dev/null
@@ -1,95 +0,0 @@
-From: Laszlo Ersek <lersek@redhat.com>
-Date: Tue, 19 Jan 2016 14:17:20 +0100
-Subject: [PATCH] e1000: eliminate infinite loops on out-of-bounds transfer
- start
-
-The start_xmit() and e1000_receive_iov() functions implement DMA transfers
-iterating over a set of descriptors that the guest's e1000 driver
-prepares:
-
-- the TDLEN and RDLEN registers store the total size of the descriptor
-  area,
-
-- while the TDH and RDH registers store the offset (in whole tx / rx
-  descriptors) into the area where the transfer is supposed to start.
-
-Each time a descriptor is processed, the TDH and RDH register is bumped
-(as appropriate for the transfer direction).
-
-QEMU already contains logic to deal with bogus transfers submitted by the
-guest:
-
-- Normally, the transmit case wants to increase TDH from its initial value
-  to TDT. (TDT is allowed to be numerically smaller than the initial TDH
-  value; wrapping at or above TDLEN bytes to zero is normal.) The failsafe
-  that QEMU currently has here is a check against reaching the original
-  TDH value again -- a complete wraparound, which should never happen.
-
-- In the receive case RDH is increased from its initial value until
-  "total_size" bytes have been received; preferably in a single step, or
-  in "s->rxbuf_size" byte steps, if the latter is smaller. However, null
-  RX descriptors are skipped without receiving data, while RDH is
-  incremented just the same. QEMU tries to prevent an infinite loop
-  (processing only null RX descriptors) by detecting whether RDH assumes
-  its original value during the loop. (Again, wrapping from RDLEN to 0 is
-  normal.)
-
-What both directions miss is that the guest could program TDLEN and RDLEN
-so low, and the initial TDH and RDH so high, that these registers will
-immediately be truncated to zero, and then never reassume their initial
-values in the loop -- a full wraparound will never occur.
-
-The condition that expresses this is:
-
-  xdh_start >= s->mac_reg[XDLEN] / sizeof(desc)
-
-i.e., TDH or RDH start out after the last whole rx or tx descriptor that
-fits into the TDLEN or RDLEN sized area.
-
-This condition could be checked before we enter the loops, but
-pci_dma_read() / pci_dma_write() knows how to fill in buffers safely for
-bogus DMA addresses, so we just extend the existing failsafes with the
-above condition.
-
-This is CVE-2016-1981.
-
-Cc: "Michael S. Tsirkin" <mst@redhat.com>
-Cc: Petr Matousek <pmatouse@redhat.com>
-Cc: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
-Cc: Prasad Pandit <ppandit@redhat.com>
-Cc: Michael Roth <mdroth@linux.vnet.ibm.com>
-Cc: Jason Wang <jasowang@redhat.com>
-Cc: qemu-stable@nongnu.org
-RHBZ: https://bugzilla.redhat.com/show_bug.cgi?id=1296044
-Signed-off-by: Laszlo Ersek <lersek@redhat.com>
-Reviewed-by: Jason Wang <jasowang@redhat.com>
-Signed-off-by: Jason Wang <jasowang@redhat.com>
-(cherry picked from commit dd793a74882477ca38d49e191110c17dfee51dcc)
----
- hw/net/e1000.c | 6 ++++--
- 1 file changed, 4 insertions(+), 2 deletions(-)
-
-diff --git a/hw/net/e1000.c b/hw/net/e1000.c
-index bec06e9..34d0823 100644
---- a/hw/net/e1000.c
-+++ b/hw/net/e1000.c
-@@ -908,7 +908,8 @@ start_xmit(E1000State *s)
-          * bogus values to TDT/TDLEN.
-          * there's nothing too intelligent we could do about this.
-          */
--        if (s->mac_reg[TDH] == tdh_start) {
-+        if (s->mac_reg[TDH] == tdh_start ||
-+            tdh_start >= s->mac_reg[TDLEN] / sizeof(desc)) {
-             DBGOUT(TXERR, "TDH wraparound @%x, TDT %x, TDLEN %x\n",
-                    tdh_start, s->mac_reg[TDT], s->mac_reg[TDLEN]);
-             break;
-@@ -1165,7 +1166,8 @@ e1000_receive_iov(NetClientState *nc, const struct iovec *iov, int iovcnt)
-         if (++s->mac_reg[RDH] * sizeof(desc) >= s->mac_reg[RDLEN])
-             s->mac_reg[RDH] = 0;
-         /* see comment in start_xmit; same here */
--        if (s->mac_reg[RDH] == rdh_start) {
-+        if (s->mac_reg[RDH] == rdh_start ||
-+            rdh_start >= s->mac_reg[RDLEN] / sizeof(desc)) {
-             DBGOUT(RXERR, "RDH wraparound @%x, RDT %x, RDLEN %x\n",
-                    rdh_start, s->mac_reg[RDT], s->mac_reg[RDLEN]);
-             set_ics(s, 0, E1000_ICS_RXO);
diff --git a/gnu/packages/patches/qemu-CVE-2016-2197.patch b/gnu/packages/patches/qemu-CVE-2016-2197.patch
deleted file mode 100644
index d851e1ec75..0000000000
--- a/gnu/packages/patches/qemu-CVE-2016-2197.patch
+++ /dev/null
@@ -1,40 +0,0 @@
-From: John Snow <jsnow@redhat.com>
-Date: Wed, 10 Feb 2016 13:29:40 -0500
-Subject: [PATCH] ahci: Do not unmap NULL addresses
-
-Definitely don't try to unmap a garbage address.
-
-Reported-by: Zuozhi fzz <zuozhi.fzz@alibaba-inc.com>
-Signed-off-by: John Snow <jsnow@redhat.com>
-Message-id: 1454103689-13042-2-git-send-email-jsnow@redhat.com
-(cherry picked from commit 99b4cb71069f109b79b27bc629fc0cf0886dbc4b)
----
- hw/ide/ahci.c | 8 ++++++++
- 1 file changed, 8 insertions(+)
-
-diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c
-index 17f1cbd..cdc9299 100644
---- a/hw/ide/ahci.c
-+++ b/hw/ide/ahci.c
-@@ -661,6 +661,10 @@ static bool ahci_map_fis_address(AHCIDevice *ad)
- 
- static void ahci_unmap_fis_address(AHCIDevice *ad)
- {
-+    if (ad->res_fis == NULL) {
-+        DPRINTF(ad->port_no, "Attempt to unmap NULL FIS address\n");
-+        return;
-+    }
-     dma_memory_unmap(ad->hba->as, ad->res_fis, 256,
-                      DMA_DIRECTION_FROM_DEVICE, 256);
-     ad->res_fis = NULL;
-@@ -677,6 +681,10 @@ static bool ahci_map_clb_address(AHCIDevice *ad)
- 
- static void ahci_unmap_clb_address(AHCIDevice *ad)
- {
-+    if (ad->lst == NULL) {
-+        DPRINTF(ad->port_no, "Attempt to unmap NULL CLB address\n");
-+        return;
-+    }
-     dma_memory_unmap(ad->hba->as, ad->lst, 1024,
-                      DMA_DIRECTION_FROM_DEVICE, 1024);
-     ad->lst = NULL;
diff --git a/gnu/packages/patches/qemu-usb-ehci-oob-read.patch b/gnu/packages/patches/qemu-usb-ehci-oob-read.patch
deleted file mode 100644
index d63c0832b8..0000000000
--- a/gnu/packages/patches/qemu-usb-ehci-oob-read.patch
+++ /dev/null
@@ -1,49 +0,0 @@
-From: Prasad J Pandit <pjp@fedoraproject.org>
-Date: Wed, 20 Jan 2016 01:26:46 +0530
-Subject: [PATCH] usb: check page select value while processing iTD
-
-While processing isochronous transfer descriptors(iTD), the page
-select(PG) field value could lead to an OOB read access. Add
-check to avoid it.
-
-Reported-by: Qinghao Tang <luodalongde@gmail.com>
-Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
-Message-id: 1453233406-12165-1-git-send-email-ppandit@redhat.com
-Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
-(cherry picked from commit 49d925ce50383a286278143c05511d30ec41a36e)
----
- hw/usb/hcd-ehci.c | 10 ++++++----
- 1 file changed, 6 insertions(+), 4 deletions(-)
-
-diff --git a/hw/usb/hcd-ehci.c b/hw/usb/hcd-ehci.c
-index d07f228..c40013e 100644
---- a/hw/usb/hcd-ehci.c
-+++ b/hw/usb/hcd-ehci.c
-@@ -1404,21 +1404,23 @@ static int ehci_process_itd(EHCIState *ehci,
-         if (itd->transact[i] & ITD_XACT_ACTIVE) {
-             pg   = get_field(itd->transact[i], ITD_XACT_PGSEL);
-             off  = itd->transact[i] & ITD_XACT_OFFSET_MASK;
--            ptr1 = (itd->bufptr[pg] & ITD_BUFPTR_MASK);
--            ptr2 = (itd->bufptr[pg+1] & ITD_BUFPTR_MASK);
-             len  = get_field(itd->transact[i], ITD_XACT_LENGTH);
- 
-             if (len > max * mult) {
-                 len = max * mult;
-             }
--
--            if (len > BUFF_SIZE) {
-+            if (len > BUFF_SIZE || pg > 6) {
-                 return -1;
-             }
- 
-+            ptr1 = (itd->bufptr[pg] & ITD_BUFPTR_MASK);
-             qemu_sglist_init(&ehci->isgl, ehci->device, 2, ehci->as);
-             if (off + len > 4096) {
-                 /* transfer crosses page border */
-+                if (pg == 6) {
-+                    return -1;  /* avoid page pg + 1 */
-+                }
-+                ptr2 = (itd->bufptr[pg + 1] & ITD_BUFPTR_MASK);
-                 uint32_t len2 = off + len - 4096;
-                 uint32_t len1 = len - len2;
-                 qemu_sglist_add(&ehci->isgl, ptr1 + off, len1);
diff --git a/gnu/packages/patches/qemu-virtio-9p-use-accessor-to-get-thread-pool.patch b/gnu/packages/patches/qemu-virtio-9p-use-accessor-to-get-thread-pool.patch
deleted file mode 100644
index 497e49f1d9..0000000000
--- a/gnu/packages/patches/qemu-virtio-9p-use-accessor-to-get-thread-pool.patch
+++ /dev/null
@@ -1,34 +0,0 @@
-From 4b3a4f2d458ca5a7c6c16ac36a8d9ac22cc253d6 Mon Sep 17 00:00:00 2001
-From: Greg Kurz <gkurz@linux.vnet.ibm.com>
-Date: Wed, 23 Dec 2015 10:56:58 +0100
-Subject: [PATCH] virtio-9p: use accessor to get thread_pool
-
-The aio_context_new() function does not allocate a thread pool. This is
-deferred to the first call to the aio_get_thread_pool() accessor. It is
-hence forbidden to access the thread_pool field directly, as it may be
-NULL. The accessor *must* be used always.
-
-Fixes: ebac1202c95a4f1b76b6ef3f0f63926fa76e753e
-Reviewed-by: Michael Tokarev <mjt@tls.msk.ru>
-Tested-by: Michael Tokarev <mjt@tls.msk.ru>
-Cc: qemu-stable@nongnu.org
-Signed-off-by: Greg Kurz <gkurz@linux.vnet.ibm.com>
----
- hw/9pfs/virtio-9p-coth.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/hw/9pfs/virtio-9p-coth.c b/hw/9pfs/virtio-9p-coth.c
-index fb6e8f8..ab9425c 100644
---- a/hw/9pfs/virtio-9p-coth.c
-+++ b/hw/9pfs/virtio-9p-coth.c
-@@ -36,6 +36,6 @@ static int coroutine_enter_func(void *arg)
- void co_run_in_worker_bh(void *opaque)
- {
-     Coroutine *co = opaque;
--    thread_pool_submit_aio(qemu_get_aio_context()->thread_pool,
-+    thread_pool_submit_aio(aio_get_thread_pool(qemu_get_aio_context()),
-                            coroutine_enter_func, co, coroutine_enter_cb, co);
- }
--- 
-2.6.3
-
diff --git a/gnu/packages/patches/totem-debug-format-fix.patch b/gnu/packages/patches/totem-debug-format-fix.patch
new file mode 100644
index 0000000000..7ddd31ee10
--- /dev/null
+++ b/gnu/packages/patches/totem-debug-format-fix.patch
@@ -0,0 +1,11 @@
+--- totem-3.20.1/src/backend/bacon-video-widget.c.orig	2016-03-22 12:45:32.000000000 -0400
++++ totem-3.20.1/src/backend/bacon-video-widget.c	2016-05-11 02:49:55.299109551 -0400
+@@ -2334,7 +2334,7 @@
+     if (!gst_toc_entry_get_start_stop_times (entry, &start, &stop)) {
+       GST_DEBUG ("Chapter #%d (couldn't get times)", i);
+     } else {
+-      GST_DEBUG ("Chapter #%d (start: %li stop: %li)", i, start, stop);
++      GST_DEBUG ("Chapter #%d (start: %li stop: %li)", i, (long) start, (long) stop);
+     }
+   }
+ 
diff --git a/gnu/packages/patches/tvtime-gcc41.patch b/gnu/packages/patches/tvtime-gcc41.patch
deleted file mode 100644
index d6e42721b8..0000000000
--- a/gnu/packages/patches/tvtime-gcc41.patch
+++ /dev/null
@@ -1,58 +0,0 @@
-Source: https://projects.archlinux.org/svntogit/community.git/tree/trunk/tvtime-1.0.2-gcc41.patch?h=packages/tvtime
-
---- tvtime-1.0.1/plugins/greedyh.asm	2005-08-14 18:16:43.000000000 +0200
-+++ tvtime-1.0.1-gcc41/plugins/greedyh.asm	2005-11-28 17:53:09.210774544 +0100
-@@ -18,7 +18,7 @@
- 
- #include "x86-64_macros.inc"
- 
--void DScalerFilterGreedyH::FUNCT_NAME(TDeinterlaceInfo* pInfo)
-+void FUNCT_NAME(TDeinterlaceInfo* pInfo)
- {
-     int64_t i;
-     bool InfoIsOdd = (pInfo->PictureHistory[0]->Flags & PICTURE_INTERLACED_ODD) ? 1 : 0;
-diff -Naur tvtime-1.0.1/plugins/tomsmocomp/TomsMoCompAll2.inc tvtime-1.0.1-gcc41/plugins/tomsmocomp/TomsMoCompAll2.inc
---- tvtime-1.0.1/plugins/tomsmocomp/TomsMoCompAll2.inc	2004-10-20 17:31:05.000000000 +0200
-+++ tvtime-1.0.1-gcc41/plugins/tomsmocomp/TomsMoCompAll2.inc	2005-11-28 17:53:33.251119856 +0100
-@@ -5,9 +5,9 @@
- #endif
- 
- #ifdef USE_STRANGE_BOB
--#define SEARCH_EFFORT_FUNC(n) DScalerFilterTomsMoComp::SEFUNC(n##_SB)
-+#define SEARCH_EFFORT_FUNC(n) SEFUNC(n##_SB)
- #else
--#define SEARCH_EFFORT_FUNC(n) DScalerFilterTomsMoComp::SEFUNC(n)
-+#define SEARCH_EFFORT_FUNC(n) SEFUNC(n)
- #endif
- 
- int SEARCH_EFFORT_FUNC(0)		// we don't try at all ;-)
-diff -Naur tvtime-1.0.1/plugins/tomsmocomp.cpp tvtime-1.0.1-gcc41/plugins/tomsmocomp.cpp
---- tvtime-1.0.1/plugins/tomsmocomp.cpp	2004-10-20 19:38:04.000000000 +0200
-+++ tvtime-1.0.1-gcc41/plugins/tomsmocomp.cpp	2005-11-28 17:52:53.862107896 +0100
-@@ -31,7 +31,7 @@
- 
- #define IS_MMX
- #define SSE_TYPE MMX
--#define FUNCT_NAME DScalerFilterTomsMoComp::filterDScaler_MMX
-+#define FUNCT_NAME filterDScaler_MMX
- #include "tomsmocomp/TomsMoCompAll.inc"
- #undef  IS_MMX
- #undef  SSE_TYPE
-@@ -39,7 +39,7 @@
- 
- #define IS_3DNOW
- #define SSE_TYPE 3DNOW
--#define FUNCT_NAME DScalerFilterTomsMoComp::filterDScaler_3DNOW
-+#define FUNCT_NAME filterDScaler_3DNOW
- #include "tomsmocomp/TomsMoCompAll.inc"
- #undef  IS_3DNOW
- #undef  SSE_TYPE
-@@ -47,7 +47,7 @@
- 
- #define IS_SSE
- #define SSE_TYPE SSE
--#define FUNCT_NAME DScalerFilterTomsMoComp::filterDScaler_SSE
-+#define FUNCT_NAME filterDScaler_SSE
- #include "tomsmocomp/TomsMoCompAll.inc"
- #undef  IS_SSE
- #undef  SSE_TYPE
diff --git a/gnu/packages/patches/tvtime-pngoutput.patch b/gnu/packages/patches/tvtime-pngoutput.patch
deleted file mode 100644
index 0d14f77ca1..0000000000
--- a/gnu/packages/patches/tvtime-pngoutput.patch
+++ /dev/null
@@ -1,15 +0,0 @@
-Source: https://sources.debian.net/src/tvtime/1.0.2-14/debian/patches/libpng.diff
-
-From: Nobuhiro Iwamatsu <iwamatsu@nigauri.org>
-Date: Mon, 14 May 2012 19:01:31 +0900
-Prepares the package for libpng 1.5.  Closes: #650582.
-
---- tvtime-1.0.2.orig/src/pngoutput.c
-+++ tvtime-1.0.2/src/pngoutput.c
-@@ -18,5 +18,6 @@
- 
- #include <stdio.h>
- #include <stdlib.h>
-+#include <zlib.h>
- #include <png.h>
- #include "pngoutput.h" 
diff --git a/gnu/packages/patches/tvtime-videodev2.patch b/gnu/packages/patches/tvtime-videodev2.patch
deleted file mode 100644
index 74131f25d0..0000000000
--- a/gnu/packages/patches/tvtime-videodev2.patch
+++ /dev/null
@@ -1,15 +0,0 @@
-Fix compilation error: non-existing header file.
-
-This is an excerpt from the debian patch:
-http://http.debian.net/debian/pool/main/t/tvtime/tvtime_1.0.2-14.diff.gz
-
---- tvtime-1.0.2.orig/src/videodev2.h
-+++ tvtime-1.0.2/src/videodev2.h
-@@ -16,7 +16,6 @@
- #ifdef __KERNEL__
- #include <linux/time.h> /* need struct timeval */
- #endif
--#include <linux/compiler.h> /* need __user */
- 
- /* for kernel versions 2.4.26 and below: */
- #ifndef __user
diff --git a/gnu/packages/patches/tvtime-xmltv.patch b/gnu/packages/patches/tvtime-xmltv.patch
deleted file mode 100644
index 2f4afc6e5a..0000000000
--- a/gnu/packages/patches/tvtime-xmltv.patch
+++ /dev/null
@@ -1,28 +0,0 @@
-Fix compilation error: conflicting types for 'locale_t'.
-
-This is an excerpt from the debian patch ... 
-http://http.debian.net/debian/pool/main/t/tvtime/tvtime_1.0.2-14.diff.gz
-
---- tvtime-1.0.2.orig/src/xmltv.c
-+++ tvtime-1.0.2/src/xmltv.c
-@@ -118,9 +118,9 @@
- typedef struct {
-     const char *code;
-     const char *name;
--} locale_t;
-+} tvtime_locale_t;
- 
--static locale_t locale_table[] = {
-+static tvtime_locale_t locale_table[] = {
-     {"AA", "Afar"},           {"AB", "Abkhazian"},      {"AF", "Afrikaans"},
-     {"AM", "Amharic"},        {"AR", "Arabic"},         {"AS", "Assamese"},
-     {"AY", "Aymara"},         {"AZ", "Azerbaijani"},    {"BA", "Bashkir"},
-@@ -168,7 +168,7 @@
-     {"XH", "Xhosa"},          {"YO", "Yoruba"},         {"ZH", "Chinese"},
-     {"ZU", "Zulu"} };
- 
--const int num_locales = sizeof( locale_table ) / sizeof( locale_t );
-+const int num_locales = sizeof( locale_table ) / sizeof( tvtime_locale_t );
- 
- /**
-  * Timezone parsing code based loosely on the algorithm in
diff --git a/gnu/packages/patches/wpa-supplicant-CVE-2016-4476.patch b/gnu/packages/patches/wpa-supplicant-CVE-2016-4476.patch
new file mode 100644
index 0000000000..acad6be0a4
--- /dev/null
+++ b/gnu/packages/patches/wpa-supplicant-CVE-2016-4476.patch
@@ -0,0 +1,82 @@
+From ecbb0b3dc122b0d290987cf9c84010bbe53e1022 Mon Sep 17 00:00:00 2001
+From: Jouni Malinen <jouni@qca.qualcomm.com>
+Date: Fri, 4 Mar 2016 17:20:18 +0200
+Subject: [PATCH 1/5] WPS: Reject a Credential with invalid passphrase
+
+WPA/WPA2-Personal passphrase is not allowed to include control
+characters. Reject a Credential received from a WPS Registrar both as
+STA (Credential) and AP (AP Settings) if the credential is for WPAPSK or
+WPA2PSK authentication type and includes an invalid passphrase.
+
+This fixes an issue where hostapd or wpa_supplicant could have updated
+the configuration file PSK/passphrase parameter with arbitrary data from
+an external device (Registrar) that may not be fully trusted. Should
+such data include a newline character, the resulting configuration file
+could become invalid and fail to be parsed.
+
+Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com>
+---
+ src/utils/common.c         | 12 ++++++++++++
+ src/utils/common.h         |  1 +
+ src/wps/wps_attr_process.c | 10 ++++++++++
+ 3 files changed, 23 insertions(+)
+
+diff --git a/src/utils/common.c b/src/utils/common.c
+index 450e2c6..27b7c02 100644
+--- a/src/utils/common.c
++++ b/src/utils/common.c
+@@ -697,6 +697,18 @@ int is_hex(const u8 *data, size_t len)
+ }
+ 
+ 
++int has_ctrl_char(const u8 *data, size_t len)
++{
++	size_t i;
++
++	for (i = 0; i < len; i++) {
++		if (data[i] < 32 || data[i] == 127)
++			return 1;
++	}
++	return 0;
++}
++
++
+ size_t merge_byte_arrays(u8 *res, size_t res_len,
+ 			 const u8 *src1, size_t src1_len,
+ 			 const u8 *src2, size_t src2_len)
+diff --git a/src/utils/common.h b/src/utils/common.h
+index 701dbb2..a972240 100644
+--- a/src/utils/common.h
++++ b/src/utils/common.h
+@@ -488,6 +488,7 @@ const char * wpa_ssid_txt(const u8 *ssid, size_t ssid_len);
+ 
+ char * wpa_config_parse_string(const char *value, size_t *len);
+ int is_hex(const u8 *data, size_t len);
++int has_ctrl_char(const u8 *data, size_t len);
+ size_t merge_byte_arrays(u8 *res, size_t res_len,
+ 			 const u8 *src1, size_t src1_len,
+ 			 const u8 *src2, size_t src2_len);
+diff --git a/src/wps/wps_attr_process.c b/src/wps/wps_attr_process.c
+index eadb22f..e8c4579 100644
+--- a/src/wps/wps_attr_process.c
++++ b/src/wps/wps_attr_process.c
+@@ -229,6 +229,16 @@ static int wps_workaround_cred_key(struct wps_credential *cred)
+ 		cred->key_len--;
+ #endif /* CONFIG_WPS_STRICT */
+ 	}
++
++
++	if (cred->auth_type & (WPS_AUTH_WPAPSK | WPS_AUTH_WPA2PSK) &&
++	    (cred->key_len < 8 || has_ctrl_char(cred->key, cred->key_len))) {
++		wpa_printf(MSG_INFO, "WPS: Reject credential with invalid WPA/WPA2-Personal passphrase");
++		wpa_hexdump_ascii_key(MSG_INFO, "WPS: Network Key",
++				      cred->key, cred->key_len);
++		return -1;
++	}
++
+ 	return 0;
+ }
+ 
+-- 
+1.9.1
+
diff --git a/gnu/packages/patches/wpa-supplicant-CVE-2016-4477-pt1.patch b/gnu/packages/patches/wpa-supplicant-CVE-2016-4477-pt1.patch
new file mode 100644
index 0000000000..507a96e47c
--- /dev/null
+++ b/gnu/packages/patches/wpa-supplicant-CVE-2016-4477-pt1.patch
@@ -0,0 +1,51 @@
+From 73e4abb24a936014727924d8b0b2965edfc117dd Mon Sep 17 00:00:00 2001
+From: Jouni Malinen <jouni@qca.qualcomm.com>
+Date: Fri, 4 Mar 2016 18:46:41 +0200
+Subject: [PATCH 2/5] Reject psk parameter set with invalid passphrase
+ character
+
+WPA/WPA2-Personal passphrase is not allowed to include control
+characters. Reject a passphrase configuration attempt if that passphrase
+includes an invalid passphrase.
+
+This fixes an issue where wpa_supplicant could have updated the
+configuration file psk parameter with arbitrary data from the control
+interface or D-Bus interface. While those interfaces are supposed to be
+accessible only for trusted users/applications, it may be possible that
+an untrusted user has access to a management software component that
+does not validate the passphrase value before passing it to
+wpa_supplicant.
+
+This could allow such an untrusted user to inject up to 63 characters of
+almost arbitrary data into the configuration file. Such configuration
+file could result in wpa_supplicant trying to load a library (e.g.,
+opensc_engine_path, pkcs11_engine_path, pkcs11_module_path,
+load_dynamic_eap) from user controlled location when starting again.
+This would allow code from that library to be executed under the
+wpa_supplicant process privileges.
+
+Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com>
+---
+ wpa_supplicant/config.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c
+index b1c7870..fdd9643 100644
+--- a/wpa_supplicant/config.c
++++ b/wpa_supplicant/config.c
+@@ -478,6 +478,12 @@ static int wpa_config_parse_psk(const struct parse_data *data,
+ 		}
+ 		wpa_hexdump_ascii_key(MSG_MSGDUMP, "PSK (ASCII passphrase)",
+ 				      (u8 *) value, len);
++		if (has_ctrl_char((u8 *) value, len)) {
++			wpa_printf(MSG_ERROR,
++				   "Line %d: Invalid passphrase character",
++				   line);
++			return -1;
++		}
+ 		if (ssid->passphrase && os_strlen(ssid->passphrase) == len &&
+ 		    os_memcmp(ssid->passphrase, value, len) == 0) {
+ 			/* No change to the previously configured value */
+-- 
+1.9.1
+
diff --git a/gnu/packages/patches/wpa-supplicant-CVE-2016-4477-pt2.patch b/gnu/packages/patches/wpa-supplicant-CVE-2016-4477-pt2.patch
new file mode 100644
index 0000000000..684d25de96
--- /dev/null
+++ b/gnu/packages/patches/wpa-supplicant-CVE-2016-4477-pt2.patch
@@ -0,0 +1,82 @@
+From 0fe5a234240a108b294a87174ad197f6b5cb38e9 Mon Sep 17 00:00:00 2001
+From: Paul Stewart <pstew@google.com>
+Date: Thu, 3 Mar 2016 15:40:19 -0800
+Subject: [PATCH 3/5] Remove newlines from wpa_supplicant config network
+ output
+
+Spurious newlines output while writing the config file can corrupt the
+wpa_supplicant configuration. Avoid writing these for the network block
+parameters. This is a generic filter that cover cases that may not have
+been explicitly addressed with a more specific commit to avoid control
+characters in the psk parameter.
+
+Signed-off-by: Paul Stewart <pstew@google.com>
+---
+ src/utils/common.c      | 11 +++++++++++
+ src/utils/common.h      |  1 +
+ wpa_supplicant/config.c | 15 +++++++++++++--
+ 3 files changed, 25 insertions(+), 2 deletions(-)
+
+diff --git a/src/utils/common.c b/src/utils/common.c
+index 27b7c02..9856463 100644
+--- a/src/utils/common.c
++++ b/src/utils/common.c
+@@ -709,6 +709,17 @@ int has_ctrl_char(const u8 *data, size_t len)
+ }
+ 
+ 
++int has_newline(const char *str)
++{
++	while (*str) {
++		if (*str == '\n' || *str == '\r')
++			return 1;
++		str++;
++	}
++	return 0;
++}
++
++
+ size_t merge_byte_arrays(u8 *res, size_t res_len,
+ 			 const u8 *src1, size_t src1_len,
+ 			 const u8 *src2, size_t src2_len)
+diff --git a/src/utils/common.h b/src/utils/common.h
+index a972240..d19927b 100644
+--- a/src/utils/common.h
++++ b/src/utils/common.h
+@@ -489,6 +489,7 @@ const char * wpa_ssid_txt(const u8 *ssid, size_t ssid_len);
+ char * wpa_config_parse_string(const char *value, size_t *len);
+ int is_hex(const u8 *data, size_t len);
+ int has_ctrl_char(const u8 *data, size_t len);
++int has_newline(const char *str);
+ size_t merge_byte_arrays(u8 *res, size_t res_len,
+ 			 const u8 *src1, size_t src1_len,
+ 			 const u8 *src2, size_t src2_len);
+diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c
+index fdd9643..eb97cd5 100644
+--- a/wpa_supplicant/config.c
++++ b/wpa_supplicant/config.c
+@@ -2699,8 +2699,19 @@ char * wpa_config_get(struct wpa_ssid *ssid, const char *var)
+ 
+ 	for (i = 0; i < NUM_SSID_FIELDS; i++) {
+ 		const struct parse_data *field = &ssid_fields[i];
+-		if (os_strcmp(var, field->name) == 0)
+-			return field->writer(field, ssid);
++		if (os_strcmp(var, field->name) == 0) {
++			char *ret = field->writer(field, ssid);
++
++			if (ret && has_newline(ret)) {
++				wpa_printf(MSG_ERROR,
++					   "Found newline in value for %s; not returning it",
++					   var);
++				os_free(ret);
++				ret = NULL;
++			}
++
++			return ret;
++		}
+ 	}
+ 
+ 	return NULL;
+-- 
+1.9.1
+
diff --git a/gnu/packages/patches/wpa-supplicant-CVE-2016-4477-pt3.patch b/gnu/packages/patches/wpa-supplicant-CVE-2016-4477-pt3.patch
new file mode 100644
index 0000000000..2dd38fee31
--- /dev/null
+++ b/gnu/packages/patches/wpa-supplicant-CVE-2016-4477-pt3.patch
@@ -0,0 +1,62 @@
+From b166cd84a77a6717be9600bf95378a0055d6f5a5 Mon Sep 17 00:00:00 2001
+From: Jouni Malinen <jouni@qca.qualcomm.com>
+Date: Tue, 5 Apr 2016 23:33:10 +0300
+Subject: [PATCH 4/5] Reject SET_CRED commands with newline characters in the
+ string values
+
+Most of the cred block parameters are written as strings without
+filtering and if there is an embedded newline character in the value,
+unexpected configuration file data might be written.
+
+This fixes an issue where wpa_supplicant could have updated the
+configuration file cred parameter with arbitrary data from the control
+interface or D-Bus interface. While those interfaces are supposed to be
+accessible only for trusted users/applications, it may be possible that
+an untrusted user has access to a management software component that
+does not validate the credential value before passing it to
+wpa_supplicant.
+
+This could allow such an untrusted user to inject almost arbitrary data
+into the configuration file. Such configuration file could result in
+wpa_supplicant trying to load a library (e.g., opensc_engine_path,
+pkcs11_engine_path, pkcs11_module_path, load_dynamic_eap) from user
+controlled location when starting again. This would allow code from that
+library to be executed under the wpa_supplicant process privileges.
+
+Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com>
+---
+ wpa_supplicant/config.c | 9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c
+index eb97cd5..69152ef 100644
+--- a/wpa_supplicant/config.c
++++ b/wpa_supplicant/config.c
+@@ -2896,6 +2896,8 @@ int wpa_config_set_cred(struct wpa_cred *cred, const char *var,
+ 
+ 	if (os_strcmp(var, "password") == 0 &&
+ 	    os_strncmp(value, "ext:", 4) == 0) {
++		if (has_newline(value))
++			return -1;
+ 		str_clear_free(cred->password);
+ 		cred->password = os_strdup(value);
+ 		cred->ext_password = 1;
+@@ -2946,9 +2948,14 @@ int wpa_config_set_cred(struct wpa_cred *cred, const char *var,
+ 	}
+ 
+ 	val = wpa_config_parse_string(value, &len);
+-	if (val == NULL) {
++	if (val == NULL ||
++	    (os_strcmp(var, "excluded_ssid") != 0 &&
++	     os_strcmp(var, "roaming_consortium") != 0 &&
++	     os_strcmp(var, "required_roaming_consortium") != 0 &&
++	     has_newline(val))) {
+ 		wpa_printf(MSG_ERROR, "Line %d: invalid field '%s' string "
+ 			   "value '%s'.", line, var, value);
++		os_free(val);
+ 		return -1;
+ 	}
+ 
+-- 
+1.9.1
+
diff --git a/gnu/packages/patches/wpa-supplicant-CVE-2016-4477-pt4.patch b/gnu/packages/patches/wpa-supplicant-CVE-2016-4477-pt4.patch
new file mode 100644
index 0000000000..5f42aa9219
--- /dev/null
+++ b/gnu/packages/patches/wpa-supplicant-CVE-2016-4477-pt4.patch
@@ -0,0 +1,50 @@
+From 2a3f56502b52375c3bf113cf92adfa99bad6b488 Mon Sep 17 00:00:00 2001
+From: Jouni Malinen <jouni@qca.qualcomm.com>
+Date: Tue, 5 Apr 2016 23:55:48 +0300
+Subject: [PATCH 5/5] Reject SET commands with newline characters in the
+ string values
+
+Many of the global configuration parameters are written as strings
+without filtering and if there is an embedded newline character in the
+value, unexpected configuration file data might be written.
+
+This fixes an issue where wpa_supplicant could have updated the
+configuration file global parameter with arbitrary data from the control
+interface or D-Bus interface. While those interfaces are supposed to be
+accessible only for trusted users/applications, it may be possible that
+an untrusted user has access to a management software component that
+does not validate the value of a parameter before passing it to
+wpa_supplicant.
+
+This could allow such an untrusted user to inject almost arbitrary data
+into the configuration file. Such configuration file could result in
+wpa_supplicant trying to load a library (e.g., opensc_engine_path,
+pkcs11_engine_path, pkcs11_module_path, load_dynamic_eap) from user
+controlled location when starting again. This would allow code from that
+library to be executed under the wpa_supplicant process privileges.
+
+Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com>
+---
+ wpa_supplicant/config.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c
+index 69152ef..d9a1603 100644
+--- a/wpa_supplicant/config.c
++++ b/wpa_supplicant/config.c
+@@ -3764,6 +3764,12 @@ static int wpa_global_config_parse_str(const struct global_parse_data *data,
+ 		return -1;
+ 	}
+ 
++	if (has_newline(pos)) {
++		wpa_printf(MSG_ERROR, "Line %d: invalid %s value with newline",
++			   line, data->name);
++		return -1;
++	}
++
+ 	tmp = os_strdup(pos);
+ 	if (tmp == NULL)
+ 		return -1;
+-- 
+1.9.1
+