From 752c6c0042aa1de559139e79be59aa258efa70c1 Mon Sep 17 00:00:00 2001 From: Glenn Randers-Pehrson Date: Sun, 6 Aug 2017 19:14:18 -0500 Subject: [libpng15] Moved chunk-name and chunk-length checks into PNG_EXTERN private png_check_chunk_name() and png_check_chunk_length() functions (Suggested by Max Stepin). Merged pngtest.c with libpng-1.6.32. --- ANNOUNCE | 8 +++++-- CHANGES | 6 ++++- libpng-manual.txt | 26 ++++++++++++++-------- libpng.3 | 36 ++++++++++++++++++------------ pngpread.c | 5 +++-- pngpriv.h | 19 +++++++++------- pngrutil.c | 49 +++++++++++++++++++++++++++++++++++++---- pngtest.c | 66 +++++++++++++++++++++++++++++++++++++++++++------------ 8 files changed, 161 insertions(+), 54 deletions(-) diff --git a/ANNOUNCE b/ANNOUNCE index 67d876657..41e004e81 100644 --- a/ANNOUNCE +++ b/ANNOUNCE @@ -1,5 +1,5 @@ -Libpng 1.5.29beta02 - April 1, 2017 +Libpng 1.5.29beta02 - August 7, 2017 This is not intended to be a public release. It will be replaced within a few weeks by a public version or by another test version. @@ -34,7 +34,11 @@ version 1.5.29beta01 [April 1, 2017] Silence clang -Wcomma warnings (Viktor Szakats). Update Sourceforge URLs in documentation (https instead of http). -version 1.5.29beta02 [April 1, 2017] +version 1.5.29beta02 [August 7, 2017] + Moved chunk-name and chunk-length checks into PNG_EXTERN private + png_check_chunk_name() and png_check_chunk_length() functions + (Suggested by Max Stepin). + Merged pngtest.c with libpng-1.6.32. Send comments/corrections/commendations to png-mng-implement at lists.sf.net (subscription required; visit diff --git a/CHANGES b/CHANGES index e355d2775..0310d00fd 100644 --- a/CHANGES +++ b/CHANGES @@ -4539,7 +4539,11 @@ version 1.5.29beta01 [April 1, 2017] Silence clang -Wcomma warnings (Viktor Szakats). Update Sourceforge URLs in documentation (https instead of http). -version 1.5.29beta02 [April 1, 2017] +version 1.5.29beta02 [August 7, 2017] + Moved chunk-name and chunk-length checks into PNG_EXTERN private + png_check_chunk_name() and png_check_chunk_length() functions + (Suggested by Max Stepin). + Merged pngtest.c with libpng-1.6.32. Send comments/corrections/commendations to png-mng-implement at lists.sf.net (subscription required; visit diff --git a/libpng-manual.txt b/libpng-manual.txt index 5ec8fccff..489fac970 100644 --- a/libpng-manual.txt +++ b/libpng-manual.txt @@ -1,6 +1,6 @@ Libpng-manual.txt - A description on how to use and modify libpng - libpng version 1.5.29beta02 - May 22, 2017 + libpng version 1.5.29beta02 - August 7, 2017 Updated and distributed by Glenn Randers-Pehrson Copyright (c) 1998-2014 Glenn Randers-Pehrson @@ -11,7 +11,7 @@ Libpng-manual.txt - A description on how to use and modify libpng Based on: - libpng versions 0.97, January 1998, through 1.5.29beta02 - May 22, 2017 + libpng versions 0.97, January 1998, through 1.5.29beta02 - August 7, 2017 Updated and distributed by Glenn Randers-Pehrson Copyright (c) 1998-2014 Glenn Randers-Pehrson @@ -82,7 +82,7 @@ majority of the needs of its users. Libpng uses zlib for its compression and decompression of PNG files. Further information about zlib, and the latest version of zlib, can -be found at the zlib home page, . +be found at the zlib home page, . The zlib compression utility is a general purpose utility that is useful for more than PNG files, and can be used without libpng. See the documentation delivered with zlib for more details. @@ -652,8 +652,10 @@ where 0x7fffffffL means unlimited. You can retrieve this limit with chunk_cache_max = png_get_chunk_cache_max(png_ptr); -You can also set a limit on the amount of memory that a compressed chunk -other than IDAT can occupy, with +Libpng imposes a limit of 8 Megabytes (8,000,000 bytes) on the amount of +memory that any chunk other than IDAT can occupy, originally or when +decompressed (prior to libpng-1.6.32 the limit was only applied to compressed +chunks after decompression). You can change this limit with png_set_chunk_malloc_max(png_ptr, user_chunk_malloc_max); @@ -4370,11 +4372,13 @@ control. The git repository was built from old libpng-x.y.z.tar.gz files going back to version 0.70. You can access the git repository (read only) at - git://git.code.sf.net/p/libpng/code.git + https://github.com/glennrp/libpng or + https://git.code.sf.net/p/libpng/code.git -or you can browse it with a web browser by selecting the "code" button at +or you can browse it with a web browser at - https://sourceforge.net/projects/libpng + https://github.com/glennrp/libpng or + https://sourceforge.net/p/libpng/code/ci/libpng16/tree/ Patches can be sent to glennrp at users.sourceforge.net or to png-mng-implement at lists.sourceforge.net or you can upload them to @@ -4382,10 +4386,14 @@ the libpng bug tracker at https://libpng.sourceforge.io/ +or as a "pull request" to + + https://github.com/glennrp/libpng/pulls + We also accept patches built from the tar or zip distributions, and simple verbal discriptions of bug fixes, reported either to the SourceForge bug tracker, to the png-mng-implement at lists.sf.net -mailing list, or directly to glennrp. +mailing list, as github issues, or directly to glennrp. XIII. Coding style diff --git a/libpng.3 b/libpng.3 index b534fe6f1..c5b53618f 100644 --- a/libpng.3 +++ b/libpng.3 @@ -1,4 +1,4 @@ -.TH LIBPNG 3 "May 22, 2017" +.TH LIBPNG 3 "August 7, 2017" .SH NAME libpng \- Portable Network Graphics (PNG) Reference Library 1.5.29beta02 .SH SYNOPSIS @@ -496,7 +496,7 @@ Following is a copy of the libpng-manual.txt file that accompanies libpng. .SH LIBPNG.TXT Libpng-manual.txt - A description on how to use and modify libpng - libpng version 1.5.29beta02 - May 22, 2017 + libpng version 1.5.29beta02 - August 7, 2017 Updated and distributed by Glenn Randers-Pehrson Copyright (c) 1998-2014 Glenn Randers-Pehrson @@ -507,7 +507,7 @@ Libpng-manual.txt - A description on how to use and modify libpng Based on: - libpng versions 0.97, January 1998, through 1.5.29beta02 - May 22, 2017 + libpng versions 0.97, January 1998, through 1.5.29beta02 - August 7, 2017 Updated and distributed by Glenn Randers-Pehrson Copyright (c) 1998-2014 Glenn Randers-Pehrson @@ -578,7 +578,7 @@ majority of the needs of its users. Libpng uses zlib for its compression and decompression of PNG files. Further information about zlib, and the latest version of zlib, can -be found at the zlib home page, . +be found at the zlib home page, . The zlib compression utility is a general purpose utility that is useful for more than PNG files, and can be used without libpng. See the documentation delivered with zlib for more details. @@ -1148,8 +1148,10 @@ where 0x7fffffffL means unlimited. You can retrieve this limit with chunk_cache_max = png_get_chunk_cache_max(png_ptr); -You can also set a limit on the amount of memory that a compressed chunk -other than IDAT can occupy, with +Libpng imposes a limit of 8 Megabytes (8,000,000 bytes) on the amount of +memory that any chunk other than IDAT can occupy, originally or when +decompressed (prior to libpng-1.6.32 the limit was only applied to compressed +chunks after decompression). You can change this limit with png_set_chunk_malloc_max(png_ptr, user_chunk_malloc_max); @@ -4866,11 +4868,13 @@ control. The git repository was built from old libpng-x.y.z.tar.gz files going back to version 0.70. You can access the git repository (read only) at - git://git.code.sf.net/p/libpng/code.git + https://github.com/glennrp/libpng or + https://git.code.sf.net/p/libpng/code.git -or you can browse it with a web browser by selecting the "code" button at +or you can browse it with a web browser at - https://sourceforge.net/projects/libpng + https://github.com/glennrp/libpng or + https://sourceforge.net/p/libpng/code/ci/libpng16/tree/ Patches can be sent to glennrp at users.sourceforge.net or to png-mng-implement at lists.sourceforge.net or you can upload them to @@ -4878,10 +4882,14 @@ the libpng bug tracker at https://libpng.sourceforge.io/ +or as a "pull request" to + + https://github.com/glennrp/libpng/pulls + We also accept patches built from the tar or zip distributions, and simple verbal discriptions of bug fixes, reported either to the SourceForge bug tracker, to the png-mng-implement at lists.sf.net -mailing list, or directly to glennrp. +mailing list, as github issues, or directly to glennrp. .SH XIII. Coding style @@ -5139,7 +5147,7 @@ http://www.libpng.org/pub/png .I libpng or at .br -http://zlib.net/ +https://zlib.net/ .LP .IR PNG specification: RFC 2083 @@ -5168,7 +5176,7 @@ possible without all of you. Thanks to Frank J. T. Wojcik for helping with the documentation. -Libpng version 1.5.29beta02 - May 22, 2017: +Libpng version 1.5.29beta02 - August 7, 2017: Initially created in 1995 by Guy Eric Schalnat, then of Group 42, Inc. Currently maintained by Glenn Randers-Pehrson (glennrp at users.sourceforge.net). @@ -5193,7 +5201,7 @@ this sentence. This code is released under the libpng license. -libpng versions 1.0.7, July 1, 2000 through 1.5.29beta02, May 22, 2017, are +libpng versions 1.0.7, July 1, 2000 through 1.5.29beta02, August 7, 2017, are Copyright (c) 2000-2002, 2004, 2006-2017 Glenn Randers-Pehrson, are derived from libpng-1.0.6, and are distributed according to the same disclaimer and license as libpng-1.0.6 with the following individuals @@ -5317,7 +5325,7 @@ files "pngbar.png" and "pngbar.jpg (88x31) and "pngnow.png" (98x31). Glenn Randers-Pehrson glennrp at users.sourceforge.net -May 22, 2017 +August 7, 2017 .\" end of man page diff --git a/pngpread.c b/pngpread.c index 86da4f9ec..c318566a6 100644 --- a/pngpread.c +++ b/pngpread.c @@ -1,8 +1,8 @@ /* pngpread.c - read a png file in push mode * - * Last changed in libpng 1.5.28 [December 29, 2016] - * Copyright (c) 1998-2002,2004,2006-2016 Glenn Randers-Pehrson + * Last changed in libpng 1.5.29 [(PENDING RELEASE)] + * Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * @@ -186,6 +186,7 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr) png_crc_read(png_ptr, chunk_tag, 4); png_ptr->chunk_name = PNG_CHUNK_FROM_STRING(chunk_tag); png_check_chunk_name(png_ptr, png_ptr->chunk_name); + png_check_chunk_length(png_ptr, png_ptr->push_length); png_ptr->mode |= PNG_HAVE_CHUNK_HEADER; } diff --git a/pngpriv.h b/pngpriv.h index e6ca9bf0d..a8b8fda04 100644 --- a/pngpriv.h +++ b/pngpriv.h @@ -1,8 +1,8 @@ /* pngpriv.h - private declarations for use inside libpng * - * Last changed in libpng 1.5.26 [December 17, 2015] - * Copyright (c) 1998-2002,2004,2006-2015 Glenn Randers-Pehrson + * Last changed in libpng 1.5.29 [(PENDING RELEASE)] + * Copyright (c) 1998-2002,2004,2006-2015,2017 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * @@ -180,12 +180,9 @@ /* SECURITY and SAFETY: * - * By default libpng is built without any internal limits on image size, - * individual heap (png_malloc) allocations or the total amount of memory used. - * If PNG_SAFE_LIMITS_SUPPORTED is defined, however, the limits below are used - * (unless individually overridden). These limits are believed to be fairly - * safe, but builders of secure systems should verify the values against the - * real system capabilities. + * libpng is built with support for internal limits on image dimensions and + * memory usage. These are documented in scripts/pnglibconf.dfa of the + * source and recorded in the machine generated header file pnglibconf.h. */ /* config.h is created by and PNG_CONFIGURE_LIBPNG is set by the "configure" @@ -1272,6 +1269,12 @@ PNG_EXTERN void png_handle_zTXt PNGARG((png_structp png_ptr, png_infop info_ptr, png_uint_32 length)); #endif +PNG_EXTERN void png_check_chunk_name PNGARG((png_structp png_ptr, + png_uint_32 chunk_name)); + +PNG_EXTERN void png_check_chunk_length PNGARG((png_structp png_ptr, + png_uint_32 chunk_length)); + PNG_EXTERN void png_handle_unknown PNGARG((png_structp png_ptr, png_infop info_ptr, png_uint_32 length)); diff --git a/pngrutil.c b/pngrutil.c index 9c3bf0557..8570c968d 100644 --- a/pngrutil.c +++ b/pngrutil.c @@ -171,6 +171,9 @@ png_read_chunk_header(png_structp png_ptr) /* Put the chunk name into png_ptr->chunk_name. */ png_ptr->chunk_name = PNG_CHUNK_FROM_STRING(buf+4); + /* Check to see if chunk name is valid. */ + png_check_chunk_name(png_ptr, png_ptr->chunk_name); + png_debug2(0, "Reading %lx chunk, length = %lu", (unsigned long)png_ptr->chunk_name, (unsigned long)length); @@ -178,8 +181,8 @@ png_read_chunk_header(png_structp png_ptr) png_reset_crc(png_ptr); png_calculate_crc(png_ptr, buf + 4, 4); - /* Check to see if chunk name is valid. */ - png_check_chunk_name(png_ptr, png_ptr->chunk_name); + /* Check for too-large chunk length */ + png_check_chunk_length(png_ptr, length); #ifdef PNG_IO_STATE_SUPPORTED png_ptr->io_state = PNG_IO_READING | PNG_IO_CHUNK_DATA; @@ -2803,17 +2806,55 @@ void /* PRIVATE */ png_check_chunk_name(png_structp png_ptr, png_uint_32 chunk_name) { int i; + png_uint_32 cn=chunk_name; png_debug(1, "in png_check_chunk_name"); for (i=1; i<=4; ++i) { - int c = chunk_name & 0xff; + int c = cn & 0xff; if (c < 65 || c > 122 || (c > 90 && c < 97)) png_chunk_error(png_ptr, "invalid chunk type"); - chunk_name >>= 8; + cn >>= 8; + } +} + +void /* PRIVATE */ +png_check_chunk_length(png_structp png_ptr, png_uint_32 length) +{ + png_uint_32 limit = PNG_UINT_31_MAX; + + if (png_ptr->chunk_name != png_IDAT) + { +# ifdef PNG_SET_USER_LIMITS_SUPPORTED + if (png_ptr->user_chunk_malloc_max > 0 && + png_ptr->user_chunk_malloc_max < limit) + limit = png_ptr->user_chunk_malloc_max; +# elif PNG_USER_CHUNK_MALLOC_MAX > 0 + if (PNG_USER_CHUNK_MALLOC_MAX < limit) + limit = PNG_USER_CHUNK_MALLOC_MAX; +# endif + } + else + { + size_t row_factor = + (png_ptr->width * png_ptr->channels * (png_ptr->bit_depth > 8? 2: 1) + + 1 + (png_ptr->interlaced? 6: 0)); + if (png_ptr->height > PNG_UINT_32_MAX/row_factor) + limit=PNG_UINT_31_MAX; + else + limit = png_ptr->height * row_factor; + limit += 6 + 5*(limit/32566+1); /* zlib+deflate overhead */ + limit=limit < PNG_UINT_31_MAX? limit : PNG_UINT_31_MAX; + } + + if (length > limit) + { + png_debug2(0," length = %lu, limit = %lu", + (unsigned long)length,(unsigned long)limit); + png_chunk_error(png_ptr, "chunk data is too large"); } } diff --git a/pngtest.c b/pngtest.c index 90e8d35e4..3c7044fb7 100644 --- a/pngtest.c +++ b/pngtest.c @@ -1,8 +1,8 @@ /* pngtest.c - a simple test program to test libpng * - * Last changed in libpng 1.5.28 [December 29, 2016] - * Copyright (c) 1998-2002,2004,2006-2016 Glenn Randers-Pehrson + * Last changed in libpng 1.6.32 [(PENDING RELEASE)] + * Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * @@ -144,6 +144,7 @@ tIME_to_str(png_structp png_ptr, png_charp ts, png_const_timep t) static int verbose = 0; static int strict = 0; static int relaxed = 0; +static int xfail = 0; static int unsupported_chunks = 0; /* chunk unsupported by libpng in input */ static int error_count = 0; /* count calls to png_error */ static int warning_count = 0; /* count calls to png_warning */ @@ -463,7 +464,7 @@ pngtest_warning(png_structp png_ptr, png_const_charp message) if (test != NULL && test->file_name != NULL) name = test->file_name; - fprintf(STDERR, "%s: libpng warning: %s\n", name, message); + fprintf(STDERR, "\n%s: libpng warning: %s\n", name, message); } /* This is the default error handling function. Note that replacements for @@ -936,8 +937,12 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname) fprintf(STDERR, "%s -> %s: libpng read error\n", inname, outname); png_free(read_ptr, row_buf); row_buf = NULL; + if (verbose != 0) + fprintf(STDERR, " destroy read structs\n"); png_destroy_read_struct(&read_ptr, &read_info_ptr, &end_info_ptr); #ifdef PNG_WRITE_SUPPORTED + if (verbose != 0) + fprintf(STDERR, " destroy write structs\n"); png_destroy_info_struct(write_ptr, &write_end_info_ptr); png_destroy_write_struct(&write_ptr, &write_info_ptr); #endif @@ -952,11 +957,13 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname) if (setjmp(png_jmpbuf(write_ptr))) { fprintf(STDERR, "%s -> %s: libpng write error\n", inname, outname); + if (verbose != 0) + fprintf(STDERR, " destroying read structs\n"); png_destroy_read_struct(&read_ptr, &read_info_ptr, &end_info_ptr); + if (verbose != 0) + fprintf(STDERR, " destroying write structs\n"); png_destroy_info_struct(write_ptr, &write_end_info_ptr); -#ifdef PNG_WRITE_SUPPORTED png_destroy_write_struct(&write_ptr, &write_info_ptr); -#endif FCLOSE(fpin); FCLOSE(fpout); return (1); @@ -986,9 +993,14 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname) /* Allow application (pngtest) errors and warnings to pass */ png_set_benign_errors(read_ptr, 1); - /* Turn off CRC and ADLER32 checking while reading */ + /* Turn off CRC checking while reading */ png_set_crc_action(read_ptr, PNG_CRC_QUIET_USE, PNG_CRC_QUIET_USE); +#ifdef PNG_IGNORE_ADLER32 + /* Turn off ADLER32 checking while reading */ + png_set_option(read_ptr, PNG_IGNORE_ADLER32, PNG_OPTION_ON); +#endif + # ifdef PNG_WRITE_SUPPORTED png_set_benign_errors(write_ptr, 1); # endif @@ -1297,10 +1309,10 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname) { int i; - printf("\n"); + fprintf(STDERR,"\n"); for (i=0; i