Index: GraphicsMagick-1.2.5/coders/pict.c
===================================================================
--- GraphicsMagick-1.2.5.orig/coders/pict.c	2017-05-15 14:19:54.013092466 +0200
+++ GraphicsMagick-1.2.5/coders/pict.c	2017-05-15 14:24:36.785977807 +0200
@@ -66,23 +66,27 @@
   pixmap.plane_bytes=ReadBlobMSBLong(image); \
   pixmap.table=ReadBlobMSBLong(image); \
   pixmap.reserved=ReadBlobMSBLong(image); \
-  if (pixmap.bits_per_pixel <= 0 || pixmap.bits_per_pixel > 32 || \
-      pixmap.component_count <= 0 || pixmap.component_count > 4 || \
-      pixmap.component_size <= 0) \
-    ThrowReaderException(CorruptImageError,ImproperImageHeader,image); \
 }
 
+#define ValidatePixmap(pixmap) \
+  (!(EOFBlob(image) ||                                                 \
+     pixmap.bits_per_pixel <= 0 || pixmap.bits_per_pixel > 32 ||       \
+     pixmap.component_count <= 0 || pixmap.component_count > 4 ||      \
+     pixmap.component_size <= 0))
+
 #define ReadRectangle(rectangle) \
 { \
   rectangle.top=ReadBlobMSBShort(image); \
   rectangle.left=ReadBlobMSBShort(image); \
   rectangle.bottom=ReadBlobMSBShort(image); \
   rectangle.right=ReadBlobMSBShort(image); \
-  if (rectangle.top > rectangle.bottom || \
-      rectangle.left > rectangle.right) \
-    ThrowReaderException(CorruptImageError,ImproperImageHeader,image); \
 }
 
+#define ValidateRectangle(rectangle) \
+  (!(EOFBlob(image) || \
+     (rectangle.top > rectangle.bottom || rectangle.left > rectangle.right)))
+
+
 typedef struct _PICTCode
 {
   char
@@ -733,6 +737,13 @@ static size_t EncodeImage(Image *image,c
 %
 %
 */
+#define ThrowPICTReaderException(code_,reason_,image_) \
+{ \
+  if (clone_info) \
+    DestroyImageInfo(clone_info); \
+  ThrowReaderException(code_,reason_,image_); \
+}
+
 static Image *ReadPICTImage(const ImageInfo *image_info,
   ExceptionInfo *exception)
 {
@@ -742,6 +753,9 @@ static Image *ReadPICTImage(const ImageI
   Image
     *image;
 
+  ImageInfo
+    *clone_info = (ImageInfo *) NULL;
+
   IndexPacket
     index;
 
@@ -790,7 +804,7 @@ static Image *ReadPICTImage(const ImageI
   image=AllocateImage(image_info);
   status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
   if (status == False)
-    ThrowReaderException(FileOpenError,UnableToOpenFile,image);
+    ThrowPICTReaderException(FileOpenError,UnableToOpenFile,image);
   pixmap.bits_per_pixel=0;
   pixmap.component_count=0;
   /*
@@ -802,26 +816,28 @@ static Image *ReadPICTImage(const ImageI
     (void) ReadBlobByte(image);  /* skip header */
   (void) ReadBlobMSBShort(image);  /* skip picture size */
   ReadRectangle(frame);
+  if (!ValidateRectangle(frame))
+    ThrowPICTReaderException(CorruptImageError,ImproperImageHeader,image);
   while ((c=ReadBlobByte(image)) == 0);
   if (c != 0x11)
-    ThrowReaderException(CorruptImageError,ImproperImageHeader,image);
+    ThrowPICTReaderException(CorruptImageError,ImproperImageHeader,image);
   version=ReadBlobByte(image);
   if (version == 2)
     {
       c=ReadBlobByte(image);
       if (c != 0xff)
-        ThrowReaderException(CorruptImageError,ImproperImageHeader,image);
+        ThrowPICTReaderException(CorruptImageError,ImproperImageHeader,image);
     }
   else
     if (version != 1)
-      ThrowReaderException(CorruptImageError,ImproperImageHeader,image);
+      ThrowPICTReaderException(CorruptImageError,ImproperImageHeader,image);
   /*
     Validate dimensions
   */
   if ((frame.left < 0) || (frame.right < 0) || (frame.top < 0) || (frame.bottom < 0) ||
       (frame.left >= frame.right) || (frame.top >= frame.bottom))
     {
-      ThrowReaderException(CorruptImageError,ImproperImageHeader,image);
+      ThrowPICTReaderException(CorruptImageError,ImproperImageHeader,image);
     }
 
   /*
@@ -873,6 +889,8 @@ static Image *ReadPICTImage(const ImageI
                 break;
               }
             ReadRectangle(frame);
+            if (!ValidateRectangle(frame))
+              ThrowPICTReaderException(CorruptImageError,ImproperImageHeader,image);
             if ((frame.left & 0x8000) || (frame.top & 0x8000))
               break;
             image->columns=frame.right-frame.left;
@@ -904,11 +922,15 @@ static Image *ReadPICTImage(const ImageI
                 break;
               }
             if (pattern != 1)
-              ThrowReaderException(CorruptImageError,UnknownPatternType,
+              ThrowPICTReaderException(CorruptImageError,UnknownPatternType,
                 image);
             length=ReadBlobMSBShort(image);
             ReadRectangle(frame);
+            if (!ValidateRectangle(frame))
+              ThrowPICTReaderException(CorruptImageError,ImproperImageHeader,image);
             ReadPixmap(pixmap);
+            if (!ValidatePixmap(pixmap))
+              ThrowPICTReaderException(CorruptImageError,ImproperImageHeader,image);
             (void) ReadBlobMSBLong(image);
             flags=ReadBlobMSBShort(image);
             length=ReadBlobMSBShort(image);
@@ -1009,6 +1031,8 @@ static Image *ReadPICTImage(const ImageI
                 (void) ReadBlobMSBShort(image);
               }
             ReadRectangle(frame);
+            if (!ValidateRectangle(frame))
+              ThrowPICTReaderException(CorruptImageError,ImproperImageHeader,image);
             /*
               Initialize tile image.
             */
@@ -1021,6 +1045,11 @@ static Image *ReadPICTImage(const ImageI
             if ((code == 0x9a) || (code == 0x9b) || (bytes_per_line & 0x8000))
               {
                 ReadPixmap(pixmap);
+                if (!ValidatePixmap(pixmap))
+                {
+                  DestroyImage(tile_image);
+                  ThrowPICTReaderException(CorruptImageError,ImproperImageHeader,image);
+                }
                 tile_image->matte=pixmap.component_count == 4;
               }
             if ((code != 0x9a) && (code != 0x9b))
@@ -1038,7 +1067,7 @@ static Image *ReadPICTImage(const ImageI
                 if (!AllocateImageColormap(tile_image,tile_image->colors))
                   {
                     DestroyImage(tile_image);
-                    ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,image)
+                    ThrowPICTReaderException(ResourceLimitError,MemoryAllocationFailed,image)
                   }
                 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
                   "Allocated tile image colormap with %u colors",tile_image->colors);
@@ -1071,7 +1100,17 @@ static Image *ReadPICTImage(const ImageI
                   }
               }
             ReadRectangle(source);
+            if (!ValidateRectangle(source))
+            {
+              DestroyImage(tile_image);
+              ThrowPICTReaderException(CorruptImageError,ImproperImageHeader,image);
+            }
             ReadRectangle(destination);
+            if (!ValidateRectangle(destination))
+            {
+              DestroyImage(tile_image);
+              ThrowPICTReaderException(CorruptImageError,ImproperImageHeader,image);
+            }
             (void) ReadBlobMSBShort(image);
             if ((code == 0x91) || (code == 0x99) || (code == 0x9b))
               {
@@ -1091,7 +1130,7 @@ static Image *ReadPICTImage(const ImageI
             if (pixels == (unsigned char *) NULL)
               {
                 DestroyImage(tile_image);
-                ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,image)
+                ThrowPICTReaderException(ResourceLimitError,MemoryAllocationFailed,image)
               }
             /*
               Convert PICT tile image to pixel packets.
@@ -1161,8 +1200,8 @@ static Image *ReadPICTImage(const ImageI
               if ((code == 0x9a) || (code == 0x9b) ||
                   (bytes_per_line & 0x8000))
                 (void) CompositeImage(image,CopyCompositeOp,tile_image,
-                   destination.left,destination.top);
-                DestroyImage(tile_image);
+                                      destination.left,destination.top);
+            DestroyImage(tile_image);
             if (destination.bottom != (long) image->rows)
               if (!MagickMonitor(LoadImageText,destination.bottom,image->rows,&image->exception))
                 break;
@@ -1198,7 +1237,7 @@ static Image *ReadPICTImage(const ImageI
                 if (length == 0)
                   break;
                 if (SetImageProfile(image,"ICM",info,length) == MagickFail)
-                  ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,image);
+                  ThrowPICTReaderException(ResourceLimitError,MemoryAllocationFailed,image);
                 MagickFreeMemory(info);
                 break;
               }
@@ -1207,7 +1246,7 @@ static Image *ReadPICTImage(const ImageI
                 if (length == 0)
                   break;
                 if (SetImageProfile(image,"IPTC",info,length) == MagickFail)
-                  ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,image);
+                  ThrowPICTReaderException(ResourceLimitError,MemoryAllocationFailed,image);
                 MagickFreeMemory(info);
                 break;
               }
@@ -1250,9 +1289,6 @@ static Image *ReadPICTImage(const ImageI
         Image
           *tile_image;
 
-        ImageInfo
-          *clone_info;
-
         /*
           Embedded JPEG.
         */
@@ -1267,20 +1303,31 @@ static Image *ReadPICTImage(const ImageI
             ThrowReaderTemporaryFileException(clone_info->filename);
           }
         length=ReadBlobMSBLong(image);
-        for (i=0; i < 6; i++)
-          (void) ReadBlobMSBLong(image);
-        ReadRectangle(frame);
-        for (i=0; i < 122; i++)
-          (void) ReadBlobByte(image);
-        for (i=0; i < (long) (length-154); i++)
-        {
-          c=ReadBlobByte(image);
-          (void) fputc(c,file);
-        }
+        if (length > 154)
+          {
+            for (i=0; i < 6; i++)
+              (void) ReadBlobMSBLong(image);
+            ReadRectangle(frame);
+            if (!ValidateRectangle(frame))
+              {
+                (void) fclose(file);
+                ThrowPICTReaderException(CorruptImageError,ImproperImageHeader,image);
+              }
+            for (i=0; i < 122; i++)
+              if (ReadBlobByte(image) == EOF)
+                break;
+            for (i=0; i < (long) (length-154); i++)
+              {
+                if ((c=ReadBlobByte(image)) == EOF)
+                  break;
+                (void) fputc(c,file);
+              }
+          }
         (void) fclose(file);
         tile_image=ReadImage(clone_info,exception);
         (void) LiberateTemporaryFile(clone_info->filename);
         DestroyImageInfo(clone_info);
+        clone_info=(ImageInfo *) NULL;
         if (tile_image == (Image *) NULL)
           continue;
         FormatString(geometry,"%lux%lu",Max(image->columns,tile_image->columns),
@@ -1302,7 +1349,8 @@ static Image *ReadPICTImage(const ImageI
         */
         length=ReadBlobMSBShort(image);
         for (i=0; i < (long) length; i++)
-          (void) ReadBlobByte(image);
+          if (ReadBlobByte(image) == EOF)
+            break;
         continue;
       }
     if ((code >= 0x100) && (code <= 0x7fff))
@@ -1312,7 +1360,8 @@ static Image *ReadPICTImage(const ImageI
         */
         length=(code >> 7) & 0xff;
         for (i=0; i < (long) length; i++)
-          (void) ReadBlobByte(image);
+          if (ReadBlobByte(image) == EOF)
+            break;
         continue;
       }
   }
@@ -1422,6 +1471,17 @@ ModuleExport void UnregisterPICTImage(vo
 %
 %
 */
+#define LiberatePICTAllocations()               \
+  {                                             \
+    MagickFreeMemory(buffer);                   \
+    MagickFreeMemory(packed_scanline);          \
+    MagickFreeMemory(scanline);                 \
+  }
+#define ThrowPICTWriterException(code_,reason_,image_)  \
+  {                                                     \
+    LiberatePICTAllocations();                          \
+    ThrowWriterException(code_,reason_,image_);         \
+  }
 static unsigned int WritePICTImage(const ImageInfo *image_info,Image *image)
 {
 #define MaxCount  128U
@@ -1472,19 +1532,19 @@ static unsigned int WritePICTImage(const
     x;
 
   size_t
-    count;
+    bytes_per_line,
+    count,
+    row_bytes;
 
   unsigned char
-    *buffer,
-    *packed_scanline,
-    *scanline;
+    *buffer = (unsigned char *) NULL,
+    *packed_scanline = (unsigned char *) NULL,
+    *scanline = (unsigned char *) NULL;
 
   unsigned int
     status;
 
   unsigned long
-    bytes_per_line,
-    row_bytes,
     storage_class;
 
   unsigned short
@@ -1499,10 +1559,10 @@ static unsigned int WritePICTImage(const
   assert(image != (Image *) NULL);
   assert(image->signature == MagickSignature);
   if ((image->columns > 65535L) || (image->rows > 65535L))
-    ThrowWriterException(ImageError,WidthOrHeightExceedsLimit,image);
+    ThrowPICTWriterException(ImageError,WidthOrHeightExceedsLimit,image);
   status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
   if (status == False)
-    ThrowWriterException(FileOpenError,UnableToOpenFile,image);
+    ThrowPICTWriterException(FileOpenError,UnableToOpenFile,image);
   (void) TransformColorspace(image,RGBColorspace);
   /*
     Initialize image info.
@@ -1558,7 +1618,7 @@ static unsigned int WritePICTImage(const
   if ((buffer == (unsigned char *) NULL) ||
       (packed_scanline == (unsigned char *) NULL) ||
       (scanline == (unsigned char *) NULL))
-    ThrowWriterException(ResourceLimitError,MemoryAllocationFailed,image);
+    ThrowPICTWriterException(ResourceLimitError,MemoryAllocationFailed,image);
   /*
     Write header, header size, size bounding box, version, and reserved.
   */
@@ -1638,6 +1698,7 @@ static unsigned int WritePICTImage(const
       jpeg_image=CloneImage(image,0,0,True,&image->exception);
       if (jpeg_image == (Image *) NULL)
         {
+          LiberatePICTAllocations();
           CloseBlob(image);
           return (False);
         }
@@ -1648,7 +1709,11 @@ static unsigned int WritePICTImage(const
         &image->exception);
       DestroyImage(jpeg_image);
       if (blob == (unsigned char *) NULL)
-        return(False);
+        {
+          LiberatePICTAllocations();
+          CloseBlob(image);
+          return(False);
+        }
       (void) WriteBlobMSBShort(image,PictJPEGOp);
       (void) WriteBlobMSBLong(image,length+154);
       (void) WriteBlobMSBShort(image,0x0000);
@@ -1711,7 +1776,7 @@ static unsigned int WritePICTImage(const
       (void) WriteBlobMSBShort(image,PictPixmapOp);
       (void) WriteBlobMSBLong(image,(unsigned long) base_address);
     }
-  (void) WriteBlobMSBShort(image,row_bytes | 0x8000);
+  (void) WriteBlobMSBShort(image,(unsigned short) (row_bytes | 0x8000));
   (void) WriteBlobMSBShort(image,bounds.top);
   (void) WriteBlobMSBShort(image,bounds.left);
   (void) WriteBlobMSBShort(image,bounds.bottom);
@@ -1828,7 +1893,7 @@ static unsigned int WritePICTImage(const
               *opacity++=ScaleQuantumToChar(MaxRGB-p->opacity);
             p++;
           }
-          count+=EncodeImage(image,scanline,bytes_per_line,packed_scanline);
+          count+=EncodeImage(image,scanline,bytes_per_line & 0x7FFF,packed_scanline);
           if (QuantumTick(y,image->rows))
             if (!MagickMonitor(SaveImageText,y,image->rows,&image->exception))
               break;
