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 309352 8fd07f16556c8ca5305cb629ec90dce75c77c798
parent 309351 2b9a31603e348c8edac61f74627674f5a9284976
child 309353 810a43be36dea816105520b23758e7988f972def
push id30561
push userkwierso@gmail.com
push dateMon, 15 Aug 2016 21:20:49 +0000
treeherdermozilla-central@91a319101587 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjrmuizel
bugs1288588
milestone51.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 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");