]> granicus.if.org Git - imagemagick/commitdiff
...
authorCristy <urban-warrior@imagemagick.org>
Sat, 9 Jun 2018 15:14:31 +0000 (11:14 -0400)
committerCristy <urban-warrior@imagemagick.org>
Sat, 9 Jun 2018 15:14:31 +0000 (11:14 -0400)
ChangeLog
MagickCore/blob-private.h
MagickCore/blob.c
MagickCore/draw.c
coders/mat.c
coders/png.c
coders/wpg.c

index f63fdfd2a33d5f0dd56dc3c8d5a51f6b85caf578..8db1ba1c4d5ff2954700cc082e1ccc214c527d6c 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2018-06-06  7.0.7-39  <quetzlzacatenango@image...>
+  * Fixed numerous use of uninitialized values, integer overflow, memory
+    exceeded, and timeouts (credit to OSS Fuzz).
+
 2018-06-02  7.0.7-38 Cristy  <quetzlzacatenango@image...>
   * Release ImageMagick version 7.0.7-38, GIT revision 14409:01e395a73:20180602.
 
index 659e55c50a48f1bb341efb586c2318ffc82d7428..e203af1e949153cbbb3c26a2d7e9a419fb3ccb1c 100644 (file)
@@ -77,6 +77,7 @@ extern MagickExport float
 
 extern MagickExport int
   EOFBlob(const Image *),
+  ErrorBlob(const Image *),
   ReadBlobByte(Image *);
 
 extern MagickExport MagickBooleanType
index 9484541b5fbca9491ee0f98fd0457833be5b0dab..f5caebe512a43248cdb61d9976af924ca8e3767d 100644 (file)
@@ -126,6 +126,9 @@ struct _BlobInfo
     mapped,
     eof;
 
+  int
+    error;
+
   MagickOffsetType
     offset;
 
@@ -657,6 +660,7 @@ MagickExport MagickBooleanType CloseBlob(Image *image)
   blob_info->size=GetBlobSize(image);
   image->extent=blob_info->size;
   blob_info->eof=MagickFalse;
+  blob_info->error=0;
   blob_info->mode=UndefinedBlobMode;
   if (blob_info->exempt != MagickFalse)
     {
@@ -1002,6 +1006,7 @@ MagickExport void *DetachBlob(BlobInfo *blob_info)
   blob_info->length=0;
   blob_info->offset=0;
   blob_info->eof=MagickFalse;
+  blob_info->error=0;
   blob_info->exempt=MagickFalse;
   blob_info->type=UndefinedStream;
   blob_info->file_info.file=(FILE *) NULL;
@@ -1244,6 +1249,79 @@ MagickExport int EOFBlob(const Image *image)
 %                                                                             %
 %                                                                             %
 %                                                                             %
++  E r r o r B l o b                                                          %
+%                                                                             %
+%                                                                             %
+%                                                                             %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%  ErrorBlob() returns a non-zero value when an error has been detected reading
+%  from a blob or file.
+%
+%  The format of the ErrorBlob method is:
+%
+%      int ErrorBlob(const Image *image)
+%
+%  A description of each parameter follows:
+%
+%    o image: the image.
+%
+*/
+MagickExport int ErrorBlob(const Image *image)
+{
+  BlobInfo
+    *magick_restrict blob_info;
+
+  assert(image != (Image *) NULL);
+  assert(image->signature == MagickCoreSignature);
+  if (image->debug != MagickFalse)
+    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
+  assert(image->blob != (BlobInfo *) NULL);
+  assert(image->blob->type != UndefinedStream);
+  blob_info=image->blob;
+  switch (blob_info->type)
+  {
+    case UndefinedStream:
+    case StandardStream:
+      break;
+    case FileStream:
+    case PipeStream:
+    {
+      blob_info->error=ferror(blob_info->file_info.file);
+      break;
+    }
+    case ZipStream:
+    {
+#if defined(MAGICKCORE_ZLIB_DELEGATE)
+      (void) gzerror(blob_info->file_info.gzfile,&blob_info->error);
+#endif
+      break;
+    }
+    case BZipStream:
+    {
+#if defined(MAGICKCORE_BZLIB_DELEGATE)
+      (void) BZ2_bzerror(blob_info->file_info.bzfile,&blob_info->error);
+#endif
+      break;
+    }
+    case FifoStream:
+    {
+      blob_info->error=0;
+      break;
+    }
+    case BlobStream:
+      break;
+    case CustomStream:
+      break;
+  }
+  return(blob_info->error);
+}
+\f
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%                                                                             %
+%                                                                             %
+%                                                                             %
 %   F i l e T o B l o b                                                       %
 %                                                                             %
 %                                                                             %
@@ -3648,8 +3726,21 @@ MagickExport ssize_t ReadBlob(Image *image,const size_t length,void *data)
       {
         default:
         {
-          count=(ssize_t) gzread(blob_info->file_info.gzfile,q,
-            (unsigned int) length);
+          register ssize_t
+            i;
+
+          for (i=0; i < (ssize_t) length; i+=count)
+          {
+            count=(ssize_t) gzread(blob_info->file_info.gzfile,q+i,
+              (unsigned int) MagickMin(length-i,MagickMaxBufferExtent));
+            if (count <= 0)
+              {
+                count=0;
+                if (errno != EINTR)
+                  break;
+              }
+          }
+          count=i;
           break;
         }
         case 4:
@@ -3693,7 +3784,21 @@ MagickExport ssize_t ReadBlob(Image *image,const size_t length,void *data)
     case BZipStream:
     {
 #if defined(MAGICKCORE_BZLIB_DELEGATE)
-      count=(ssize_t) BZ2_bzread(blob_info->file_info.bzfile,q,(int) length);
+      register ssize_t
+        i;
+
+      for (i=0; i < (ssize_t) length; i+=count)
+      {
+        count=(ssize_t) BZ2_bzread(blob_info->file_info.bzfile,q+i,
+          (unsigned int) MagickMin(length-i,MagickMaxBufferExtent));
+        if (count <= 0)
+          {
+            count=0;
+            if (errno != EINTR)
+              break;
+          }
+      }
+      count=i;
 #endif
       break;
     }
@@ -5394,6 +5499,9 @@ MagickExport ssize_t WriteBlob(Image *image,const size_t length,
   register const unsigned char
     *p;
 
+  register unsigned char
+    *q;
+
   ssize_t
     count;
 
@@ -5407,6 +5515,7 @@ MagickExport ssize_t WriteBlob(Image *image,const size_t length,
   blob_info=image->blob;
   count=0;
   p=(const unsigned char *) data;
+  q=(unsigned char *) data;
   switch (blob_info->type)
   {
     case UndefinedStream:
@@ -5463,8 +5572,21 @@ MagickExport ssize_t WriteBlob(Image *image,const size_t length,
       {
         default:
         {
-          count=(ssize_t) gzwrite(blob_info->file_info.gzfile,(void *) data,
-            (unsigned int) length);
+          register ssize_t
+            i;
+
+          for (i=0; i < (ssize_t) length; i+=count)
+          {
+            count=(ssize_t) gzwrite(blob_info->file_info.gzfile,q+i,
+              (unsigned int) MagickMin(length-i,MagickMaxBufferExtent));
+            if (count <= 0)
+              {
+                count=0;
+                if (errno != EINTR)
+                  break;
+              }
+          }
+          count=i;
           break;
         }
         case 4:
@@ -5504,8 +5626,21 @@ MagickExport ssize_t WriteBlob(Image *image,const size_t length,
     case BZipStream:
     {
 #if defined(MAGICKCORE_BZLIB_DELEGATE)
-      count=(ssize_t) BZ2_bzwrite(blob_info->file_info.bzfile,(void *) data,
-        (int) length);
+      register ssize_t
+        i;
+
+      for (i=0; i < (ssize_t) length; i+=count)
+      {
+        count=(ssize_t) BZ2_bzwrite(blob_info->file_info.bzfile,q+i,
+          (int) MagickMin(length-i,MagickMaxBufferExtent));
+        if (count <= 0)
+          {
+            count=0;
+            if (errno != EINTR)
+              break;
+          }
+      }
+      count=i;
 #endif
       break;
     }
index 603f1b05238819e913b6f64bc4d5f92f372f6c35..970af134657687b3bb5832d60729e28516746d92 100644 (file)
@@ -2218,7 +2218,6 @@ static MagickBooleanType CheckPrimitiveExtent(MVGInfo *mvg_info,
   extent=(size_t) mvg_info->offset+pad+4096;
   if (extent <= *mvg_info->extent)
     return(MagickTrue);
-  primitive_info=(*mvg_info->primitive_info);
   primitive_info=AcquireQuantumMemory(extent,sizeof(*primitive_info));
   if (primitive_info == (PrimitiveInfo *) NULL)
     {
@@ -6588,6 +6587,7 @@ static size_t TracePath(MVGInfo *mvg_info,const char *path,
         TracePoint(q,point);
         mvg_info->offset+=q->coordinates;
         q+=q->coordinates;
+        primitive_info=(*mvg_info->primitive_info)+subpath_offset;
         primitive_info->coordinates=(size_t) (q-primitive_info);
         primitive_info->closed_subpath=MagickTrue;
         number_coordinates+=primitive_info->coordinates;
index b11c065db8737a9f7f5de59d66ba449a8e9e931b..9ee5e803909d025ac31586df259b2ab7fc014441 100644 (file)
@@ -98,20 +98,20 @@ typedef struct
   char identific[124];
   unsigned short Version;
   char EndianIndicator[2];
-  unsigned long DataType;
+  unsigned int DataType;
   unsigned int ObjectSize;
-  unsigned long unknown1;
-  unsigned long unknown2;
+  unsigned int unknown1;
+  unsigned int unknown2;
 
   unsigned short unknown5;
   unsigned char StructureFlag;
   unsigned char StructureClass;
-  unsigned long unknown3;
-  unsigned long unknown4;
-  unsigned long DimFlag;
+  unsigned int unknown3;
+  unsigned int unknown4;
+  unsigned int DimFlag;
 
-  unsigned long SizeX;
-  unsigned long SizeY;
+  unsigned int SizeX;
+  unsigned int SizeY;
   unsigned short Flag1;
   unsigned short NameFlag;
 }
@@ -1183,7 +1183,7 @@ RestoreMSCWarning
     image->colors = GetQuantumRange(image->depth);
     if (image->columns == 0 || image->rows == 0)
       goto MATLAB_KO;
-    if((unsigned long)ldblk*MATLAB_HDR.SizeY > MATLAB_HDR.ObjectSize)
+    if((unsigned int)ldblk*MATLAB_HDR.SizeY > MATLAB_HDR.ObjectSize)
       goto MATLAB_KO;
     /* Image is gray when no complex flag is set and 2D Matrix */
     if ((MATLAB_HDR.DimFlag == 8) &&
index 70219bf90558208acdcd4605fe00b798069844d8..33723484a3ffbe0dcf14679c190485a33fa80796 100644 (file)
@@ -1792,7 +1792,7 @@ Magick_png_read_raw_profile(png_struct *ping,Image *image,
   StringInfo
     *profile;
 
-  const unsigned char
+  static const unsigned char
     unhex[103]={0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,
                  0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,
                  0,0,0,0,0,0,0,0,0,1, 2,3,4,5,6,7,8,9,0,0,
index a058285abac40958161d5179d59ea3dc3fb6be52..de7dbd839fed001f9529a39c5ed2ce29245cfcb5 100644 (file)
@@ -792,7 +792,11 @@ static Image *ExtractPostscript(Image *image,const ImageInfo *image_info,
     goto FINISH;
 
   /* Copy postscript to temporary file */
-  (void) SeekBlob(image,PS_Offset,SEEK_SET);
+  if (SeekBlob(image,PS_Offset,SEEK_SET) != PS_Offset)
+    {
+      DestroyImageInfo(clone_info);
+      ThrowReaderException(CorruptImageError,"ImproperImageHeader");
+    }
   count=ReadBlob(image, 2*MagickPathExtent, magick);
   if (count < 1)
     {
@@ -800,7 +804,11 @@ static Image *ExtractPostscript(Image *image,const ImageInfo *image_info,
       ThrowReaderException(CorruptImageError,"ImproperImageHeader");
     }
 
-  (void) SeekBlob(image,PS_Offset,SEEK_SET);
+  if (SeekBlob(image,PS_Offset,SEEK_SET) != PS_Offset)
+    {
+      DestroyImageInfo(clone_info);
+      ThrowReaderException(CorruptImageError,"ImproperImageHeader");
+    }
   while (PS_Size-- > 0)
   {
     c=ReadBlobByte(image);
@@ -1092,7 +1100,8 @@ static Image *ReadWPGImage(const ImageInfo *image_info,
     case 1:     /* WPG level 1 */
       while(!EOFBlob(image)) /* object parser loop */
         {
-          (void) SeekBlob(image,Header.DataOffset,SEEK_SET);
+          if (SeekBlob(image,Header.DataOffset,SEEK_SET) != Header.DataOffset)
+            break;
           if(EOFBlob(image))
             break;
 
@@ -1324,8 +1333,9 @@ static Image *ReadWPGImage(const ImageInfo *image_info,
       StartWPG.PosSizePrecision = 0;
       while(!EOFBlob(image)) /* object parser loop */
         {
-          (void) SeekBlob(image,Header.DataOffset,SEEK_SET);
-          if(EOFBlob(image))
+          if (SeekBlob(image,Header.DataOffset,SEEK_SET) != Header.DataOffset)
+            break;
+          if (EOFBlob(image))
             break;
 
           Rec2.Class=(i=ReadBlobByte(image));