Bug 1367496 - Check for too-large PNG width. r=tn
☠☠ backed out by 0d00b9dfaeb8 ☠ ☠
authorGlenn Randers-Pehrson <glennrp+bmo@gmail.com>
Sat, 03 Jun 2017 14:37:00 -0400
changeset 411042 76404bf85ef79bacff8fd82b364698af17275d6b
parent 411041 7fb451a4d22c87e7de74be4c169c85601bdb938e
child 411043 c5aaa3f7b79e2c8ccec4447b9c38109677d4cd01
push id7391
push usermtabara@mozilla.com
push dateMon, 12 Jun 2017 13:08:53 +0000
treeherdermozilla-beta@2191d7f87e2e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerstn
bugs1367496
milestone55.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1367496 - Check for too-large PNG width. r=tn
image/decoders/nsPNGDecoder.cpp
media/libpng/pnglibconf.h
--- a/image/decoders/nsPNGDecoder.cpp
+++ b/image/decoders/nsPNGDecoder.cpp
@@ -14,17 +14,19 @@
 #include "gfxPlatform.h"
 #include "imgFrame.h"
 #include "nsColor.h"
 #include "nsIInputStream.h"
 #include "nsMemory.h"
 #include "nsRect.h"
 #include "nspr.h"
 #include "png.h"
+
 #include "RasterImage.h"
+#include "SurfaceCache.h"
 #include "SurfacePipeFactory.h"
 #include "mozilla/DebugOnly.h"
 #include "mozilla/Telemetry.h"
 
 using namespace mozilla::gfx;
 
 using std::min;
 
@@ -564,16 +566,23 @@ nsPNGDecoder::info_callback(png_structp 
   // Always decode to 24-bit RGB or 32-bit RGBA
   png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type,
                &interlace_type, &compression_type, &filter_type);
 
   const IntRect frameRect(0, 0, width, height);
 
   // Post our size to the superclass
   decoder->PostSize(frameRect.width, frameRect.height);
+
+  if (width >
+    SurfaceCache::MaximumCapacity()/(bit_depth > 8 ? 16:8)) {
+    // libpng needs space to allocate two row buffers
+    png_error(decoder->mPNG, "Image is too wide");
+  }
+
   if (decoder->HasError()) {
     // Setting the size led to an error.
     png_error(decoder->mPNG, "Sizing error");
   }
 
   if (color_type == PNG_COLOR_TYPE_PALETTE) {
     png_set_expand(png_ptr);
   }
@@ -730,16 +739,21 @@ nsPNGDecoder::info_callback(png_structp 
     if (!decoder->mCMSLine) {
       png_error(decoder->mPNG, "malloc of mCMSLine failed");
     }
   }
 
   if (interlace_type == PNG_INTERLACE_ADAM7) {
     if (frameRect.height < INT32_MAX / (frameRect.width * int32_t(channels))) {
       const size_t bufferSize = channels * frameRect.width * frameRect.height;
+
+      if (bufferSize > SurfaceCache::MaximumCapacity()) {
+        png_error(decoder->mPNG, "Insufficient memory to deinterlace image");
+      }
+
       decoder->interlacebuf = static_cast<uint8_t*>(malloc(bufferSize));
     }
     if (!decoder->interlacebuf) {
       png_error(decoder->mPNG, "malloc of interlacebuf failed");
     }
   }
 }
 
--- a/media/libpng/pnglibconf.h
+++ b/media/libpng/pnglibconf.h
@@ -3,22 +3,25 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef PNGLCONF_H
 #define PNGLCONF_H
 
 #define MOZ_EMBEDDED_LIBPNG
 
 /* Limit image dimensions (bug #251381, #591822, #967656, and #1283961) */
+#define PNG_USER_LIMITS_SUPPORTED
 #ifndef MOZ_PNG_MAX_WIDTH
 #  define MOZ_PNG_MAX_WIDTH 0x7fffffffL /* Unlimited */
 #endif
 #ifndef MOZ_PNG_MAX_HEIGHT
 #  define MOZ_PNG_MAX_HEIGHT 0x7fffffffL /* Unlimited */
 #endif
+/* but allow nsPNGDecoder to override the limits (bug #1368407) */
+#define PNG_SET_USER_LIMITS_SUPPORTED
 
 #define PNG_API_RULE 0
 #define PNG_COST_SHIFT 3
 #define PNG_GAMMA_THRESHOLD_FIXED 5000
 #define PNG_IDAT_READ_SIZE PNG_ZBUF_SIZE
 #define PNG_INFLATE_BUF_SIZE 1024
 #define PNG_LINKAGE_API extern
 #define PNG_LINKAGE_CALLBACK extern