PAM: Fix buffer overflow when writing gray+alpha 1-bit/sample.
authorBob Friesenhahn <bfriesen@GraphicsMagick.org>
Wed, 06 Dec 2017 21:08:47 -0600
changeset 15290 f1c418ef0260
parent 15289 3cb8b4753e82
child 15291 5b8414c0d0c4
PAM: Fix buffer overflow when writing gray+alpha 1-bit/sample.
ChangeLog
VisualMagick/installer/inc/version.isx
coders/pnm.c
magick/version.h
www/Changelog.html
--- a/ChangeLog	Tue Dec 05 20:00:47 2017 -0600
+++ b/ChangeLog	Wed Dec 06 21:08:47 2017 -0600
@@ -1,3 +1,8 @@
+2017-12-06  Bob Friesenhahn  <bfriesen@simple.dallas.tx.us>
+
+	* coders/pnm.c (WritePNMImage): Fix SourceForge bug #525
+	"heap-buffer-overflow in MagickBitStreamMSBWrite".
+
 2017-12-05  Bob Friesenhahn  <bfriesen@simple.dallas.tx.us>
 
 	* coders/dcm.c (DCM_ReadElement): Eliminate huge memory allocation
--- a/VisualMagick/installer/inc/version.isx	Tue Dec 05 20:00:47 2017 -0600
+++ b/VisualMagick/installer/inc/version.isx	Wed Dec 06 21:08:47 2017 -0600
@@ -10,5 +10,5 @@
 
 #define public MagickPackageName "GraphicsMagick"
 #define public MagickPackageVersion "1.4"
-#define public MagickPackageVersionAddendum ".020171205"
-#define public MagickPackageReleaseDate "snapshot-20171205"
+#define public MagickPackageVersionAddendum ".020171206"
+#define public MagickPackageReleaseDate "snapshot-20171206"
--- a/coders/pnm.c	Tue Dec 05 20:00:47 2017 -0600
+++ b/coders/pnm.c	Wed Dec 06 21:08:47 2017 -0600
@@ -859,19 +859,18 @@
             sample_scale=MaxRGBDouble/sample_max;
             use_scaling=(MaxRGB != sample_max);
             bytes_per_row=0;
+
             if (1 == samples_per_pixel)
               {
                 if (1 == bits_per_sample)
                   {
                     /* PBM */
-                    bytes_per_row=((image->columns+7U) >> 3);
                     import_options.grayscale_miniswhite=MagickTrue;
                     quantum_type=GrayQuantum;
                   }
                 else
                   {
                     /* PGM & XV_332 */
-                    bytes_per_row=MagickArraySize(((bits_per_sample+7U)/8U),image->columns);
                     if ((XV_332_Format == format) && (image->storage_class == PseudoClass))
                       {
                         quantum_type=IndexQuantum;
@@ -882,31 +881,57 @@
                       }
                   }
               }
+            else if (2 == samples_per_pixel && image->matte)
+              {
+                quantum_type=GrayAlphaQuantum;
+              }
+            else if (3 == samples_per_pixel)
+              {
+                /* PPM */
+                quantum_type=RGBQuantum;
+              }
+            else if (4 == samples_per_pixel)
+              {
+                if (CMYKColorspace == image->colorspace)
+                  quantum_type=CMYKQuantum;
+                else
+                  quantum_type=RGBAQuantum;
+              }
+            else if (5 == samples_per_pixel)
+              {
+                if (CMYKColorspace == image->colorspace)
+                  quantum_type=CMYKAQuantum;
+              }
+
+            if (image->logging)
+              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+                                    "Import Quantum Type: %s",
+                                    QuantumTypeToString(quantum_type));
+
+            samples_per_pixel=MagickGetQuantumSamplesPerPixel(quantum_type);
+            if (image->logging)
+              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+                                    "Samples/Pixel: %u", samples_per_pixel);
+
+            if (1 == bits_per_sample)
+              {
+                /* bytes_per_row=(((size_t) image->columns*samples_per_pixel+7) >> 3); */
+                bytes_per_row=MagickArraySize(image->columns,samples_per_pixel);
+                if (bytes_per_row)
+                  bytes_per_row += 7;
+                if (bytes_per_row)
+                  bytes_per_row >>= 3;
+              }
             else
               {
-                bytes_per_row=MagickArraySize((((bits_per_sample+7)/8)*samples_per_pixel),
-                                              image->columns);
-                if (3 == samples_per_pixel)
-                  {
-                    /* PPM */
-                    quantum_type=RGBQuantum;
-                  }
-                else if (4 == samples_per_pixel)
-                  {
-                    if (CMYKColorspace == image->colorspace)
-                      quantum_type=CMYKQuantum;
-                    else
-                      quantum_type=RGBAQuantum;
-                  }
-                else if (5 == samples_per_pixel)
-                  {
-                    if (CMYKColorspace == image->colorspace)
-                      quantum_type=CMYKAQuantum;
-                  }
+                bytes_per_row=MagickArraySize(((bits_per_sample+7)/8)*
+                                              samples_per_pixel,image->columns);
               }
-            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
-                                  "using %s QuantumType",
-                                  QuantumTypeToString(quantum_type));
+
+            if (image->logging)
+              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+                                    "Bytes/Row: %" MAGICK_SIZE_T_F "u",
+                                    (MAGICK_SIZE_T) bytes_per_row);
 
             if (1 == samples_per_pixel)
               {
@@ -1851,13 +1876,35 @@
                       quantum_type=RGBQuantum;
                   }
               }
+            if (image->logging)
+              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+                                    "Export Quantum Type: %s",
+                                    QuantumTypeToString(quantum_type));
 
             samples_per_pixel=MagickGetQuantumSamplesPerPixel(quantum_type);
+            if (image->logging)
+              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+                                    "Samples/Pixel: %u", samples_per_pixel);
 
             if (1 == bits_per_sample)
-              bytes_per_row=((image->columns+7) >> 3);
+              {
+                /* bytes_per_row=(((size_t) image->columns*samples_per_pixel+7) >> 3); */
+                bytes_per_row=MagickArraySize(image->columns,samples_per_pixel);
+                if (bytes_per_row)
+                  bytes_per_row += 7;
+                if (bytes_per_row)
+                  bytes_per_row >>= 3;
+              }
             else
-              bytes_per_row=(((bits_per_sample+7)/8)*samples_per_pixel)*image->columns;
+              {
+                bytes_per_row=MagickArraySize(((bits_per_sample+7)/8)*
+                                              samples_per_pixel,image->columns);
+              }
+
+            if (image->logging)
+              (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+                                    "Bytes/Row: %" MAGICK_SIZE_T_F "u",
+                                    (MAGICK_SIZE_T) bytes_per_row);
 
             ExportPixelAreaOptionsInit(&export_options);
             export_options.grayscale_miniswhite=grayscale_miniswhite;
@@ -1903,9 +1950,18 @@
                 else if (CMYKAQuantum == quantum_type)
                   tuple_type="CMYK_ALPHA";
 
-                FormatString(buffer,"WIDTH %lu\nHEIGHT %lu\nDEPTH %u\nMAXVAL %lu\nTUPLTYPE %s\n",
+                FormatString(buffer,"WIDTH %lu\nHEIGHT %lu\nDEPTH %u"
+                             "\nMAXVAL %lu\nTUPLTYPE %s\n",
                              image->columns,image->rows,samples_per_pixel,
                              MaxValueGivenBits(bits_per_sample),tuple_type);
+                if (image->logging)
+                  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+                                        "PAM Header: WIDTH %lu, HEIGHT %lu, "
+                                        "DEPTH %u, MAXVAL %lu, TUPLTYPE %s",
+                                        image->columns,
+                                        image->rows,samples_per_pixel,
+                                        MaxValueGivenBits(bits_per_sample),
+                                        tuple_type);
                 WriteBlobString(image,buffer);
 
                 (void) WriteBlobString(image,"ENDHDR\n");
--- a/magick/version.h	Tue Dec 05 20:00:47 2017 -0600
+++ b/magick/version.h	Wed Dec 06 21:08:47 2017 -0600
@@ -38,8 +38,8 @@
 #define MagickLibVersion  0x191600
 #define MagickLibVersionText  "1.4"
 #define MagickLibVersionNumber 19,16,0
-#define MagickChangeDate   "20171205"
-#define MagickReleaseDate  "snapshot-20171205"
+#define MagickChangeDate   "20171206"
+#define MagickReleaseDate  "snapshot-20171206"
 	
 /*
   The MagickLibInterfaceNewest and MagickLibInterfaceOldest defines
--- a/www/Changelog.html	Tue Dec 05 20:00:47 2017 -0600
+++ b/www/Changelog.html	Wed Dec 06 21:08:47 2017 -0600
@@ -35,6 +35,13 @@
 <div class="document">
 
 
+<p>2017-12-06  Bob Friesenhahn  &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/pnm.c (WritePNMImage): Fix SourceForge bug #525
+&quot;heap-buffer-overflow in MagickBitStreamMSBWrite&quot;.</li>
+</ul>
+</blockquote>
 <p>2017-12-05  Bob Friesenhahn  &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
 <blockquote>
 <ul class="simple">