aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoremmaleer <emmaleer@google.com>2015-06-16 11:24:51 -0400
committerEmmalee Roach <emmaleer@google.com>2015-06-16 17:11:13 +0000
commit62fc3c2adc07fcc6adaa3d407b2c9e837091609e (patch)
tree8fc72ef9d8384091c574510d2376e31d026845f9
parent771583a01bd0756a1b6861ab1f00b7bd1842a0cd (diff)
downloadlibpng-marshmallow-release.tar.gz
The error was caused by an incorrect crc value being calculated. A crc value is calculated based on an images IDAT chunks (png blocks of image data). Since region decoder skips part of the data to decode a partial image, the crc value will only be calculated with the partial data read, not the entire data, resulting in an incorrect crc value. The solution is to call png_opt_crc_finish() when checking the crc value instead of png_crc_finish(). png_opt_crc_finish() treats the png_crc_error as a warning, instead of an error, as png_crc_finish() does. The case where there are multiple IDAT chunks was already handled in png_read_IDAT_data() line 3994 in pngrutil.c. When moving on to the next IDAT chunk it calls png_opt_crc_finish(), as we may not have decoded the entire previous IDAT chunk and there could be a crc error. Since this particular image only has one IDAT chunk, the first IDAT chunk's crc was being verified in png_read_finish_IDAT(), which is called when we are done reading the image. In this function I added a call to png_opt_crc_finish(), if png indexing is supported, in opposed to png_crc_finish(), which fixed the error. BUG:20224409 Change-Id: I97727f93f091f34700cea772bf796f168e85fc8f
-rw-r--r--pngrutil.c15
1 files changed, 15 insertions, 0 deletions
diff --git a/pngrutil.c b/pngrutil.c
index 381d83076..f78934807 100644
--- a/pngrutil.c
+++ b/pngrutil.c
@@ -236,6 +236,13 @@ png_crc_finish(png_structrp png_ptr, png_uint_32 skip)
}
#ifdef PNG_INDEX_SUPPORTED
+/* If tile index is used to skip over data and decode a partial image
+ * the crc value may be incorrect.
+ * The crc will only be calculated for the partial data read,
+ * not the entire data, which will result in an incorrect crc value.
+ * This function treats a png_crc_error as a warning, as opposed to the
+ * original function png_crc_finish, which will treat it as an error.
+ */
int /* PRIVATE */
png_opt_crc_finish(png_structrp png_ptr, png_uint_32 skip)
{
@@ -4143,6 +4150,14 @@ png_read_finish_IDAT(png_structrp png_ptr)
* crc_finish here. If idat_size is non-zero we also need to read the
* spurious bytes at the end of the chunk now.
*/
+#ifdef PNG_INDEX_SUPPORTED
+ if (png_ptr->index)
+ {
+ (void)png_opt_crc_finish(png_ptr, png_ptr->idat_size);
+ png_ptr->index->stream_idat_position = png_ptr->total_data_read;
+ }
+ else
+#endif
(void)png_crc_finish(png_ptr, png_ptr->idat_size);
}
}