Bug 1288588 - Exit on bad CRC in fcTL or fdAT chunk in an APNG file. r=jrmuizel
authorGlenn Randers-Pehrson <glennrp+bmo@gmail.com>
Fri, 12 Aug 2016 21:31:31 -0400
changeset 309376 8fd07f16556c8ca5305cb629ec90dce75c77c798
parent 309375 2b9a31603e348c8edac61f74627674f5a9284976
child 309377 810a43be36dea816105520b23758e7988f972def
push id20308
push userkwierso@gmail.com
push dateMon, 15 Aug 2016 22:04:54 +0000
treeherderfx-team@2697bf7ad45d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjrmuizel
bugs1288588
milestone51.0a1
Bug 1288588 - Exit on bad CRC in fcTL or fdAT chunk in an APNG file. r=jrmuizel
image/decoders/nsPNGDecoder.cpp
media/libpng/apng.patch
media/libpng/pnglibconf.h
media/libpng/pngset.c
--- a/image/decoders/nsPNGDecoder.cpp
+++ b/image/decoders/nsPNGDecoder.cpp
@@ -968,16 +968,24 @@ nsPNGDecoder::frame_info_callback(png_st
 
   // Save the information necessary to create the frame; we'll actually create
   // it when we return from the yield.
   const IntRect frameRect(png_get_next_frame_x_offset(png_ptr, decoder->mInfo),
                           png_get_next_frame_y_offset(png_ptr, decoder->mInfo),
                           png_get_next_frame_width(png_ptr, decoder->mInfo),
                           png_get_next_frame_height(png_ptr, decoder->mInfo));
 
+#ifndef PNGLCONF_H
+  // if using system library, check frame_width and height against 0
+  if (frameRect.width == 0)
+    png_error(png_ptr, "Frame width must not be 0");
+  if (frameRect.height == 0)
+    png_error(png_ptr, "Frame height must not be 0");
+#endif
+
   const bool isInterlaced = bool(decoder->interlacebuf);
 
   decoder->mNextFrameInfo = Some(FrameInfo{ decoder->format,
                                             frameRect,
                                             isInterlaced });
 
   // Yield to the caller to notify them that the previous frame is now complete.
   return decoder->DoYield(png_ptr);
--- a/media/libpng/apng.patch
+++ b/media/libpng/apng.patch
@@ -1040,19 +1040,19 @@ Index: pngset.c
 +void /* PRIVATE */
 +png_ensure_fcTL_is_valid(png_structp png_ptr,
 +    png_uint_32 width, png_uint_32 height,
 +    png_uint_32 x_offset, png_uint_32 y_offset,
 +    png_uint_16 delay_num, png_uint_16 delay_den,
 +    png_byte dispose_op, png_byte blend_op)
 +{
 +    if (width == 0 || width > PNG_UINT_31_MAX)
-+        png_error(png_ptr, "invalid width in fcTL (> 2^31-1)");
++        png_error(png_ptr, "invalid width in fcTL (0 or > 2^31-1)");
 +    if (height == 0 || height > PNG_UINT_31_MAX)
-+        png_error(png_ptr, "invalid height in fcTL (> 2^31-1)");
++        png_error(png_ptr, "invalid height in fcTL (0 or > 2^31-1)");
 +    if (x_offset > PNG_UINT_31_MAX)
 +        png_error(png_ptr, "invalid x_offset in fcTL (> 2^31-1)");
 +    if (y_offset > PNG_UINT_31_MAX)
 +        png_error(png_ptr, "invalid y_offset in fcTL (> 2^31-1)");
 +    if (width + x_offset > png_ptr->first_frame_width ||
 +        height + y_offset > png_ptr->first_frame_height)
 +        png_error(png_ptr, "dimensions of a frame are greater than "
 +                           "the ones in IHDR");
--- a/media/libpng/pnglibconf.h
+++ b/media/libpng/pnglibconf.h
@@ -1,15 +1,17 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * 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) */
 #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
 
--- a/media/libpng/pngset.c
+++ b/media/libpng/pngset.c
@@ -1191,19 +1191,19 @@ png_set_next_frame_fcTL(png_structp png_
 void /* PRIVATE */
 png_ensure_fcTL_is_valid(png_structp png_ptr,
     png_uint_32 width, png_uint_32 height,
     png_uint_32 x_offset, png_uint_32 y_offset,
     png_uint_16 delay_num, png_uint_16 delay_den,
     png_byte dispose_op, png_byte blend_op)
 {
     if (width == 0 || width > PNG_UINT_31_MAX)
-        png_error(png_ptr, "invalid width in fcTL (> 2^31-1)");
+        png_error(png_ptr, "invalid width in fcTL (0 or > 2^31-1)");
     if (height == 0 || height > PNG_UINT_31_MAX)
-        png_error(png_ptr, "invalid height in fcTL (> 2^31-1)");
+        png_error(png_ptr, "invalid height in fcTL (0 or > 2^31-1)");
     if (x_offset > PNG_UINT_31_MAX)
         png_error(png_ptr, "invalid x_offset in fcTL (> 2^31-1)");
     if (y_offset > PNG_UINT_31_MAX)
         png_error(png_ptr, "invalid y_offset in fcTL (> 2^31-1)");
     if (width + x_offset > png_ptr->first_frame_width ||
         height + y_offset > png_ptr->first_frame_height)
         png_error(png_ptr, "dimensions of a frame are greater than "
                            "the ones in IHDR");