File GraphicsMagick-bmp.c-update.patch of Package GraphicsMagick.openSUSE_Leap_42.3_Update

--- GraphicsMagick-1.3.25/coders/bmp.c	2019-01-03 10:18:28.613510939 +0100
+++ GraphicsMagick-1.3.29/coders/bmp.c	2018-04-29 20:01:26.000000000 +0200
@@ -1,5 +1,5 @@
 /*
-% Copyright (C) 2003 - 2015 GraphicsMagick Group
+% Copyright (C) 2003 - 2018 GraphicsMagick Group
 % Copyright (C) 2002 ImageMagick Studio
 % Copyright 1991-1999 E. I. du Pont de Nemours and Company
 %
@@ -92,33 +92,37 @@
 */
 typedef struct _BMPInfo
 {
-  unsigned long
-    file_size,
+  size_t
+    file_size,  /* 0 or size of file in bytes */
+    image_size; /* bytes_per_line*image->rows or uint32_t from file */
+
+  magick_uint32_t
     ba_offset,
-    offset_bits,
-    size;
+    offset_bits,/* Starting position of image data in bytes */
+    size;       /* Header size 12 = v2, 12-64 OS/2 v2, 40 = v3, 108 = v4, 124 = v5 */
 
-  long
-    width,
-    height;
+  magick_int32_t
+    width,      /* BMP width */
+    height;     /* BMP height (negative means bottom-up) */
 
-  unsigned short
+  magick_uint16_t
     planes,
     bits_per_pixel;
 
-  unsigned long
+  magick_uint32_t
     compression,
-    image_size,
     x_pixels,
     y_pixels,
     number_colors,
+    colors_important;
+
+  magick_uint32_t
     red_mask,
     green_mask,
     blue_mask,
-    alpha_mask,
-    colors_important;
+    alpha_mask;
 
-  long
+  magick_int32_t
     colorspace;
 
   PrimaryInfo
@@ -168,19 +172,22 @@ static unsigned int
 %    o pixels:  The address of a byte (8 bits) array of pixel data created by
 %      the decoding process.
 %
+%    o pixels_size: The size of the allocated buffer array.
 %
 */
 static MagickPassFail DecodeImage(Image *image,const unsigned long compression,
-  unsigned char *pixels)
+                                  unsigned char *pixels, const size_t pixels_size)
 {
-  long
-    byte,
-    count,
+  unsigned long
+    x,
     y;
 
-  register long
-    i,
-    x;
+  unsigned int
+    i;
+
+  int
+    byte,
+    count;
 
   register unsigned char
     *q;
@@ -190,133 +197,175 @@ static MagickPassFail DecodeImage(Image
 
   assert(image != (Image *) NULL);
   assert(pixels != (unsigned char *) NULL);
-  (void) LogMagickEvent(CoderEvent,GetMagickModule(),"  Decoding RLE pixels");
-  (void) memset(pixels,0,image->columns*image->rows);
+  if (image->logging)
+    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+                          "  Decoding RLE compressed pixels to"
+                          " %" MAGICK_SIZE_T_F "u bytes",
+                          image->rows*image->columns);
+
+  (void) memset(pixels,0,pixels_size);
   byte=0;
   x=0;
   q=pixels;
-  end=pixels + (size_t) image->columns*image->rows;
-  for (y=0; y < (long) image->rows; )
-  {
-    if (q < pixels || q  >= end)
-      break;
-    count=ReadBlobByte(image);
-    if (count == EOF)
-      return MagickFail;
-    if (count != 0)
-      {
-        count=Min(count, end - q);
-        /*
-          Encoded mode.
-        */
-        byte=ReadBlobByte(image);
-        if (byte == EOF)
-          return MagickFail;
-        if (compression == BI_RLE8)
-          {
-            for ( i=count; i != 0; --i )
+  end=pixels + pixels_size;
+  /*
+    Decompress sufficient data to support the number of pixels (or
+    rows) in the image and then return.
+
+    Do not wait to read the final EOL and EOI markers (if not yet
+    encountered) since we always read this marker just before we
+    return.
+  */
+  for (y=0; y < image->rows; )
+    {
+      if (q < pixels || q >= end)
+        {
+          if (image->logging)
+            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+                                  "  Decode buffer full (y=%lu, "
+                                  "pixels_size=%" MAGICK_SIZE_T_F "u, "
+                                  "pixels=%p, q=%p, end=%p)",
+                                  y, (MAGICK_SIZE_T) pixels_size, pixels, q, end);
+          break;
+        }
+      count=ReadBlobByte(image);
+      if (count == EOF)
+        return MagickFail;
+      if (count > 0)
+        {
+          count=Min(count, end - q);
+          /*
+            Encoded mode.
+          */
+          byte=ReadBlobByte(image);
+          if (byte == EOF)
+            return MagickFail;
+          if (compression == BI_RLE8)
+            {
+              for ( i=count; i != 0; --i )
+                {
+                  *q++=(unsigned char) byte;
+                }
+            }
+          else
+            {
+              for ( i=0; i < (unsigned int) count; i++ )
+                {
+                  *q++=(unsigned char)
+                    ((i & 0x01) ? (byte & 0x0f) : ((byte >> 4) & 0x0f));
+                }
+            }
+          x+=count;
+        }
+      else
+        {
+          /*
+            Escape mode.
+          */
+          count=ReadBlobByte(image);
+          if (count == EOF)
+            return MagickFail;
+          if (count == 0x01)
+            {
+              if (image->logging)
+                (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+                                      "  RLE Escape code encountered");
+              goto rle_decode_done;
+            }
+          switch (count)
+            {
+            case 0x00:
               {
-                *q++=(unsigned char) byte;
+                /*
+                  End of line.
+                */
+                x=0;
+                y++;
+                q=pixels+y*image->columns;
+                break;
               }
-          }
-        else
-          {
-            for ( i=0; i < count; i++ )
+            case 0x02:
               {
-                *q++=(unsigned char)
-                  ((i & 0x01) ? (byte & 0x0f) : ((byte >> 4) & 0x0f));
+                /*
+                  Delta mode.
+                */
+                byte=ReadBlobByte(image);
+                if (byte == EOF)
+                  return MagickFail;
+                x+=byte;
+                byte=ReadBlobByte(image);
+                if (byte == EOF)
+                  return MagickFail;
+                y+=byte;
+                q=pixels+y*image->columns+x;
+                break;
               }
-          }
-        x+=count;
-      }
-    else
-      {
-        /*
-          Escape mode.
-        */
-        count=ReadBlobByte(image);
-        if (count == EOF)
-          return MagickFail;
-        if (count == 0x01)
-          return(MagickPass);
-        switch ((int) count)
-        {
-          case 0x00:
-          {
-            /*
-              End of line.
-            */
-            x=0;
-            y++;
-            q=pixels+y*image->columns;
-            break;
-          }
-          case 0x02:
-          {
-            /*
-              Delta mode.
-            */
-            byte=ReadBlobByte(image);
-            if (byte == EOF)
-              return MagickFail;
-            x+=byte;
-            byte=ReadBlobByte(image);
-            if (byte == EOF)
-              return MagickFail;
-            y+=byte;
-            q=pixels+y*image->columns+x;
-            break;
-          }
-          default:
-          {
-            /*
-              Absolute mode.
-            */
-    	    count=Min(count, end - q);
-            if (compression == BI_RLE8)
-              for (i=count; i != 0; --i)
-                {
-                  byte=ReadBlobByte(image);
-                  if (byte == EOF)
-                    return MagickFail;
-                  *q++=byte;
-                }
-            else
-              for (i=0; i < count; i++)
+            default:
               {
-                if ((i & 0x01) == 0)
+                /*
+                  Absolute mode.
+                */
+                count=Min(count, end - q);
+                if (count < 0)
+                  return MagickFail;
+                if (compression == BI_RLE8)
+                  for (i=count; i != 0; --i)
+                    {
+                      byte=ReadBlobByte(image);
+                      if (byte == EOF)
+                        return MagickFail;
+                      *q++=byte;
+                    }
+                else
+                  for (i=0; i < (unsigned int) count; i++)
+                    {
+                      if ((i & 0x01) == 0)
+                        {
+                          byte=ReadBlobByte(image);
+                          if (byte == EOF)
+                            return MagickFail;
+                        }
+                      *q++=(unsigned char)
+                        ((i & 0x01) ? (byte & 0x0f) : ((byte >> 4) & 0x0f));
+                    }
+                x+=count;
+                /*
+                  Read pad byte.
+                */
+                if (compression == BI_RLE8)
                   {
-                    byte=ReadBlobByte(image);
-                    if (byte == EOF)
-                      return MagickFail;
+                    if (count & 0x01)
+                      if (ReadBlobByte(image) == EOF)
+                        return MagickFail;
                   }
-                *q++=(unsigned char)
-                  ((i & 0x01) ? (byte & 0x0f) : ((byte >> 4) & 0x0f));
-              }
-            x+=count;
-            /*
-              Read pad byte.
-            */
-            if (compression == BI_RLE8)
-              {
-                if (count & 0x01)
-                  (void) ReadBlobByte(image);
+                else
+                  if (((count & 0x03) == 1) || ((count & 0x03) == 2))
+                    if (ReadBlobByte(image) == EOF)
+                      return MagickFail;
+                break;
               }
-            else
-              if (((count & 0x03) == 1) || ((count & 0x03) == 2))
-                (void) ReadBlobByte(image);
-            break;
-          }
+            }
         }
-      }
-    if (QuantumTick(y,image->rows))
-      if (!MagickMonitorFormatted(y,image->rows,&image->exception,
-                                  LoadImageText,image->filename,
-				  image->columns,image->rows))
-        break;
-  }
+      if (QuantumTick(y,image->rows))
+        if (!MagickMonitorFormatted(y,image->rows,&image->exception,
+                                    LoadImageText,image->filename,
+                                    image->columns,image->rows))
+          break;
+    }
   (void) ReadBlobByte(image);  /* end of line */
   (void) ReadBlobByte(image);
+ rle_decode_done:
+  if (image->logging)
+    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+                          "  Decoded %" MAGICK_SIZE_T_F "u bytes",
+                          (MAGICK_SIZE_T) (q-pixels));
+  if ((MAGICK_SIZE_T) (q-pixels) < pixels_size)
+    {
+      if (image->logging)
+        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+                              "  RLE decoded output is truncated");
+      return MagickFail;
+    }
   return(MagickPass);
 }
 
@@ -403,7 +452,7 @@ static size_t EncodeImage(Image *image,c
     if (QuantumTick(y,image->rows))
       if (!MagickMonitorFormatted(y,image->rows,&image->exception,
                                   SaveImageText,image->filename,
-				  image->columns,image->rows))
+                                  image->columns,image->rows))
         break;
   }
   /*
@@ -510,7 +559,7 @@ static Image *ReadBMPImage(const ImageIn
   long
     y;
 
-  unsigned long
+  magick_uint32_t
     blue,
     green,
     opacity,
@@ -532,8 +581,10 @@ static Image *ReadBMPImage(const ImageIn
     *p;
 
   size_t
+    bytes_per_line,
     count,
-    length;
+    length,
+    pixels_size;
 
   unsigned char
     *bmp_colormap,
@@ -543,11 +594,10 @@ static Image *ReadBMPImage(const ImageIn
   unsigned int
     status;
 
-  unsigned long
-    bytes_per_line;
-
   magick_off_t
-    file_size;
+    file_remaining,
+    file_size,
+    offset;
 
   /*
     Open image file.
@@ -570,6 +620,7 @@ static Image *ReadBMPImage(const ImageIn
   (void) memset(&bmp_info,0,sizeof(BMPInfo));
   bmp_info.ba_offset=0;
   start_position=0;
+  magick[0]=magick[1]=0;
   count=ReadBlob(image,2,(char *) magick);
   do
   {
@@ -584,8 +635,10 @@ static Image *ReadBMPImage(const ImageIn
     /*
       Verify BMP identifier.
     */
+    /* if (bmp_info.ba_offset == 0) */ /* FIXME: Investigate. Start position needs to always advance! */
     start_position=TellBlob(image)-2;
     bmp_info.ba_offset=0;
+     /* "BA" is OS/2 bitmap array file */
     while (LocaleNCompare((char *) magick,"BA",2) == 0)
     {
       bmp_info.file_size=ReadBlobLSBLong(image);
@@ -594,29 +647,49 @@ static Image *ReadBMPImage(const ImageIn
       if ((count=ReadBlob(image,2,(char *) magick)) != 2)
         break;
     }
-    if (logging)
+    if (logging && count == 2)
       (void) LogMagickEvent(CoderEvent,GetMagickModule(),"  Magick: %c%c",
         magick[0],magick[1]);
-    if ((count != 2) || ((LocaleNCompare((char *) magick,"BM",2) != 0) &&
-        (LocaleNCompare((char *) magick,"CI",2) != 0)))
+    if ((count != 2) || /* Found "BA" header from above above */
+        ((LocaleNCompare((char *) magick,"BM",2) != 0) && /* "BM" is Windows or OS/2 file. */
+         (LocaleNCompare((char *) magick,"CI",2) != 0)))  /* "CI" is OS/2 Color Icon */
       ThrowBMPReaderException(CorruptImageError,ImproperImageHeader,image);
-    bmp_info.file_size=ReadBlobLSBLong(image);
-    (void) ReadBlobLSBLong(image);
-    bmp_info.offset_bits=ReadBlobLSBLong(image);
-    bmp_info.size=ReadBlobLSBLong(image);
+    bmp_info.file_size=ReadBlobLSBLong(image); /* File size in bytes */
+    if (logging)
+      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+                            "  File size: Claimed=%" MAGICK_SIZE_T_F "u, Actual=%"
+                            MAGICK_OFF_F "d",
+                            (MAGICK_SIZE_T) bmp_info.file_size, file_size);
+    (void) ReadBlobLSBLong(image); /* Reserved */
+    bmp_info.offset_bits=ReadBlobLSBLong(image); /* Bit map offset from start of file */
+    bmp_info.size=ReadBlobLSBLong(image);  /* BMP Header size */
     if (logging)
       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
-        "  BMP size: %lu, File size: %" MAGICK_OFF_F "u",
-        bmp_info.size, GetBlobSize(image));
+                            "  Header size: %u\n"
+                            "    Offset bits: %u\n"
+                            "    Image data offset: %u",
+                            bmp_info.size,
+                            bmp_info.offset_bits,
+                            bmp_info.ba_offset);
+
+    if ((bmp_info.file_size != 0) && ((magick_off_t) bmp_info.file_size > file_size))
+      ThrowBMPReaderException(CorruptImageError,ImproperImageHeader,image);
+    if ((bmp_info.size != 12) && (bmp_info.size != 40) && (bmp_info.size != 108)
+        && (bmp_info.size != 124) &&
+        (!(bmp_info.size >= 12 && bmp_info.size <= 64)))
+      ThrowBMPReaderException(CorruptImageError,ImproperImageHeader,image);
+    if (bmp_info.offset_bits < bmp_info.size)
+      ThrowBMPReaderException(CorruptImageError,ImproperImageHeader,image);
+
     if (bmp_info.size == 12)
       {
         /*
           Windows 2.X or OS/2 BMP image file.
         */
-        bmp_info.width=(magick_int16_t) ReadBlobLSBShort(image);
-        bmp_info.height=(magick_int16_t) ReadBlobLSBShort(image);
-        bmp_info.planes=ReadBlobLSBShort(image);
-        bmp_info.bits_per_pixel=ReadBlobLSBShort(image);
+        bmp_info.width=(magick_int16_t) ReadBlobLSBShort(image); /* Width */
+        bmp_info.height=(magick_int16_t) ReadBlobLSBShort(image); /* Height */
+        bmp_info.planes=ReadBlobLSBShort(image); /* # of color planes */
+        bmp_info.bits_per_pixel=ReadBlobLSBShort(image); /* Bits per pixel */
         bmp_info.x_pixels=0;
         bmp_info.y_pixels=0;
         bmp_info.number_colors=0;
@@ -628,11 +701,11 @@ static Image *ReadBMPImage(const ImageIn
             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
               "  Format: Windows 2.X or OS/2 Bitmap");
             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
-              "  Geometry: %ldx%ld",bmp_info.width,bmp_info.height);
+              "  Geometry: %dx%d",bmp_info.width,bmp_info.height);
             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
-              "  Planes: %d",bmp_info.planes);
+              "  Planes: %u",bmp_info.planes);
             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
-              "  Bits per pixel: %d",bmp_info.bits_per_pixel);
+              "  Bits per pixel: %u",bmp_info.bits_per_pixel);
           }
       }
     else
@@ -652,18 +725,16 @@ static Image *ReadBMPImage(const ImageIn
           origin in the upper-left corner.  The meaning of negative values
           is not defined for width.
         */
-        bmp_info.width=(magick_int32_t) ReadBlobLSBLong(image);
-        bmp_info.height=(magick_int32_t) ReadBlobLSBLong(image);
-        bmp_info.planes=ReadBlobLSBShort(image);
-        bmp_info.bits_per_pixel=ReadBlobLSBShort(image);
-        bmp_info.compression=ReadBlobLSBLong(image);
-        bmp_info.image_size=ReadBlobLSBLong(image);
-        bmp_info.x_pixels=ReadBlobLSBLong(image);
-        bmp_info.y_pixels=ReadBlobLSBLong(image);
-        bmp_info.number_colors=ReadBlobLSBLong(image);
-        if (bmp_info.number_colors > GetBlobSize(image))
-          ThrowReaderException(CorruptImageError,InsufficientImageDataInFile,image);
-        bmp_info.colors_important=ReadBlobLSBLong(image);
+        bmp_info.width=(magick_int32_t) ReadBlobLSBLong(image); /* Width */
+        bmp_info.height=(magick_int32_t) ReadBlobLSBLong(image); /* Height */
+        bmp_info.planes=ReadBlobLSBShort(image); /* # of color planes */
+        bmp_info.bits_per_pixel=ReadBlobLSBShort(image); /* Bits per pixel (1/4/8/16/24/32) */
+        bmp_info.compression=ReadBlobLSBLong(image); /* Compression method */
+        bmp_info.image_size=ReadBlobLSBLong(image); /* Bitmap size (bytes) */
+        bmp_info.x_pixels=ReadBlobLSBLong(image); /* Horizontal resolution (pixels/meter) */
+        bmp_info.y_pixels=ReadBlobLSBLong(image); /* Vertical resolution (pixels/meter) */
+        bmp_info.number_colors=ReadBlobLSBLong(image); /* Number of colors */
+        bmp_info.colors_important=ReadBlobLSBLong(image); /* Minimum important colors */
         profile_data=0;
         profile_size=0;
         if (logging)
@@ -671,11 +742,11 @@ static Image *ReadBMPImage(const ImageIn
             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
               "  Format: MS Windows bitmap 3.X");
             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
-              "  Geometry: %ldx%ld",bmp_info.width,bmp_info.height);
+              "  Geometry: %dx%d",bmp_info.width,bmp_info.height);
             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
-              "  Planes: %d",bmp_info.planes);
+              "  Planes: %u",bmp_info.planes);
             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
-              "  Bits per pixel: %d",bmp_info.bits_per_pixel);
+              "  Bits per pixel: %u",bmp_info.bits_per_pixel);
             switch ((int) bmp_info.compression)
             {
               case BI_RGB:
@@ -720,13 +791,13 @@ static Image *ReadBMPImage(const ImageIn
               default:
               {
                 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
-                  "  Compression: UNKNOWN (%lu)",bmp_info.compression);
+                  "  Compression: UNKNOWN (%u)",bmp_info.compression);
               }
             }
             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
-              "  Number of colors: %lu",bmp_info.number_colors);
+              "  Number of colors: %u",bmp_info.number_colors);
             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
-              "  Important colors: %lu",bmp_info.colors_important);
+              "  Important colors: %u",bmp_info.colors_important);
           }
 
         bmp_info.red_mask=ReadBlobLSBLong(image);
@@ -742,7 +813,7 @@ static Image *ReadBMPImage(const ImageIn
               Read color management information.
             */
             bmp_info.alpha_mask=ReadBlobLSBLong(image);
-            bmp_info.colorspace=(long) ReadBlobLSBLong(image);
+            bmp_info.colorspace=(magick_int32_t) ReadBlobLSBLong(image);
             /*
               Decode 2^30 fixed point formatted CIE primaries.
             */
@@ -767,6 +838,7 @@ static Image *ReadBMPImage(const ImageIn
 
             sum=bmp_info.red_primary.x+bmp_info.red_primary.y+
               bmp_info.red_primary.z;
+            sum=Max(MagickEpsilon,sum);
             bmp_info.red_primary.x/=sum;
             bmp_info.red_primary.y/=sum;
             image->chromaticity.red_primary.x=bmp_info.red_primary.x;
@@ -774,6 +846,7 @@ static Image *ReadBMPImage(const ImageIn
 
             sum=bmp_info.green_primary.x+bmp_info.green_primary.y+
               bmp_info.green_primary.z;
+            sum=Max(MagickEpsilon,sum);
             bmp_info.green_primary.x/=sum;
             bmp_info.green_primary.y/=sum;
             image->chromaticity.green_primary.x=bmp_info.green_primary.x;
@@ -781,6 +854,7 @@ static Image *ReadBMPImage(const ImageIn
 
             sum=bmp_info.blue_primary.x+bmp_info.blue_primary.y+
               bmp_info.blue_primary.z;
+            sum=Max(MagickEpsilon,sum);
             bmp_info.blue_primary.x/=sum;
             bmp_info.blue_primary.y/=sum;
             image->chromaticity.blue_primary.x=bmp_info.blue_primary.x;
@@ -832,29 +906,34 @@ static Image *ReadBMPImage(const ImageIn
             }
             profile_data=ReadBlobLSBLong(image);
             profile_size=ReadBlobLSBLong(image);
-	    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
-				  "  Profile: size %lu data %lu",
-				  profile_size,profile_data);
+            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+                                  "  Profile: size %lu data %lu",
+                                  profile_size,profile_data);
             (void) ReadBlobLSBLong(image);  /* Reserved byte */
           }
       }
 
     if (logging)
       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
-                            "File size: Claimed=%lu, Actual=%"
+                            "  File size: Claimed=%" MAGICK_SIZE_T_F "u, Actual=%"
                             MAGICK_OFF_F "d",
-                            bmp_info.file_size, file_size);
-    if ((magick_off_t) bmp_info.file_size > file_size)
+                            (MAGICK_SIZE_T) bmp_info.file_size, file_size);
+    /*
+      It seems that some BMPs claim a file size two bytes larger than
+      they actually are so allow some slop before warning about file
+      size.
+    */
+    if ((magick_off_t) bmp_info.file_size > file_size+2)
       {
         ThrowException(exception,CorruptImageWarning,
                        LengthAndFilesizeDoNotMatch,image->filename);
       }
     if (logging && (magick_off_t) bmp_info.file_size < file_size)
       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
-                              "Discarding all data beyond bmp_info.file_size");
+                              "  Discarding all data beyond bmp_info.file_size");
     if (bmp_info.width <= 0)
       ThrowBMPReaderException(CorruptImageError,NegativeOrZeroImageSize,image);
-    if (bmp_info.height == 0)
+    if ((bmp_info.height) == 0 || (bmp_info.height < -2147483647))
       ThrowBMPReaderException(CorruptImageError,NegativeOrZeroImageSize,image);
     if ((bmp_info.height < 0) && (bmp_info.compression !=0))
       ThrowBMPReaderException(CorruptImageError,CompressionNotValid,image);
@@ -933,10 +1012,16 @@ static Image *ReadBMPImage(const ImageIn
           packet_size=3;
         else
           packet_size=4;
-        if (SeekBlob(image,start_position+14+bmp_info.size,SEEK_SET) == -1)
-	  ThrowBMPReaderException(CorruptImageError,ImproperImageHeader,image);
+        offset=start_position+14+bmp_info.size;
+        if (logging)
+          (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+                                "Seek offset %" MAGICK_OFF_F "d",
+                                (magick_off_t) offset);
+        if ((offset < start_position) ||
+            (SeekBlob(image,offset,SEEK_SET) != (magick_off_t) offset))
+          ThrowBMPReaderException(CorruptImageError,ImproperImageHeader,image);
         if (ReadBlob(image,packet_size*image->colors,(char *) bmp_colormap)
-            != packet_size*image->colors)
+            != (size_t) packet_size*image->colors)
           ThrowBMPReaderException(CorruptImageError,UnexpectedEndOfFile,image);
         p=bmp_colormap;
         for (i=0; i < (long) image->colors; i++)
@@ -962,20 +1047,34 @@ static Image *ReadBMPImage(const ImageIn
     /*
       Read image data.
     */
-    if (SeekBlob(image,start_position+bmp_info.offset_bits,SEEK_SET) == -1)
-      ThrowBMPReaderException(CorruptImageError,ImproperImageHeader,image)
+    if (logging)
+      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+                            "start_position %" MAGICK_OFF_F "d,"
+                            " bmp_info.offset_bits %" MAGICK_OFF_F "d,"
+                            " bmp_info.ba_offset %" MAGICK_OFF_F "d" ,
+                            (magick_off_t) start_position,
+                            (magick_off_t) bmp_info.offset_bits,
+                            (magick_off_t) bmp_info.ba_offset);
+    offset=start_position+bmp_info.offset_bits;
+    if (logging)
+      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+                            "Seek offset %" MAGICK_OFF_F "d",
+                            (magick_off_t) offset);
+    if ((offset < start_position) ||
+        (SeekBlob(image,offset,SEEK_SET) != (magick_off_t) offset))
+      ThrowBMPReaderException(CorruptImageError,ImproperImageHeader,image);
     if (bmp_info.compression == BI_RLE4)
       bmp_info.bits_per_pixel<<=1;
     bytes_per_line=4*((image->columns*bmp_info.bits_per_pixel+31)/32);
     if (logging)
       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
-                            "Bytes per line: %" MAGICK_SIZE_T_F "u",
+                            "  Bytes per line: %" MAGICK_SIZE_T_F "u",
                             (MAGICK_SIZE_T) bytes_per_line);
 
-    length=bytes_per_line*image->rows;
+    length=MagickArraySize(bytes_per_line,image->rows);
     if (logging)
       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
-                            "Expected total raster length: %" MAGICK_SIZE_T_F "u",
+                            "  Expected total raster length: %" MAGICK_SIZE_T_F "u",
                             (MAGICK_SIZE_T) length);
     if (length/image->rows != bytes_per_line)
       ThrowBMPReaderException(ResourceLimitError,MemoryAllocationFailed,image);
@@ -990,7 +1089,8 @@ static Image *ReadBMPImage(const ImageIn
         /*
           Not compressed.
         */
-        if (length >= (size_t) file_size)
+        file_remaining=file_size-TellBlob(image);
+        if (file_remaining < (magick_off_t) length)
           ThrowBMPReaderException(CorruptImageError,InsufficientImageDataInFile,
                                   image);
       }
@@ -998,14 +1098,15 @@ static Image *ReadBMPImage(const ImageIn
              (bmp_info.compression == BI_RLE8))
       {
         /* RLE Compressed.  Assume a maximum compression ratio. */
-        if ((file_size == 0) || (((double) length/file_size) > 254.0))
+        file_remaining=file_size-TellBlob(image);
+        if ((file_remaining <= 0) || (((double) length/file_remaining) > 254.0))
           ThrowBMPReaderException(CorruptImageError,InsufficientImageDataInFile,
                                   image);
       }
 
-    pixels=MagickAllocateArray(unsigned char *,
-                               Max(bytes_per_line,image->columns+1),
-                               image->rows);
+    pixels_size=MagickArraySize(Max(bytes_per_line,image->columns+1),
+                                image->rows);
+    pixels=MagickAllocateMemory(unsigned char *, pixels_size);
     if (pixels == (unsigned char *) NULL)
       ThrowBMPReaderException(ResourceLimitError,MemoryAllocationFailed,image);
     if ((bmp_info.compression == BI_RGB) ||
@@ -1015,14 +1116,18 @@ static Image *ReadBMPImage(const ImageIn
           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
             "  Reading pixels (%" MAGICK_SIZE_T_F "u bytes)",
                                 (MAGICK_SIZE_T) length);
-        (void) ReadBlob(image,length,(char *) pixels);
+        if (ReadBlob(image,length,(char *) pixels) != (size_t) length)
+          ThrowBMPReaderException(CorruptImageError,UnexpectedEndOfFile,image);
       }
     else
       {
         /*
           Convert run-length encoded raster pixels.
+
+          DecodeImage() normally decompresses to rows*columns bytes of data.
         */
-        status=DecodeImage(image,bmp_info.compression,pixels);
+        status=DecodeImage(image,bmp_info.compression,pixels,
+                           image->rows*image->columns);
         if (status == MagickFail)
           ThrowBMPReaderException(CorruptImageError,UnableToRunlengthDecodeImage,
             image);
@@ -1038,23 +1143,23 @@ static Image *ReadBMPImage(const ImageIn
     */
     if (bmp_info.compression == BI_RGB)
       {
-        bmp_info.alpha_mask=(image->matte ? 0xff000000L : 0);
-        bmp_info.red_mask=0x00ff0000L;
-        bmp_info.green_mask=0x0000ff00L;
-        bmp_info.blue_mask=0x000000ffL;
+        bmp_info.alpha_mask=(image->matte ? 0xff000000U : 0U);
+        bmp_info.red_mask=0x00ff0000U;
+        bmp_info.green_mask=0x0000ff00U;
+        bmp_info.blue_mask=0x000000ffU;
         if (bmp_info.bits_per_pixel == 16)
           {
             /*
               RGB555.
             */
-            bmp_info.red_mask=0x00007c00L;
-            bmp_info.green_mask=0x000003e0L;
-            bmp_info.blue_mask=0x0000001fL;
+            bmp_info.red_mask=0x00007c00U;
+            bmp_info.green_mask=0x000003e0U;
+            bmp_info.blue_mask=0x0000001fU;
           }
       }
     if ((bmp_info.bits_per_pixel == 16) || (bmp_info.bits_per_pixel == 32))
       {
-        register unsigned long
+        register magick_uint32_t
           sample;
 
         /*
@@ -1062,32 +1167,32 @@ static Image *ReadBMPImage(const ImageIn
         */
         (void) memset(&shift,0,sizeof(PixelPacket));
         (void) memset(&quantum_bits,0,sizeof(PixelPacket));
-        if (bmp_info.red_mask != 0)
-          while ((shift.red < 32U) && (((bmp_info.red_mask << shift.red) & 0x80000000UL) == 0))
+        if (bmp_info.red_mask != 0U)
+          while ((shift.red < 32U) && (((bmp_info.red_mask << shift.red) & 0x80000000U) == 0))
             shift.red++;
         if (bmp_info.green_mask != 0)
-          while ((shift.green < 32U) && (((bmp_info.green_mask << shift.green) & 0x80000000UL) == 0))
+          while ((shift.green < 32U) && (((bmp_info.green_mask << shift.green) & 0x80000000U) == 0))
             shift.green++;
         if (bmp_info.blue_mask != 0)
-          while ((shift.blue < 32U) && (((bmp_info.blue_mask << shift.blue) & 0x80000000UL) == 0))
+          while ((shift.blue < 32U) && (((bmp_info.blue_mask << shift.blue) & 0x80000000U) == 0))
             shift.blue++;
         if (bmp_info.alpha_mask != 0)
-          while ((shift.opacity < 32U) && (((bmp_info.alpha_mask << shift.opacity) & 0x80000000UL) == 0))
+          while ((shift.opacity < 32U) && (((bmp_info.alpha_mask << shift.opacity) & 0x80000000U) == 0))
             shift.opacity++;
         sample=shift.red;
-        while ((sample < 32U) && (((bmp_info.red_mask << sample) & 0x80000000UL) != 0))
+        while ((sample < 32U) && (((bmp_info.red_mask << sample) & 0x80000000U) != 0))
           sample++;
         quantum_bits.red=(Quantum) (sample-shift.red);
         sample=shift.green;
-        while ((sample < 32U) && (((bmp_info.green_mask << sample) & 0x80000000UL) != 0))
+        while ((sample < 32U) && (((bmp_info.green_mask << sample) & 0x80000000U) != 0))
           sample++;
         quantum_bits.green=(Quantum) (sample-shift.green);
         sample=shift.blue;
-        while ((sample < 32U) && (((bmp_info.blue_mask << sample) & 0x80000000UL) != 0))
+        while ((sample < 32U) && (((bmp_info.blue_mask << sample) & 0x80000000U) != 0))
           sample++;
         quantum_bits.blue=(Quantum) (sample-shift.blue);
         sample=shift.opacity;
-        while ((sample < 32U) && (((bmp_info.alpha_mask << sample) & 0x80000000UL) != 0))
+        while ((sample < 32U) && (((bmp_info.alpha_mask << sample) & 0x80000000U) != 0))
           sample++;
         quantum_bits.opacity=(Quantum) (sample-shift.opacity);
       }
@@ -1115,7 +1220,7 @@ static Image *ReadBMPImage(const ImageIn
                 status=MagickMonitorFormatted(image->rows-y-1,image->rows,
                                               exception,LoadImageText,
                                               image->filename,
-					      image->columns,image->rows);
+                                              image->columns,image->rows);
                 if (status == False)
                   break;
               }
@@ -1144,7 +1249,7 @@ static Image *ReadBMPImage(const ImageIn
                 status=MagickMonitorFormatted(image->rows-y-1,image->rows,
                                               exception,LoadImageText,
                                               image->filename,
-					      image->columns,image->rows);
+                                              image->columns,image->rows);
                 if (status == False)
                   break;
               }
@@ -1176,7 +1281,7 @@ static Image *ReadBMPImage(const ImageIn
                 status=MagickMonitorFormatted(image->rows-y-1,image->rows,
                                               exception,LoadImageText,
                                               image->filename,
-					      image->columns,image->rows);
+                                              image->columns,image->rows);
                 if (status == False)
                   break;
               }
@@ -1185,7 +1290,7 @@ static Image *ReadBMPImage(const ImageIn
       }
       case 16:
       {
-        unsigned long
+        magick_uint32_t
           pixel;
 
         /*
@@ -1235,7 +1340,7 @@ static Image *ReadBMPImage(const ImageIn
                 status=MagickMonitorFormatted(image->rows-y-1,image->rows,
                                               exception,LoadImageText,
                                               image->filename,
-					      image->columns,image->rows);
+                                              image->columns,image->rows);
                 if (status == False)
                   break;
               }
@@ -1269,7 +1374,7 @@ static Image *ReadBMPImage(const ImageIn
                 status=MagickMonitorFormatted(image->rows-y-1,image->rows,
                                               exception,LoadImageText,
                                               image->filename,
-					      image->columns,image->rows);
+                                              image->columns,image->rows);
                 if (status == False)
                   break;
               }
@@ -1287,7 +1392,7 @@ static Image *ReadBMPImage(const ImageIn
         bytes_per_line=4*(image->columns);
         for (y=(long) image->rows-1; y >= 0; y--)
         {
-          unsigned long
+          magick_uint32_t
             pixel;
 
           p=pixels+(image->rows-y-1)*bytes_per_line;
@@ -1296,10 +1401,10 @@ static Image *ReadBMPImage(const ImageIn
             break;
           for (x=0; x < (long) image->columns; x++)
           {
-            pixel =(*p++);
-            pixel|=(*p++ << 8);
-            pixel|=(*p++ << 16);
-            pixel|=(unsigned long) (*p++ << 24);
+            pixel =((magick_uint32_t) *p++);
+            pixel|=((magick_uint32_t) *p++ << 8);
+            pixel|=((magick_uint32_t) *p++ << 16);
+            pixel|=((magick_uint32_t) *p++ << 24);
             red=((pixel & bmp_info.red_mask) << shift.red) >> 16;
             if (quantum_bits.red == 8)
               red|=(red >> 8);
@@ -1329,7 +1434,7 @@ static Image *ReadBMPImage(const ImageIn
                 status=MagickMonitorFormatted(image->rows-y-1,image->rows,
                                               exception,LoadImageText,
                                               image->filename,
-					      image->columns,image->rows);
+                                              image->columns,image->rows);
                 if (status == False)
                   break;
               }
@@ -1360,8 +1465,8 @@ static Image *ReadBMPImage(const ImageIn
             DestroyImageList(image);
             return((Image *) NULL);
           }
-	DestroyBlob(flipped_image);
-	flipped_image->blob=ReferenceBlob(image->blob);
+        DestroyBlob(flipped_image);
+        flipped_image->blob=ReferenceBlob(image->blob);
         ReplaceImageInList(&image,flipped_image);
       }
     /*
@@ -1371,10 +1476,20 @@ static Image *ReadBMPImage(const ImageIn
       if (image->scene >= (image_info->subimage+image_info->subrange-1))
         break;
     *magick='\0';
-    if (bmp_info.ba_offset != 0)
-      if (SeekBlob(image,bmp_info.ba_offset,SEEK_SET) == -1)
-        ThrowBMPReaderException(CorruptImageError,ImproperImageHeader,image)
-    (void) ReadBlob(image,2,(char *) magick);
+    file_remaining=file_size-TellBlob(image);
+    if (file_remaining == 0)
+      break;
+    offset=bmp_info.ba_offset;
+    if (logging)
+      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+                            "Seek offset %" MAGICK_OFF_F "d",
+                            (magick_off_t) offset);
+    if (offset > 0)
+      if ((offset < TellBlob(image)) ||
+          (SeekBlob(image,offset,SEEK_SET) != (magick_off_t) offset))
+      ThrowBMPReaderException(CorruptImageError,ImproperImageHeader,image);
+    if (ReadBlob(image,2,(char *) magick) != (size_t) 2)
+      break;
     if (IsBMP(magick,2))
       {
         /*
@@ -1559,6 +1674,9 @@ static unsigned int WriteBMPImage(const
   size_t
     color_profile_length=0;
 
+  size_t
+    image_list_length;
+
   /*
     Open output image file.
   */
@@ -1566,6 +1684,7 @@ static unsigned int WriteBMPImage(const
   assert(image_info->signature == MagickSignature);
   assert(image != (Image *) NULL);
   assert(image->signature == MagickSignature);
+  image_list_length=GetImageListLength(image);
   logging=LogMagickEvent(CoderEvent,GetMagickModule(),"enter");
   status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
   if (status == False)
@@ -1594,7 +1713,7 @@ static unsigned int WriteBMPImage(const
     bmp_info.file_size=14+12;
     if (type > 2)
       bmp_info.file_size+=28;
-    bmp_info.offset_bits=bmp_info.file_size;
+    bmp_info.offset_bits=(magick_uint32_t) bmp_info.file_size;
     bmp_info.compression=BI_RGB;
     if ((image->storage_class != DirectClass) && (image->colors > 256))
       (void) SetImageType(image,TrueColorType);
@@ -1618,12 +1737,12 @@ static unsigned int WriteBMPImage(const
             (void) SetImageType(image,TrueColorType);
           else
             {
-              bmp_info.file_size+=3*(1 << bmp_info.bits_per_pixel);
-              bmp_info.offset_bits+=3*(1 << bmp_info.bits_per_pixel);
+              bmp_info.file_size+=3U*(1U << bmp_info.bits_per_pixel);
+              bmp_info.offset_bits+=3U*(1U << bmp_info.bits_per_pixel);
               if (type > 2)
                 {
-                  bmp_info.file_size+=(1 << bmp_info.bits_per_pixel);
-                  bmp_info.offset_bits+=(1 << bmp_info.bits_per_pixel);
+                  bmp_info.file_size+=(size_t) (1U << bmp_info.bits_per_pixel);
+                  bmp_info.offset_bits+=(1U << bmp_info.bits_per_pixel);
                 }
             }
       }
@@ -1671,25 +1790,22 @@ static unsigned int WriteBMPImage(const
     */
     if (type == 2)
       {
-	bmp_info.width=(magick_int16_t) image->columns;
-	bmp_info.height=(magick_int16_t) image->rows;
+        bmp_info.width=(magick_int16_t) image->columns;
+        bmp_info.height=(magick_int16_t) image->rows;
       }
     else
       {
-	bmp_info.width=(magick_int32_t) image->columns;
-	bmp_info.height=(magick_int32_t) image->rows;
+        bmp_info.width=(magick_int32_t) image->columns;
+        bmp_info.height=(magick_int32_t) image->rows;
       }
     if (((unsigned long) bmp_info.width != image->columns) ||
-	((unsigned long) bmp_info.height != image->rows))
+        ((unsigned long) bmp_info.height != image->rows))
       {
-	ThrowWriterException(CoderError,ImageColumnOrRowSizeIsNotSupported,image);
+        ThrowWriterException(CoderError,ImageColumnOrRowSizeIsNotSupported,image);
       }
 
-    if ((image->columns != (signed int) image->columns) ||
-        (image->rows != (signed int) image->rows))
-      ThrowWriterException(ImageError,WidthOrHeightExceedsLimit,image);
     bmp_info.planes=1;
-    bmp_info.image_size=(unsigned long) bytes_per_line*image->rows;
+    bmp_info.image_size=MagickArraySize(bytes_per_line,image->rows);
     bmp_info.file_size+=bmp_info.image_size;
     bmp_info.x_pixels=75*39;
     bmp_info.y_pixels=75*39;
@@ -1738,7 +1854,7 @@ static unsigned int WriteBMPImage(const
                 if (QuantumTick(y,image->rows))
                   if (!MagickMonitorFormatted(y,image->rows,&image->exception,
                                               SaveImageText,image->filename,
-					      image->columns,image->rows))
+                                              image->columns,image->rows))
                     break;
             }
           break;
@@ -1769,7 +1885,7 @@ static unsigned int WriteBMPImage(const
            if (QuantumTick(y,image->rows))
              if (!MagickMonitorFormatted(y,image->rows,&image->exception,
                                          SaveImageText,image->filename,
-					 image->columns,image->rows))
+                                         image->columns,image->rows))
                break;
         }
         break;
@@ -1799,7 +1915,7 @@ static unsigned int WriteBMPImage(const
             if (QuantumTick(y,image->rows))
               if (!MagickMonitorFormatted(y,image->rows,&image->exception,
                                           SaveImageText,image->filename,
-					  image->columns,image->rows))
+                                          image->columns,image->rows))
                 break;
         }
         break;
@@ -1835,7 +1951,7 @@ static unsigned int WriteBMPImage(const
             if (QuantumTick(y,image->rows))
               if (!MagickMonitorFormatted(y,image->rows,&image->exception,
                                           SaveImageText,image->filename,
-					  image->columns,image->rows))
+                                          image->columns,image->rows))
                 break;
         }
         break;
@@ -1890,8 +2006,9 @@ static unsigned int WriteBMPImage(const
         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
           "   BMP bits_per_pixel=%d",bmp_info.bits_per_pixel);
        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
-          "   BMP file_size=%lu bytes",bmp_info.file_size);
-        switch ((int) bmp_info.compression)
+                             "   BMP file_size=%" MAGICK_SIZE_T_F "u bytes",
+                             (MAGICK_SIZE_T) bmp_info.file_size);
+        switch (bmp_info.compression)
         {
            case BI_RGB:
            {
@@ -1914,7 +2031,7 @@ static unsigned int WriteBMPImage(const
            default:
            {
              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
-               "   Compression=UNKNOWN (%lu)",bmp_info.compression);
+               "   Compression=UNKNOWN (%u)",bmp_info.compression);
              break;
            }
         }
@@ -1923,10 +2040,10 @@ static unsigned int WriteBMPImage(const
             "   Number_colors=unspecified");
         else
           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
-            "   Number_colors=%lu",bmp_info.number_colors);
+            "   Number_colors=%u",bmp_info.number_colors);
       }
     (void) WriteBlob(image,2,"BM");
-    (void) WriteBlobLSBLong(image,bmp_info.file_size);
+    (void) WriteBlobLSBLong(image,(magick_uint32_t) bmp_info.file_size);
     (void) WriteBlobLSBLong(image,bmp_info.ba_offset);  /* always 0 */
     (void) WriteBlobLSBLong(image,bmp_info.offset_bits);
     if (type == 2)
@@ -1951,7 +2068,7 @@ static unsigned int WriteBMPImage(const
         (void) WriteBlobLSBShort(image,bmp_info.planes);
         (void) WriteBlobLSBShort(image,bmp_info.bits_per_pixel);
         (void) WriteBlobLSBLong(image,bmp_info.compression);
-        (void) WriteBlobLSBLong(image,bmp_info.image_size);
+        (void) WriteBlobLSBLong(image,(magick_uint32_t) bmp_info.image_size);
         (void) WriteBlobLSBLong(image,bmp_info.x_pixels);
         (void) WriteBlobLSBLong(image,bmp_info.y_pixels);
         (void) WriteBlobLSBLong(image,bmp_info.number_colors);
@@ -2078,13 +2195,14 @@ static unsigned int WriteBMPImage(const
       }
     if (logging)
       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
-        "  Pixels:  %lu bytes",bmp_info.image_size);
+                            "  Pixels:  %" MAGICK_SIZE_T_F "u bytes",
+                            (MAGICK_SIZE_T) bmp_info.image_size);
     (void) WriteBlob(image,bmp_info.image_size,(char *) pixels);
     MagickFreeMemory(pixels);
     if (image->next == (Image *) NULL)
       break;
     image=SyncNextImageInList(image);
-    status=MagickMonitorFormatted(scene++,GetImageListLength(image),
+    status=MagickMonitorFormatted(scene++,image_list_length,
                                   &image->exception,SaveImagesText,
                                   image->filename);
     if (status == False)
openSUSE Build Service is sponsored by