diff --git a/ANNOUNCE b/ANNOUNCE index faa48cd20..5c37932d3 100644 --- a/ANNOUNCE +++ b/ANNOUNCE @@ -310,6 +310,13 @@ Version 1.6.0beta18 [March 16, 2012] this is necessary because the VS2010 output window otherwise simply loses the error messages on error (they weren't flushed to the window before the process exited, apparently!) + Added configuration support for benign errors and changed the read + default. Also changed some warnings in the iCCP and sRGB handling + from to benign errors. Configuration now makes read benign + errors warnings and write benign errors to errors by default (thus + changing the behavior on read). The simplified API always forces + read errors to benign errors (regardless of the system default, unless + this is disabled in which case the simplified API can't be built.) Send comments/corrections/commendations to png-mng-implement at lists.sf.net (subscription required; visit diff --git a/CHANGES b/CHANGES index 40cebb7f0..5dec7bd34 100644 --- a/CHANGES +++ b/CHANGES @@ -4061,6 +4061,13 @@ Version 1.6.0beta18 [March 16, 2012] this is necessary because the VS2010 output window otherwise simply loses the error messages on error (they weren't flushed to the window before the process exited, apparently!) + Added configuration support for benign errors and changed the read + default. Also changed some warnings in the iCCP and sRGB handling + from to benign errors. Configuration now makes read benign + errors warnings and write benign errors to errors by default (thus + changing the behavior on read). The simplified API always forces + read errors to benign errors (regardless of the system default, unless + this is disabled in which case the simplified API can't be built.) Send comments/corrections/commendations to png-mng-implement at lists.sf.net (subscription required; visit diff --git a/pngread.c b/pngread.c index 36e02d5ee..4601f8e83 100644 --- a/pngread.c +++ b/pngread.c @@ -50,12 +50,17 @@ png_create_read_struct_2,(png_const_charp user_png_ver, png_voidp error_ptr, { png_ptr->mode = PNG_IS_READ_STRUCT; - /* Adding in libpng-1.6.0; this can be used to detect a read structure if + /* Added in libpng-1.6.0; this can be used to detect a read structure if * required (it will be zero in a write structure.) */ # ifdef PNG_SEQUENTIAL_READ_SUPPORTED png_ptr->IDAT_read_size = PNG_IDAT_READ_SIZE; # endif + +# ifdef PNG_BENIGN_READ_ERRORS_SUPPORTED + png_ptr->flags |= PNG_FLAG_BENIGN_ERRORS_WARN; +# endif + /* TODO: delay this, it can be done in png_init_io (if the app doesn't * do it itself) avoiding setting the default function if it is not * required. @@ -1085,6 +1090,7 @@ png_read_png(png_structrp png_ptr, png_inforp info_ptr, /* Arguments to png_image_finish_read: */ /* Encoding of PNG data (used by the color-map code) */ +/* TODO: change these, dang, ANSI-C reserves the 'E' namespace. */ # define E_NOTSET 0 /* File encoding not yet known */ # define E_sRGB 1 /* 8-bit encoded to sRGB gamma */ # define E_LINEAR 2 /* 16-bit linear: not encoded, NOT pre-multiplied! */ @@ -1237,6 +1243,7 @@ png_image_read_header(png_voidp argument) png_structrp png_ptr = image->opaque->png_ptr; png_inforp info_ptr = image->opaque->info_ptr; + png_set_benign_errors(png_ptr, 1/*warn*/); png_read_info(png_ptr, info_ptr); /* Do this the fast way; just read directly out of png_struct. */ diff --git a/pngrutil.c b/pngrutil.c index 981a1bbbe..6d7eec45d 100644 --- a/pngrutil.c +++ b/pngrutil.c @@ -1297,31 +1297,33 @@ png_handle_sRGB(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) png_debug(1, "in png_handle_sRGB"); + if (png_ptr->mode & PNG_HAVE_iCCP) + { + png_crc_finish(png_ptr, length); + png_chunk_benign_error(png_ptr, "duplicate color profile"); + return; + } + + png_ptr->mode |= PNG_HAVE_iCCP; /* well, a colorspace */ + if (!(png_ptr->mode & PNG_HAVE_IHDR)) - png_error(png_ptr, "Missing IHDR before sRGB"); + png_error(png_ptr, "missing IHDR"); else if (png_ptr->mode & PNG_HAVE_IDAT) { - png_warning(png_ptr, "Invalid sRGB after IDAT"); png_crc_finish(png_ptr, length); + png_chunk_benign_error(png_ptr, "invalid after IDAT"); return; } else if (png_ptr->mode & PNG_HAVE_PLTE) /* Should be an error, but we can cope with it */ - png_warning(png_ptr, "Out of place sRGB chunk"); - - if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sRGB)) - { - png_warning(png_ptr, "Duplicate sRGB chunk"); - png_crc_finish(png_ptr, length); - return; - } + png_chunk_benign_error(png_ptr, "out of place"); if (length != 1) { - png_warning(png_ptr, "Incorrect sRGB chunk length"); png_crc_finish(png_ptr, length); + png_chunk_benign_error(png_ptr, "incorrect length"); return; } @@ -1419,7 +1421,7 @@ png_handle_sRGB(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) #ifdef PNG_READ_iCCP_SUPPORTED void /* PRIVATE */ png_handle_iCCP(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) -/* Note: this does not properly handle chunks that are > 64K under DOS */ +/* Note: this does not properly handle profiles that are > 64K under DOS */ { png_uint_32 keyword_length; png_const_charp error_message = NULL; @@ -1427,13 +1429,23 @@ png_handle_iCCP(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) png_debug(1, "in png_handle_iCCP"); + /* Do this first to set the 'HAVE_iCCP' flag in all cases, even errors */ + if (png_ptr->mode & PNG_HAVE_iCCP) + { + png_crc_finish(png_ptr, length); + png_chunk_benign_error(png_ptr, "duplicate color profile"); + return; + } + + png_ptr->mode |= PNG_HAVE_iCCP; + if (!(png_ptr->mode & PNG_HAVE_IHDR)) - png_error(png_ptr, "Missing IHDR before iCCP"); + png_error(png_ptr, "missing IHDR"); else if (png_ptr->mode & PNG_HAVE_IDAT) { png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "Invalid iCCP after IDAT"); + png_chunk_benign_error(png_ptr, "invalid after IDAT"); return; } @@ -1443,19 +1455,22 @@ png_handle_iCCP(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) * *have* to do so, so it is misleading if libpng handles them. */ png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "Out of place iCCP chunk"); + png_chunk_benign_error(png_ptr, "out of place"); return; } - if ((png_ptr->mode & PNG_HAVE_iCCP) || (info_ptr != NULL && - (info_ptr->valid & (PNG_INFO_iCCP|PNG_INFO_sRGB)))) + else if (length < 132) /* minimum ICC profile size */ { png_crc_finish(png_ptr, length); - png_chunk_benign_error(png_ptr, "Duplicate color profile"); + png_chunk_benign_error(png_ptr, "too short"); return; } - png_ptr->mode |= PNG_HAVE_iCCP; + /* Now read the first 132 bytes. The largest LZ data requirement for 132 + * bytes of input is infinite; by doing really foolish things with the SYNC + * options to deflate it is possible to extend 132 bytes without limit. + */ + /**** WIP ****/ /* TODO: read the chunk in pieces, validating it as we go. */ buffer = png_read_buffer(png_ptr, length, 0/*!warn*/); diff --git a/pngwrite.c b/pngwrite.c index 7f213c9a6..8b3ed0604 100644 --- a/pngwrite.c +++ b/pngwrite.c @@ -491,6 +491,15 @@ png_create_write_struct_2,(png_const_charp user_png_ver, png_voidp error_ptr, png_ptr->zlib_text_method = 8; #endif /* PNG_WRITE_COMPRESSED_TEXT_SUPPORTED */ + /* This is a highly dubious configuration option; by default it is off, but + * it may be appropriate for private builds that are testing extensions not + * conformant to the current specification, or of applications that must not + * fail to write at all costs! + */ +# ifdef PNG_BENIGN_WRITE_ERRORS_SUPPORTED + png_ptr->flags |= PNG_FLAG_BENIGN_ERRORS_WARN; +# endif + if (png_ptr != NULL) { /* TODO: delay this, it can be done in png_init_io() (if the app doesn't @@ -1982,6 +1991,11 @@ png_image_write_main(png_voidp argument) int alpha = !colormap && (format & PNG_FORMAT_FLAG_ALPHA) != 0; int write_16bit = linear && !colormap && !display->convert_to_8bit; +# ifdef PNG_BENIGN_ERRORS_SUPPORTED + /* Make sure we error out on any bad situation */ + png_set_benign_errors(png_ptr, 0/*error*/); +# endif + /* Default the 'row_stride' parameter if required. */ if (display->row_stride == 0) display->row_stride = PNG_IMAGE_ROW_STRIDE(*image); diff --git a/scripts/pnglibconf.dfa b/scripts/pnglibconf.dfa index cc8e78655..97149771e 100644 --- a/scripts/pnglibconf.dfa +++ b/scripts/pnglibconf.dfa @@ -186,10 +186,36 @@ option READ_INT_FUNCTIONS requires READ option WRITE_INT_FUNCTIONS disabled option WRITE enables WRITE_INT_FUNCTIONS -# Generic options - affect both read and write. +# Error controls +# +# WARNINGS: normally on, if off no warnings are generated +# ERROR_TEXT: normally on, if off errors happen but there is no message +# ERROR_NUMBERS: unimplemented feature, therefore disabled +# BENIGN_ERRORS: support for just issuing warnings for recoverable errors +# +# BENIGN_READ_ERRORS: +# By default recoverable errors on read should just generate warnings, +# generally safe but PNG files that don't conform to the specification will +# be accepted if a meaningful result can be produced. +# +# BENIGN_WRITE_ERRORS: +# By default recoverable errors on write should just generate warnings, +# not generally safe because this allows the application to write invalid +# PNG files. Applications should enable this themselves; it's useful +# because it means that a failure to write an ancilliary chunk can often be +# ignored. option WARNINGS +option ERROR_TEXT +option ERROR_NUMBERS disabled + option BENIGN_ERRORS +option BENIGN_WRITE_ERRORS requires BENIGN_ERRORS disabled +option BENIGN_READ_ERRORS requires BENIGN_ERRORS + + +# Generic options - affect both read and write. + option MNG_FEATURES # Arithmetic options, the first is the big switch that chooses between internal @@ -200,10 +226,6 @@ option FLOATING_ARITHMETIC option FLOATING_POINT enables ok_math option FIXED_POINT enables ok_math -# Added at libpng version 1.4.0 - -option ERROR_TEXT - # The following is always on (defined empty) setting CALLOC_SUPPORTED default @@ -230,10 +252,6 @@ option TIME_RFC1123 option SETJMP = NO_SETJMP SETJMP_NOT_SUPPORTED -# For the moment this is disabled (no code support): - -option ERROR_NUMBERS disabled - # If this is disabled it is not possible for apps to get the # values from the 'info' structure, this effectively removes # quite a lot of the READ API. @@ -622,6 +640,7 @@ option WRITE_CHECK_FOR_INVALID_INDEX requires WRITE CHECK_FOR_INVALID_INDEX # Simplified API options (added at libpng-1.6.0) # Read: option SIMPLIFIED_READ requires SEQUENTIAL_READ READ_TRANSFORMS SETJMP +option SIMPLIFIED_READ requires BENIGN_ERRORS option SIMPLIFIED_READ enables READ_EXPAND READ_16BIT READ_EXPAND_16 option SIMPLIFIED_READ enables READ_SCALE_16_TO_8 READ_RGB_TO_GRAY option SIMPLIFIED_READ enables READ_ALPHA_MODE READ_BACKGROUND READ_STRIP_ALPHA diff --git a/scripts/pnglibconf.h.prebuilt b/scripts/pnglibconf.h.prebuilt index 07505ff9a..b7ac98317 100644 --- a/scripts/pnglibconf.h.prebuilt +++ b/scripts/pnglibconf.h.prebuilt @@ -3,7 +3,7 @@ /* pnglibconf.h - library build configuration */ -/* Libpng 1.6.0beta18 - March 10, 2012 */ +/* Libpng 1.6.0beta18 - March 16, 2012 */ /* Copyright (c) 1998-2012 Glenn Randers-Pehrson */ @@ -40,6 +40,8 @@ #define PNG_16BIT_SUPPORTED #define PNG_ALIGN_MEMORY_SUPPORTED #define PNG_BENIGN_ERRORS_SUPPORTED +#define PNG_BENIGN_READ_ERRORS_SUPPORTED +/*#undef PNG_BENIGN_WRITE_ERRORS_SUPPORTED*/ #define PNG_bKGD_SUPPORTED #define PNG_BUILD_GRAYSCALE_PALETTE_SUPPORTED #define PNG_CHECK_cHRM_SUPPORTED @@ -120,6 +122,7 @@ #define PNG_READ_USER_CHUNKS_SUPPORTED #define PNG_READ_USER_TRANSFORM_SUPPORTED #define PNG_READ_zTXt_SUPPORTED +/*#undef PNG_SAFE_LIMITS_SUPPORTED*/ #define PNG_SAVE_INT_32_SUPPORTED #define PNG_sBIT_SUPPORTED #define PNG_sCAL_SUPPORTED