From 8a6253ed6fe8c60cae2a19346110ce23fef7221b Mon Sep 17 00:00:00 2001 From: Glenn Randers-Pehrson Date: Mon, 16 Feb 2015 22:56:30 -0600 Subject: [PATCH] [libpng15] Merged pngtest.c with libpng-1.6.17/pngtest.c Display user limits in the output from pngtest. Eliminated the PNG_SAFE_LIMITS macro and restored the 1-million-column and 1-million-row default limits in pnglibconf.dfa, that can be reset by the user at build time or run time. This provides a more robust defense against DOS and as-yet undiscovered overflows. --- ANNOUNCE | 10 ++- CHANGES | 8 +- pngpriv.h | 43 +++------- pngtest.c | 152 +++++++++++++++++++++------------- pngusr.dfa | 8 +- scripts/pnglibconf.dfa | 57 ++++++------- scripts/pnglibconf.h.prebuilt | 6 +- 7 files changed, 151 insertions(+), 133 deletions(-) diff --git a/ANNOUNCE b/ANNOUNCE index 6199cfe37..4345c6756 100644 --- a/ANNOUNCE +++ b/ANNOUNCE @@ -1,5 +1,5 @@ -Libpng 1.5.22beta02 - January 29, 2015 +Libpng 1.5.22beta02 - February 17, 2015 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. @@ -33,7 +33,13 @@ Version 1.5.22beta01 [January 29, 2015] values that are exactly 2^bit_depth, and work on 16-bit platforms. Quieted some warnings from Coverity-scan. -Version 1.5.22beta02 [January 29, 2015] +Version 1.5.22beta02 [February 17, 2015] + Merged pngtest.c with libpng-1.6.17/pngtest.c + Display user limits in the output from pngtest. + Eliminated the PNG_SAFE_LIMITS macro and restored the 1-million-column + and 1-million-row default limits in pnglibconf.dfa, that can be reset + by the user at build time or run time. This provides a more robust + defense against DOS and as-yet undiscovered overflows. Send comments/corrections/commendations to png-mng-implement at lists.sf.net (subscription required; visit diff --git a/CHANGES b/CHANGES index 2af07d20d..10728dabb 100644 --- a/CHANGES +++ b/CHANGES @@ -4297,7 +4297,13 @@ Version 1.5.22beta01 [January 29, 2015] values that are exactly 2^bit_depth, and work on 16-bit platforms. Quieted some warnings from Coverity-scan. -Version 1.5.22beta02 [January 29, 2015] +Version 1.5.22beta02 [February 17, 2015] + Merged pngtest.c with libpng-1.6.17/pngtest.c + Display user limits in the output from pngtest. + Eliminated the PNG_SAFE_LIMITS macro and restored the 1-million-column + and 1-million-row default limits in pnglibconf.dfa, that can be reset + by the user at build time or run time. This provides a more robust + defense against DOS and as-yet undiscovered overflows. Send comments/corrections/commendations to png-mng-implement at lists.sf.net (subscription required; visit diff --git a/pngpriv.h b/pngpriv.h index 5a41e94b2..fedb5238c 100644 --- a/pngpriv.h +++ b/pngpriv.h @@ -188,36 +188,6 @@ * real system capabilities. */ -#ifdef PNG_SAFE_LIMITS_SUPPORTED - /* 'safe' limits */ -# ifndef PNG_USER_WIDTH_MAX -# define PNG_USER_WIDTH_MAX 1000000 -# endif -# ifndef PNG_USER_HEIGHT_MAX -# define PNG_USER_HEIGHT_MAX 1000000 -# endif -# ifndef PNG_USER_CHUNK_CACHE_MAX -# define PNG_USER_CHUNK_CACHE_MAX 128 -# endif -# ifndef PNG_USER_CHUNK_MALLOC_MAX -# define PNG_USER_CHUNK_MALLOC_MAX 8000000 -# endif -#else - /* values for no limits */ -# ifndef PNG_USER_WIDTH_MAX -# define PNG_USER_WIDTH_MAX 0x7fffffff -# endif -# ifndef PNG_USER_HEIGHT_MAX -# define PNG_USER_HEIGHT_MAX 0x7fffffff -# endif -# ifndef PNG_USER_CHUNK_CACHE_MAX -# define PNG_USER_CHUNK_CACHE_MAX 0 -# endif -# ifndef PNG_USER_CHUNK_MALLOC_MAX -# define PNG_USER_CHUNK_MALLOC_MAX 0 -# endif -#endif - /* config.h is created by and PNG_CONFIGURE_LIBPNG is set by the "configure" * script. We may need it here to get the correct configuration on things * like limits. @@ -228,9 +198,11 @@ # endif #endif -/* Moved to pngpriv.h at libpng-1.5.0 */ -/* NOTE: some of these may have been used in external applications as - * these definitions were exposed in pngconf.h prior to 1.5. +/* SECURITY and SAFETY: + * + * 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. */ /* If you are running on a machine where you cannot allocate more @@ -248,6 +220,11 @@ # define PNG_MAX_MALLOC_64K #endif +/* Moved to pngpriv.h at libpng-1.5.0 */ +/* NOTE: some of these may have been used in external applications as + * these definitions were exposed in pngconf.h prior to 1.5. + */ + #ifndef PNG_UNUSED /* Unused formal parameter warnings are silenced using the following macro * which is expected to have no bad effects on performance (optimizing diff --git a/pngtest.c b/pngtest.c index 8703029cd..cde814f4f 100644 --- a/pngtest.c +++ b/pngtest.c @@ -1,8 +1,7 @@ - /* pngtest.c - a simple test program to test libpng * - * Last changed in libpng 1.5.19 [August 21, 2014] - * Copyright (c) 1998-2014 Glenn Randers-Pehrson + * Last changed in libpng 1.5.22 [(PENDING RELEASE)] + * Copyright (c) 1998-2015 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.) * @@ -283,7 +282,8 @@ count_zero_samples(png_structp png_ptr, png_row_infop row_info, png_bytep data) png_uint_32 n, nstop; int channel; int color_channels = row_info->channels; - if (row_info->color_type > 3)color_channels--; + if (row_info->color_type > 3) + color_channels--; for (n = 0, nstop=row_info->width; nnext == NULL) { - fprintf(STDERR, "Pointer %x not found\n", (unsigned int)ptr); + fprintf(STDERR, "Pointer %p not found\n", ptr); break; } @@ -604,7 +604,7 @@ png_debug_free(png_structp png_ptr, png_voidp ptr) free(ptr); ptr = NULL; } -#endif /* PNG_USER_MEM_SUPPORTED && PNG_DEBUG */ +#endif /* USER_MEM && DEBUG */ /* END of code to test memory allocation/deallocation */ @@ -643,7 +643,7 @@ set_location(png_structp png_ptr, struct user_chunk_data *data, int what) { int location; - if ((data->location[0] & what) || (data->location[1] & what)) + if ((data->location[0] & what) != 0 || (data->location[1] & what) != 0) return 0; /* already have one of these */ /* Find where we are (the code below zeroes info_ptr to indicate that the @@ -652,7 +652,7 @@ set_location(png_structp png_ptr, struct user_chunk_data *data, int what) if (data->info_ptr == NULL) /* after IDAT */ location = what | after_IDAT; - else if (png_get_valid(png_ptr, data->info_ptr, PNG_INFO_PLTE)) + else if (png_get_valid(png_ptr, data->info_ptr, PNG_INFO_PLTE) != 0) location = what | before_IDAT; else @@ -667,8 +667,8 @@ set_location(png_structp png_ptr, struct user_chunk_data *data, int what) return 1; /* handled */ } -static int PNGCBAPI read_user_chunk_callback(png_struct *png_ptr, - png_unknown_chunkp chunk) +static int PNGCBAPI +read_user_chunk_callback(png_struct *png_ptr, png_unknown_chunkp chunk) { struct user_chunk_data *my_user_chunk_data = (struct user_chunk_data*)png_get_user_chunk_ptr(png_ptr); @@ -699,7 +699,7 @@ static int PNGCBAPI read_user_chunk_callback(png_struct *png_ptr, if (chunk->data[0] != 0 && chunk->data[0] != 1) return (-1); /* Invalid mode */ - if (set_location(png_ptr, my_user_chunk_data, have_sTER)) + if (set_location(png_ptr, my_user_chunk_data, have_sTER) != 0) { my_user_chunk_data->sTER_mode=chunk->data[0]; return (1); @@ -718,7 +718,7 @@ static int PNGCBAPI read_user_chunk_callback(png_struct *png_ptr, if (chunk->size != 9) return (-1); /* Error return */ - if (!set_location(png_ptr, my_user_chunk_data, have_vpAg)) + if (set_location(png_ptr, my_user_chunk_data, have_vpAg) == 0) return (0); /* duplicate vpAg */ my_user_chunk_data->vpAg_width = png_get_uint_31(png_ptr, chunk->data); @@ -779,8 +779,8 @@ write_chunks(png_structp write_ptr, int location) write_vpAg_chunk(write_ptr); } } -#endif /* PNG_WRITE_SUPPORTED */ -#else /* !PNG_READ_USER_CHUNKS_SUPPORTED */ +#endif /* WRITE */ +#else /* !READ_USER_CHUNKS */ # define write_chunks(pp,loc) ((void)0) #endif /* END of code to demonstrate user chunk support */ @@ -1049,7 +1049,7 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname) int interlace_type, compression_type, filter_type; if (png_get_IHDR(read_ptr, read_info_ptr, &width, &height, &bit_depth, - &color_type, &interlace_type, &compression_type, &filter_type)) + &color_type, &interlace_type, &compression_type, &filter_type) != 0) { png_set_IHDR(write_ptr, write_info_ptr, width, height, bit_depth, color_type, interlace_type, compression_type, filter_type); @@ -1082,7 +1082,7 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname) blue_y; if (png_get_cHRM_fixed(read_ptr, read_info_ptr, &white_x, &white_y, - &red_x, &red_y, &green_x, &green_y, &blue_x, &blue_y)) + &red_x, &red_y, &green_x, &green_y, &blue_x, &blue_y) != 0) { png_set_cHRM_fixed(write_ptr, write_info_ptr, white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y); @@ -1093,7 +1093,7 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname) { png_fixed_point gamma; - if (png_get_gAMA_fixed(read_ptr, read_info_ptr, &gamma)) + if (png_get_gAMA_fixed(read_ptr, read_info_ptr, &gamma) != 0) png_set_gAMA_fixed(write_ptr, write_info_ptr, gamma); } #endif @@ -1105,7 +1105,7 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname) blue_y; if (png_get_cHRM(read_ptr, read_info_ptr, &white_x, &white_y, &red_x, - &red_y, &green_x, &green_y, &blue_x, &blue_y)) + &red_y, &green_x, &green_y, &blue_x, &blue_y) != 0) { png_set_cHRM(write_ptr, write_info_ptr, white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y); @@ -1116,7 +1116,7 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname) { double gamma; - if (png_get_gAMA(read_ptr, read_info_ptr, &gamma)) + if (png_get_gAMA(read_ptr, read_info_ptr, &gamma) != 0) png_set_gAMA(write_ptr, write_info_ptr, gamma); } #endif @@ -1130,7 +1130,7 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname) int compression_type; if (png_get_iCCP(read_ptr, read_info_ptr, &name, &compression_type, - &profile, &proflen)) + &profile, &proflen) != 0) { png_set_iCCP(write_ptr, write_info_ptr, name, compression_type, profile, proflen); @@ -1141,7 +1141,7 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname) { int intent; - if (png_get_sRGB(read_ptr, read_info_ptr, &intent)) + if (png_get_sRGB(read_ptr, read_info_ptr, &intent) != 0) png_set_sRGB(write_ptr, write_info_ptr, intent); } #endif @@ -1149,14 +1149,14 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname) png_colorp palette; int num_palette; - if (png_get_PLTE(read_ptr, read_info_ptr, &palette, &num_palette)) + if (png_get_PLTE(read_ptr, read_info_ptr, &palette, &num_palette) != 0) png_set_PLTE(write_ptr, write_info_ptr, palette, num_palette); } #ifdef PNG_bKGD_SUPPORTED { png_color_16p background; - if (png_get_bKGD(read_ptr, read_info_ptr, &background)) + if (png_get_bKGD(read_ptr, read_info_ptr, &background) != 0) { png_set_bKGD(write_ptr, write_info_ptr, background); } @@ -1166,7 +1166,7 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname) { png_uint_16p hist; - if (png_get_hIST(read_ptr, read_info_ptr, &hist)) + if (png_get_hIST(read_ptr, read_info_ptr, &hist) != 0) png_set_hIST(write_ptr, write_info_ptr, hist); } #endif @@ -1176,7 +1176,7 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname) int unit_type; if (png_get_oFFs(read_ptr, read_info_ptr, &offset_x, &offset_y, - &unit_type)) + &unit_type) != 0) { png_set_oFFs(write_ptr, write_info_ptr, offset_x, offset_y, unit_type); } @@ -1190,7 +1190,7 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname) int type, nparams; if (png_get_pCAL(read_ptr, read_info_ptr, &purpose, &X0, &X1, &type, - &nparams, &units, ¶ms)) + &nparams, &units, ¶ms) != 0) { png_set_pCAL(write_ptr, write_info_ptr, purpose, X0, X1, type, nparams, units, params); @@ -1202,7 +1202,8 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname) png_uint_32 res_x, res_y; int unit_type; - if (png_get_pHYs(read_ptr, read_info_ptr, &res_x, &res_y, &unit_type)) + if (png_get_pHYs(read_ptr, read_info_ptr, &res_x, &res_y, + &unit_type) != 0) png_set_pHYs(write_ptr, write_info_ptr, res_x, res_y, unit_type); } #endif @@ -1210,7 +1211,7 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname) { png_color_8p sig_bit; - if (png_get_sBIT(read_ptr, read_info_ptr, &sig_bit)) + if (png_get_sBIT(read_ptr, read_info_ptr, &sig_bit) != 0) png_set_sBIT(write_ptr, write_info_ptr, sig_bit); } #endif @@ -1222,7 +1223,7 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname) double scal_width, scal_height; if (png_get_sCAL(read_ptr, read_info_ptr, &unit, &scal_width, - &scal_height)) + &scal_height) != 0) { png_set_sCAL(write_ptr, write_info_ptr, unit, scal_width, scal_height); } @@ -1234,7 +1235,7 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname) png_charp scal_width, scal_height; if (png_get_sCAL_s(read_ptr, read_info_ptr, &unit, &scal_width, - &scal_height)) + &scal_height) != 0) { png_set_sCAL_s(write_ptr, write_info_ptr, unit, scal_width, scal_height); @@ -1274,7 +1275,7 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname) { png_timep mod_time; - if (png_get_tIME(read_ptr, read_info_ptr, &mod_time)) + if (png_get_tIME(read_ptr, read_info_ptr, &mod_time) != 0) { png_set_tIME(write_ptr, write_info_ptr, mod_time); #ifdef PNG_TIME_RFC1123_SUPPORTED @@ -1283,12 +1284,12 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname) * we use it. */ memcpy(tIME_string, - png_convert_to_rfc1123(read_ptr, mod_time), - png_sizeof(tIME_string)); + png_convert_to_rfc1123(read_ptr, mod_time), + png_sizeof(tIME_string)); tIME_string[png_sizeof(tIME_string) - 1] = '\0'; tIME_chunk_present++; -#endif /* PNG_TIME_RFC1123_SUPPORTED */ +#endif /* TIME_RFC1123 */ } } #endif @@ -1299,7 +1300,7 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname) png_color_16p trans_color; if (png_get_tRNS(read_ptr, read_info_ptr, &trans_alpha, &num_trans, - &trans_color)) + &trans_color) != 0) { int sample_max = (1 << bit_depth); /* libpng doesn't reject a tRNS chunk with out-of-range samples */ @@ -1382,11 +1383,12 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname) { #ifndef SINGLE_ROWBUF_ALLOC pngtest_debug2("Allocating row buffer (pass %d, y = %u)...", pass, y); + row_buf = (png_bytep)png_malloc(read_ptr, png_get_rowbytes(read_ptr, read_info_ptr)); - pngtest_debug2("\t0x%08lx (%u bytes)", (unsigned long)row_buf, - png_get_rowbytes(read_ptr, read_info_ptr)); + pngtest_debug2("\t0x%08lx (%lu bytes)", (unsigned long)row_buf, + (unsigned long)png_get_rowbytes(read_ptr, read_info_ptr)); #endif /* !SINGLE_ROWBUF_ALLOC */ png_read_rows(read_ptr, (png_bytepp)&row_buf, NULL, 1); @@ -1403,7 +1405,7 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname) t_encode += (t_stop - t_start); t_start = t_stop; #endif -#endif /* PNG_WRITE_SUPPORTED */ +#endif /* WRITE */ #ifndef SINGLE_ROWBUF_ALLOC pngtest_debug2("Freeing row buffer (pass %d, y = %u)", pass, y); @@ -1456,7 +1458,7 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname) { png_timep mod_time; - if (png_get_tIME(read_ptr, end_info_ptr, &mod_time)) + if (png_get_tIME(read_ptr, end_info_ptr, &mod_time) != 0) { png_set_tIME(write_ptr, write_end_info_ptr, mod_time); #ifdef PNG_TIME_RFC1123_SUPPORTED @@ -1464,12 +1466,12 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname) pointed to by png_convert_to_rfc1123() gets free'ed before we use it */ memcpy(tIME_string, - png_convert_to_rfc1123(read_ptr, mod_time), - png_sizeof(tIME_string)); + png_convert_to_rfc1123(read_ptr, mod_time), + png_sizeof(tIME_string)); tIME_string[png_sizeof(tIME_string) - 1] = '\0'; tIME_chunk_present++; -#endif /* PNG_TIME_RFC1123_SUPPORTED */ +#endif /* TIME_RFC1123 */ } } #endif @@ -1674,7 +1676,7 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname) } } } -#endif /* PNG_WRITE_SUPPORTED */ +#endif /* WRITE */ FCLOSE(fpin); FCLOSE(fpout); @@ -1697,6 +1699,8 @@ main(int argc, char *argv[]) int multiple = 0; int ierror = 0; + png_structp dummy_ptr; + fprintf(STDERR, "\n Testing libpng version %s\n", PNG_LIBPNG_VER_STRING); fprintf(STDERR, " with zlib version %s\n", ZLIB_VERSION); fprintf(STDERR, "%s", png_get_copyright(NULL)); @@ -1779,10 +1783,11 @@ main(int argc, char *argv[]) } } - if (!multiple && argc == 3 + verbose) + if (multiple == 0 && argc == 3 + verbose) outname = argv[2 + verbose]; - if ((!multiple && argc > 3 + verbose) || (multiple && argc < 2)) + if ((multiple == 0 && argc > 3 + verbose) || + (multiple != 0 && argc < 2)) { fprintf(STDERR, "usage: %s [infile.png] [outfile.png]\n\t%s -m {infile.png}\n", @@ -1804,6 +1809,9 @@ main(int argc, char *argv[]) { int kerror; fprintf(STDERR, "\n Testing %s:", argv[i]); +#if PNG_DEBUG > 0 + fprintf(STDERR, "\n"); +#endif kerror = test_one_file(argv[i], outname); if (kerror == 0) { @@ -1818,16 +1826,14 @@ main(int argc, char *argv[]) #endif #ifdef PNG_READ_USER_TRANSFORM_SUPPORTED for (k = 0; k<256; k++) - if (filters_used[k]) + if (filters_used[k] != 0) fprintf(STDERR, " Filter %d was used %lu times\n", k, (unsigned long)filters_used[k]); #endif #ifdef PNG_TIME_RFC1123_SUPPORTED - if (tIME_chunk_present != 0) - fprintf(STDERR, " tIME = %s\n", tIME_string); - - tIME_chunk_present = 0; -#endif /* PNG_TIME_RFC1123_SUPPORTED */ + if (tIME_chunk_present != 0) + fprintf(STDERR, " tIME = %s\n", tIME_string); +#endif /* TIME_RFC1123 */ } else @@ -1849,9 +1855,9 @@ main(int argc, char *argv[]) while (pinfo != NULL) { - fprintf(STDERR, " %lu bytes at %x\n", + fprintf(STDERR, " %lu bytes at %p\n", (unsigned long)pinfo->size, - (unsigned int)pinfo->pointer); + pinfo->pointer); pinfo = pinfo->next; } } @@ -1885,7 +1891,12 @@ main(int argc, char *argv[]) status_dots_requested = 0; if (i == 0 || verbose == 1 || ierror != 0) + { fprintf(STDERR, "\n Testing %s:", inname); +#if PNG_DEBUG > 0 + fprintf(STDERR, "\n"); +#endif + } kerror = test_one_file(inname, outname); @@ -1904,21 +1915,26 @@ main(int argc, char *argv[]) #endif #ifdef PNG_READ_USER_TRANSFORM_SUPPORTED for (k = 0; k<256; k++) - if (filters_used[k]) + if (filters_used[k] != 0) fprintf(STDERR, " Filter %d was used %lu times\n", k, (unsigned long)filters_used[k]); #endif #ifdef PNG_TIME_RFC1123_SUPPORTED if (tIME_chunk_present != 0) fprintf(STDERR, " tIME = %s\n", tIME_string); -#endif /* PNG_TIME_RFC1123_SUPPORTED */ +#endif /* TIME_RFC1123 */ } } else { if (verbose == 0 && i != 2) + { fprintf(STDERR, "\n Testing %s:", inname); +#if PNG_DEBUG > 0 + fprintf(STDERR, "\n"); +#endif + } fprintf(STDERR, " FAIL\n"); ierror += kerror; @@ -1937,8 +1953,8 @@ main(int argc, char *argv[]) while (pinfo != NULL) { - fprintf(STDERR, " %lu bytes at %x\n", - (unsigned long)pinfo->size, (unsigned int)pinfo->pointer); + fprintf(STDERR, " %lu bytes at %p\n", + (unsigned long)pinfo->size, pinfo->pointer); pinfo = pinfo->next; } } @@ -1976,6 +1992,24 @@ main(int argc, char *argv[]) else fprintf(STDERR, " libpng FAILS test\n"); + dummy_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); + fprintf(STDERR, " Default limits:\n"); + fprintf(STDERR, " width_max = %lu\n", + (unsigned long) png_get_user_width_max(dummy_ptr)); + fprintf(STDERR, " height_max = %lu\n", + (unsigned long) png_get_user_height_max(dummy_ptr)); + if (png_get_chunk_cache_max(dummy_ptr) == 0) + fprintf(STDERR, " cache_max = unlimited\n"); + else + fprintf(STDERR, " cache_max = %lu\n", + (unsigned long) png_get_chunk_cache_max(dummy_ptr)); + if (png_get_chunk_malloc_max(dummy_ptr) == 0) + fprintf(STDERR, " malloc_max = unlimited\n"); + else + fprintf(STDERR, " malloc_max = %lu\n", + (unsigned long) png_get_chunk_malloc_max(dummy_ptr)); + png_destroy_read_struct(&dummy_ptr, NULL, NULL); + return (int)(ierror != 0); } #else diff --git a/pngusr.dfa b/pngusr.dfa index 9d39564b5..83067c38c 100644 --- a/pngusr.dfa +++ b/pngusr.dfa @@ -8,7 +8,7 @@ # here by entering the appropriate values as #defines preceded by '@' (to cause, # them to be passed through to the build of pnglibconf.h), for example: # -# @# define PNG_USER_WIDTH_MAX 1000000 -# @# define PNG_USER_HEIGHT_MAX 1000000 -# @# define PNG_USER_CHUNK_CACHE_MAX 128 -# @# define PNG_USER_CHUNK_MALLOC_MAX 8000000 +# @# define PNG_USER_WIDTH_MAX 65535 +# @# define PNG_USER_HEIGHT_MAX 65535 +# @# define PNG_USER_CHUNK_CACHE_MAX 256 +# @# define PNG_USER_CHUNK_MALLOC_MAX 640000 diff --git a/scripts/pnglibconf.dfa b/scripts/pnglibconf.dfa index 986b8078f..4c0cb2e85 100644 --- a/scripts/pnglibconf.dfa +++ b/scripts/pnglibconf.dfa @@ -282,41 +282,32 @@ option IO_STATE #option READ_BIG_ENDIAN disabled -# Allow users to control limits on what the READ code will -# read: - -# Added at libpng-1.2.43; adds limit fields to png_struct, -# allows some usages of these fields - -option USER_LIMITS - -# Added at libpng-1.2.6; adds setting APIs, allows additional -# usage of this field (UTSL) - -option SET_USER_LIMITS requires USER_LIMITS - -# Feature added at libpng-1.4.0, this flag added at 1.4.1 -option SET_USER_LIMITS enables SET_CHUNK_CACHE_LIMIT -# Feature added at libpng-1.4.1, this flag added at 1.4.1 - -option SET_USER_LIMITS enables SET_CHUNK_MALLOC_LIMIT - -# Libpng limits. +# Libpng limits: limit the size of images and data on read. # -# If these settings are *not* set libpng will not limit the size of -# images or the size of data in ancilliary chunks. This does lead to -# security issues if PNG files come from untrusted sources. -setting USER_WIDTH_MAX -setting USER_HEIGHT_MAX -setting USER_CHUNK_CACHE_MAX -setting USER_CHUNK_MALLOC_MAX +# If this option is disabled all the limit checking code will be disabled: -# To default all these settings to values that are large but probably -# safe turn the SAFE_LIMITS option on; this will cause the value in -# pngpriv.h to be used. Individual values can also be set, simply set -# them in pngusr.dfa with '@#define PNG_setting value' lines. -option SAFE_LIMITS enables USER_LIMITS disabled -= SAFE_LIMITS SAFE_LIMITS +option USER_LIMITS requires READ + +# The default settings given below for the limits mean that libpng will +# limit the size of images or the size of data in ancilliary chunks to less +# than the specification or implementation limits. Settings have the +# following interpretations: +# +# USER_WIDTH_MAX: maximum width of an image that will be read +# USER_HEIGHT_MAX: maximum height +# USER_CHUNK_MALLOC_MAX: maximum in-memory (decompressed) size of a single chunk +# USER_CHUNK_CACHE_MAX: maximum number of chunks to be cached +# +# Only chunks that are variable in number are counted towards the +# USER_CHUNK_CACHE_MAX limit +setting USER_WIDTH_MAX default 1000000 /* Use 0x7fffffff for unlimited */ +setting USER_HEIGHT_MAX default 1000000 /* Use 0x7fffffff for unlimited */ +setting USER_CHUNK_CACHE_MAX default 1000 /* Use 0 for unlimited */ +setting USER_CHUNK_MALLOC_MAX default 8000000 /* Use 0 for unlimited */ + +# If this option is enabled APIs to set the above limits at run time are added; +# without this the hardwired (compile time) limits will be used. +option SET_USER_LIMITS requires USER_LIMITS # All of the following options relate to code capabilities for # processing image data before creating a PNG or after reading one. diff --git a/scripts/pnglibconf.h.prebuilt b/scripts/pnglibconf.h.prebuilt index 1da0119c3..655284d35 100644 --- a/scripts/pnglibconf.h.prebuilt +++ b/scripts/pnglibconf.h.prebuilt @@ -1,7 +1,7 @@ /* 1.5.22beta02 STANDARD API DEFINITION */ /* pnglibconf.h - library build configuration */ -/* libpng version 1.5.22beta02 - January 29, 2015 */ +/* libpng version 1.5.22beta02 - February 17, 2015 */ /* Copyright (c) 1998-2013 Glenn Randers-Pehrson */ @@ -179,6 +179,10 @@ #define PNG_QUANTIZE_BLUE_BITS 5 #define PNG_QUANTIZE_GREEN_BITS 5 #define PNG_QUANTIZE_RED_BITS 5 +#define PNG_USER_CHUNK_CACHE_MAX 1000 /* Use 0 for unlimited */ +#define PNG_USER_CHUNK_MALLOC_MAX 8000000 /* Use 0 for unlimited */ +#define PNG_USER_HEIGHT_MAX 1000000 /* Use 0x7fffffff for unlimited */ +#define PNG_USER_WIDTH_MAX 1000000 /* Use 0x7fffffff for unlimited */ #define PNG_WEIGHT_SHIFT 8 #define PNG_ZBUF_SIZE 8192 #define PNG_sCAL_PRECISION 5