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/gd-CVE-2017-7890.patch30
-rw-r--r--gnu/packages/patches/graphicsmagick-CVE-2017-13775.patch195
-rw-r--r--gnu/packages/patches/graphicsmagick-CVE-2017-13776+CVE-2017-13777.patch179
-rw-r--r--gnu/packages/patches/libxml2-CVE-2017-0663.patch53
-rw-r--r--gnu/packages/patches/libxml2-CVE-2017-7375.patch45
-rw-r--r--gnu/packages/patches/libxml2-CVE-2017-7376.patch41
-rw-r--r--gnu/packages/patches/libxml2-CVE-2017-9047+CVE-2017-9048.patch130
-rw-r--r--gnu/packages/patches/libxml2-CVE-2017-9049+CVE-2017-9050.patch319
-rw-r--r--gnu/packages/patches/libzip-CVE-2017-12858.patch45
-rw-r--r--gnu/packages/patches/metabat-fix-boost-issue.patch27
-rw-r--r--gnu/packages/patches/metabat-remove-compilation-date.patch16
-rw-r--r--gnu/packages/patches/multiqc-fix-git-subprocess-error.patch16
-rw-r--r--gnu/packages/patches/python2-larch-coverage-4.0a6-compatibility.patch29
-rw-r--r--gnu/packages/patches/qemu-CVE-2017-10664.patch27
-rw-r--r--gnu/packages/patches/qemu-CVE-2017-10806.patch38
-rw-r--r--gnu/packages/patches/qemu-CVE-2017-10911.patch106
-rw-r--r--gnu/packages/patches/qemu-CVE-2017-11334.patch52
-rw-r--r--gnu/packages/patches/qemu-CVE-2017-11434.patch25
-rw-r--r--gnu/packages/patches/qemu-CVE-2017-12809.patch38
-rw-r--r--gnu/packages/patches/qemu-CVE-2017-7493.patch182
-rw-r--r--gnu/packages/patches/qemu-CVE-2017-8112.patch41
-rw-r--r--gnu/packages/patches/qemu-CVE-2017-8309.patch46
-rw-r--r--gnu/packages/patches/qemu-CVE-2017-8379.patch98
-rw-r--r--gnu/packages/patches/qemu-CVE-2017-8380.patch53
-rw-r--r--gnu/packages/patches/qemu-CVE-2017-9524.patch287
-rw-r--r--gnu/packages/patches/ruby-2.2.7-rubygems-2613-ruby22.patch355
-rw-r--r--gnu/packages/patches/ruby-2.3.4-rubygems-2613-ruby23.patch355
-rw-r--r--gnu/packages/patches/ruby-rubygems-2612-ruby24.patch437
-rw-r--r--gnu/packages/patches/ruby-rubygems-2613-ruby24.patch355
-rw-r--r--gnu/packages/patches/wmfire-update-for-new-gdk-versions.patch2
-rw-r--r--gnu/packages/patches/wxwidgets-fix-windowGTK.patch18
31 files changed, 2539 insertions, 1101 deletions
diff --git a/gnu/packages/patches/gd-CVE-2017-7890.patch b/gnu/packages/patches/gd-CVE-2017-7890.patch
deleted file mode 100644
index 66034c5703..0000000000
--- a/gnu/packages/patches/gd-CVE-2017-7890.patch
+++ /dev/null
@@ -1,30 +0,0 @@
-From 99ba5c353373ed198f54af66fe4e355ebb96e363 Mon Sep 17 00:00:00 2001
-From: LEPILLER Julien <julien@lepiller.eu>
-Date: Thu, 3 Aug 2017 17:04:17 +0200
-Subject: [PATCH] Fix #399: Buffer over-read into uninitialized memory.
-
-The stack allocated color map buffers were not zeroed before usage, and
-so undefined palette indexes could cause information leakage.
-
-This is CVE-2017-7890.
----
- src/gd_gif_in.c | 3 +++
- 1 file changed, 3 insertions(+)
-
-diff --git a/src/gd_gif_in.c b/src/gd_gif_in.c
-index 008d1ec..c195448 100644
---- a/src/gd_gif_in.c
-+++ b/src/gd_gif_in.c
-@@ -216,6 +216,9 @@ BGD_DECLARE(gdImagePtr) gdImageCreateFromGifCtx(gdIOCtxPtr fd)
- 
- 	gdImagePtr im = 0;
- 
-+	memset(ColorMap, 0, 3 * MAXCOLORMAPSIZE);
-+	memset(localColorMap, 0, 3 * MAXCOLORMAPSIZE);
-+
- 	if(!ReadOK(fd, buf, 6)) {
- 		return 0;
- 	}
--- 
-2.13.3
-
diff --git a/gnu/packages/patches/graphicsmagick-CVE-2017-13775.patch b/gnu/packages/patches/graphicsmagick-CVE-2017-13775.patch
new file mode 100644
index 0000000000..83478c13b3
--- /dev/null
+++ b/gnu/packages/patches/graphicsmagick-CVE-2017-13775.patch
@@ -0,0 +1,195 @@
+http://openwall.com/lists/oss-security/2017/08/31/3
+http://hg.code.sf.net/p/graphicsmagick/code/raw-rev/b037d79b6ccd
+
+some changes were made to make the patch apply
+
+# HG changeset patch
+# User Bob Friesenhahn <bfriesen@GraphicsMagick.org>
+# Date 1503774853 18000
+# Node ID b037d79b6ccd0cfba7ba9ce09b454ed46d688036
+# Parent  198ea602ea7cc767dc3022bbcf887bcd4534158d
+JNX: Fix DOS issues
+
+diff -r 198ea602ea7c -r b037d79b6ccd coders/jnx.c
+--- a/coders/jnx.c	Tue Aug 22 08:08:30 2017 -0500
++++ b/coders/jnx.c	Sat Aug 26 14:14:13 2017 -0500
+@@ -1,5 +1,5 @@
+ /*
+-% Copyright (C) 2012-2015 GraphicsMagick Group
++% Copyright (C) 2012-2017 GraphicsMagick Group
+ %
+ % This program is covered by multiple licenses, which are described in
+ % Copyright.txt. You should have received a copy of Copyright.txt with this
+@@ -100,6 +100,7 @@
+ 
+   char img_label_str[MaxTextExtent];
+ 
++
+   alloc_size = TileInfo->PicSize + 2;
+ 
+   if (image->logging)
+@@ -242,6 +243,9 @@
+     total_tiles,
+     current_tile;
+ 
++  magick_off_t
++    file_size;
++
+   /* Open image file. */
+   assert(image_info != (const ImageInfo *) NULL);
+   assert(image_info->signature == MagickSignature);
+@@ -254,9 +258,8 @@
+   if (status == False)
+     ThrowReaderException(FileOpenError, UnableToOpenFile, image);
+ 
+-  memset(JNXLevelInfo, 0, sizeof(JNXLevelInfo));
+-
+   /* Read JNX image header. */
++  (void) memset(&JNXHeader, 0, sizeof(JNXHeader));
+   JNXHeader.Version = ReadBlobLSBLong(image);
+   if (JNXHeader.Version > 4)
+     ThrowReaderException(CorruptImageError, ImproperImageHeader, image);
+@@ -266,8 +269,6 @@
+   JNXHeader.MapBounds.SouthWest.lat = ReadBlobLSBLong(image);
+   JNXHeader.MapBounds.SouthWest.lon = ReadBlobLSBLong(image);
+   JNXHeader.Levels = ReadBlobLSBLong(image);
+-  if (JNXHeader.Levels > 20)
+-    ThrowReaderException(CorruptImageError, ImproperImageHeader, image);
+   JNXHeader.Expiration = ReadBlobLSBLong(image);
+   JNXHeader.ProductID = ReadBlobLSBLong(image);
+   JNXHeader.CRC = ReadBlobLSBLong(image);
+@@ -279,7 +280,41 @@
+   if (EOFBlob(image))
+     ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image);
+ 
++  file_size = GetBlobSize(image);
++
++  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
++                        "JNX Header:\n"
++                        "    Version:    %u\n"
++                        "    DeviceSN:   %u\n"
++                        "    MapBounds:\n"
++                        "      NorthEast: lat = %u, lon = %u\n"
++                        "      SouthWest: lat = %u, lon = %u\n"
++                        "    Levels:     %u\n"
++                        "    Expiration: %u\n"
++                        "    ProductID:  %u\n"
++                        "    CRC:        %u\n"
++                        "    SigVersion: %u\n"
++                        "    SigOffset:  %u\n"
++                        "    ZOrder:     %u",
++                        JNXHeader.Version,
++                        JNXHeader.DeviceSN,
++                        JNXHeader.MapBounds.NorthEast.lat,
++                        JNXHeader.MapBounds.NorthEast.lon,
++                        JNXHeader.MapBounds.SouthWest.lat,
++                        JNXHeader.MapBounds.SouthWest.lon,
++                        JNXHeader.Levels,
++                        JNXHeader.Expiration,
++                        JNXHeader.ProductID,
++                        JNXHeader.CRC,
++                        JNXHeader.SigVersion,
++                        JNXHeader.SigOffset,
++                        JNXHeader.ZOrder);
++
++  if (JNXHeader.Levels > 20)
++    ThrowReaderException(CorruptImageError, ImproperImageHeader, image);
++
+   /* Read JNX image level info. */
++  memset(JNXLevelInfo, 0, sizeof(JNXLevelInfo));
+   total_tiles = 0;
+   current_tile = 0;
+   for (i = 0; i < JNXHeader.Levels; i++)
+@@ -302,11 +337,23 @@
+         {
+           JNXLevelInfo[i].Copyright = NULL;
+         }
++
++      if (EOFBlob(image))
++        ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image);
++
++      if (image->logging)
++        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
++                              "Level[%u] Info:"
++                              "  TileCount: %4u"
++                              "  TilesOffset: %6u"
++                              "  Scale: %04u",
++                              i,
++                              JNXLevelInfo[i].TileCount,
++                              JNXLevelInfo[i].TilesOffset,
++                              JNXLevelInfo[i].Scale
++                              );
+     }
+ 
+-  if (EOFBlob(image))
+-    ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image);
+-
+   /* Get the current limit */
+   SaveLimit = GetMagickResourceLimit(MapResource);
+ 
+@@ -316,11 +363,32 @@
+   /* Read JNX image data. */
+   for (i = 0; i < JNXHeader.Levels; i++)
+     {
++      /*
++        Validate TileCount against remaining file data
++      */
++      const magick_off_t current_offset = TellBlob(image);
++      const size_t pos_list_entry_size =
++        sizeof(magick_uint32_t) + sizeof(magick_uint32_t) + sizeof(magick_uint32_t) +
++        sizeof(magick_uint32_t) + sizeof(magick_uint16_t) + sizeof(magick_uint16_t) +
++        sizeof(magick_uint32_t) + sizeof(magick_uint32_t);
++      const magick_off_t remaining = file_size-current_offset;
++      const size_t needed = MagickArraySize(pos_list_entry_size,JNXLevelInfo[i].TileCount);
++
++      if ((needed == 0U) || (remaining <= 0) || (remaining < (magick_off_t) needed))
++        {
++          (void) SetMagickResourceLimit(MapResource, SaveLimit);
++          ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image);
++        }
++
+       PositionList = MagickAllocateArray(TJNXTileInfo *,
+                                          JNXLevelInfo[i].TileCount,
+                                          sizeof(TJNXTileInfo));
+       if (PositionList == NULL)
+-        continue;
++        {
++          (void) SetMagickResourceLimit(MapResource, SaveLimit);
++          ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,
++                               image);
++        }
+ 
+       (void) SeekBlob(image, JNXLevelInfo[i].TilesOffset, SEEK_SET);
+       for (j = 0; j < JNXLevelInfo[i].TileCount; j++)
+@@ -333,12 +401,15 @@
+           PositionList[j].PicHeight = ReadBlobLSBShort(image);
+           PositionList[j].PicSize = ReadBlobLSBLong(image);
+           PositionList[j].PicOffset = ReadBlobLSBLong(image);
+-        }
+ 
+-      if (EOFBlob(image))
+-        {
+-          MagickFreeMemory(PositionList);
+-          ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image);
++          if (EOFBlob(image) ||
++              ((magick_off_t) PositionList[j].PicOffset +
++               PositionList[j].PicSize > file_size))
++            {
++              (void) SetMagickResourceLimit(MapResource, SaveLimit);
++              MagickFreeMemory(PositionList);
++              ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image);
++            }
+         }
+ 
+       for (j = 0; j < JNXLevelInfo[i].TileCount; j++)
+@@ -351,6 +422,9 @@
+           image = ExtractTileJPG(image, image_info, PositionList+j, exception);
+           (void) SetMonitorHandler(previous_handler);
+ 
++          if (exception->severity >= ErrorException)
++            break;
++
+           current_tile++;
+           if (QuantumTick(current_tile,total_tiles))
+             if (!MagickMonitorFormatted(current_tile,total_tiles,exception,
+
diff --git a/gnu/packages/patches/graphicsmagick-CVE-2017-13776+CVE-2017-13777.patch b/gnu/packages/patches/graphicsmagick-CVE-2017-13776+CVE-2017-13777.patch
new file mode 100644
index 0000000000..e129fd58fc
--- /dev/null
+++ b/gnu/packages/patches/graphicsmagick-CVE-2017-13776+CVE-2017-13777.patch
@@ -0,0 +1,179 @@
+http://openwall.com/lists/oss-security/2017/08/31/1
+http://openwall.com/lists/oss-security/2017/08/31/2
+http://hg.code.sf.net/p/graphicsmagick/code/raw-rev/233a720bfd5e
+
+some changes were made to make the patch apply
+
+# HG changeset patch
+# User Bob Friesenhahn <bfriesen@GraphicsMagick.org>
+# Date 1503779175 18000
+# Node ID 233a720bfd5efd378f133a776507ed41230da617
+# Parent  b037d79b6ccd0cfba7ba9ce09b454ed46d688036
+XBM: Fix DOS issues.
+
+diff -r b037d79b6ccd -r 233a720bfd5e coders/xbm.c
+--- a/coders/xbm.c	Sat Aug 26 14:14:13 2017 -0500
++++ b/coders/xbm.c	Sat Aug 26 15:26:15 2017 -0500
+@@ -1,5 +1,5 @@
+ /*
+-% Copyright (C) 2003 -2012 GraphicsMagick Group
++% Copyright (C) 2003-2017 GraphicsMagick Group
+ % Copyright (C) 2002 ImageMagick Studio
+ % Copyright 1991-1999 E. I. du Pont de Nemours and Company
+ %
+@@ -121,13 +121,15 @@
+ 
+ static int XBMInteger(Image *image,short int *hex_digits)
+ {
++  unsigned int
++    flag;
++
+   int
+     c,
+-    flag,
+     value;
+ 
+   value=0;
+-  flag=0;
++  flag=0U;
+   for ( ; ; )
+   {
+     c=ReadBlobByte(image);
+@@ -158,18 +160,14 @@
+   Image
+     *image;
+ 
+-  int
+-    bit;
+-
+-  long
+-    y;
+-
+   register IndexPacket
+     *indexes;
+ 
+-  register long
++  register size_t
++    bytes_per_line,
+     i,
+-    x;
++    x,
++    y;
+ 
+   register PixelPacket
+     *q;
+@@ -177,22 +175,24 @@
+   register unsigned char
+     *p;
+ 
+-  short int
+-    hex_digits[256];
+-
+   unsigned char
+     *data;
+ 
+   unsigned int
++    bit,
++    byte,
++    padding,
++    version;
++
++  int
++    value;
++
++  short int
++    hex_digits[256];
++
++  MagickPassFail
+     status;
+ 
+-  unsigned long
+-    byte,
+-    bytes_per_line,
+-    padding,
+-    value,
+-    version;
+-
+   /*
+     Open image file.
+   */
+@@ -207,6 +207,8 @@
+   /*
+     Read X bitmap header.
+   */
++  (void) memset(buffer,0,sizeof(buffer));
++  name[0]='\0';
+   while (ReadBlobString(image,buffer) != (char *) NULL)
+     if (sscanf(buffer,"#define %s %lu",name,&image->columns) == 2)
+       if ((strlen(name) >= 6) &&
+@@ -278,6 +280,8 @@
+   /*
+     Initialize hex values.
+   */
++  for (i = 0; i < sizeof(hex_digits)/sizeof(hex_digits[0]); i++)
++    hex_digits[i]=(-1);
+   hex_digits['0']=0;
+   hex_digits['1']=1;
+   hex_digits['2']=2;
+@@ -311,40 +315,50 @@
+   */
+   p=data;
+   if (version == 10)
+-    for (i=0; i < (long) (bytes_per_line*image->rows); (i+=2))
++    for (i=0; i < (bytes_per_line*image->rows); (i+=2))
+     {
+       value=XBMInteger(image,hex_digits);
++      if (value < 0)
++        {
++          MagickFreeMemory(data);
++          ThrowReaderException(CorruptImageError,ImproperImageHeader,image);
++        }
+       *p++=(unsigned char) value;
+       if (!padding || ((i+2) % bytes_per_line))
+         *p++=(unsigned char) (value >> 8);
+     }
+   else
+-    for (i=0; i < (long) (bytes_per_line*image->rows); i++)
++    for (i=0; i < (bytes_per_line*image->rows); i++)
+     {
+       value=XBMInteger(image,hex_digits);
++      if (value < 0)
++        {
++          MagickFreeMemory(data);
++          ThrowReaderException(CorruptImageError,ImproperImageHeader,image);
++        }
+       *p++=(unsigned char) value;
+     }
+   /*
+     Convert X bitmap image to pixel packets.
+   */
+   p=data;
+-  for (y=0; y < (long) image->rows; y++)
++  for (y=0; y < image->rows; y++)
+   {
+     q=SetImagePixels(image,0,y,image->columns,1);
+     if (q == (PixelPacket *) NULL)
+       break;
+     indexes=AccessMutableIndexes(image);
+-    bit=0;
+-    byte=0;
+-    for (x=0; x < (long) image->columns; x++)
++    bit=0U;
++    byte=0U;
++    for (x=0; x < image->columns; x++)
+     {
+-      if (bit == 0)
++      if (bit == 0U)
+         byte=(*p++);
+       indexes[x]=byte & 0x01 ? 0x01 : 0x00;
+       bit++;
+-      byte>>=1;
+-      if (bit == 8)
+-        bit=0;
++      byte>>=1U;
++      if (bit == 8U)
++        bit=0U;
+     }
+     if (!SyncImagePixels(image))
+       break;
+
diff --git a/gnu/packages/patches/libxml2-CVE-2017-0663.patch b/gnu/packages/patches/libxml2-CVE-2017-0663.patch
new file mode 100644
index 0000000000..b0277a2d23
--- /dev/null
+++ b/gnu/packages/patches/libxml2-CVE-2017-0663.patch
@@ -0,0 +1,53 @@
+Fix CVE-2017-0663:
+
+https://bugzilla.gnome.org/show_bug.cgi?id=780228 (not yet public)
+https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-0663
+https://security-tracker.debian.org/tracker/CVE-2017-0663
+
+Patch copied from upstream source repository:
+
+https://git.gnome.org/browse/libxml2/commit/?id=92b9e8c8b3787068565a1820ba575d042f9eec66
+
+From 92b9e8c8b3787068565a1820ba575d042f9eec66 Mon Sep 17 00:00:00 2001
+From: Nick Wellnhofer <wellnhofer@aevum.de>
+Date: Tue, 6 Jun 2017 12:56:28 +0200
+Subject: [PATCH] Fix type confusion in xmlValidateOneNamespace
+
+Comment out code that casts xmlNsPtr to xmlAttrPtr. ID types on
+namespace declarations make no practical sense anyway.
+
+Fixes bug 780228.
+
+Found with libFuzzer and ASan.
+---
+ valid.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/valid.c b/valid.c
+index 8075d3a0..c51ea290 100644
+--- a/valid.c
++++ b/valid.c
+@@ -4627,6 +4627,12 @@ xmlNodePtr elem, const xmlChar *prefix, xmlNsPtr ns, const xmlChar *value) {
+ 	}
+     }
+ 
++    /*
++     * Casting ns to xmlAttrPtr is wrong. We'd need separate functions
++     * xmlAddID and xmlAddRef for namespace declarations, but it makes
++     * no practical sense to use ID types anyway.
++     */
++#if 0
+     /* Validity Constraint: ID uniqueness */
+     if (attrDecl->atype == XML_ATTRIBUTE_ID) {
+         if (xmlAddID(ctxt, doc, value, (xmlAttrPtr) ns) == NULL)
+@@ -4638,6 +4644,7 @@ xmlNodePtr elem, const xmlChar *prefix, xmlNsPtr ns, const xmlChar *value) {
+         if (xmlAddRef(ctxt, doc, value, (xmlAttrPtr) ns) == NULL)
+ 	    ret = 0;
+     }
++#endif
+ 
+     /* Validity Constraint: Notation Attributes */
+     if (attrDecl->atype == XML_ATTRIBUTE_NOTATION) {
+-- 
+2.14.1
+
diff --git a/gnu/packages/patches/libxml2-CVE-2017-7375.patch b/gnu/packages/patches/libxml2-CVE-2017-7375.patch
new file mode 100644
index 0000000000..32af1ff6ba
--- /dev/null
+++ b/gnu/packages/patches/libxml2-CVE-2017-7375.patch
@@ -0,0 +1,45 @@
+Fix CVE-2017-7375:
+
+https://bugzilla.gnome.org/show_bug.cgi?id=780691 (not yet public)
+https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-7375
+https://security-tracker.debian.org/tracker/CVE-2017-7375
+
+Patch copied from upstream source repository:
+
+https://git.gnome.org/browse/libxml2/commit/?id=90ccb58242866b0ba3edbef8fe44214a101c2b3e
+
+From 90ccb58242866b0ba3edbef8fe44214a101c2b3e Mon Sep 17 00:00:00 2001
+From: Neel Mehta <nmehta@google.com>
+Date: Fri, 7 Apr 2017 17:43:02 +0200
+Subject: [PATCH] Prevent unwanted external entity reference
+
+For https://bugzilla.gnome.org/show_bug.cgi?id=780691
+
+* parser.c: add a specific check to avoid PE reference
+---
+ parser.c | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+diff --git a/parser.c b/parser.c
+index 609a2703..c2c812de 100644
+--- a/parser.c
++++ b/parser.c
+@@ -8123,6 +8123,15 @@ xmlParsePEReference(xmlParserCtxtPtr ctxt)
+ 	    if (xmlPushInput(ctxt, input) < 0)
+ 		return;
+ 	} else {
++	    if ((entity->etype == XML_EXTERNAL_PARAMETER_ENTITY) &&
++	        ((ctxt->options & XML_PARSE_NOENT) == 0) &&
++		((ctxt->options & XML_PARSE_DTDVALID) == 0) &&
++		((ctxt->options & XML_PARSE_DTDLOAD) == 0) &&
++		((ctxt->options & XML_PARSE_DTDATTR) == 0) &&
++		(ctxt->replaceEntities == 0) &&
++		(ctxt->validate == 0))
++		return;
++
+ 	    /*
+ 	     * TODO !!!
+ 	     * handle the extra spaces added before and after
+-- 
+2.14.1
+
diff --git a/gnu/packages/patches/libxml2-CVE-2017-7376.patch b/gnu/packages/patches/libxml2-CVE-2017-7376.patch
new file mode 100644
index 0000000000..5b9e45bd83
--- /dev/null
+++ b/gnu/packages/patches/libxml2-CVE-2017-7376.patch
@@ -0,0 +1,41 @@
+Fix CVE-2017-7376:
+
+https://bugzilla.gnome.org/show_bug.cgi?id=780690 (not yet public)
+https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-7376
+https://security-tracker.debian.org/tracker/CVE-2017-7376
+
+Patch copied from upstream source repository:
+
+https://git.gnome.org/browse/libxml2/commit/?id=5dca9eea1bd4263bfa4d037ab2443de1cd730f7e
+
+From 5dca9eea1bd4263bfa4d037ab2443de1cd730f7e Mon Sep 17 00:00:00 2001
+From: Daniel Veillard <veillard@redhat.com>
+Date: Fri, 7 Apr 2017 17:13:28 +0200
+Subject: [PATCH] Increase buffer space for port in HTTP redirect support
+
+For https://bugzilla.gnome.org/show_bug.cgi?id=780690
+
+nanohttp.c: the code wrongly assumed a short int port value.
+---
+ nanohttp.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/nanohttp.c b/nanohttp.c
+index e109ad75..373425de 100644
+--- a/nanohttp.c
++++ b/nanohttp.c
+@@ -1423,9 +1423,9 @@ retry:
+     if (ctxt->port != 80) {
+ 	/* reserve space for ':xxxxx', incl. potential proxy */
+ 	if (proxy)
+-	    blen += 12;
++	    blen += 17;
+ 	else
+-	    blen += 6;
++	    blen += 11;
+     }
+     bp = (char*)xmlMallocAtomic(blen);
+     if ( bp == NULL ) {
+-- 
+2.14.1
+
diff --git a/gnu/packages/patches/libxml2-CVE-2017-9047+CVE-2017-9048.patch b/gnu/packages/patches/libxml2-CVE-2017-9047+CVE-2017-9048.patch
new file mode 100644
index 0000000000..0a0e6d34cf
--- /dev/null
+++ b/gnu/packages/patches/libxml2-CVE-2017-9047+CVE-2017-9048.patch
@@ -0,0 +1,130 @@
+Fix CVE-2017-{9047,9048}:
+
+https://bugzilla.gnome.org/show_bug.cgi?id=781333 (not yet public)
+https://bugzilla.gnome.org/show_bug.cgi?id=781701 (not yet public)
+https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-9047
+https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-9048
+http://www.openwall.com/lists/oss-security/2017/05/15/1
+https://security-tracker.debian.org/tracker/CVE-2017-9047
+https://security-tracker.debian.org/tracker/CVE-2017-9048
+
+Patch copied from upstream source repository:
+
+https://git.gnome.org/browse/libxml2/commit/?id=932cc9896ab41475d4aa429c27d9afd175959d74
+
+From 932cc9896ab41475d4aa429c27d9afd175959d74 Mon Sep 17 00:00:00 2001
+From: Nick Wellnhofer <wellnhofer@aevum.de>
+Date: Sat, 3 Jun 2017 02:01:29 +0200
+Subject: [PATCH] Fix buffer size checks in xmlSnprintfElementContent
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+xmlSnprintfElementContent failed to correctly check the available
+buffer space in two locations.
+
+Fixes bug 781333 (CVE-2017-9047) and bug 781701 (CVE-2017-9048).
+
+Thanks to Marcel Böhme and Thuan Pham for the report.
+---
+ result/valid/781333.xml         |  5 +++++
+ result/valid/781333.xml.err     |  3 +++
+ result/valid/781333.xml.err.rdr |  6 ++++++
+ test/valid/781333.xml           |  4 ++++
+ valid.c                         | 20 +++++++++++---------
+ 5 files changed, 29 insertions(+), 9 deletions(-)
+ create mode 100644 result/valid/781333.xml
+ create mode 100644 result/valid/781333.xml.err
+ create mode 100644 result/valid/781333.xml.err.rdr
+ create mode 100644 test/valid/781333.xml
+
+diff --git a/result/valid/781333.xml b/result/valid/781333.xml
+new file mode 100644
+index 00000000..45dc451d
+--- /dev/null
++++ b/result/valid/781333.xml
+@@ -0,0 +1,5 @@
++<?xml version="1.0"?>
++<!DOCTYPE a [
++<!ELEMENT a (pppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppp:llllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll)>
++]>
++<a/>
+diff --git a/result/valid/781333.xml.err b/result/valid/781333.xml.err
+new file mode 100644
+index 00000000..b401b49a
+--- /dev/null
++++ b/result/valid/781333.xml.err
+@@ -0,0 +1,3 @@
++./test/valid/781333.xml:4: element a: validity error : Element a content does not follow the DTD, expecting ( ..., got 
++<a/>
++    ^
+diff --git a/result/valid/781333.xml.err.rdr b/result/valid/781333.xml.err.rdr
+new file mode 100644
+index 00000000..5ff56992
+--- /dev/null
++++ b/result/valid/781333.xml.err.rdr
+@@ -0,0 +1,6 @@
++./test/valid/781333.xml:4: element a: validity error : Element a content does not follow the DTD, expecting ( ..., got 
++<a/>
++    ^
++./test/valid/781333.xml:5: element a: validity error : Element a content does not follow the DTD, Expecting more child
++
++^
+diff --git a/test/valid/781333.xml b/test/valid/781333.xml
+new file mode 100644
+index 00000000..b29e5a68
+--- /dev/null
++++ b/test/valid/781333.xml
+@@ -0,0 +1,4 @@
++<!DOCTYPE a [
++    <!ELEMENT a (pppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppp:llllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll)>
++]>
++<a/>
+diff --git a/valid.c b/valid.c
+index 19f84b82..9b2df56a 100644
+--- a/valid.c
++++ b/valid.c
+@@ -1262,22 +1262,23 @@ xmlSnprintfElementContent(char *buf, int size, xmlElementContentPtr content, int
+         case XML_ELEMENT_CONTENT_PCDATA:
+             strcat(buf, "#PCDATA");
+ 	    break;
+-	case XML_ELEMENT_CONTENT_ELEMENT:
++	case XML_ELEMENT_CONTENT_ELEMENT: {
++            int qnameLen = xmlStrlen(content->name);
++
++	    if (content->prefix != NULL)
++                qnameLen += xmlStrlen(content->prefix) + 1;
++	    if (size - len < qnameLen + 10) {
++		strcat(buf, " ...");
++		return;
++	    }
+ 	    if (content->prefix != NULL) {
+-		if (size - len < xmlStrlen(content->prefix) + 10) {
+-		    strcat(buf, " ...");
+-		    return;
+-		}
+ 		strcat(buf, (char *) content->prefix);
+ 		strcat(buf, ":");
+ 	    }
+-	    if (size - len < xmlStrlen(content->name) + 10) {
+-		strcat(buf, " ...");
+-		return;
+-	    }
+ 	    if (content->name != NULL)
+ 		strcat(buf, (char *) content->name);
+ 	    break;
++        }
+ 	case XML_ELEMENT_CONTENT_SEQ:
+ 	    if ((content->c1->type == XML_ELEMENT_CONTENT_OR) ||
+ 	        (content->c1->type == XML_ELEMENT_CONTENT_SEQ))
+@@ -1319,6 +1320,7 @@ xmlSnprintfElementContent(char *buf, int size, xmlElementContentPtr content, int
+ 		xmlSnprintfElementContent(buf, size, content->c2, 0);
+ 	    break;
+     }
++    if (size - strlen(buf) <= 2) return;
+     if (englob)
+         strcat(buf, ")");
+     switch (content->ocur) {
+-- 
+2.14.1
+
diff --git a/gnu/packages/patches/libxml2-CVE-2017-9049+CVE-2017-9050.patch b/gnu/packages/patches/libxml2-CVE-2017-9049+CVE-2017-9050.patch
new file mode 100644
index 0000000000..890e9c2284
--- /dev/null
+++ b/gnu/packages/patches/libxml2-CVE-2017-9049+CVE-2017-9050.patch
@@ -0,0 +1,319 @@
+Fix CVE-2017-{9049,9050}:
+
+https://bugzilla.gnome.org/show_bug.cgi?id=781205 (not yet public)
+https://bugzilla.gnome.org/show_bug.cgi?id=781361 (not yet public)
+https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-9049
+https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-9050
+http://www.openwall.com/lists/oss-security/2017/05/15/1
+https://security-tracker.debian.org/tracker/CVE-2017-9049
+https://security-tracker.debian.org/tracker/CVE-2017-9050
+
+Patch copied from upstream source repository:
+
+https://git.gnome.org/browse/libxml2/commit/?id=e26630548e7d138d2c560844c43820b6767251e3
+
+Changes to 'runtest.c' are removed since they introduce test failure
+when applying to libxml2 2.9.4 release tarball.
+
+From e26630548e7d138d2c560844c43820b6767251e3 Mon Sep 17 00:00:00 2001
+From: Nick Wellnhofer <wellnhofer@aevum.de>
+Date: Mon, 5 Jun 2017 15:37:17 +0200
+Subject: [PATCH] Fix handling of parameter-entity references
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+There were two bugs where parameter-entity references could lead to an
+unexpected change of the input buffer in xmlParseNameComplex and
+xmlDictLookup being called with an invalid pointer.
+
+Percent sign in DTD Names
+=========================
+
+The NEXTL macro used to call xmlParserHandlePEReference. When parsing
+"complex" names inside the DTD, this could result in entity expansion
+which created a new input buffer. The fix is to simply remove the call
+to xmlParserHandlePEReference from the NEXTL macro. This is safe because
+no users of the macro require expansion of parameter entities.
+
+- xmlParseNameComplex
+- xmlParseNCNameComplex
+- xmlParseNmtoken
+
+The percent sign is not allowed in names, which are grammatical tokens.
+
+- xmlParseEntityValue
+
+Parameter-entity references in entity values are expanded but this
+happens in a separate step in this function.
+
+- xmlParseSystemLiteral
+
+Parameter-entity references are ignored in the system literal.
+
+- xmlParseAttValueComplex
+- xmlParseCharDataComplex
+- xmlParseCommentComplex
+- xmlParsePI
+- xmlParseCDSect
+
+Parameter-entity references are ignored outside the DTD.
+
+- xmlLoadEntityContent
+
+This function is only called from xmlStringLenDecodeEntities and
+entities are replaced in a separate step immediately after the function
+call.
+
+This bug could also be triggered with an internal subset and double
+entity expansion.
+
+This fixes bug 766956 initially reported by Wei Lei and independently by
+Chromium's ClusterFuzz, Hanno Böck, and Marco Grassi. Thanks to everyone
+involved.
+
+xmlParseNameComplex with XML_PARSE_OLD10
+========================================
+
+When parsing Names inside an expanded parameter entity with the
+XML_PARSE_OLD10 option, xmlParseNameComplex would call xmlGROW via the
+GROW macro if the input buffer was exhausted. At the end of the
+parameter entity's replacement text, this function would then call
+xmlPopInput which invalidated the input buffer.
+
+There should be no need to invoke GROW in this situation because the
+buffer is grown periodically every XML_PARSER_CHUNK_SIZE characters and,
+at least for UTF-8, in xmlCurrentChar. This also matches the code path
+executed when XML_PARSE_OLD10 is not set.
+
+This fixes bugs 781205 (CVE-2017-9049) and 781361 (CVE-2017-9050).
+Thanks to Marcel Böhme and Thuan Pham for the report.
+
+Additional hardening
+====================
+
+A separate check was added in xmlParseNameComplex to validate the
+buffer size.
+---
+ Makefile.am                     | 18 ++++++++++++++++++
+ parser.c                        | 18 ++++++++++--------
+ result/errors10/781205.xml      |  0
+ result/errors10/781205.xml.err  | 21 +++++++++++++++++++++
+ result/errors10/781361.xml      |  0
+ result/errors10/781361.xml.err  | 13 +++++++++++++
+ result/valid/766956.xml         |  0
+ result/valid/766956.xml.err     |  9 +++++++++
+ result/valid/766956.xml.err.rdr | 10 ++++++++++
+ runtest.c                       |  3 +++
+ test/errors10/781205.xml        |  3 +++
+ test/errors10/781361.xml        |  3 +++
+ test/valid/766956.xml           |  2 ++
+ test/valid/dtds/766956.dtd      |  2 ++
+ 14 files changed, 94 insertions(+), 8 deletions(-)
+ create mode 100644 result/errors10/781205.xml
+ create mode 100644 result/errors10/781205.xml.err
+ create mode 100644 result/errors10/781361.xml
+ create mode 100644 result/errors10/781361.xml.err
+ create mode 100644 result/valid/766956.xml
+ create mode 100644 result/valid/766956.xml.err
+ create mode 100644 result/valid/766956.xml.err.rdr
+ create mode 100644 test/errors10/781205.xml
+ create mode 100644 test/errors10/781361.xml
+ create mode 100644 test/valid/766956.xml
+ create mode 100644 test/valid/dtds/766956.dtd
+
+diff --git a/Makefile.am b/Makefile.am
+index 6fc8ffa9..10e716a5 100644
+--- a/Makefile.am
++++ b/Makefile.am
+@@ -427,6 +427,24 @@ Errtests : xmllint$(EXEEXT)
+ 	      if [ -n "$$log" ] ; then echo $$name result ; echo "$$log" ; fi ; \
+ 	      rm result.$$name error.$$name ; \
+ 	  fi ; fi ; done)
++	@echo "## Error cases regression tests (old 1.0)"
++	-@(for i in $(srcdir)/test/errors10/*.xml ; do \
++	  name=`basename $$i`; \
++	  if [ ! -d $$i ] ; then \
++	  if [ ! -f $(srcdir)/result/errors10/$$name ] ; then \
++	      echo New test file $$name ; \
++	      $(CHECKER) $(top_builddir)/xmllint --oldxml10 $$i \
++	         2> $(srcdir)/result/errors10/$$name.err \
++		 > $(srcdir)/result/errors10/$$name ; \
++	      grep "MORY ALLO" .memdump  | grep -v "MEMORY ALLOCATED : 0"; \
++	  else \
++	      log=`$(CHECKER) $(top_builddir)/xmllint --oldxml10 $$i 2> error.$$name > result.$$name ; \
++	      grep "MORY ALLO" .memdump  | grep -v "MEMORY ALLOCATED : 0"; \
++	      diff $(srcdir)/result/errors10/$$name result.$$name ; \
++	      diff $(srcdir)/result/errors10/$$name.err error.$$name` ; \
++	      if [ -n "$$log" ] ; then echo $$name result ; echo "$$log" ; fi ; \
++	      rm result.$$name error.$$name ; \
++	  fi ; fi ; done)
+ 	@echo "## Error cases stream regression tests"
+ 	-@(for i in $(srcdir)/test/errors/*.xml ; do \
+ 	  name=`basename $$i`; \
+diff --git a/parser.c b/parser.c
+index df2efa55..a175ac4e 100644
+--- a/parser.c
++++ b/parser.c
+@@ -2121,7 +2121,6 @@ static void xmlGROW (xmlParserCtxtPtr ctxt) {
+ 	ctxt->input->line++; ctxt->input->col = 1;			\
+     } else ctxt->input->col++;						\
+     ctxt->input->cur += l;				\
+-    if (*ctxt->input->cur == '%') xmlParserHandlePEReference(ctxt);	\
+   } while (0)
+ 
+ #define CUR_CHAR(l) xmlCurrentChar(ctxt, &l)
+@@ -3412,13 +3411,6 @@ xmlParseNameComplex(xmlParserCtxtPtr ctxt) {
+ 	    len += l;
+ 	    NEXTL(l);
+ 	    c = CUR_CHAR(l);
+-	    if (c == 0) {
+-		count = 0;
+-		GROW;
+-                if (ctxt->instate == XML_PARSER_EOF)
+-                    return(NULL);
+-		c = CUR_CHAR(l);
+-	    }
+ 	}
+     }
+     if ((len > XML_MAX_NAME_LENGTH) &&
+@@ -3426,6 +3418,16 @@ xmlParseNameComplex(xmlParserCtxtPtr ctxt) {
+         xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "Name");
+         return(NULL);
+     }
++    if (ctxt->input->cur - ctxt->input->base < len) {
++        /*
++         * There were a couple of bugs where PERefs lead to to a change
++         * of the buffer. Check the buffer size to avoid passing an invalid
++         * pointer to xmlDictLookup.
++         */
++        xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
++                    "unexpected change of input buffer");
++        return (NULL);
++    }
+     if ((*ctxt->input->cur == '\n') && (ctxt->input->cur[-1] == '\r'))
+         return(xmlDictLookup(ctxt->dict, ctxt->input->cur - (len + 1), len));
+     return(xmlDictLookup(ctxt->dict, ctxt->input->cur - len, len));
+diff --git a/result/errors10/781205.xml b/result/errors10/781205.xml
+new file mode 100644
+index 00000000..e69de29b
+diff --git a/result/errors10/781205.xml.err b/result/errors10/781205.xml.err
+new file mode 100644
+index 00000000..da15c3f7
+--- /dev/null
++++ b/result/errors10/781205.xml.err
+@@ -0,0 +1,21 @@
++Entity: line 1: parser error : internal error: xmlParseInternalSubset: error detected in Markup declaration
++
++ %a; 
++    ^
++Entity: line 1: 
++<:0000
++^
++Entity: line 1: parser error : DOCTYPE improperly terminated
++ %a; 
++    ^
++Entity: line 1: 
++<:0000
++^
++namespace error : Failed to parse QName ':0000'
++ %a; 
++    ^
++<:0000
++      ^
++./test/errors10/781205.xml:4: parser error : Couldn't find end of Start Tag :0000 line 1
++
++^
+diff --git a/result/errors10/781361.xml b/result/errors10/781361.xml
+new file mode 100644
+index 00000000..e69de29b
+diff --git a/result/errors10/781361.xml.err b/result/errors10/781361.xml.err
+new file mode 100644
+index 00000000..655f41a2
+--- /dev/null
++++ b/result/errors10/781361.xml.err
+@@ -0,0 +1,13 @@
++./test/errors10/781361.xml:4: parser error : xmlParseElementDecl: 'EMPTY', 'ANY' or '(' expected
++
++^
++./test/errors10/781361.xml:4: parser error : internal error: xmlParseInternalSubset: error detected in Markup declaration
++
++
++^
++./test/errors10/781361.xml:4: parser error : DOCTYPE improperly terminated
++
++^
++./test/errors10/781361.xml:4: parser error : Start tag expected, '<' not found
++
++^
+diff --git a/result/valid/766956.xml b/result/valid/766956.xml
+new file mode 100644
+index 00000000..e69de29b
+diff --git a/result/valid/766956.xml.err b/result/valid/766956.xml.err
+new file mode 100644
+index 00000000..34b1dae6
+--- /dev/null
++++ b/result/valid/766956.xml.err
+@@ -0,0 +1,9 @@
++test/valid/dtds/766956.dtd:2: parser error : PEReference: expecting ';'
++%ä%ent;
++   ^
++Entity: line 1: parser error : Content error in the external subset
++ %ent; 
++      ^
++Entity: line 1: 
++value
++^
+diff --git a/result/valid/766956.xml.err.rdr b/result/valid/766956.xml.err.rdr
+new file mode 100644
+index 00000000..77603462
+--- /dev/null
++++ b/result/valid/766956.xml.err.rdr
+@@ -0,0 +1,10 @@
++test/valid/dtds/766956.dtd:2: parser error : PEReference: expecting ';'
++%ä%ent;
++   ^
++Entity: line 1: parser error : Content error in the external subset
++ %ent; 
++      ^
++Entity: line 1: 
++value
++^
++./test/valid/766956.xml : failed to parse
+diff --git a/test/errors10/781205.xml b/test/errors10/781205.xml
+new file mode 100644
+index 00000000..d9e9e839
+--- /dev/null
++++ b/test/errors10/781205.xml
+@@ -0,0 +1,3 @@
++<!DOCTYPE D [
++  <!ENTITY % a "<:0000">
++  %a;
+diff --git a/test/errors10/781361.xml b/test/errors10/781361.xml
+new file mode 100644
+index 00000000..67476bcb
+--- /dev/null
++++ b/test/errors10/781361.xml
+@@ -0,0 +1,3 @@
++<!DOCTYPE doc [
++  <!ENTITY % elem "<!ELEMENT e0000000000">
++  %elem;
+diff --git a/test/valid/766956.xml b/test/valid/766956.xml
+new file mode 100644
+index 00000000..19a95a0e
+--- /dev/null
++++ b/test/valid/766956.xml
+@@ -0,0 +1,2 @@
++<!DOCTYPE test SYSTEM "dtds/766956.dtd">
++<test/>
+diff --git a/test/valid/dtds/766956.dtd b/test/valid/dtds/766956.dtd
+new file mode 100644
+index 00000000..dddde68b
+--- /dev/null
++++ b/test/valid/dtds/766956.dtd
+@@ -0,0 +1,2 @@
++<!ENTITY % ent "value">
++%ä%ent;
+-- 
+2.14.1
+
diff --git a/gnu/packages/patches/libzip-CVE-2017-12858.patch b/gnu/packages/patches/libzip-CVE-2017-12858.patch
new file mode 100644
index 0000000000..8125173f95
--- /dev/null
+++ b/gnu/packages/patches/libzip-CVE-2017-12858.patch
@@ -0,0 +1,45 @@
+Fix CVE-2017-12858:
+
+http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-12858
+
+Patch copied from upstream source repository:
+
+https://github.com/nih-at/libzip/commit/2217022b7d1142738656d891e00b3d2d9179b796
+
+From 2217022b7d1142738656d891e00b3d2d9179b796 Mon Sep 17 00:00:00 2001
+From: Thomas Klausner <tk@giga.or.at>
+Date: Mon, 14 Aug 2017 10:55:44 +0200
+Subject: [PATCH] Fix double free().
+
+Found by Brian 'geeknik' Carpenter using AFL.
+---
+ THANKS           | 1 +
+ lib/zip_dirent.c | 3 ---
+ 2 files changed, 1 insertion(+), 3 deletions(-)
+
+diff --git a/THANKS b/THANKS
+index be0cca9..a80ee1d 100644
+--- a/THANKS
++++ b/THANKS
+@@ -12,6 +12,7 @@ BALATON Zoltan <balaton@eik.bme.hu>
+ Benjamin Gilbert <bgilbert@backtick.net>
+ Boaz Stolk <bstolk@aweta.nl>
+ Bogdan <bogiebog@gmail.com>
++Brian 'geeknik' Carpenter <geeknik@protonmail.ch>
+ Chris Nehren <cnehren+libzip@pobox.com>
+ Coverity <info@coverity.com>
+ Dane Springmeyer <dane.springmeyer@gmail.com>
+diff --git a/lib/zip_dirent.c b/lib/zip_dirent.c
+index a369900..e5a7cc9 100644
+--- a/lib/zip_dirent.c
++++ b/lib/zip_dirent.c
+@@ -579,9 +579,6 @@ _zip_dirent_read(zip_dirent_t *zde, zip_source_t *src, zip_buffer_t *buffer, boo
+     }
+ 
+     if (!_zip_dirent_process_winzip_aes(zde, error)) {
+-	if (!from_buffer) {
+-	    _zip_buffer_free(buffer);
+-	}
+ 	return -1;
+     }
+ 
diff --git a/gnu/packages/patches/metabat-fix-boost-issue.patch b/gnu/packages/patches/metabat-fix-boost-issue.patch
deleted file mode 100644
index 3382d84d66..0000000000
--- a/gnu/packages/patches/metabat-fix-boost-issue.patch
+++ /dev/null
@@ -1,27 +0,0 @@
-This patch fixes the issue described at
-https://bitbucket.org/berkeleylab/metabat/issues/28/compilation-fail-with-boost-164
-
-diff --git a/src/metabat.h b/src/metabat.h
-index 32ae94c..2292c04 100644
---- a/src/metabat.h
-+++ b/src/metabat.h
-@@ -35,6 +35,7 @@ KSEQ_INIT(gzFile, gzread)
- 
- #include <boost/program_options.hpp>
- #include <boost/algorithm/string.hpp>
-+#include <boost/serialization/array_wrapper.hpp>
- #include <boost/numeric/ublas/matrix.hpp>
- #include <boost/math/distributions.hpp>
- #include <boost/serialization/serialization.hpp>
-diff --git a/src/metabat2.h b/src/metabat2.h
-index 60a9998..19fa815 100644
---- a/src/metabat2.h
-+++ b/src/metabat2.h
-@@ -41,6 +41,7 @@ KSEQ_INIT(gzFile, gzread)
- 
- #include <boost/program_options.hpp>
- #include <boost/algorithm/string.hpp>
-+#include <boost/serialization/array_wrapper.hpp>
- #include <boost/numeric/ublas/matrix.hpp>
- #include <boost/numeric/ublas/matrix_sparse.hpp>
- #include <boost/numeric/ublas/matrix_proxy.hpp>
diff --git a/gnu/packages/patches/metabat-remove-compilation-date.patch b/gnu/packages/patches/metabat-remove-compilation-date.patch
deleted file mode 100644
index 7672205b22..0000000000
--- a/gnu/packages/patches/metabat-remove-compilation-date.patch
+++ /dev/null
@@ -1,16 +0,0 @@
-Remove the reference to the compilation date so that the build is
-reproducible.
-
-diff --git a/src/metabat.cpp b/src/metabat.cpp
-index 88e06de..c95cb1a 100644
---- a/src/metabat.cpp
-+++ b/src/metabat.cpp
-@@ -49,7 +49,7 @@ int main(int ac, char* av[]) {
- 	po::notify(vm);
- 
- 	if (vm.count("help") || inFile.length() == 0 || outFile.length() == 0) {
--		cerr << "\nMetaBAT: Metagenome Binning based on Abundance and Tetranucleotide frequency (version " << version << "; " << __DATE__ << " " << __TIME__ << ")" << endl;
-+		cerr << "\nMetaBAT: Metagenome Binning based on Abundance and Tetranucleotide frequency (version " << version << "; unknown compilation date)" << endl;
- 		cerr << "by Don Kang (ddkang@lbl.gov), Jeff Froula, Rob Egan, and Zhong Wang (zhongwang@lbl.gov) \n" << endl;
- 		cerr << desc << endl << endl;
- 
diff --git a/gnu/packages/patches/multiqc-fix-git-subprocess-error.patch b/gnu/packages/patches/multiqc-fix-git-subprocess-error.patch
deleted file mode 100644
index 87be6142f4..0000000000
--- a/gnu/packages/patches/multiqc-fix-git-subprocess-error.patch
+++ /dev/null
@@ -1,16 +0,0 @@
-Without this patch, the incorrect exception is caught when 'git' is not in
-PATH.  See https://github.com/ewels/MultiQC/pull/377.
-
-diff --git a/multiqc/utils/config.py b/multiqc/utils/config.py
-index 01fa554..4a11793 100755
---- a/multiqc/utils/config.py
-+++ b/multiqc/utils/config.py
-@@ -28,7 +28,7 @@ try:
-     git_hash = subprocess.check_output(['git', 'rev-parse', 'HEAD'], stderr=subprocess.STDOUT)
-     git_hash_short = git_hash[:7]
-     version = '{} ({})'.format(version, git_hash_short)
--except subprocess.CalledProcessError:
-+except (subprocess.CalledProcessError, FileNotFoundError):
-     pass
- os.chdir(cwd)
- 
diff --git a/gnu/packages/patches/python2-larch-coverage-4.0a6-compatibility.patch b/gnu/packages/patches/python2-larch-coverage-4.0a6-compatibility.patch
new file mode 100644
index 0000000000..f1db5d7c3b
--- /dev/null
+++ b/gnu/packages/patches/python2-larch-coverage-4.0a6-compatibility.patch
@@ -0,0 +1,29 @@
+From ca548da9ba78ddee90779051210e3e89185e4f7d Mon Sep 17 00:00:00 2001
+From: Michel Alexandre Salim <michel@michel-slm.name>
+Date: Mon, 15 Feb 2016 23:03:42 +0700
+Subject: coverage-4.0a6 compatibility
+
+coverage 4.0a6 no longer generates .coverage file, so use -f when
+deleting .coverage to ensure deletion does not fail.
+---
+ Makefile | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+(limited to 'Makefile')
+
+diff --git a/Makefile b/Makefile
+index 7818f57..362c07f 100644
+--- a/Makefile
++++ b/Makefile
+@@ -23,7 +23,7 @@ fsck-larch.1: fsck-larch.1.in fsck-larch
+ 
+ check:
+ 	python -m CoverageTestRunner --ignore-missing-from=without-tests
+-	rm .coverage
++	rm -f .coverage
+ 	./insert-remove-test tempdir 100
+ 	rm -r tempdir larch.log
+ 	cmdtest tests
+-- 
+cgit v1.1
+
diff --git a/gnu/packages/patches/qemu-CVE-2017-10664.patch b/gnu/packages/patches/qemu-CVE-2017-10664.patch
deleted file mode 100644
index 2b60de3dca..0000000000
--- a/gnu/packages/patches/qemu-CVE-2017-10664.patch
+++ /dev/null
@@ -1,27 +0,0 @@
-Fix CVE-2017-10664:
-
-https://lists.gnu.org/archive/html/qemu-devel/2017-06/msg02693.html
-https://bugzilla.redhat.com/show_bug.cgi?id=1466190
-https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-10664
-https://security-tracker.debian.org/tracker/CVE-2017-10664
-
-Patch copied from upstream source repository:
-
-https://git.qemu.org/gitweb.cgi?p=qemu.git;a=commitdiff;h=041e32b8d9d076980b4e35317c0339e57ab888f1
-
-diff --git a/qemu-nbd.c b/qemu-nbd.c
-index 9464a0461c..4dd3fd4732 100644
---- a/qemu-nbd.c
-+++ b/qemu-nbd.c
-@@ -581,6 +581,10 @@ int main(int argc, char **argv)
-     sa_sigterm.sa_handler = termsig_handler;
-     sigaction(SIGTERM, &sa_sigterm, NULL);
- 
-+#ifdef CONFIG_POSIX
-+    signal(SIGPIPE, SIG_IGN);
-+#endif
-+
-     module_call_init(MODULE_INIT_TRACE);
-     qcrypto_init(&error_fatal);
- 
-
diff --git a/gnu/packages/patches/qemu-CVE-2017-10806.patch b/gnu/packages/patches/qemu-CVE-2017-10806.patch
deleted file mode 100644
index ebf782fe7b..0000000000
--- a/gnu/packages/patches/qemu-CVE-2017-10806.patch
+++ /dev/null
@@ -1,38 +0,0 @@
-Fix CVE-2017-10806:
-
-https://lists.nongnu.org/archive/html/qemu-devel/2017-05/msg03087.html
-https://bugzilla.redhat.com/show_bug.cgi?id=1468496
-https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-10806
-https://security-tracker.debian.org/tracker/CVE-2017-10806
-
-Patch copied from upstream source repository:
-
-https://git.qemu.org/gitweb.cgi?p=qemu.git;a=commit;h=bd4a683505b27adc1ac809f71e918e58573d851d
-
-diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c
-index b001a27f05..ad5ef783a6 100644
---- a/hw/usb/redirect.c
-+++ b/hw/usb/redirect.c
-@@ -229,21 +229,10 @@ static void usbredir_log(void *priv, int level, const char *msg)
- static void usbredir_log_data(USBRedirDevice *dev, const char *desc,
-     const uint8_t *data, int len)
- {
--    int i, j, n;
--
-     if (dev->debug < usbredirparser_debug_data) {
-         return;
-     }
--
--    for (i = 0; i < len; i += j) {
--        char buf[128];
--
--        n = sprintf(buf, "%s", desc);
--        for (j = 0; j < 8 && i + j < len; j++) {
--            n += sprintf(buf + n, " %02X", data[i + j]);
--        }
--        error_report("%s", buf);
--    }
-+    qemu_hexdump((char *)data, stderr, desc, len);
- }
- 
- /*
diff --git a/gnu/packages/patches/qemu-CVE-2017-10911.patch b/gnu/packages/patches/qemu-CVE-2017-10911.patch
deleted file mode 100644
index 1dcb860a2d..0000000000
--- a/gnu/packages/patches/qemu-CVE-2017-10911.patch
+++ /dev/null
@@ -1,106 +0,0 @@
-Fix CVE-2017-10911:
-
-https://xenbits.xen.org/xsa/advisory-216.html
-https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-10911
-https://security-tracker.debian.org/tracker/CVE-2017-10911
-
-Patch copied from Xen Security Advisory:
-
-https://xenbits.xen.org/xsa/xsa216-qemuu.patch
-
---- a/hw/block/xen_blkif.h
-+++ b/hw/block/xen_blkif.h
-@@ -14,9 +14,6 @@
- struct blkif_common_request {
-     char dummy;
- };
--struct blkif_common_response {
--    char dummy;
--};
- 
- /* i386 protocol version */
- #pragma pack(push, 4)
-@@ -36,13 +33,7 @@ struct blkif_x86_32_request_discard {
-     blkif_sector_t sector_number;    /* start sector idx on disk (r/w only)  */
-     uint64_t       nr_sectors;       /* # of contiguous sectors to discard   */
- };
--struct blkif_x86_32_response {
--    uint64_t        id;              /* copied from request */
--    uint8_t         operation;       /* copied from request */
--    int16_t         status;          /* BLKIF_RSP_???       */
--};
- typedef struct blkif_x86_32_request blkif_x86_32_request_t;
--typedef struct blkif_x86_32_response blkif_x86_32_response_t;
- #pragma pack(pop)
- 
- /* x86_64 protocol version */
-@@ -62,20 +53,14 @@ struct blkif_x86_64_request_discard {
-     blkif_sector_t sector_number;    /* start sector idx on disk (r/w only)  */
-     uint64_t       nr_sectors;       /* # of contiguous sectors to discard   */
- };
--struct blkif_x86_64_response {
--    uint64_t       __attribute__((__aligned__(8))) id;
--    uint8_t         operation;       /* copied from request */
--    int16_t         status;          /* BLKIF_RSP_???       */
--};
- typedef struct blkif_x86_64_request blkif_x86_64_request_t;
--typedef struct blkif_x86_64_response blkif_x86_64_response_t;
- 
- DEFINE_RING_TYPES(blkif_common, struct blkif_common_request,
--                  struct blkif_common_response);
-+                  struct blkif_response);
- DEFINE_RING_TYPES(blkif_x86_32, struct blkif_x86_32_request,
--                  struct blkif_x86_32_response);
-+                  struct blkif_response QEMU_PACKED);
- DEFINE_RING_TYPES(blkif_x86_64, struct blkif_x86_64_request,
--                  struct blkif_x86_64_response);
-+                  struct blkif_response);
- 
- union blkif_back_rings {
-     blkif_back_ring_t        native;
---- a/hw/block/xen_disk.c
-+++ b/hw/block/xen_disk.c
-@@ -769,31 +769,30 @@ static int blk_send_response_one(struct
-     struct XenBlkDev  *blkdev = ioreq->blkdev;
-     int               send_notify   = 0;
-     int               have_requests = 0;
--    blkif_response_t  resp;
--    void              *dst;
--
--    resp.id        = ioreq->req.id;
--    resp.operation = ioreq->req.operation;
--    resp.status    = ioreq->status;
-+    blkif_response_t  *resp;
- 
-     /* Place on the response ring for the relevant domain. */
-     switch (blkdev->protocol) {
-     case BLKIF_PROTOCOL_NATIVE:
--        dst = RING_GET_RESPONSE(&blkdev->rings.native, blkdev->rings.native.rsp_prod_pvt);
-+        resp = RING_GET_RESPONSE(&blkdev->rings.native,
-+                                 blkdev->rings.native.rsp_prod_pvt);
-         break;
-     case BLKIF_PROTOCOL_X86_32:
--        dst = RING_GET_RESPONSE(&blkdev->rings.x86_32_part,
--                                blkdev->rings.x86_32_part.rsp_prod_pvt);
-+        resp = RING_GET_RESPONSE(&blkdev->rings.x86_32_part,
-+                                 blkdev->rings.x86_32_part.rsp_prod_pvt);
-         break;
-     case BLKIF_PROTOCOL_X86_64:
--        dst = RING_GET_RESPONSE(&blkdev->rings.x86_64_part,
--                                blkdev->rings.x86_64_part.rsp_prod_pvt);
-+        resp = RING_GET_RESPONSE(&blkdev->rings.x86_64_part,
-+                                 blkdev->rings.x86_64_part.rsp_prod_pvt);
-         break;
-     default:
--        dst = NULL;
-         return 0;
-     }
--    memcpy(dst, &resp, sizeof(resp));
-+
-+    resp->id        = ioreq->req.id;
-+    resp->operation = ioreq->req.operation;
-+    resp->status    = ioreq->status;
-+
-     blkdev->rings.common.rsp_prod_pvt++;
- 
-     RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(&blkdev->rings.common, send_notify);
diff --git a/gnu/packages/patches/qemu-CVE-2017-11334.patch b/gnu/packages/patches/qemu-CVE-2017-11334.patch
deleted file mode 100644
index cb68c803aa..0000000000
--- a/gnu/packages/patches/qemu-CVE-2017-11334.patch
+++ /dev/null
@@ -1,52 +0,0 @@
-Fix CVE-2017-11334:
-
-https://bugzilla.redhat.com/show_bug.cgi?id=1471638
-https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-11334
-
-Patch copied from upstream source repository:
-
-http://git.qemu.org/?p=qemu.git;a=commitdiff;h=04bf2526ce87f21b32c9acba1c5518708c243ad0
-
-From 04bf2526ce87f21b32c9acba1c5518708c243ad0 Mon Sep 17 00:00:00 2001
-From: Prasad J Pandit <pjp@fedoraproject.org>
-Date: Wed, 12 Jul 2017 18:08:40 +0530
-Subject: [PATCH] exec: use qemu_ram_ptr_length to access guest ram
-
-When accessing guest's ram block during DMA operation, use
-'qemu_ram_ptr_length' to get ram block pointer. It ensures
-that DMA operation of given length is possible; And avoids
-any OOB memory access situations.
-
-Reported-by: Alex <broscutamaker@gmail.com>
-Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
-Message-Id: <20170712123840.29328-1-ppandit@redhat.com>
-Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
----
- exec.c | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
-diff --git a/exec.c b/exec.c
-index a083ff89ad..ad103ce483 100644
---- a/exec.c
-+++ b/exec.c
-@@ -2929,7 +2929,7 @@ static MemTxResult address_space_write_continue(AddressSpace *as, hwaddr addr,
-             }
-         } else {
-             /* RAM case */
--            ptr = qemu_map_ram_ptr(mr->ram_block, addr1);
-+            ptr = qemu_ram_ptr_length(mr->ram_block, addr1, &l);
-             memcpy(ptr, buf, l);
-             invalidate_and_set_dirty(mr, addr1, l);
-         }
-@@ -3020,7 +3020,7 @@ MemTxResult address_space_read_continue(AddressSpace *as, hwaddr addr,
-             }
-         } else {
-             /* RAM case */
--            ptr = qemu_map_ram_ptr(mr->ram_block, addr1);
-+            ptr = qemu_ram_ptr_length(mr->ram_block, addr1, &l);
-             memcpy(buf, ptr, l);
-         }
- 
--- 
-2.13.3
-
diff --git a/gnu/packages/patches/qemu-CVE-2017-11434.patch b/gnu/packages/patches/qemu-CVE-2017-11434.patch
deleted file mode 100644
index 4da701a73d..0000000000
--- a/gnu/packages/patches/qemu-CVE-2017-11434.patch
+++ /dev/null
@@ -1,25 +0,0 @@
-Fix CVE-2017-11434:
-
-https://lists.gnu.org/archive/html/qemu-devel/2017-07/msg05001.html
-https://bugzilla.redhat.com/show_bug.cgi?id=1472611
-https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-11434
-https://security-tracker.debian.org/tracker/CVE-2017-11434
-
-Patch copied from upstream source repository:
-
-https://git.qemu.org/gitweb.cgi?p=qemu.git;a=commit;h=413d463f43fbc4dd3a601e80a5724aa384a265a0
-
-diff --git a/slirp/bootp.c b/slirp/bootp.c
-index 5a4646c182..5dd1a415b5 100644
---- a/slirp/bootp.c
-+++ b/slirp/bootp.c
-@@ -123,6 +123,9 @@ static void dhcp_decode(const struct bootp_t *bp, int *pmsg_type,
-             if (p >= p_end)
-                 break;
-             len = *p++;
-+            if (p + len > p_end) {
-+                break;
-+            }
-             DPRINTF("dhcp: tag=%d len=%d\n", tag, len);
- 
-             switch(tag) {
diff --git a/gnu/packages/patches/qemu-CVE-2017-12809.patch b/gnu/packages/patches/qemu-CVE-2017-12809.patch
deleted file mode 100644
index e40a14b4e0..0000000000
--- a/gnu/packages/patches/qemu-CVE-2017-12809.patch
+++ /dev/null
@@ -1,38 +0,0 @@
-http://openwall.com/lists/oss-security/2017/08/21/2
-https://lists.gnu.org/archive/html/qemu-devel/2017-08/msg01850.html
-
-The block backend changed in a way that flushing empty CDROM drives now
-crashes.  Amend IDE to avoid doing so until the root problem can be
-addressed for 2.11.
-
-Original patch by John Snow <address@hidden>.
-
-Reported-by: Kieron Shorrock <address@hidden>
-Signed-off-by: Stefan Hajnoczi <address@hidden>
----
- hw/ide/core.c | 10 +++++++++-
- 1 file changed, 9 insertions(+), 1 deletion(-)
-
-diff --git a/hw/ide/core.c b/hw/ide/core.c
-index 0b48b64d3a..bea39536b0 100644
---- a/hw/ide/core.c
-+++ b/hw/ide/core.c
-@@ -1063,7 +1063,15 @@ static void ide_flush_cache(IDEState *s)
-     s->status |= BUSY_STAT;
-     ide_set_retry(s);
-     block_acct_start(blk_get_stats(s->blk), &s->acct, 0, BLOCK_ACCT_FLUSH);
--    s->pio_aiocb = blk_aio_flush(s->blk, ide_flush_cb, s);
-+
-+    if (blk_bs(s->blk)) {
-+        s->pio_aiocb = blk_aio_flush(s->blk, ide_flush_cb, s);
-+    } else {
-+        /* XXX blk_aio_flush() crashes when blk_bs(blk) is NULL, remove this
-+         * temporary workaround when blk_aio_*() functions handle NULL blk_bs.
-+         */
-+        ide_flush_cb(s, 0);
-+    }
- }
-      
- static void ide_cfata_metadata_inquiry(IDEState *s)
--- 
-2.13.3
diff --git a/gnu/packages/patches/qemu-CVE-2017-7493.patch b/gnu/packages/patches/qemu-CVE-2017-7493.patch
deleted file mode 100644
index 67b26fad81..0000000000
--- a/gnu/packages/patches/qemu-CVE-2017-7493.patch
+++ /dev/null
@@ -1,182 +0,0 @@
-Fix CVE-2017-7493:
-
-https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-7493
-
-Patch copied from upstream source repository:
-
-http://git.qemu.org/?p=qemu.git;a=commit;h=7a95434e0ca8a037fd8aa1a2e2461f92585eb77b
-
-From 7a95434e0ca8a037fd8aa1a2e2461f92585eb77b Mon Sep 17 00:00:00 2001
-From: Greg Kurz <groug@kaod.org>
-Date: Fri, 5 May 2017 14:48:08 +0200
-Subject: [PATCH] 9pfs: local: forbid client access to metadata (CVE-2017-7493)
-
-When using the mapped-file security mode, we shouldn't let the client mess
-with the metadata. The current code already tries to hide the metadata dir
-from the client by skipping it in local_readdir(). But the client can still
-access or modify it through several other operations. This can be used to
-escalate privileges in the guest.
-
-Affected backend operations are:
-- local_mknod()
-- local_mkdir()
-- local_open2()
-- local_symlink()
-- local_link()
-- local_unlinkat()
-- local_renameat()
-- local_rename()
-- local_name_to_path()
-
-Other operations are safe because they are only passed a fid path, which
-is computed internally in local_name_to_path().
-
-This patch converts all the functions listed above to fail and return
-EINVAL when being passed the name of the metadata dir. This may look
-like a poor choice for errno, but there's no such thing as an illegal
-path name on Linux and I could not think of anything better.
-
-This fixes CVE-2017-7493.
-
-Reported-by: Leo Gaspard <leo@gaspard.io>
-Signed-off-by: Greg Kurz <groug@kaod.org>
-Reviewed-by: Eric Blake <eblake@redhat.com>
----
- hw/9pfs/9p-local.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++--
- 1 file changed, 56 insertions(+), 2 deletions(-)
-
-diff --git a/hw/9pfs/9p-local.c b/hw/9pfs/9p-local.c
-index f3ebca4f7a..a2486566af 100644
---- a/hw/9pfs/9p-local.c
-+++ b/hw/9pfs/9p-local.c
-@@ -452,6 +452,11 @@ static off_t local_telldir(FsContext *ctx, V9fsFidOpenState *fs)
-     return telldir(fs->dir.stream);
- }
- 
-+static bool local_is_mapped_file_metadata(FsContext *fs_ctx, const char *name)
-+{
-+    return !strcmp(name, VIRTFS_META_DIR);
-+}
-+
- static struct dirent *local_readdir(FsContext *ctx, V9fsFidOpenState *fs)
- {
-     struct dirent *entry;
-@@ -465,8 +470,8 @@ again:
-     if (ctx->export_flags & V9FS_SM_MAPPED) {
-         entry->d_type = DT_UNKNOWN;
-     } else if (ctx->export_flags & V9FS_SM_MAPPED_FILE) {
--        if (!strcmp(entry->d_name, VIRTFS_META_DIR)) {
--            /* skp the meta data directory */
-+        if (local_is_mapped_file_metadata(ctx, entry->d_name)) {
-+            /* skip the meta data directory */
-             goto again;
-         }
-         entry->d_type = DT_UNKNOWN;
-@@ -559,6 +564,12 @@ static int local_mknod(FsContext *fs_ctx, V9fsPath *dir_path,
-     int err = -1;
-     int dirfd;
- 
-+    if (fs_ctx->export_flags & V9FS_SM_MAPPED_FILE &&
-+        local_is_mapped_file_metadata(fs_ctx, name)) {
-+        errno = EINVAL;
-+        return -1;
-+    }
-+
-     dirfd = local_opendir_nofollow(fs_ctx, dir_path->data);
-     if (dirfd == -1) {
-         return -1;
-@@ -605,6 +616,12 @@ static int local_mkdir(FsContext *fs_ctx, V9fsPath *dir_path,
-     int err = -1;
-     int dirfd;
- 
-+    if (fs_ctx->export_flags & V9FS_SM_MAPPED_FILE &&
-+        local_is_mapped_file_metadata(fs_ctx, name)) {
-+        errno = EINVAL;
-+        return -1;
-+    }
-+
-     dirfd = local_opendir_nofollow(fs_ctx, dir_path->data);
-     if (dirfd == -1) {
-         return -1;
-@@ -694,6 +711,12 @@ static int local_open2(FsContext *fs_ctx, V9fsPath *dir_path, const char *name,
-     int err = -1;
-     int dirfd;
- 
-+    if (fs_ctx->export_flags & V9FS_SM_MAPPED_FILE &&
-+        local_is_mapped_file_metadata(fs_ctx, name)) {
-+        errno = EINVAL;
-+        return -1;
-+    }
-+
-     /*
-      * Mark all the open to not follow symlinks
-      */
-@@ -752,6 +775,12 @@ static int local_symlink(FsContext *fs_ctx, const char *oldpath,
-     int err = -1;
-     int dirfd;
- 
-+    if (fs_ctx->export_flags & V9FS_SM_MAPPED_FILE &&
-+        local_is_mapped_file_metadata(fs_ctx, name)) {
-+        errno = EINVAL;
-+        return -1;
-+    }
-+
-     dirfd = local_opendir_nofollow(fs_ctx, dir_path->data);
-     if (dirfd == -1) {
-         return -1;
-@@ -826,6 +855,12 @@ static int local_link(FsContext *ctx, V9fsPath *oldpath,
-     int ret = -1;
-     int odirfd, ndirfd;
- 
-+    if (ctx->export_flags & V9FS_SM_MAPPED_FILE &&
-+        local_is_mapped_file_metadata(ctx, name)) {
-+        errno = EINVAL;
-+        return -1;
-+    }
-+
-     odirfd = local_opendir_nofollow(ctx, odirpath);
-     if (odirfd == -1) {
-         goto out;
-@@ -1096,6 +1131,12 @@ static int local_lremovexattr(FsContext *ctx, V9fsPath *fs_path,
- static int local_name_to_path(FsContext *ctx, V9fsPath *dir_path,
-                               const char *name, V9fsPath *target)
- {
-+    if (ctx->export_flags & V9FS_SM_MAPPED_FILE &&
-+        local_is_mapped_file_metadata(ctx, name)) {
-+        errno = EINVAL;
-+        return -1;
-+    }
-+
-     if (dir_path) {
-         v9fs_path_sprintf(target, "%s/%s", dir_path->data, name);
-     } else if (strcmp(name, "/")) {
-@@ -1116,6 +1157,13 @@ static int local_renameat(FsContext *ctx, V9fsPath *olddir,
-     int ret;
-     int odirfd, ndirfd;
- 
-+    if (ctx->export_flags & V9FS_SM_MAPPED_FILE &&
-+        (local_is_mapped_file_metadata(ctx, old_name) ||
-+         local_is_mapped_file_metadata(ctx, new_name))) {
-+        errno = EINVAL;
-+        return -1;
-+    }
-+
-     odirfd = local_opendir_nofollow(ctx, olddir->data);
-     if (odirfd == -1) {
-         return -1;
-@@ -1206,6 +1254,12 @@ static int local_unlinkat(FsContext *ctx, V9fsPath *dir,
-     int ret;
-     int dirfd;
- 
-+    if (ctx->export_flags & V9FS_SM_MAPPED_FILE &&
-+        local_is_mapped_file_metadata(ctx, name)) {
-+        errno = EINVAL;
-+        return -1;
-+    }
-+
-     dirfd = local_opendir_nofollow(ctx, dir->data);
-     if (dirfd == -1) {
-         return -1;
--- 
-2.13.0
-
diff --git a/gnu/packages/patches/qemu-CVE-2017-8112.patch b/gnu/packages/patches/qemu-CVE-2017-8112.patch
deleted file mode 100644
index 88b33aa2f0..0000000000
--- a/gnu/packages/patches/qemu-CVE-2017-8112.patch
+++ /dev/null
@@ -1,41 +0,0 @@
-Fix CVE-2017-8112:
-
-https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-8112
-
-Patch copied from upstream source repository:
-
-http://git.qemu.org/?p=qemu.git;a=commitdiff;h=f68826989cd4d1217797251339579c57b3c0934e
-
-From f68826989cd4d1217797251339579c57b3c0934e Mon Sep 17 00:00:00 2001
-From: P J P <ppandit@redhat.com>
-Date: Tue, 25 Apr 2017 18:36:23 +0530
-Subject: [PATCH] vmw_pvscsi: check message ring page count at initialisation
-
-A guest could set the message ring page count to zero, resulting in
-infinite loop. Add check to avoid it.
-
-Reported-by: YY Z <bigbird475958471@gmail.com>
-Signed-off-by: P J P <ppandit@redhat.com>
-Message-Id: <20170425130623.3649-1-ppandit@redhat.com>
-Reviewed-by: Dmitry Fleytman <dmitry@daynix.com>
-Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
----
- hw/scsi/vmw_pvscsi.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/hw/scsi/vmw_pvscsi.c b/hw/scsi/vmw_pvscsi.c
-index 75575461e2..4a106da856 100644
---- a/hw/scsi/vmw_pvscsi.c
-+++ b/hw/scsi/vmw_pvscsi.c
-@@ -202,7 +202,7 @@ pvscsi_ring_init_msg(PVSCSIRingInfo *m, PVSCSICmdDescSetupMsgRing *ri)
-     uint32_t len_log2;
-     uint32_t ring_size;
- 
--    if (ri->numPages > PVSCSI_SETUP_MSG_RING_MAX_NUM_PAGES) {
-+    if (!ri->numPages || ri->numPages > PVSCSI_SETUP_MSG_RING_MAX_NUM_PAGES) {
-         return -1;
-     }
-     ring_size = ri->numPages * PVSCSI_MAX_NUM_MSG_ENTRIES_PER_PAGE;
--- 
-2.13.0
-
diff --git a/gnu/packages/patches/qemu-CVE-2017-8309.patch b/gnu/packages/patches/qemu-CVE-2017-8309.patch
deleted file mode 100644
index dc4b4006b7..0000000000
--- a/gnu/packages/patches/qemu-CVE-2017-8309.patch
+++ /dev/null
@@ -1,46 +0,0 @@
-Fix CVE-2017-8309:
-
-https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-8309
-
-Patch copied from upstream source repository:
-
-http://git.qemu.org/?p=qemu.git;a=commitdiff;h=3268a845f41253fb55852a8429c32b50f36f349a
-
-From 3268a845f41253fb55852a8429c32b50f36f349a Mon Sep 17 00:00:00 2001
-From: Gerd Hoffmann <kraxel@redhat.com>
-Date: Fri, 28 Apr 2017 09:56:12 +0200
-Subject: [PATCH] audio: release capture buffers
-
-AUD_add_capture() allocates two buffers which are never released.
-Add the missing calls to AUD_del_capture().
-
-Impact: Allows vnc clients to exhaust host memory by repeatedly
-starting and stopping audio capture.
-
-Fixes: CVE-2017-8309
-Cc: P J P <ppandit@redhat.com>
-Cc: Huawei PSIRT <PSIRT@huawei.com>
-Reported-by: "Jiangxin (hunter, SCC)" <jiangxin1@huawei.com>
-Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
-Reviewed-by: Prasad J Pandit <pjp@fedoraproject.org>
-Message-id: 20170428075612.9997-1-kraxel@redhat.com
----
- audio/audio.c | 2 ++
- 1 file changed, 2 insertions(+)
-
-diff --git a/audio/audio.c b/audio/audio.c
-index c8898d8422..beafed209b 100644
---- a/audio/audio.c
-+++ b/audio/audio.c
-@@ -2028,6 +2028,8 @@ void AUD_del_capture (CaptureVoiceOut *cap, void *cb_opaque)
-                     sw = sw1;
-                 }
-                 QLIST_REMOVE (cap, entries);
-+                g_free (cap->hw.mix_buf);
-+                g_free (cap->buf);
-                 g_free (cap);
-             }
-             return;
--- 
-2.13.0
-
diff --git a/gnu/packages/patches/qemu-CVE-2017-8379.patch b/gnu/packages/patches/qemu-CVE-2017-8379.patch
deleted file mode 100644
index 200b133d3e..0000000000
--- a/gnu/packages/patches/qemu-CVE-2017-8379.patch
+++ /dev/null
@@ -1,98 +0,0 @@
-Fix CVE-2017-8379:
-
-https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-8379
-
-Patch copied from upstream source repository:
-
-http://git.qemu.org/?p=qemu.git;a=commitdiff;h=fa18f36a461984eae50ab957e47ec78dae3c14fc
-
-From fa18f36a461984eae50ab957e47ec78dae3c14fc Mon Sep 17 00:00:00 2001
-From: Gerd Hoffmann <kraxel@redhat.com>
-Date: Fri, 28 Apr 2017 10:42:37 +0200
-Subject: [PATCH] input: limit kbd queue depth
-
-Apply a limit to the number of items we accept into the keyboard queue.
-
-Impact: Without this limit vnc clients can exhaust host memory by
-sending keyboard events faster than qemu feeds them to the guest.
-
-Fixes: CVE-2017-8379
-Cc: P J P <ppandit@redhat.com>
-Cc: Huawei PSIRT <PSIRT@huawei.com>
-Reported-by: jiangxin1@huawei.com
-Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
-Message-id: 20170428084237.23960-1-kraxel@redhat.com
----
- ui/input.c | 14 +++++++++++---
- 1 file changed, 11 insertions(+), 3 deletions(-)
-
-diff --git a/ui/input.c b/ui/input.c
-index ed88cda6d6..fb1f404095 100644
---- a/ui/input.c
-+++ b/ui/input.c
-@@ -41,6 +41,8 @@ static QTAILQ_HEAD(QemuInputEventQueueHead, QemuInputEventQueue) kbd_queue =
-     QTAILQ_HEAD_INITIALIZER(kbd_queue);
- static QEMUTimer *kbd_timer;
- static uint32_t kbd_default_delay_ms = 10;
-+static uint32_t queue_count;
-+static uint32_t queue_limit = 1024;
- 
- QemuInputHandlerState *qemu_input_handler_register(DeviceState *dev,
-                                                    QemuInputHandler *handler)
-@@ -268,6 +270,7 @@ static void qemu_input_queue_process(void *opaque)
-             break;
-         }
-         QTAILQ_REMOVE(queue, item, node);
-+        queue_count--;
-         g_free(item);
-     }
- }
-@@ -282,6 +285,7 @@ static void qemu_input_queue_delay(struct QemuInputEventQueueHead *queue,
-     item->delay_ms = delay_ms;
-     item->timer = timer;
-     QTAILQ_INSERT_TAIL(queue, item, node);
-+    queue_count++;
- 
-     if (start_timer) {
-         timer_mod(item->timer, qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL)
-@@ -298,6 +302,7 @@ static void qemu_input_queue_event(struct QemuInputEventQueueHead *queue,
-     item->src = src;
-     item->evt = evt;
-     QTAILQ_INSERT_TAIL(queue, item, node);
-+    queue_count++;
- }
- 
- static void qemu_input_queue_sync(struct QemuInputEventQueueHead *queue)
-@@ -306,6 +311,7 @@ static void qemu_input_queue_sync(struct QemuInputEventQueueHead *queue)
- 
-     item->type = QEMU_INPUT_QUEUE_SYNC;
-     QTAILQ_INSERT_TAIL(queue, item, node);
-+    queue_count++;
- }
- 
- void qemu_input_event_send_impl(QemuConsole *src, InputEvent *evt)
-@@ -381,7 +387,7 @@ void qemu_input_event_send_key(QemuConsole *src, KeyValue *key, bool down)
-         qemu_input_event_send(src, evt);
-         qemu_input_event_sync();
-         qapi_free_InputEvent(evt);
--    } else {
-+    } else if (queue_count < queue_limit) {
-         qemu_input_queue_event(&kbd_queue, src, evt);
-         qemu_input_queue_sync(&kbd_queue);
-     }
-@@ -409,8 +415,10 @@ void qemu_input_event_send_key_delay(uint32_t delay_ms)
-         kbd_timer = timer_new_ms(QEMU_CLOCK_VIRTUAL, qemu_input_queue_process,
-                                  &kbd_queue);
-     }
--    qemu_input_queue_delay(&kbd_queue, kbd_timer,
--                           delay_ms ? delay_ms : kbd_default_delay_ms);
-+    if (queue_count < queue_limit) {
-+        qemu_input_queue_delay(&kbd_queue, kbd_timer,
-+                               delay_ms ? delay_ms : kbd_default_delay_ms);
-+    }
- }
- 
- InputEvent *qemu_input_event_new_btn(InputButton btn, bool down)
--- 
-2.13.0
-
diff --git a/gnu/packages/patches/qemu-CVE-2017-8380.patch b/gnu/packages/patches/qemu-CVE-2017-8380.patch
deleted file mode 100644
index 65e49fc885..0000000000
--- a/gnu/packages/patches/qemu-CVE-2017-8380.patch
+++ /dev/null
@@ -1,53 +0,0 @@
-Fix CVE-2017-8380:
-
-https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-8380
-
-Patch copied from upstream source repository:
-
-http://git.qemu.org/?p=qemu.git;a=commitdiff;h=24dfa9fa2f90a95ac33c7372de4f4f2c8a2c141f
-
-From 24dfa9fa2f90a95ac33c7372de4f4f2c8a2c141f Mon Sep 17 00:00:00 2001
-From: Prasad J Pandit <pjp@fedoraproject.org>
-Date: Mon, 24 Apr 2017 17:36:34 +0530
-Subject: [PATCH] scsi: avoid an off-by-one error in megasas_mmio_write
-
-While reading magic sequence(MFI_SEQ) in megasas_mmio_write,
-an off-by-one error could occur as 's->adp_reset' index is not
-reset after reading the last sequence.
-
-Reported-by: YY Z <bigbird475958471@gmail.com>
-Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
-Message-Id: <20170424120634.12268-1-ppandit@redhat.com>
-Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
----
- hw/scsi/megasas.c | 10 +++++-----
- 1 file changed, 5 insertions(+), 5 deletions(-)
-
-diff --git a/hw/scsi/megasas.c b/hw/scsi/megasas.c
-index 84b8caf901..804122ab05 100644
---- a/hw/scsi/megasas.c
-+++ b/hw/scsi/megasas.c
-@@ -2138,15 +2138,15 @@ static void megasas_mmio_write(void *opaque, hwaddr addr,
-     case MFI_SEQ:
-         trace_megasas_mmio_writel("MFI_SEQ", val);
-         /* Magic sequence to start ADP reset */
--        if (adp_reset_seq[s->adp_reset] == val) {
--            s->adp_reset++;
-+        if (adp_reset_seq[s->adp_reset++] == val) {
-+            if (s->adp_reset == 6) {
-+                s->adp_reset = 0;
-+                s->diag = MFI_DIAG_WRITE_ENABLE;
-+            }
-         } else {
-             s->adp_reset = 0;
-             s->diag = 0;
-         }
--        if (s->adp_reset == 6) {
--            s->diag = MFI_DIAG_WRITE_ENABLE;
--        }
-         break;
-     case MFI_DIAG:
-         trace_megasas_mmio_writel("MFI_DIAG", val);
--- 
-2.13.0
-
diff --git a/gnu/packages/patches/qemu-CVE-2017-9524.patch b/gnu/packages/patches/qemu-CVE-2017-9524.patch
deleted file mode 100644
index 57160055e3..0000000000
--- a/gnu/packages/patches/qemu-CVE-2017-9524.patch
+++ /dev/null
@@ -1,287 +0,0 @@
-Fix CVE-2017-9524:
-
-https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-9524
-http://seclists.org/oss-sec/2017/q2/454
-
-Patches copied from upstream source repository:
-
-http://git.qemu.org/?p=qemu.git;a=commitdiff;h=df8ad9f128c15aa0a0ebc7b24e9a22c9775b67af
-http://git.qemu.org/?p=qemu.git;a=commitdiff;h=0c9390d978cbf61e8f16c9f580fa96b305c43568
-
-From df8ad9f128c15aa0a0ebc7b24e9a22c9775b67af Mon Sep 17 00:00:00 2001
-From: Eric Blake <eblake@redhat.com>
-Date: Fri, 26 May 2017 22:04:21 -0500
-Subject: [PATCH] nbd: Fully initialize client in case of failed negotiation
-
-If a non-NBD client connects to qemu-nbd, we would end up with
-a SIGSEGV in nbd_client_put() because we were trying to
-unregister the client's association to the export, even though
-we skipped inserting the client into that list.  Easy trigger
-in two terminals:
-
-$ qemu-nbd -p 30001 --format=raw file
-$ nmap 127.0.0.1 -p 30001
-
-nmap claims that it thinks it connected to a pago-services1
-server (which probably means nmap could be updated to learn the
-NBD protocol and give a more accurate diagnosis of the open
-port - but that's not our problem), then terminates immediately,
-so our call to nbd_negotiate() fails.  The fix is to reorder
-nbd_co_client_start() to ensure that all initialization occurs
-before we ever try talking to a client in nbd_negotiate(), so
-that the teardown sequence on negotiation failure doesn't fault
-while dereferencing a half-initialized object.
-
-While debugging this, I also noticed that nbd_update_server_watch()
-called by nbd_client_closed() was still adding a channel to accept
-the next client, even when the state was no longer RUNNING.  That
-is fixed by making nbd_can_accept() pay attention to the current
-state.
-
-Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1451614
-
-Signed-off-by: Eric Blake <eblake@redhat.com>
-Message-Id: <20170527030421.28366-1-eblake@redhat.com>
-Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
----
- nbd/server.c | 8 +++-----
- qemu-nbd.c   | 2 +-
- 2 files changed, 4 insertions(+), 6 deletions(-)
-
-diff --git a/nbd/server.c b/nbd/server.c
-index ee59e5d234..49b55f6ede 100644
---- a/nbd/server.c
-+++ b/nbd/server.c
-@@ -1358,16 +1358,14 @@ static coroutine_fn void nbd_co_client_start(void *opaque)
- 
-     if (exp) {
-         nbd_export_get(exp);
-+        QTAILQ_INSERT_TAIL(&exp->clients, client, next);
-     }
-+    qemu_co_mutex_init(&client->send_lock);
-+
-     if (nbd_negotiate(data)) {
-         client_close(client);
-         goto out;
-     }
--    qemu_co_mutex_init(&client->send_lock);
--
--    if (exp) {
--        QTAILQ_INSERT_TAIL(&exp->clients, client, next);
--    }
- 
-     nbd_client_receive_next_request(client);
- 
-diff --git a/qemu-nbd.c b/qemu-nbd.c
-index f60842fd86..651f85ecc1 100644
---- a/qemu-nbd.c
-+++ b/qemu-nbd.c
-@@ -325,7 +325,7 @@ out:
- 
- static int nbd_can_accept(void)
- {
--    return nb_fds < shared;
-+    return state == RUNNING && nb_fds < shared;
- }
- 
- static void nbd_export_closed(NBDExport *exp)
--- 
-2.13.1
-
-From 0c9390d978cbf61e8f16c9f580fa96b305c43568 Mon Sep 17 00:00:00 2001
-From: Eric Blake <eblake@redhat.com>
-Date: Thu, 8 Jun 2017 17:26:17 -0500
-Subject: [PATCH] nbd: Fix regression on resiliency to port scan
-
-Back in qemu 2.5, qemu-nbd was immune to port probes (a transient
-server would not quit, regardless of how many probe connections
-came and went, until a connection actually negotiated).  But we
-broke that in commit ee7d7aa when removing the return value to
-nbd_client_new(), although that patch also introduced a bug causing
-an assertion failure on a client that fails negotiation.  We then
-made it worse during refactoring in commit 1a6245a (a segfault
-before we could even assert); the (masked) assertion was cleaned
-up in d3780c2 (still in 2.6), and just recently we finally fixed
-the segfault ("nbd: Fully intialize client in case of failed
-negotiation").  But that still means that ever since we added
-TLS support to qemu-nbd, we have been vulnerable to an ill-timed
-port-scan being able to cause a denial of service by taking down
-qemu-nbd before a real client has a chance to connect.
-
-Since negotiation is now handled asynchronously via coroutines,
-we no longer have a synchronous point of return by re-adding a
-return value to nbd_client_new().  So this patch instead wires
-things up to pass the negotiation status through the close_fn
-callback function.
-
-Simple test across two terminals:
-$ qemu-nbd -f raw -p 30001 file
-$ nmap 127.0.0.1 -p 30001 && \
-  qemu-io -c 'r 0 512' -f raw nbd://localhost:30001
-
-Note that this patch does not change what constitutes successful
-negotiation (thus, a client must enter transmission phase before
-that client can be considered as a reason to terminate the server
-when the connection ends).  Perhaps we may want to tweak things
-in a later patch to also treat a client that uses NBD_OPT_ABORT
-as being a 'successful' negotiation (the client correctly talked
-the NBD protocol, and informed us it was not going to use our
-export after all), but that's a discussion for another day.
-
-Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1451614
-
-Signed-off-by: Eric Blake <eblake@redhat.com>
-Message-Id: <20170608222617.20376-1-eblake@redhat.com>
-Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
----
- blockdev-nbd.c      |  6 +++++-
- include/block/nbd.h |  2 +-
- nbd/server.c        | 24 +++++++++++++++---------
- qemu-nbd.c          |  4 ++--
- 4 files changed, 23 insertions(+), 13 deletions(-)
-
-diff --git a/blockdev-nbd.c b/blockdev-nbd.c
-index dd0860f4a6..28f551a7b0 100644
---- a/blockdev-nbd.c
-+++ b/blockdev-nbd.c
-@@ -27,6 +27,10 @@ typedef struct NBDServerData {
- 
- static NBDServerData *nbd_server;
- 
-+static void nbd_blockdev_client_closed(NBDClient *client, bool ignored)
-+{
-+    nbd_client_put(client);
-+}
- 
- static gboolean nbd_accept(QIOChannel *ioc, GIOCondition condition,
-                            gpointer opaque)
-@@ -46,7 +50,7 @@ static gboolean nbd_accept(QIOChannel *ioc, GIOCondition condition,
-     qio_channel_set_name(QIO_CHANNEL(cioc), "nbd-server");
-     nbd_client_new(NULL, cioc,
-                    nbd_server->tlscreds, NULL,
--                   nbd_client_put);
-+                   nbd_blockdev_client_closed);
-     object_unref(OBJECT(cioc));
-     return TRUE;
- }
-diff --git a/include/block/nbd.h b/include/block/nbd.h
-index 416257abca..8fa5ce51f3 100644
---- a/include/block/nbd.h
-+++ b/include/block/nbd.h
-@@ -162,7 +162,7 @@ void nbd_client_new(NBDExport *exp,
-                     QIOChannelSocket *sioc,
-                     QCryptoTLSCreds *tlscreds,
-                     const char *tlsaclname,
--                    void (*close)(NBDClient *));
-+                    void (*close_fn)(NBDClient *, bool));
- void nbd_client_get(NBDClient *client);
- void nbd_client_put(NBDClient *client);
- 
-diff --git a/nbd/server.c b/nbd/server.c
-index 49b55f6ede..f2b1aa47ce 100644
---- a/nbd/server.c
-+++ b/nbd/server.c
-@@ -81,7 +81,7 @@ static QTAILQ_HEAD(, NBDExport) exports = QTAILQ_HEAD_INITIALIZER(exports);
- 
- struct NBDClient {
-     int refcount;
--    void (*close)(NBDClient *client);
-+    void (*close_fn)(NBDClient *client, bool negotiated);
- 
-     bool no_zeroes;
-     NBDExport *exp;
-@@ -778,7 +778,7 @@ void nbd_client_put(NBDClient *client)
-     }
- }
- 
--static void client_close(NBDClient *client)
-+static void client_close(NBDClient *client, bool negotiated)
- {
-     if (client->closing) {
-         return;
-@@ -793,8 +793,8 @@ static void client_close(NBDClient *client)
-                          NULL);
- 
-     /* Also tell the client, so that they release their reference.  */
--    if (client->close) {
--        client->close(client);
-+    if (client->close_fn) {
-+        client->close_fn(client, negotiated);
-     }
- }
- 
-@@ -975,7 +975,7 @@ void nbd_export_close(NBDExport *exp)
- 
-     nbd_export_get(exp);
-     QTAILQ_FOREACH_SAFE(client, &exp->clients, next, next) {
--        client_close(client);
-+        client_close(client, true);
-     }
-     nbd_export_set_name(exp, NULL);
-     nbd_export_set_description(exp, NULL);
-@@ -1337,7 +1337,7 @@ done:
- 
- out:
-     nbd_request_put(req);
--    client_close(client);
-+    client_close(client, true);
-     nbd_client_put(client);
- }
- 
-@@ -1363,7 +1363,7 @@ static coroutine_fn void nbd_co_client_start(void *opaque)
-     qemu_co_mutex_init(&client->send_lock);
- 
-     if (nbd_negotiate(data)) {
--        client_close(client);
-+        client_close(client, false);
-         goto out;
-     }
- 
-@@ -1373,11 +1373,17 @@ out:
-     g_free(data);
- }
- 
-+/*
-+ * Create a new client listener on the given export @exp, using the
-+ * given channel @sioc.  Begin servicing it in a coroutine.  When the
-+ * connection closes, call @close_fn with an indication of whether the
-+ * client completed negotiation.
-+ */
- void nbd_client_new(NBDExport *exp,
-                     QIOChannelSocket *sioc,
-                     QCryptoTLSCreds *tlscreds,
-                     const char *tlsaclname,
--                    void (*close_fn)(NBDClient *))
-+                    void (*close_fn)(NBDClient *, bool))
- {
-     NBDClient *client;
-     NBDClientNewData *data = g_new(NBDClientNewData, 1);
-@@ -1394,7 +1400,7 @@ void nbd_client_new(NBDExport *exp,
-     object_ref(OBJECT(client->sioc));
-     client->ioc = QIO_CHANNEL(sioc);
-     object_ref(OBJECT(client->ioc));
--    client->close = close_fn;
-+    client->close_fn = close_fn;
- 
-     data->client = client;
-     data->co = qemu_coroutine_create(nbd_co_client_start, data);
-diff --git a/qemu-nbd.c b/qemu-nbd.c
-index 651f85ecc1..9464a0461c 100644
---- a/qemu-nbd.c
-+++ b/qemu-nbd.c
-@@ -336,10 +336,10 @@ static void nbd_export_closed(NBDExport *exp)
- 
- static void nbd_update_server_watch(void);
- 
--static void nbd_client_closed(NBDClient *client)
-+static void nbd_client_closed(NBDClient *client, bool negotiated)
- {
-     nb_fds--;
--    if (nb_fds == 0 && !persistent && state == RUNNING) {
-+    if (negotiated && nb_fds == 0 && !persistent && state == RUNNING) {
-         state = TERMINATE;
-     }
-     nbd_update_server_watch();
--- 
-2.13.1
-
diff --git a/gnu/packages/patches/ruby-2.2.7-rubygems-2613-ruby22.patch b/gnu/packages/patches/ruby-2.2.7-rubygems-2613-ruby22.patch
new file mode 100644
index 0000000000..d68b836c71
--- /dev/null
+++ b/gnu/packages/patches/ruby-2.2.7-rubygems-2613-ruby22.patch
@@ -0,0 +1,355 @@
+diff --git lib/rubygems.rb lib/rubygems.rb
+index f48496aa31..0e1855b148 100644
+--- ruby-2.2.7/lib/rubygems.rb
++++ ruby-2.2.7/lib/rubygems.rb
+@@ -9,7 +9,7 @@ require 'rbconfig'
+ require 'thread'
+ 
+ module Gem
+-  VERSION = '2.4.5.2'
++  VERSION = '2.4.5.3'
+ end
+ 
+ # Must be first since it unloads the prelude from 1.9.2
+diff --git lib/rubygems/commands/query_command.rb lib/rubygems/commands/query_command.rb
+index 432250e033..44364cfab2 100644
+--- ruby-2.2.7/lib/rubygems/commands/query_command.rb
++++ ruby-2.2.7/lib/rubygems/commands/query_command.rb
+@@ -218,7 +218,7 @@ is too hard to use.
+         end
+       end
+ 
+-      output << make_entry(matching_tuples, platforms)
++      output << clean_text(make_entry(matching_tuples, platforms))
+     end
+   end
+ 
+@@ -336,7 +336,8 @@ is too hard to use.
+   end
+ 
+   def spec_summary entry, spec
+-    entry << "\n\n" << format_text(spec.summary, 68, 4)
++    summary = truncate_text(spec.summary, "the summary for #{spec.full_name}")
++    entry << "\n\n" << format_text(summary, 68, 4)
+   end
+ 
+ end
+diff --git lib/rubygems/installer.rb lib/rubygems/installer.rb
+index 10fc1a34a5..a27569fe2e 100644
+--- ruby-2.2.7/lib/rubygems/installer.rb
++++ ruby-2.2.7/lib/rubygems/installer.rb
+@@ -646,6 +646,11 @@ class Gem::Installer
+       unpack or File.writable?(gem_home)
+   end
+ 
++  def verify_spec_name
++    return if spec.name =~ Gem::Specification::VALID_NAME_PATTERN
++    raise Gem::InstallError, "#{spec} has an invalid name"
++  end
++
+   ##
+   # Return the text for an application file.
+ 
+@@ -771,6 +776,8 @@ TEXT
+ 
+     ensure_loadable_spec
+ 
++    verify_spec_name
++
+     if options[:install_as_default]
+       Gem.ensure_default_gem_subdirectories gem_home
+     else
+diff --git lib/rubygems/remote_fetcher.rb lib/rubygems/remote_fetcher.rb
+index b1f6dd17fc..2b9d61c0a1 100644
+--- ruby-2.2.7/lib/rubygems/remote_fetcher.rb
++++ ruby-2.2.7/lib/rubygems/remote_fetcher.rb
+@@ -96,7 +96,7 @@ class Gem::RemoteFetcher
+     else
+       target = res.target.to_s.strip
+ 
+-      if /\.#{Regexp.quote(host)}\z/ =~ target
++      if URI("http://" + target).host.end_with?(".#{host}")
+         return URI.parse "#{uri.scheme}://#{target}#{uri.path}"
+       end
+ 
+diff --git lib/rubygems/specification.rb lib/rubygems/specification.rb
+index ab1cd92270..faca837128 100644
+--- ruby-2.2.7/lib/rubygems/specification.rb
++++ ruby-2.2.7/lib/rubygems/specification.rb
+@@ -106,6 +106,8 @@ class Gem::Specification < Gem::BasicSpecification
+ 
+   private_constant :LOAD_CACHE if defined? private_constant
+ 
++  VALID_NAME_PATTERN = /\A[a-zA-Z0-9\.\-\_]+\z/ # :nodoc:
++
+   # :startdoc:
+ 
+   ##
+@@ -2477,9 +2479,15 @@ class Gem::Specification < Gem::BasicSpecification
+       end
+     end
+ 
+-    unless String === name then
++    if !name.is_a?(String) then
+       raise Gem::InvalidSpecificationException,
+-            "invalid value for attribute name: \"#{name.inspect}\""
++            "invalid value for attribute name: \"#{name.inspect}\" must be a string"
++    elsif name !~ /[a-zA-Z]/ then
++      raise Gem::InvalidSpecificationException,
++            "invalid value for attribute name: #{name.dump} must include at least one letter"
++    elsif name !~ VALID_NAME_PATTERN then
++      raise Gem::InvalidSpecificationException,
++            "invalid value for attribute name: #{name.dump} can only include letters, numbers, dashes, and underscores"
+     end
+ 
+     if raw_require_paths.empty? then
+diff --git lib/rubygems/text.rb lib/rubygems/text.rb
+index 5c9287ad2e..86a722ffc0 100644
+--- ruby-2.2.7/lib/rubygems/text.rb
++++ ruby-2.2.7/lib/rubygems/text.rb
+@@ -5,13 +5,26 @@ require 'rubygems'
+ 
+ module Gem::Text
+ 
++  ##
++  # Remove any non-printable characters and make the text suitable for
++  # printing.
++  def clean_text(text)
++    text.gsub(/[\000-\b\v-\f\016-\037\177]/, ".".freeze)
++  end
++
++  def truncate_text(text, description, max_length = 100_000)
++    raise ArgumentError, "max_length must be positive" unless max_length > 0
++    return text if text.size <= max_length
++    "Truncating #{description} to #{max_length.to_s.reverse.gsub(/...(?=.)/,'\&,').reverse} characters:\n" + text[0, max_length]
++  end
++
+   ##
+   # Wraps +text+ to +wrap+ characters and optionally indents by +indent+
+   # characters
+ 
+   def format_text(text, wrap, indent=0)
+     result = []
+-    work = text.dup
++    work = clean_text(text)
+ 
+     while work.length > wrap do
+       if work =~ /^(.{0,#{wrap}})[ \n]/ then
+diff --git test/rubygems/test_gem_commands_query_command.rb test/rubygems/test_gem_commands_query_command.rb
+index 43fa82571d..ccd2621874 100644
+--- ruby-2.2.7/test/rubygems/test_gem_commands_query_command.rb
++++ ruby-2.2.7/test/rubygems/test_gem_commands_query_command.rb
+@@ -147,6 +147,86 @@ a (2)
+     This is a lot of text. This is a lot of text. This is a lot of text.
+     This is a lot of text.
+ 
++pl (1)
++    Platform: i386-linux
++    Author: A User
++    Homepage: http://example.com
++
++    this is a summary
++    EOF
++
++    assert_equal expected, @ui.output
++    assert_equal '', @ui.error
++  end
++
++  def test_execute_details_cleans_text
++    spec_fetcher do |fetcher|
++      fetcher.spec 'a', 2 do |s|
++        s.summary = 'This is a lot of text. ' * 4
++        s.authors = ["Abraham Lincoln \x01", "\x02 Hirohito"]
++        s.homepage = "http://a.example.com/\x03"
++      end
++
++      fetcher.legacy_platform
++    end
++
++    @cmd.handle_options %w[-r -d]
++
++    use_ui @ui do
++      @cmd.execute
++    end
++
++    expected = <<-EOF
++
++*** REMOTE GEMS ***
++
++a (2)
++    Authors: Abraham Lincoln ., . Hirohito
++    Homepage: http://a.example.com/.
++
++    This is a lot of text. This is a lot of text. This is a lot of text.
++    This is a lot of text.
++
++pl (1)
++    Platform: i386-linux
++    Author: A User
++    Homepage: http://example.com
++
++    this is a summary
++    EOF
++
++    assert_equal expected, @ui.output
++    assert_equal '', @ui.error
++  end
++
++  def test_execute_details_truncates_summary
++    spec_fetcher do |fetcher|
++      fetcher.spec 'a', 2 do |s|
++        s.summary = 'This is a lot of text. ' * 10_000
++        s.authors = ["Abraham Lincoln \x01", "\x02 Hirohito"]
++        s.homepage = "http://a.example.com/\x03"
++      end
++
++      fetcher.legacy_platform
++    end
++
++    @cmd.handle_options %w[-r -d]
++
++    use_ui @ui do
++      @cmd.execute
++    end
++
++    expected = <<-EOF
++
++*** REMOTE GEMS ***
++
++a (2)
++    Authors: Abraham Lincoln ., . Hirohito
++    Homepage: http://a.example.com/.
++
++    Truncating the summary for a-2 to 100,000 characters:
++#{"    This is a lot of text. This is a lot of text. This is a lot of text.\n" * 1449}    This is a lot of te
++
+ pl (1)
+     Platform: i386-linux
+     Author: A User
+diff --git test/rubygems/test_gem_installer.rb test/rubygems/test_gem_installer.rb
+index 6f8012feb8..aba73af181 100644
+--- ruby-2.2.7/test/rubygems/test_gem_installer.rb
++++ ruby-2.2.7/test/rubygems/test_gem_installer.rb
+@@ -1214,6 +1214,26 @@ gem 'other', version
+     end
+   end
+ 
++  def test_pre_install_checks_malicious_name
++    spec = util_spec '../malicious', '1'
++    def spec.full_name # so the spec is buildable
++      "malicious-1"
++    end
++    def spec.validate; end
++
++    util_build_gem spec
++
++    gem = File.join(@gemhome, 'cache', spec.file_name)
++
++    use_ui @ui do
++      @installer = Gem::Installer.at gem
++      e = assert_raises Gem::InstallError do
++        @installer.pre_install_checks
++      end
++      assert_equal '#<Gem::Specification name=../malicious version=1> has an invalid name', e.message
++    end
++  end
++
+   def test_shebang
+     util_make_exec @spec, "#!/usr/bin/ruby"
+ 
+diff --git test/rubygems/test_gem_remote_fetcher.rb test/rubygems/test_gem_remote_fetcher.rb
+index 63dd8feb38..ca4627810b 100644
+--- ruby-2.2.7/test/rubygems/test_gem_remote_fetcher.rb
++++ ruby-2.2.7/test/rubygems/test_gem_remote_fetcher.rb
+@@ -181,6 +181,21 @@ gems:
+     dns.verify
+   end
+ 
++  def test_api_endpoint_ignores_trans_domain_values_that_end_with_original_in_path
++    uri = URI.parse "http://example.com/foo"
++    target = MiniTest::Mock.new
++    target.expect :target, "evil.com/a.example.com"
++
++    dns = MiniTest::Mock.new
++    dns.expect :getresource, target, [String, Object]
++
++    fetch = Gem::RemoteFetcher.new nil, dns
++    assert_equal URI.parse("http://example.com/foo"), fetch.api_endpoint(uri)
++
++    target.verify
++    dns.verify
++  end
++
+   def test_api_endpoint_ignores_trans_domain_values
+     uri = URI.parse "http://gems.example.com/foo"
+     target = MiniTest::Mock.new
+diff --git test/rubygems/test_gem_specification.rb test/rubygems/test_gem_specification.rb
+index 3cadc55d5d..4f7076a03a 100644
+--- ruby-2.2.7/test/rubygems/test_gem_specification.rb
++++ ruby-2.2.7/test/rubygems/test_gem_specification.rb
+@@ -2610,7 +2610,37 @@ http://opensource.org/licenses/alphabetical
+       @a1.validate
+     end
+ 
+-    assert_equal 'invalid value for attribute name: ":json"', e.message
++    assert_equal 'invalid value for attribute name: ":json" must be a string', e.message
++
++    @a1.name = []
++    e = assert_raises Gem::InvalidSpecificationException do
++      @a1.validate
++    end
++    assert_equal "invalid value for attribute name: \"[]\" must be a string", e.message
++
++    @a1.name = ""
++    e = assert_raises Gem::InvalidSpecificationException do
++      @a1.validate
++    end
++    assert_equal "invalid value for attribute name: \"\" must include at least one letter", e.message
++
++    @a1.name = "12345"
++    e = assert_raises Gem::InvalidSpecificationException do
++      @a1.validate
++    end
++    assert_equal "invalid value for attribute name: \"12345\" must include at least one letter", e.message
++
++    @a1.name = "../malicious"
++    e = assert_raises Gem::InvalidSpecificationException do
++      @a1.validate
++    end
++    assert_equal "invalid value for attribute name: \"../malicious\" can only include letters, numbers, dashes, and underscores", e.message
++
++    @a1.name = "\ba\t"
++    e = assert_raises Gem::InvalidSpecificationException do
++      @a1.validate
++    end
++    assert_equal "invalid value for attribute name: \"\\ba\\t\" can only include letters, numbers, dashes, and underscores", e.message
+   end
+ 
+   def test_validate_non_nil
+diff --git test/rubygems/test_gem_text.rb test/rubygems/test_gem_text.rb
+index e5cfc41e61..9b270b481b 100644
+--- ruby-2.2.7/test/rubygems/test_gem_text.rb
++++ ruby-2.2.7/test/rubygems/test_gem_text.rb
+@@ -35,6 +35,10 @@ Without the wrapping, the text might not look good in the RSS feed.
+     assert_equal expected, format_text(text, 78)
+   end
+ 
++  def test_format_removes_nonprintable_characters
++    assert_equal "text with weird .. stuff .", format_text("text with weird \x1b\x02 stuff \x7f", 40)
++  end
++
+   def test_min3
+     assert_equal 1, min3(1, 1, 1)
+     assert_equal 1, min3(1, 1, 2)
+@@ -71,4 +75,11 @@ Without the wrapping, the text might not look good in the RSS feed.
+     assert_equal 7, levenshtein_distance("xxxxxxx", "ZenTest")
+     assert_equal 7, levenshtein_distance("zentest", "xxxxxxx")
+   end
++
++  def test_truncate_text
++    assert_equal "abc", truncate_text("abc", "desc")
++    assert_equal "Truncating desc to 2 characters:\nab", truncate_text("abc", "desc", 2)
++    s = "ab" * 500_001
++    assert_equal "Truncating desc to 1,000,000 characters:\n#{s[0, 1_000_000]}", truncate_text(s, "desc", 1_000_000)
++  end
+ end
diff --git a/gnu/packages/patches/ruby-2.3.4-rubygems-2613-ruby23.patch b/gnu/packages/patches/ruby-2.3.4-rubygems-2613-ruby23.patch
new file mode 100644
index 0000000000..8f4758293e
--- /dev/null
+++ b/gnu/packages/patches/ruby-2.3.4-rubygems-2613-ruby23.patch
@@ -0,0 +1,355 @@
+diff --git lib/rubygems.rb lib/rubygems.rb
+index 04031c765c..9c0219ce06 100644
+--- ruby-2.3.4/lib/rubygems.rb
++++ ruby-2.3.4/lib/rubygems.rb
+@@ -10,7 +10,7 @@
+ require 'thread'
+ 
+ module Gem
+-  VERSION = '2.5.2'
++  VERSION = '2.5.2.1'
+ end
+ 
+ # Must be first since it unloads the prelude from 1.9.2
+diff --git lib/rubygems/commands/query_command.rb lib/rubygems/commands/query_command.rb
+index d6196b44ed..61e9808860 100644
+--- ruby-2.3.4/lib/rubygems/commands/query_command.rb
++++ ruby-2.3.4/lib/rubygems/commands/query_command.rb
+@@ -226,7 +226,7 @@ def output_versions output, versions
+         end
+       end
+ 
+-      output << make_entry(matching_tuples, platforms)
++      output << clean_text(make_entry(matching_tuples, platforms))
+     end
+   end
+ 
+@@ -344,7 +344,8 @@ def spec_platforms entry, platforms
+   end
+ 
+   def spec_summary entry, spec
+-    entry << "\n\n" << format_text(spec.summary, 68, 4)
++    summary = truncate_text(spec.summary, "the summary for #{spec.full_name}")
++    entry << "\n\n" << format_text(summary, 68, 4)
+   end
+ 
+ end
+diff --git lib/rubygems/installer.rb lib/rubygems/installer.rb
+index 85358e0d1a..709b77d126 100644
+--- ruby-2.3.4/lib/rubygems/installer.rb
++++ ruby-2.3.4/lib/rubygems/installer.rb
+@@ -693,6 +693,11 @@ def verify_gem_home(unpack = false) # :nodoc:
+       unpack or File.writable?(gem_home)
+   end
+ 
++  def verify_spec_name
++    return if spec.name =~ Gem::Specification::VALID_NAME_PATTERN
++    raise Gem::InstallError, "#{spec} has an invalid name"
++  end
++
+   ##
+   # Return the text for an application file.
+ 
+@@ -812,6 +817,8 @@ def pre_install_checks
+ 
+     ensure_loadable_spec
+ 
++    verify_spec_name
++
+     if options[:install_as_default]
+       Gem.ensure_default_gem_subdirectories gem_home
+     else
+diff --git lib/rubygems/remote_fetcher.rb lib/rubygems/remote_fetcher.rb
+index fda1e067ef..254bebfadf 100644
+--- ruby-2.3.4/lib/rubygems/remote_fetcher.rb
++++ ruby-2.3.4/lib/rubygems/remote_fetcher.rb
+@@ -104,7 +104,7 @@ def api_endpoint(uri)
+     else
+       target = res.target.to_s.strip
+ 
+-      if /\.#{Regexp.quote(host)}\z/ =~ target
++      if URI("http://" + target).host.end_with?(".#{host}")
+         return URI.parse "#{uri.scheme}://#{target}#{uri.path}"
+       end
+ 
+diff --git lib/rubygems/specification.rb lib/rubygems/specification.rb
+index 8e2557cdb2..dd4fde1776 100644
+--- ruby-2.3.4/lib/rubygems/specification.rb
++++ ruby-2.3.4/lib/rubygems/specification.rb
+@@ -108,6 +108,8 @@ class Gem::Specification < Gem::BasicSpecification
+ 
+   private_constant :LOAD_CACHE if defined? private_constant
+ 
++  VALID_NAME_PATTERN = /\A[a-zA-Z0-9\.\-\_]+\z/ # :nodoc:
++
+   # :startdoc:
+ 
+   ##
+@@ -2665,9 +2667,15 @@ def validate packaging = true
+       end
+     end
+ 
+-    unless String === name then
++    if !name.is_a?(String) then
+       raise Gem::InvalidSpecificationException,
+-            "invalid value for attribute name: \"#{name.inspect}\""
++            "invalid value for attribute name: \"#{name.inspect}\" must be a string"
++    elsif name !~ /[a-zA-Z]/ then
++      raise Gem::InvalidSpecificationException,
++            "invalid value for attribute name: #{name.dump} must include at least one letter"
++    elsif name !~ VALID_NAME_PATTERN then
++      raise Gem::InvalidSpecificationException,
++            "invalid value for attribute name: #{name.dump} can only include letters, numbers, dashes, and underscores"
+     end
+ 
+     if raw_require_paths.empty? then
+diff --git lib/rubygems/text.rb lib/rubygems/text.rb
+index 732f1b99f2..b944b62c27 100644
+--- ruby-2.3.4/lib/rubygems/text.rb
++++ ruby-2.3.4/lib/rubygems/text.rb
+@@ -6,13 +6,26 @@
+ 
+ module Gem::Text
+ 
++  ##
++  # Remove any non-printable characters and make the text suitable for
++  # printing.
++  def clean_text(text)
++    text.gsub(/[\000-\b\v-\f\016-\037\177]/, ".".freeze)
++  end
++
++  def truncate_text(text, description, max_length = 100_000)
++    raise ArgumentError, "max_length must be positive" unless max_length > 0
++    return text if text.size <= max_length
++    "Truncating #{description} to #{max_length.to_s.reverse.gsub(/...(?=.)/,'\&,').reverse} characters:\n" + text[0, max_length]
++  end
++
+   ##
+   # Wraps +text+ to +wrap+ characters and optionally indents by +indent+
+   # characters
+ 
+   def format_text(text, wrap, indent=0)
+     result = []
+-    work = text.dup
++    work = clean_text(text)
+ 
+     while work.length > wrap do
+       if work =~ /^(.{0,#{wrap}})[ \n]/ then
+diff --git test/rubygems/test_gem_commands_query_command.rb test/rubygems/test_gem_commands_query_command.rb
+index 78c15a1770..9ec715492f 100644
+--- ruby-2.3.4/test/rubygems/test_gem_commands_query_command.rb
++++ ruby-2.3.4/test/rubygems/test_gem_commands_query_command.rb
+@@ -116,6 +116,86 @@ def test_execute_details
+     This is a lot of text. This is a lot of text. This is a lot of text.
+     This is a lot of text.
+ 
++pl (1)
++    Platform: i386-linux
++    Author: A User
++    Homepage: http://example.com
++
++    this is a summary
++    EOF
++
++    assert_equal expected, @ui.output
++    assert_equal '', @ui.error
++  end
++
++  def test_execute_details_cleans_text
++    spec_fetcher do |fetcher|
++      fetcher.spec 'a', 2 do |s|
++        s.summary = 'This is a lot of text. ' * 4
++        s.authors = ["Abraham Lincoln \x01", "\x02 Hirohito"]
++        s.homepage = "http://a.example.com/\x03"
++      end
++
++      fetcher.legacy_platform
++    end
++
++    @cmd.handle_options %w[-r -d]
++
++    use_ui @ui do
++      @cmd.execute
++    end
++
++    expected = <<-EOF
++
++*** REMOTE GEMS ***
++
++a (2)
++    Authors: Abraham Lincoln ., . Hirohito
++    Homepage: http://a.example.com/.
++
++    This is a lot of text. This is a lot of text. This is a lot of text.
++    This is a lot of text.
++
++pl (1)
++    Platform: i386-linux
++    Author: A User
++    Homepage: http://example.com
++
++    this is a summary
++    EOF
++
++    assert_equal expected, @ui.output
++    assert_equal '', @ui.error
++  end
++
++  def test_execute_details_truncates_summary
++    spec_fetcher do |fetcher|
++      fetcher.spec 'a', 2 do |s|
++        s.summary = 'This is a lot of text. ' * 10_000
++        s.authors = ["Abraham Lincoln \x01", "\x02 Hirohito"]
++        s.homepage = "http://a.example.com/\x03"
++      end
++
++      fetcher.legacy_platform
++    end
++
++    @cmd.handle_options %w[-r -d]
++
++    use_ui @ui do
++      @cmd.execute
++    end
++
++    expected = <<-EOF
++
++*** REMOTE GEMS ***
++
++a (2)
++    Authors: Abraham Lincoln ., . Hirohito
++    Homepage: http://a.example.com/.
++
++    Truncating the summary for a-2 to 100,000 characters:
++#{"    This is a lot of text. This is a lot of text. This is a lot of text.\n" * 1449}    This is a lot of te
++
+ pl (1)
+     Platform: i386-linux
+     Author: A User
+diff --git test/rubygems/test_gem_installer.rb test/rubygems/test_gem_installer.rb
+index 5ec71d0a01..1092a0c68f 100644
+--- ruby-2.3.4/test/rubygems/test_gem_installer.rb
++++ ruby-2.3.4/test/rubygems/test_gem_installer.rb
+@@ -1227,6 +1227,26 @@ def test_pre_install_checks_wrong_rubygems_version
+     end
+   end
+ 
++  def test_pre_install_checks_malicious_name
++    spec = util_spec '../malicious', '1'
++    def spec.full_name # so the spec is buildable
++      "malicious-1"
++    end
++    def spec.validate; end
++
++    util_build_gem spec
++
++    gem = File.join(@gemhome, 'cache', spec.file_name)
++
++    use_ui @ui do
++      @installer = Gem::Installer.at gem
++      e = assert_raises Gem::InstallError do
++        @installer.pre_install_checks
++      end
++      assert_equal '#<Gem::Specification name=../malicious version=1> has an invalid name', e.message
++    end
++  end
++
+   def test_shebang
+     util_make_exec @spec, "#!/usr/bin/ruby"
+ 
+diff --git test/rubygems/test_gem_remote_fetcher.rb test/rubygems/test_gem_remote_fetcher.rb
+index 49b6b6656c..a3919c8ef2 100644
+--- ruby-2.3.4/test/rubygems/test_gem_remote_fetcher.rb
++++ ruby-2.3.4/test/rubygems/test_gem_remote_fetcher.rb
+@@ -253,6 +253,21 @@ def test_api_endpoint_ignores_trans_domain_values_that_end_with_original
+     dns.verify
+   end
+ 
++  def test_api_endpoint_ignores_trans_domain_values_that_end_with_original_in_path
++    uri = URI.parse "http://example.com/foo"
++    target = MiniTest::Mock.new
++    target.expect :target, "evil.com/a.example.com"
++
++    dns = MiniTest::Mock.new
++    dns.expect :getresource, target, [String, Object]
++
++    fetch = Gem::RemoteFetcher.new nil, dns
++    assert_equal URI.parse("http://example.com/foo"), fetch.api_endpoint(uri)
++
++    target.verify
++    dns.verify
++  end
++
+   def test_api_endpoint_timeout_warning
+     uri = URI.parse "http://gems.example.com/foo"
+ 
+diff --git test/rubygems/test_gem_specification.rb test/rubygems/test_gem_specification.rb
+index bc1c8d2ca7..9a49bbbf59 100644
+--- ruby-2.3.4/test/rubygems/test_gem_specification.rb
++++ ruby-2.3.4/test/rubygems/test_gem_specification.rb
+@@ -2974,7 +2974,37 @@ def test_validate_name
+       @a1.validate
+     end
+ 
+-    assert_equal 'invalid value for attribute name: ":json"', e.message
++    assert_equal 'invalid value for attribute name: ":json" must be a string', e.message
++
++    @a1.name = []
++    e = assert_raises Gem::InvalidSpecificationException do
++      @a1.validate
++    end
++    assert_equal "invalid value for attribute name: \"[]\" must be a string", e.message
++
++    @a1.name = ""
++    e = assert_raises Gem::InvalidSpecificationException do
++      @a1.validate
++    end
++    assert_equal "invalid value for attribute name: \"\" must include at least one letter", e.message
++
++    @a1.name = "12345"
++    e = assert_raises Gem::InvalidSpecificationException do
++      @a1.validate
++    end
++    assert_equal "invalid value for attribute name: \"12345\" must include at least one letter", e.message
++
++    @a1.name = "../malicious"
++    e = assert_raises Gem::InvalidSpecificationException do
++      @a1.validate
++    end
++    assert_equal "invalid value for attribute name: \"../malicious\" can only include letters, numbers, dashes, and underscores", e.message
++
++    @a1.name = "\ba\t"
++    e = assert_raises Gem::InvalidSpecificationException do
++      @a1.validate
++    end
++    assert_equal "invalid value for attribute name: \"\\ba\\t\" can only include letters, numbers, dashes, and underscores", e.message
+   end
+ 
+   def test_validate_non_nil
+diff --git test/rubygems/test_gem_text.rb test/rubygems/test_gem_text.rb
+index a6e22e04da..04f3f605e8 100644
+--- ruby-2.3.4/test/rubygems/test_gem_text.rb
++++ ruby-2.3.4/test/rubygems/test_gem_text.rb
+@@ -36,6 +36,10 @@ def test_format_text_trailing # for two spaces after .
+     assert_equal expected, format_text(text, 78)
+   end
+ 
++  def test_format_removes_nonprintable_characters
++    assert_equal "text with weird .. stuff .", format_text("text with weird \x1b\x02 stuff \x7f", 40)
++  end
++
+   def test_min3
+     assert_equal 1, min3(1, 1, 1)
+     assert_equal 1, min3(1, 1, 2)
+@@ -74,4 +78,11 @@ def test_levenshtein_distance_replace
+     assert_equal 7, levenshtein_distance("xxxxxxx", "ZenTest")
+     assert_equal 7, levenshtein_distance("zentest", "xxxxxxx")
+   end
++
++  def test_truncate_text
++    assert_equal "abc", truncate_text("abc", "desc")
++    assert_equal "Truncating desc to 2 characters:\nab", truncate_text("abc", "desc", 2)
++    s = "ab" * 500_001
++    assert_equal "Truncating desc to 1,000,000 characters:\n#{s[0, 1_000_000]}", truncate_text(s, "desc", 1_000_000)
++  end
+ end
diff --git a/gnu/packages/patches/ruby-rubygems-2612-ruby24.patch b/gnu/packages/patches/ruby-rubygems-2612-ruby24.patch
new file mode 100644
index 0000000000..8ee32c0c6e
--- /dev/null
+++ b/gnu/packages/patches/ruby-rubygems-2612-ruby24.patch
@@ -0,0 +1,437 @@
+diff --git lib/rubygems.rb lib/rubygems.rb
+index 5cd1a4c47a..bc5bf9b4c2 100644
+--- ruby-2.4.1/lib/rubygems.rb
++++ ruby-2.4.1/lib/rubygems.rb
+@@ -10,7 +10,7 @@
+ require 'thread'
+ 
+ module Gem
+-  VERSION = "2.6.11"
++  VERSION = "2.6.12"
+ end
+ 
+ # Must be first since it unloads the prelude from 1.9.2
+@@ -234,6 +234,7 @@ def self.needs
+ 
+   def self.finish_resolve(request_set=Gem::RequestSet.new)
+     request_set.import Gem::Specification.unresolved_deps.values
++    request_set.import Gem.loaded_specs.values.map {|s| Gem::Dependency.new(s.name, s.version) }
+ 
+     request_set.resolve_current.each do |s|
+       s.full_spec.activate
+diff --git lib/rubygems/commands/open_command.rb lib/rubygems/commands/open_command.rb
+index a89b7421e3..059635e835 100644
+--- ruby-2.4.1/lib/rubygems/commands/open_command.rb
++++ ruby-2.4.1/lib/rubygems/commands/open_command.rb
+@@ -72,7 +72,7 @@ def open_editor path
+   end
+ 
+   def spec_for name
+-    spec = Gem::Specification.find_all_by_name(name, @version).last
++    spec = Gem::Specification.find_all_by_name(name, @version).first
+ 
+     return spec if spec
+ 
+diff --git lib/rubygems/commands/query_command.rb lib/rubygems/commands/query_command.rb
+index f25d120b88..70f8127292 100644
+--- ruby-2.4.1/lib/rubygems/commands/query_command.rb
++++ ruby-2.4.1/lib/rubygems/commands/query_command.rb
+@@ -86,7 +86,7 @@ def execute
+       name = Array(options[:name])
+     else
+       args = options[:args].to_a
+-      name = options[:exact] ? args : args.map{|arg| /#{arg}/i }
++      name = options[:exact] ? args.map{|arg| /\A#{Regexp.escape(arg)}\Z/ } : args.map{|arg| /#{arg}/i }
+     end
+ 
+     prerelease = options[:prerelease]
+diff --git lib/rubygems/commands/sources_command.rb lib/rubygems/commands/sources_command.rb
+index 9832afd214..7e46963a4c 100644
+--- ruby-2.4.1/lib/rubygems/commands/sources_command.rb
++++ ruby-2.4.1/lib/rubygems/commands/sources_command.rb
+@@ -44,7 +44,7 @@ def add_source source_uri # :nodoc:
+     source = Gem::Source.new source_uri
+ 
+     begin
+-      if Gem.sources.include? source_uri then
++      if Gem.sources.include? source then
+         say "source #{source_uri} already present in the cache"
+       else
+         source.load_specs :released
+diff --git lib/rubygems/dependency_list.rb lib/rubygems/dependency_list.rb
+index 35fe7c4c1a..d8314eaf60 100644
+--- ruby-2.4.1/lib/rubygems/dependency_list.rb
++++ ruby-2.4.1/lib/rubygems/dependency_list.rb
+@@ -104,7 +104,7 @@ def find_name(full_name)
+   end
+ 
+   def inspect # :nodoc:
+-    "#<%s:0x%x %p>" % [self.class, object_id, map { |s| s.full_name }]
++    "%s %p>" % [super[0..-2], map { |s| s.full_name }]
+   end
+ 
+   ##
+diff --git lib/rubygems/installer.rb lib/rubygems/installer.rb
+index f4d3e728de..967543c2d1 100644
+--- ruby-2.4.1/lib/rubygems/installer.rb
++++ ruby-2.4.1/lib/rubygems/installer.rb
+@@ -214,7 +214,7 @@ def check_executable_overwrite filename # :nodoc:
+ 
+       ruby_executable = true
+       existing = io.read.slice(%r{
+-          ^(
++          ^\s*(
+             gem \s |
+             load \s Gem\.bin_path\( |
+             load \s Gem\.activate_bin_path\(
+@@ -701,6 +701,8 @@ def verify_gem_home(unpack = false) # :nodoc:
+   # Return the text for an application file.
+ 
+   def app_script_text(bin_file_name)
++    # note that the `load` lines cannot be indented, as old RG versions match
++    # against the beginning of the line
+     return <<-TEXT
+ #{shebang bin_file_name}
+ #
+@@ -723,7 +725,12 @@ def app_script_text(bin_file_name)
+   end
+ end
+ 
++if Gem.respond_to?(:activate_bin_path)
+ load Gem.activate_bin_path('#{spec.name}', '#{bin_file_name}', version)
++else
++gem #{spec.name.dump}, version
++load Gem.bin_path(#{spec.name.dump}, #{bin_file_name.dump}, version)
++end
+ TEXT
+   end
+ 
+diff --git lib/rubygems/platform.rb lib/rubygems/platform.rb
+index d22d91ae54..2dd9ed5782 100644
+--- ruby-2.4.1/lib/rubygems/platform.rb
++++ ruby-2.4.1/lib/rubygems/platform.rb
+@@ -112,7 +112,7 @@ def initialize(arch)
+   end
+ 
+   def inspect
+-    "#<%s:0x%x @cpu=%p, @os=%p, @version=%p>" % [self.class, object_id, *to_a]
++    "%s @cpu=%p, @os=%p, @version=%p>" % [super[0..-2], *to_a]
+   end
+ 
+   def to_a
+diff --git lib/rubygems/security.rb lib/rubygems/security.rb
+index 119d6d56f7..6963ca156f 100644
+--- ruby-2.4.1/lib/rubygems/security.rb
++++ ruby-2.4.1/lib/rubygems/security.rb
+@@ -455,7 +455,7 @@ def self.create_cert_self_signed subject, key, age = ONE_YEAR,
+ 
+   ##
+   # Creates a new key pair of the specified +length+ and +algorithm+.  The
+-  # default is a 2048 bit RSA key.
++  # default is a 3072 bit RSA key.
+ 
+   def self.create_key length = KEY_LENGTH, algorithm = KEY_ALGORITHM
+     algorithm.new length
+diff --git lib/rubygems/server.rb lib/rubygems/server.rb
+index 81df0e608e..df4eb566d3 100644
+--- ruby-2.4.1/lib/rubygems/server.rb
++++ ruby-2.4.1/lib/rubygems/server.rb
+@@ -657,7 +657,7 @@ def root(req, res)
+       "only_one_executable" => true,
+       "full_name" => "rubygems-#{Gem::VERSION}",
+       "has_deps" => false,
+-      "homepage" => "http://docs.rubygems.org/",
++      "homepage" => "http://guides.rubygems.org/",
+       "name" => 'rubygems',
+       "ri_installed" => true,
+       "summary" => "RubyGems itself",
+diff --git lib/rubygems/specification.rb lib/rubygems/specification.rb
+index a2f289d162..500f0af768 100644
+--- ruby-2.4.1/lib/rubygems/specification.rb
++++ ruby-2.4.1/lib/rubygems/specification.rb
+@@ -2105,7 +2105,7 @@ def inspect # :nodoc:
+     if $DEBUG
+       super
+     else
+-      "#<#{self.class}:0x#{__id__.to_s(16)} #{full_name}>"
++      "#{super[0..-2]} #{full_name}>"
+     end
+   end
+ 
+diff --git lib/rubygems/test_case.rb lib/rubygems/test_case.rb
+index 86b68e1efb..4e48f1eb4c 100644
+--- ruby-2.4.1/lib/rubygems/test_case.rb
++++ ruby-2.4.1/lib/rubygems/test_case.rb
+@@ -484,7 +484,7 @@ def git_gem name = 'a', version = 1
+ 
+       system @git, 'add', gemspec
+       system @git, 'commit', '-a', '-m', 'a non-empty commit message', '--quiet'
+-      head = Gem::Util.popen('git', 'rev-parse', 'master').strip
++      head = Gem::Util.popen(@git, 'rev-parse', 'master').strip
+     end
+ 
+     return name, git_spec.version, directory, head
+@@ -1498,6 +1498,8 @@ def self.key_path key_name
+ begin
+   gem 'rdoc'
+   require 'rdoc'
++
++  require 'rubygems/rdoc'
+ rescue LoadError, Gem::LoadError
+ end
+ 
+@@ -1514,3 +1516,4 @@ def self.key_path key_name
+ pid = $$
+ END {tmpdirs.each {|dir| Dir.rmdir(dir)} if $$ == pid}
+ Gem.clear_paths
++Gem.loaded_specs.clear
+diff --git test/rubygems/test_gem.rb test/rubygems/test_gem.rb
+index a605f9cdfe..62b36dfd41 100644
+--- ruby-2.4.1/test/rubygems/test_gem.rb
++++ ruby-2.4.1/test/rubygems/test_gem.rb
+@@ -75,6 +75,29 @@ def test_self_finish_resolve_wtf
+     end
+   end
+ 
++  def test_self_finish_resolve_respects_loaded_specs
++    save_loaded_features do
++      a1 = new_spec "a", "1", "b" => "> 0"
++      b1 = new_spec "b", "1", "c" => ">= 1"
++      b2 = new_spec "b", "2", "c" => ">= 2"
++      c1 = new_spec "c", "1"
++      c2 = new_spec "c", "2"
++
++      install_specs c1, c2, b1, b2, a1
++
++      a1.activate
++      c1.activate
++
++      assert_equal %w(a-1 c-1), loaded_spec_names
++      assert_equal ["b (> 0)"], unresolved_names
++
++      Gem.finish_resolve
++
++      assert_equal %w(a-1 b-1 c-1), loaded_spec_names
++      assert_equal [], unresolved_names
++    end
++  end
++
+   def test_self_install
+     spec_fetcher do |f|
+       f.gem  'a', 1
+@@ -492,7 +515,7 @@ def test_self_find_files_with_gemfile
+     skip if RUBY_VERSION <= "1.8.7"
+ 
+     cwd = File.expand_path("test/rubygems", @@project_dir)
+-    $LOAD_PATH.unshift cwd
++    actual_load_path = $LOAD_PATH.unshift(cwd).dup
+ 
+     discover_path = File.join 'lib', 'sff', 'discover.rb'
+ 
+@@ -518,12 +541,12 @@ def test_self_find_files_with_gemfile
+     expected = [
+       File.expand_path('test/rubygems/sff/discover.rb', @@project_dir),
+       File.join(foo1.full_gem_path, discover_path)
+-    ]
++    ].sort
+ 
+-    assert_equal expected, Gem.find_files('sff/discover')
+-    assert_equal expected, Gem.find_files('sff/**.rb'), '[ruby-core:31730]'
++    assert_equal expected, Gem.find_files('sff/discover').sort
++    assert_equal expected, Gem.find_files('sff/**.rb').sort, '[ruby-core:31730]'
+   ensure
+-    assert_equal cwd, $LOAD_PATH.shift unless RUBY_VERSION <= "1.8.7"
++    assert_equal cwd, actual_load_path.shift unless RUBY_VERSION <= "1.8.7"
+   end
+ 
+   def test_self_find_latest_files
+diff --git test/rubygems/test_gem_commands_open_command.rb test/rubygems/test_gem_commands_open_command.rb
+index 3ec38972e6..a96fa6ea23 100644
+--- ruby-2.4.1/test/rubygems/test_gem_commands_open_command.rb
++++ ruby-2.4.1/test/rubygems/test_gem_commands_open_command.rb
+@@ -24,7 +24,8 @@ def test_execute
+     @cmd.options[:args] = %w[foo]
+     @cmd.options[:editor] = "#{Gem.ruby} -e0 --"
+ 
+-    spec = gem 'foo'
++    gem 'foo', '1.0.0'
++    spec = gem 'foo', '1.0.1'
+     mock = MiniTest::Mock.new
+     mock.expect(:call, true, [spec.full_gem_path])
+ 
+diff --git test/rubygems/test_gem_commands_query_command.rb test/rubygems/test_gem_commands_query_command.rb
+index 223f205b2d..d8d682b136 100644
+--- ruby-2.4.1/test/rubygems/test_gem_commands_query_command.rb
++++ ruby-2.4.1/test/rubygems/test_gem_commands_query_command.rb
+@@ -642,7 +642,7 @@ def test_execute_local_details
+     assert_equal expected, @ui.output
+   end
+ 
+-  def test_execute_exact
++  def test_execute_exact_remote
+     spec_fetcher do |fetcher|
+       fetcher.spec 'coolgem-omg', 3
+       fetcher.spec 'coolgem', '4.2.1'
+@@ -665,6 +665,60 @@ def test_execute_exact
+     assert_equal expected, @ui.output
+   end
+ 
++  def test_execute_exact_local
++    spec_fetcher do |fetcher|
++      fetcher.spec 'coolgem-omg', 3
++      fetcher.spec 'coolgem', '4.2.1'
++      fetcher.spec 'wow_coolgem', 1
++    end
++
++    @cmd.handle_options %w[--exact coolgem]
++
++    use_ui @ui do
++      @cmd.execute
++    end
++
++    expected = <<-EOF
++
++*** LOCAL GEMS ***
++
++coolgem (4.2.1)
++    EOF
++
++    assert_equal expected, @ui.output
++  end
++
++  def test_execute_exact_multiple
++    spec_fetcher do |fetcher|
++      fetcher.spec 'coolgem-omg', 3
++      fetcher.spec 'coolgem', '4.2.1'
++      fetcher.spec 'wow_coolgem', 1
++
++      fetcher.spec 'othergem-omg', 3
++      fetcher.spec 'othergem', '1.2.3'
++      fetcher.spec 'wow_othergem', 1
++    end
++
++    @cmd.handle_options %w[--exact coolgem othergem]
++
++    use_ui @ui do
++      @cmd.execute
++    end
++
++    expected = <<-EOF
++
++*** LOCAL GEMS ***
++
++coolgem (4.2.1)
++
++*** LOCAL GEMS ***
++
++othergem (1.2.3)
++    EOF
++
++    assert_equal expected, @ui.output
++  end
++
+   private
+ 
+   def add_gems_to_fetcher
+diff --git test/rubygems/test_gem_commands_sources_command.rb test/rubygems/test_gem_commands_sources_command.rb
+index 014b4b4c12..d5b6d99419 100644
+--- ruby-2.4.1/test/rubygems/test_gem_commands_sources_command.rb
++++ ruby-2.4.1/test/rubygems/test_gem_commands_sources_command.rb
+@@ -108,6 +108,58 @@ def test_execute_add_redundant_source
+     assert_equal '', @ui.error
+   end
+ 
++  def test_execute_add_redundant_source_trailing_slash
++    # Remove pre-existing gem source (w/ slash)
++    repo_with_slash = "http://gems.example.com/"
++    @cmd.handle_options %W[--remove #{repo_with_slash}]
++    use_ui @ui do
++      @cmd.execute
++    end
++    source = Gem::Source.new repo_with_slash
++    assert_equal false, Gem.sources.include?(source)
++
++    expected = <<-EOF
++#{repo_with_slash} removed from sources
++    EOF
++
++    assert_equal expected, @ui.output
++    assert_equal '', @ui.error
++
++    # Re-add pre-existing gem source (w/o slash)
++    repo_without_slash = "http://gems.example.com"
++    @cmd.handle_options %W[--add #{repo_without_slash}]
++    use_ui @ui do
++      @cmd.execute
++    end
++    source = Gem::Source.new repo_without_slash
++    assert_equal true, Gem.sources.include?(source)
++
++    expected = <<-EOF
++http://gems.example.com/ removed from sources
++http://gems.example.com added to sources
++    EOF
++
++    assert_equal expected, @ui.output
++    assert_equal '', @ui.error
++
++    # Re-add original gem source (w/ slash)
++    @cmd.handle_options %W[--add #{repo_with_slash}]
++    use_ui @ui do
++      @cmd.execute
++    end
++    source = Gem::Source.new repo_with_slash
++    assert_equal true, Gem.sources.include?(source)
++
++    expected = <<-EOF
++http://gems.example.com/ removed from sources
++http://gems.example.com added to sources
++source http://gems.example.com/ already present in the cache
++    EOF
++
++    assert_equal expected, @ui.output
++    assert_equal '', @ui.error 
++  end
++
+   def test_execute_add_http_rubygems_org
+     http_rubygems_org = 'http://rubygems.org'
+ 
+diff --git test/rubygems/test_gem_installer.rb test/rubygems/test_gem_installer.rb
+index 6ceb2c6dfc..882981d344 100644
+--- ruby-2.4.1/test/rubygems/test_gem_installer.rb
++++ ruby-2.4.1/test/rubygems/test_gem_installer.rb
+@@ -62,7 +62,12 @@ def test_app_script_text
+   end
+ end
+ 
++if Gem.respond_to?(:activate_bin_path)
+ load Gem.activate_bin_path('a', 'executable', version)
++else
++gem "a", version
++load Gem.bin_path("a", "executable", version)
++end
+     EOF
+ 
+     wrapper = @installer.app_script_text 'executable'
+diff --git test/rubygems/test_require.rb test/rubygems/test_require.rb
+index dd606e44d4..936f78fb2a 100644
+--- ruby-2.4.1/test/rubygems/test_require.rb
++++ ruby-2.4.1/test/rubygems/test_require.rb
+@@ -301,6 +301,17 @@ def test_default_gem_only
+     assert_equal %w(default-2.0.0.0), loaded_spec_names
+   end
+ 
++  def test_realworld_default_gem
++    skip "no default gems on ruby < 2.0" unless RUBY_VERSION >= "2"
++    cmd = <<-RUBY
++      $stderr = $stdout
++      require "json"
++      puts Gem.loaded_specs["json"].default_gem?
++    RUBY
++    output = Gem::Util.popen(Gem.ruby, "-e", cmd).strip
++    assert_equal "true", output
++  end
++
+   def test_default_gem_and_normal_gem
+     default_gem_spec = new_default_spec("default", "2.0.0.0",
+                                         nil, "default/gem.rb")
diff --git a/gnu/packages/patches/ruby-rubygems-2613-ruby24.patch b/gnu/packages/patches/ruby-rubygems-2613-ruby24.patch
new file mode 100644
index 0000000000..c253cc912d
--- /dev/null
+++ b/gnu/packages/patches/ruby-rubygems-2613-ruby24.patch
@@ -0,0 +1,355 @@
+diff --git lib/rubygems.rb lib/rubygems.rb
+index bc5bf9b4c2..55aa85b8b2 100644
+--- ruby-2.4.1/lib/rubygems.rb
++++ ruby-2.4.1/lib/rubygems.rb
+@@ -10,7 +10,7 @@
+ require 'thread'
+ 
+ module Gem
+-  VERSION = "2.6.12"
++  VERSION = "2.6.13"
+ end
+ 
+ # Must be first since it unloads the prelude from 1.9.2
+diff --git lib/rubygems/commands/query_command.rb lib/rubygems/commands/query_command.rb
+index 70f8127292..44144203e0 100644
+--- ruby-2.4.1/lib/rubygems/commands/query_command.rb
++++ ruby-2.4.1/lib/rubygems/commands/query_command.rb
+@@ -226,7 +226,7 @@ def output_versions output, versions
+         end
+       end
+ 
+-      output << make_entry(matching_tuples, platforms)
++      output << clean_text(make_entry(matching_tuples, platforms))
+     end
+   end
+ 
+@@ -353,7 +353,8 @@ def spec_platforms entry, platforms
+   end
+ 
+   def spec_summary entry, spec
+-    entry << "\n\n" << format_text(spec.summary, 68, 4)
++    summary = truncate_text(spec.summary, "the summary for #{spec.full_name}")
++    entry << "\n\n" << format_text(summary, 68, 4)
+   end
+ 
+ end
+diff --git lib/rubygems/installer.rb lib/rubygems/installer.rb
+index 967543c2d1..6fd3399dd4 100644
+--- ruby-2.4.1/lib/rubygems/installer.rb
++++ ruby-2.4.1/lib/rubygems/installer.rb
+@@ -697,6 +697,11 @@ def verify_gem_home(unpack = false) # :nodoc:
+       unpack or File.writable?(gem_home)
+   end
+ 
++  def verify_spec_name
++    return if spec.name =~ Gem::Specification::VALID_NAME_PATTERN
++    raise Gem::InstallError, "#{spec} has an invalid name"
++  end
++
+   ##
+   # Return the text for an application file.
+ 
+@@ -823,6 +828,8 @@ def pre_install_checks
+ 
+     ensure_loadable_spec
+ 
++    verify_spec_name
++
+     if options[:install_as_default]
+       Gem.ensure_default_gem_subdirectories gem_home
+     else
+diff --git lib/rubygems/remote_fetcher.rb lib/rubygems/remote_fetcher.rb
+index e6a13d4b8c..8f0cf0b402 100644
+--- ruby-2.4.1/lib/rubygems/remote_fetcher.rb
++++ ruby-2.4.1/lib/rubygems/remote_fetcher.rb
+@@ -110,7 +110,7 @@ def api_endpoint(uri)
+     else
+       target = res.target.to_s.strip
+ 
+-      if /\.#{Regexp.quote(host)}\z/ =~ target
++      if URI("http://" + target).host.end_with?(".#{host}")
+         return URI.parse "#{uri.scheme}://#{target}#{uri.path}"
+       end
+ 
+diff --git lib/rubygems/specification.rb lib/rubygems/specification.rb
+index 500f0af768..88e320c05a 100644
+--- ruby-2.4.1/lib/rubygems/specification.rb
++++ ruby-2.4.1/lib/rubygems/specification.rb
+@@ -108,6 +108,8 @@ class Gem::Specification < Gem::BasicSpecification
+ 
+   private_constant :LOAD_CACHE if defined? private_constant
+ 
++  VALID_NAME_PATTERN = /\A[a-zA-Z0-9\.\-\_]+\z/ # :nodoc:
++
+   # :startdoc:
+ 
+   ##
+@@ -2671,9 +2673,15 @@ def validate packaging = true
+       end
+     end
+ 
+-    unless String === name then
++    if !name.is_a?(String) then
+       raise Gem::InvalidSpecificationException,
+-            "invalid value for attribute name: \"#{name.inspect}\""
++            "invalid value for attribute name: \"#{name.inspect}\" must be a string"
++    elsif name !~ /[a-zA-Z]/ then
++      raise Gem::InvalidSpecificationException,
++            "invalid value for attribute name: #{name.dump} must include at least one letter"
++    elsif name !~ VALID_NAME_PATTERN then
++      raise Gem::InvalidSpecificationException,
++            "invalid value for attribute name: #{name.dump} can only include letters, numbers, dashes, and underscores"
+     end
+ 
+     if raw_require_paths.empty? then
+diff --git lib/rubygems/text.rb lib/rubygems/text.rb
+index 732f1b99f2..b944b62c27 100644
+--- ruby-2.4.1/lib/rubygems/text.rb
++++ ruby-2.4.1/lib/rubygems/text.rb
+@@ -6,13 +6,26 @@
+ 
+ module Gem::Text
+ 
++  ##
++  # Remove any non-printable characters and make the text suitable for
++  # printing.
++  def clean_text(text)
++    text.gsub(/[\000-\b\v-\f\016-\037\177]/, ".".freeze)
++  end
++
++  def truncate_text(text, description, max_length = 100_000)
++    raise ArgumentError, "max_length must be positive" unless max_length > 0
++    return text if text.size <= max_length
++    "Truncating #{description} to #{max_length.to_s.reverse.gsub(/...(?=.)/,'\&,').reverse} characters:\n" + text[0, max_length]
++  end
++
+   ##
+   # Wraps +text+ to +wrap+ characters and optionally indents by +indent+
+   # characters
+ 
+   def format_text(text, wrap, indent=0)
+     result = []
+-    work = text.dup
++    work = clean_text(text)
+ 
+     while work.length > wrap do
+       if work =~ /^(.{0,#{wrap}})[ \n]/ then
+diff --git test/rubygems/test_gem_commands_query_command.rb test/rubygems/test_gem_commands_query_command.rb
+index d8d682b136..469223c6c0 100644
+--- ruby-2.4.1/test/rubygems/test_gem_commands_query_command.rb
++++ ruby-2.4.1/test/rubygems/test_gem_commands_query_command.rb
+@@ -116,6 +116,86 @@ def test_execute_details
+     This is a lot of text. This is a lot of text. This is a lot of text.
+     This is a lot of text.
+ 
++pl (1)
++    Platform: i386-linux
++    Author: A User
++    Homepage: http://example.com
++
++    this is a summary
++    EOF
++
++    assert_equal expected, @ui.output
++    assert_equal '', @ui.error
++  end
++
++  def test_execute_details_cleans_text
++    spec_fetcher do |fetcher|
++      fetcher.spec 'a', 2 do |s|
++        s.summary = 'This is a lot of text. ' * 4
++        s.authors = ["Abraham Lincoln \x01", "\x02 Hirohito"]
++        s.homepage = "http://a.example.com/\x03"
++      end
++
++      fetcher.legacy_platform
++    end
++
++    @cmd.handle_options %w[-r -d]
++
++    use_ui @ui do
++      @cmd.execute
++    end
++
++    expected = <<-EOF
++
++*** REMOTE GEMS ***
++
++a (2)
++    Authors: Abraham Lincoln ., . Hirohito
++    Homepage: http://a.example.com/.
++
++    This is a lot of text. This is a lot of text. This is a lot of text.
++    This is a lot of text.
++
++pl (1)
++    Platform: i386-linux
++    Author: A User
++    Homepage: http://example.com
++
++    this is a summary
++    EOF
++
++    assert_equal expected, @ui.output
++    assert_equal '', @ui.error
++  end
++
++  def test_execute_details_truncates_summary
++    spec_fetcher do |fetcher|
++      fetcher.spec 'a', 2 do |s|
++        s.summary = 'This is a lot of text. ' * 10_000
++        s.authors = ["Abraham Lincoln \x01", "\x02 Hirohito"]
++        s.homepage = "http://a.example.com/\x03"
++      end
++
++      fetcher.legacy_platform
++    end
++
++    @cmd.handle_options %w[-r -d]
++
++    use_ui @ui do
++      @cmd.execute
++    end
++
++    expected = <<-EOF
++
++*** REMOTE GEMS ***
++
++a (2)
++    Authors: Abraham Lincoln ., . Hirohito
++    Homepage: http://a.example.com/.
++
++    Truncating the summary for a-2 to 100,000 characters:
++#{"    This is a lot of text. This is a lot of text. This is a lot of text.\n" * 1449}    This is a lot of te
++
+ pl (1)
+     Platform: i386-linux
+     Author: A User
+diff --git test/rubygems/test_gem_installer.rb test/rubygems/test_gem_installer.rb
+index 882981d344..dd049214fb 100644
+--- ruby-2.4.1/test/rubygems/test_gem_installer.rb
++++ ruby-2.4.1/test/rubygems/test_gem_installer.rb
+@@ -1448,6 +1448,26 @@ def test_pre_install_checks_wrong_rubygems_version
+     end
+   end
+ 
++  def test_pre_install_checks_malicious_name
++    spec = util_spec '../malicious', '1'
++    def spec.full_name # so the spec is buildable
++      "malicious-1"
++    end
++    def spec.validate; end
++
++    util_build_gem spec
++
++    gem = File.join(@gemhome, 'cache', spec.file_name)
++
++    use_ui @ui do
++      @installer = Gem::Installer.at gem
++      e = assert_raises Gem::InstallError do
++        @installer.pre_install_checks
++      end
++      assert_equal '#<Gem::Specification name=../malicious version=1> has an invalid name', e.message
++    end
++  end
++
+   def test_shebang
+     util_make_exec @spec, "#!/usr/bin/ruby"
+ 
+diff --git test/rubygems/test_gem_remote_fetcher.rb test/rubygems/test_gem_remote_fetcher.rb
+index cb994462cd..fbb7d89019 100644
+--- ruby-2.4.1/test/rubygems/test_gem_remote_fetcher.rb
++++ ruby-2.4.1/test/rubygems/test_gem_remote_fetcher.rb
+@@ -241,6 +241,21 @@ def test_api_endpoint_ignores_trans_domain_values_that_end_with_original
+     dns.verify
+   end
+ 
++  def test_api_endpoint_ignores_trans_domain_values_that_end_with_original_in_path
++    uri = URI.parse "http://example.com/foo"
++    target = MiniTest::Mock.new
++    target.expect :target, "evil.com/a.example.com"
++
++    dns = MiniTest::Mock.new
++    dns.expect :getresource, target, [String, Object]
++
++    fetch = Gem::RemoteFetcher.new nil, dns
++    assert_equal URI.parse("http://example.com/foo"), fetch.api_endpoint(uri)
++
++    target.verify
++    dns.verify
++  end
++
+   def test_api_endpoint_timeout_warning
+     uri = URI.parse "http://gems.example.com/foo"
+ 
+diff --git test/rubygems/test_gem_specification.rb test/rubygems/test_gem_specification.rb
+index d43289d745..0fcc11e78f 100644
+--- ruby-2.4.1/test/rubygems/test_gem_specification.rb
++++ ruby-2.4.1/test/rubygems/test_gem_specification.rb
+@@ -2985,7 +2985,37 @@ def test_validate_name
+       @a1.validate
+     end
+ 
+-    assert_equal 'invalid value for attribute name: ":json"', e.message
++    assert_equal 'invalid value for attribute name: ":json" must be a string', e.message
++
++    @a1.name = []
++    e = assert_raises Gem::InvalidSpecificationException do
++      @a1.validate
++    end
++    assert_equal "invalid value for attribute name: \"[]\" must be a string", e.message
++
++    @a1.name = ""
++    e = assert_raises Gem::InvalidSpecificationException do
++      @a1.validate
++    end
++    assert_equal "invalid value for attribute name: \"\" must include at least one letter", e.message
++
++    @a1.name = "12345"
++    e = assert_raises Gem::InvalidSpecificationException do
++      @a1.validate
++    end
++    assert_equal "invalid value for attribute name: \"12345\" must include at least one letter", e.message
++
++    @a1.name = "../malicious"
++    e = assert_raises Gem::InvalidSpecificationException do
++      @a1.validate
++    end
++    assert_equal "invalid value for attribute name: \"../malicious\" can only include letters, numbers, dashes, and underscores", e.message
++
++    @a1.name = "\ba\t"
++    e = assert_raises Gem::InvalidSpecificationException do
++      @a1.validate
++    end
++    assert_equal "invalid value for attribute name: \"\\ba\\t\" can only include letters, numbers, dashes, and underscores", e.message
+   end
+ 
+   def test_validate_non_nil
+diff --git test/rubygems/test_gem_text.rb test/rubygems/test_gem_text.rb
+index a6e22e04da..04f3f605e8 100644
+--- ruby-2.4.1/test/rubygems/test_gem_text.rb
++++ ruby-2.4.1/test/rubygems/test_gem_text.rb
+@@ -36,6 +36,10 @@ def test_format_text_trailing # for two spaces after .
+     assert_equal expected, format_text(text, 78)
+   end
+ 
++  def test_format_removes_nonprintable_characters
++    assert_equal "text with weird .. stuff .", format_text("text with weird \x1b\x02 stuff \x7f", 40)
++  end
++
+   def test_min3
+     assert_equal 1, min3(1, 1, 1)
+     assert_equal 1, min3(1, 1, 2)
+@@ -74,4 +78,11 @@ def test_levenshtein_distance_replace
+     assert_equal 7, levenshtein_distance("xxxxxxx", "ZenTest")
+     assert_equal 7, levenshtein_distance("zentest", "xxxxxxx")
+   end
++
++  def test_truncate_text
++    assert_equal "abc", truncate_text("abc", "desc")
++    assert_equal "Truncating desc to 2 characters:\nab", truncate_text("abc", "desc", 2)
++    s = "ab" * 500_001
++    assert_equal "Truncating desc to 1,000,000 characters:\n#{s[0, 1_000_000]}", truncate_text(s, "desc", 1_000_000)
++  end
+ end
diff --git a/gnu/packages/patches/wmfire-update-for-new-gdk-versions.patch b/gnu/packages/patches/wmfire-update-for-new-gdk-versions.patch
index 51d6c3e791..fd12ba4ce1 100644
--- a/gnu/packages/patches/wmfire-update-for-new-gdk-versions.patch
+++ b/gnu/packages/patches/wmfire-update-for-new-gdk-versions.patch
@@ -1,4 +1,4 @@
-This patch comes from Debian and was modified by Kei Kebreau <kei@openmailbox.org>.
+This patch comes from Debian and was modified by Kei Kebreau <kkebreau@posteo.net>.
 Link: https://anonscm.debian.org/cgit/pkg-wmaker/wmfire.git/plain/debian/patches/gdk_updates.patch?h=debian/1.2.4-2&id=a272234fc5eecdbfc469adb12133196bc62f3059
 
 Description: Update for newer versions of GDK.
diff --git a/gnu/packages/patches/wxwidgets-fix-windowGTK.patch b/gnu/packages/patches/wxwidgets-fix-windowGTK.patch
deleted file mode 100644
index 1255835d01..0000000000
--- a/gnu/packages/patches/wxwidgets-fix-windowGTK.patch
+++ /dev/null
@@ -1,18 +0,0 @@
-This patch allow Filezilla client to resize window.
-The patch was adapted from upstream source repository:
-'<http://trac.wxwidgets.org/changeset/4793e5b0a4e189e492287305859b278fed780080/git-wxWidgets>'
-
---- a/src/gtk/toplevel.cpp	2014-10-06 16:33:44.000000000 -0500
-+++ b/src/gtk/toplevel.cpp	2017-02-16 21:33:27.779907810 -0600
-@@ -1216,8 +1216,9 @@
-     int hints_mask = GDK_HINT_MIN_SIZE | GDK_HINT_MAX_SIZE;
-     hints.min_width = 1;
-     hints.min_height = 1;
--    hints.max_width = INT_MAX;
--    hints.max_height = INT_MAX;
-+    // using INT_MAX for size will lead to integer overflow with HiDPI scaling
-+    hints.max_width = INT_MAX / 16;
-+    hints.max_height = INT_MAX / 16;    
-     const int decorSize_x = m_decorSize.left + m_decorSize.right;
-     const int decorSize_y = m_decorSize.top + m_decorSize.bottom;
-     if (minSize.x > decorSize_x)