Reject oversized iCCP profile length in libpng.

cherry-pick of https://github.com/glennrp/libpng/commit/92a7c79db2c962d04006b35e2603ba9d5ce75541
BUG=chromium:729673

Change-Id: I907b4920ed6d276a075a30269be1744aff678069
Reviewed-on: https://pdfium-review.googlesource.com/11690
Commit-Queue: Lei Zhang <thestig@chromium.org>
Reviewed-by: dsinclair <dsinclair@chromium.org>
diff --git a/third_party/libpng16/0004-invalid-icc.patch b/third_party/libpng16/0004-invalid-icc.patch
new file mode 100644
index 0000000..0052c8e
--- /dev/null
+++ b/third_party/libpng16/0004-invalid-icc.patch
@@ -0,0 +1,81 @@
+diff --git a/png.c b/png.c
+index 35e14f63d..01d8d9bae 100644
+--- a/png.c
++++ b/png.c
+@@ -1931,8 +1931,8 @@ png_colorspace_set_sRGB(png_const_structrp png_ptr, png_colorspacerp colorspace,
+ static const png_byte D50_nCIEXYZ[12] =
+    { 0x00, 0x00, 0xf6, 0xd6, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd3, 0x2d };
+ 
+-int /* PRIVATE */
+-png_icc_check_length(png_const_structrp png_ptr, png_colorspacerp colorspace,
++static int /* bool */
++icc_check_length(png_const_structrp png_ptr, png_colorspacerp colorspace,
+    png_const_charp name, png_uint_32 profile_length)
+ {
+    if (profile_length < 132)
+@@ -1942,6 +1942,40 @@ png_icc_check_length(png_const_structrp png_ptr, png_colorspacerp colorspace,
+    return 1;
+ }
+ 
++#ifdef PNG_READ_iCCP_SUPPORTED
++int /* PRIVATE */
++png_icc_check_length(png_const_structrp png_ptr, png_colorspacerp colorspace,
++    png_const_charp name, png_uint_32 profile_length)
++{
++   if (!icc_check_length(png_ptr, colorspace, name, profile_length))
++      return 0;
++
++   /* This needs to be here because the 'normal' check is in
++    * png_decompress_chunk, yet this happens after the attempt to
++    * png_malloc_base the required data.  We only need this on read; on write
++    * the caller supplies the profile buffer so libpng doesn't allocate it.  See
++    * the call to icc_check_length below (the write case).
++    */
++#  ifdef PNG_SET_USER_LIMITS_SUPPORTED
++      else if (png_ptr->user_chunk_malloc_max > 0 &&
++               png_ptr->user_chunk_malloc_max < profile_length)
++         return png_icc_profile_error(png_ptr, colorspace, name, profile_length,
++             "exceeds application limits");
++#  elif PNG_USER_CHUNK_MALLOC_MAX > 0
++      else if (PNG_USER_CHUNK_MALLOC_MAX < profile_length)
++         return png_icc_profile_error(png_ptr, colorspace, name, profile_length,
++             "exceeds libpng limits");
++#  else /* !SET_USER_LIMITS */
++      /* This will get compiled out on all 32-bit and better systems. */
++      else if (PNG_SIZE_MAX < profile_length)
++         return png_icc_profile_error(png_ptr, colorspace, name, profile_length,
++             "exceeds system limits");
++#  endif /* !SET_USER_LIMITS */
++
++   return 1;
++}
++#endif /* READ_iCCP */
++
+ int /* PRIVATE */
+ png_icc_check_header(png_const_structrp png_ptr, png_colorspacerp colorspace,
+    png_const_charp name, png_uint_32 profile_length,
+@@ -2379,7 +2413,7 @@ png_colorspace_set_ICC(png_const_structrp png_ptr, png_colorspacerp colorspace,
+    if ((colorspace->flags & PNG_COLORSPACE_INVALID) != 0)
+       return 0;
+ 
+-   if (png_icc_check_length(png_ptr, colorspace, name, profile_length) != 0 &&
++   if (icc_check_length(png_ptr, colorspace, name, profile_length) != 0 &&
+        png_icc_check_header(png_ptr, colorspace, name, profile_length, profile,
+           color_type) != 0 &&
+        png_icc_check_tag_table(png_ptr, colorspace, name, profile_length,
+diff --git a/pngpriv.h b/pngpriv.h
+index 9ea023fea..633671352 100644
+--- a/pngpriv.h
++++ b/pngpriv.h
+@@ -1541,9 +1541,11 @@ PNG_INTERNAL_FUNCTION(int,png_colorspace_set_ICC,(png_const_structrp png_ptr,
+    /* The 'name' is used for information only */
+ 
+ /* Routines for checking parts of an ICC profile. */
++#ifdef PNG_READ_iCCP_SUPPORTED
+ PNG_INTERNAL_FUNCTION(int,png_icc_check_length,(png_const_structrp png_ptr,
+    png_colorspacerp colorspace, png_const_charp name,
+    png_uint_32 profile_length), PNG_EMPTY);
++#endif /* READ_iCCP */
+ PNG_INTERNAL_FUNCTION(int,png_icc_check_header,(png_const_structrp png_ptr,
+    png_colorspacerp colorspace, png_const_charp name,
+    png_uint_32 profile_length,
diff --git a/third_party/libpng16/README.pdfium b/third_party/libpng16/README.pdfium
index 47af52f..faa5959 100644
--- a/third_party/libpng16/README.pdfium
+++ b/third_party/libpng16/README.pdfium
@@ -18,3 +18,4 @@
 0000-build-config.patch: Local build configuration changes.
 0002-static-png-gt.patch: Unconditionally use static png_gt() in png.c to avoid compilation warning.
 0003-check-errors-in-set-pcal.patch: Backported github.com/glennrp/libpng/pull/135
+0004-invalid-icc.patch: Fix for large allocation for invalid ICC https://github.com/glennrp/libpng/commit/92a7c79db2c962d04006b35e2603ba9d5ce75541
diff --git a/third_party/libpng16/png.c b/third_party/libpng16/png.c
index 35e14f6..01d8d9b 100644
--- a/third_party/libpng16/png.c
+++ b/third_party/libpng16/png.c
@@ -1931,8 +1931,8 @@
 static const png_byte D50_nCIEXYZ[12] =
    { 0x00, 0x00, 0xf6, 0xd6, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd3, 0x2d };
 
-int /* PRIVATE */
-png_icc_check_length(png_const_structrp png_ptr, png_colorspacerp colorspace,
+static int /* bool */
+icc_check_length(png_const_structrp png_ptr, png_colorspacerp colorspace,
    png_const_charp name, png_uint_32 profile_length)
 {
    if (profile_length < 132)
@@ -1942,6 +1942,40 @@
    return 1;
 }
 
+#ifdef PNG_READ_iCCP_SUPPORTED
+int /* PRIVATE */
+png_icc_check_length(png_const_structrp png_ptr, png_colorspacerp colorspace,
+    png_const_charp name, png_uint_32 profile_length)
+{
+   if (!icc_check_length(png_ptr, colorspace, name, profile_length))
+      return 0;
+
+   /* This needs to be here because the 'normal' check is in
+    * png_decompress_chunk, yet this happens after the attempt to
+    * png_malloc_base the required data.  We only need this on read; on write
+    * the caller supplies the profile buffer so libpng doesn't allocate it.  See
+    * the call to icc_check_length below (the write case).
+    */
+#  ifdef PNG_SET_USER_LIMITS_SUPPORTED
+      else if (png_ptr->user_chunk_malloc_max > 0 &&
+               png_ptr->user_chunk_malloc_max < profile_length)
+         return png_icc_profile_error(png_ptr, colorspace, name, profile_length,
+             "exceeds application limits");
+#  elif PNG_USER_CHUNK_MALLOC_MAX > 0
+      else if (PNG_USER_CHUNK_MALLOC_MAX < profile_length)
+         return png_icc_profile_error(png_ptr, colorspace, name, profile_length,
+             "exceeds libpng limits");
+#  else /* !SET_USER_LIMITS */
+      /* This will get compiled out on all 32-bit and better systems. */
+      else if (PNG_SIZE_MAX < profile_length)
+         return png_icc_profile_error(png_ptr, colorspace, name, profile_length,
+             "exceeds system limits");
+#  endif /* !SET_USER_LIMITS */
+
+   return 1;
+}
+#endif /* READ_iCCP */
+
 int /* PRIVATE */
 png_icc_check_header(png_const_structrp png_ptr, png_colorspacerp colorspace,
    png_const_charp name, png_uint_32 profile_length,
@@ -2379,7 +2413,7 @@
    if ((colorspace->flags & PNG_COLORSPACE_INVALID) != 0)
       return 0;
 
-   if (png_icc_check_length(png_ptr, colorspace, name, profile_length) != 0 &&
+   if (icc_check_length(png_ptr, colorspace, name, profile_length) != 0 &&
        png_icc_check_header(png_ptr, colorspace, name, profile_length, profile,
           color_type) != 0 &&
        png_icc_check_tag_table(png_ptr, colorspace, name, profile_length,
diff --git a/third_party/libpng16/pngpriv.h b/third_party/libpng16/pngpriv.h
index 9ea023f..6336713 100644
--- a/third_party/libpng16/pngpriv.h
+++ b/third_party/libpng16/pngpriv.h
@@ -1541,9 +1541,11 @@
    /* The 'name' is used for information only */
 
 /* Routines for checking parts of an ICC profile. */
+#ifdef PNG_READ_iCCP_SUPPORTED
 PNG_INTERNAL_FUNCTION(int,png_icc_check_length,(png_const_structrp png_ptr,
    png_colorspacerp colorspace, png_const_charp name,
    png_uint_32 profile_length), PNG_EMPTY);
+#endif /* READ_iCCP */
 PNG_INTERNAL_FUNCTION(int,png_icc_check_header,(png_const_structrp png_ptr,
    png_colorspacerp colorspace, png_const_charp name,
    png_uint_32 profile_length,