mirror of
https://git.code.sf.net/p/libpng/code.git
synced 2025-07-10 18:04:09 +02:00
[libpng17] Improved some overflow handling. PNG_RELEASE_BUILD replaces tests
where the code depended on the build base type and can be defined on the command line, allowing testing in beta builds. Overflows previously handled by png_warning in png.c have been changed to use new macros/affirm functions so that beta builds will abort on overflow and release builds will quietly ignore it. This avoids release builds producing warnings that are of no use to end users.
This commit is contained in:
parent
82fa6aed0e
commit
36562c1032
8
ANNOUNCE
8
ANNOUNCE
@ -765,6 +765,14 @@ Version 1.7.0beta58 [March 22, 2015]
|
|||||||
and short assignments. Simply ignore the error in release builds
|
and short assignments. Simply ignore the error in release builds
|
||||||
(a truncated value will be used without warning). Controlled by
|
(a truncated value will be used without warning). Controlled by
|
||||||
PNG_RANGE_CHECK_SUPPORTED.
|
PNG_RANGE_CHECK_SUPPORTED.
|
||||||
|
Improved some overflow handling. PNG_RELEASE_BUILD replaces tests
|
||||||
|
where the code depended on the build base type and can be defined on
|
||||||
|
the command line, allowing testing in beta builds. Overflows previously
|
||||||
|
handled by png_warning in png.c have been changed to use new
|
||||||
|
macros/affirm functions so that beta builds will abort on overflow and
|
||||||
|
release builds will quietly ignore it. This avoids release builds
|
||||||
|
producing warnings that are of no use to end users.
|
||||||
|
|
||||||
|
|
||||||
Send comments/corrections/commendations to png-mng-implement at lists.sf.net
|
Send comments/corrections/commendations to png-mng-implement at lists.sf.net
|
||||||
(subscription required; visit
|
(subscription required; visit
|
||||||
|
|||||||
7
CHANGES
7
CHANGES
@ -5055,6 +5055,13 @@ Version 1.7.0beta58 [March 22, 2015]
|
|||||||
and short assignments. Simply ignore the error in release builds
|
and short assignments. Simply ignore the error in release builds
|
||||||
(a truncated value will be used without warning). Controlled by
|
(a truncated value will be used without warning). Controlled by
|
||||||
PNG_RANGE_CHECK_SUPPORTED.
|
PNG_RANGE_CHECK_SUPPORTED.
|
||||||
|
Improved some overflow handling. PNG_RELEASE_BUILD replaces tests
|
||||||
|
where the code depended on the build base type and can be defined on
|
||||||
|
the command line, allowing testing in beta builds. Overflows previously
|
||||||
|
handled by png_warning in png.c have been changed to use new
|
||||||
|
macros/affirm functions so that beta builds will abort on overflow and
|
||||||
|
release builds will quietly ignore it. This avoids release builds
|
||||||
|
producing warnings that are of no use to end users.
|
||||||
|
|
||||||
Send comments/corrections/commendations to png-mng-implement at lists.sf.net
|
Send comments/corrections/commendations to png-mng-implement at lists.sf.net
|
||||||
(subscription required; visit
|
(subscription required; visit
|
||||||
|
|||||||
11
png.c
11
png.c
@ -80,7 +80,7 @@ png_zalloc,(voidpf png_ptr, uInt items, uInt size),PNG_ALLOCATED)
|
|||||||
|
|
||||||
if (items >= (~(png_alloc_size_t)0)/size)
|
if (items >= (~(png_alloc_size_t)0)/size)
|
||||||
{
|
{
|
||||||
png_warning (png_voidcast(png_structrp, png_ptr),
|
png_warning(png_voidcast(png_structrp, png_ptr),
|
||||||
"Potential overflow in png_zalloc()");
|
"Potential overflow in png_zalloc()");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -3272,8 +3272,9 @@ png_muldiv_warn(png_const_structrp png_ptr, png_fixed_point a, png_int_32 times,
|
|||||||
if (png_muldiv(&result, a, times, divisor) != 0)
|
if (png_muldiv(&result, a, times, divisor) != 0)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
png_warning(png_ptr, "fixed point overflow ignored");
|
handled("fixed point overflow");
|
||||||
return 0;
|
return 0;
|
||||||
|
PNG_UNUSED(png_ptr) /* Only used in non-release builds */
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -3689,11 +3690,12 @@ png_gamma_8bit_correct(png_const_structrp png_ptr, png_uint_32 value,
|
|||||||
# endif
|
# endif
|
||||||
|
|
||||||
/* Overflow. */
|
/* Overflow. */
|
||||||
png_warning(png_ptr, "8-bit gamma overflow");
|
handled("8-bit gamma overflow");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return png_check_byte(png_ptr, value);
|
return png_check_byte(png_ptr, value);
|
||||||
|
PNG_UNUSED(png_ptr) /* Only used in non-release builds */
|
||||||
}
|
}
|
||||||
|
|
||||||
png_uint_16
|
png_uint_16
|
||||||
@ -3721,11 +3723,12 @@ png_gamma_16bit_correct(png_const_structrp png_ptr, png_uint_32 value,
|
|||||||
# endif
|
# endif
|
||||||
|
|
||||||
/* Overflow. */
|
/* Overflow. */
|
||||||
png_warning(png_ptr, "16-bit gamma overflow");
|
handled("16-bit gamma overflow");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return png_check_u16(png_ptr, value);
|
return png_check_u16(png_ptr, value);
|
||||||
|
PNG_UNUSED(png_ptr) /* Only used in non-release builds */
|
||||||
}
|
}
|
||||||
|
|
||||||
#define PNG_GAMMA_TABLE_8 0 /* 8-bit entries in png_byte */
|
#define PNG_GAMMA_TABLE_8 0 /* 8-bit entries in png_byte */
|
||||||
|
|||||||
220
pngerror.c
220
pngerror.c
@ -980,8 +980,8 @@ png_safe_execute(png_imagep image_in, int (*function)(png_voidp), png_voidp arg)
|
|||||||
* The code always produces a message if it is possible, regardless of the
|
* The code always produces a message if it is possible, regardless of the
|
||||||
* setting of PNG_ERROR_TEXT_SUPPORTED, except that in stable builds
|
* setting of PNG_ERROR_TEXT_SUPPORTED, except that in stable builds
|
||||||
* PNG_ERROR_TEXT_SUPPORTED is honoured. See pngpriv.h for the calculation of
|
* PNG_ERROR_TEXT_SUPPORTED is honoured. See pngpriv.h for the calculation of
|
||||||
* the two control macros PNG_AFFIRM_ERROR (don't abort; stable build or rc) and
|
* the two control macros PNG_RELEASE_BUILD (don't abort; stable build or rc)
|
||||||
* PNG_AFFIRM_TEXT (output text.)
|
* and PNG_AFFIRM_TEXT (output text.)
|
||||||
*/
|
*/
|
||||||
#if PNG_AFFIRM_TEXT
|
#if PNG_AFFIRM_TEXT
|
||||||
# ifdef PNG_HAVE_FORMAT_NUMBER
|
# ifdef PNG_HAVE_FORMAT_NUMBER
|
||||||
@ -1028,9 +1028,94 @@ png_affirm_number(png_charp buffer, size_t bufsize, size_t pos,
|
|||||||
}
|
}
|
||||||
# define affirm_number(a,b,c,d,e) png_affirm_number(a,b,c,d)
|
# define affirm_number(a,b,c,d,e) png_affirm_number(a,b,c,d)
|
||||||
#endif /* !HAVE_FORMAT_NUMBER */
|
#endif /* !HAVE_FORMAT_NUMBER */
|
||||||
|
|
||||||
|
#if PNG_RELEASE_BUILD
|
||||||
|
# define affirm_text(b, c, p)\
|
||||||
|
do {\
|
||||||
|
(affirm_text)(b, sizeof b, (p));\
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
static void
|
||||||
|
(affirm_text)(png_charp buffer, size_t bufsize, unsigned int position)
|
||||||
|
#else
|
||||||
|
# define affirm_text(b, c, p)\
|
||||||
|
do {\
|
||||||
|
(affirm_text)(b, sizeof b, (c), (p));\
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
static void
|
||||||
|
(affirm_text)(png_charp buffer, size_t bufsize, png_const_charp condition,
|
||||||
|
unsigned int position)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
/* Format the 'position' number and output:
|
||||||
|
*
|
||||||
|
* "<file>, <line>: affirm 'condition' failed\n"
|
||||||
|
* " libpng version <version> - <date>\n"
|
||||||
|
* " translated __DATE__ __TIME__"
|
||||||
|
*
|
||||||
|
* In the STABLE versions the output is the same for the last two lines
|
||||||
|
* but the first line becomes:
|
||||||
|
*
|
||||||
|
* "<position>: affirm failed"
|
||||||
|
*
|
||||||
|
* If there is no number formatting the numbers just get replaced by
|
||||||
|
* some binhex (see the utility above).
|
||||||
|
*/
|
||||||
|
size_t pos = 0;
|
||||||
|
|
||||||
|
# if PNG_RELEASE_BUILD /* no 'condition' parameter: minimal text */
|
||||||
|
pos = affirm_number(buffer, bufsize, pos, position, PNG_NUMBER_FORMAT_x);
|
||||||
|
pos = png_safecat(buffer, bufsize, pos, ": affirm failed");
|
||||||
|
# else /* !STABLE */
|
||||||
|
/* Break down 'position' into a file name and a line number: */
|
||||||
|
{
|
||||||
|
# define PNG_apply(f) { #f "\0", PNG_SRC_FILE_ ## f },
|
||||||
|
# define PNG_end { "", PNG_SRC_FILE_LAST }
|
||||||
|
static struct {
|
||||||
|
char filename[28]; /* GCC checks this size */
|
||||||
|
unsigned int base;
|
||||||
|
} fileinfo[] = { PNG_FILES };
|
||||||
|
# undef PNG_apply
|
||||||
|
# undef PNG_end
|
||||||
|
|
||||||
|
unsigned int i;
|
||||||
|
png_const_charp filename;
|
||||||
|
|
||||||
|
/* Do 'nfiles' this way to avoid problems with g++ where it whines
|
||||||
|
* about (size_t) being larger than (int), even though this is a
|
||||||
|
* compile time constant:
|
||||||
|
*/
|
||||||
|
# define nfiles ((sizeof fileinfo)/(sizeof (fileinfo[0])))
|
||||||
|
for (i=0; i < nfiles && position > fileinfo[i].base; ++i) {}
|
||||||
|
|
||||||
|
if (i == 0 || i > nfiles)
|
||||||
|
filename = "UNKNOWN";
|
||||||
|
else
|
||||||
|
{
|
||||||
|
filename = fileinfo[i-1].filename;
|
||||||
|
position -= fileinfo[i-1].base;
|
||||||
|
}
|
||||||
|
# undef nfiles
|
||||||
|
|
||||||
|
pos = png_safecat(buffer, bufsize, pos, filename);
|
||||||
|
pos = png_safecat(buffer, bufsize, pos, ".c, ");
|
||||||
|
pos = affirm_number(buffer, bufsize, pos, position,
|
||||||
|
PNG_NUMBER_FORMAT_u);
|
||||||
|
}
|
||||||
|
|
||||||
|
pos = png_safecat(buffer, bufsize, pos, ": affirm '");
|
||||||
|
pos = png_safecat(buffer, bufsize, pos, condition);
|
||||||
|
pos = png_safecat(buffer, bufsize, pos, "' failed\n");
|
||||||
|
# endif /* !STABLE */
|
||||||
|
|
||||||
|
pos = png_safecat(buffer, bufsize, pos, PNG_HEADER_VERSION_STRING);
|
||||||
|
pos = png_safecat(buffer, bufsize, pos,
|
||||||
|
" translated " __DATE__ " " __TIME__);
|
||||||
|
}
|
||||||
#endif /* AFFIRM_TEXT */
|
#endif /* AFFIRM_TEXT */
|
||||||
|
|
||||||
#if PNG_AFFIRM_ERROR
|
#if PNG_RELEASE_BUILD
|
||||||
PNG_FUNCTION(void, png_affirm,(png_const_structrp png_ptr,
|
PNG_FUNCTION(void, png_affirm,(png_const_structrp png_ptr,
|
||||||
unsigned int position), PNG_NORETURN)
|
unsigned int position), PNG_NORETURN)
|
||||||
#else
|
#else
|
||||||
@ -1039,74 +1124,12 @@ PNG_FUNCTION(void, png_affirm,(png_const_structrp png_ptr,
|
|||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
# if PNG_AFFIRM_TEXT
|
# if PNG_AFFIRM_TEXT
|
||||||
/* Format the 'position' number and output:
|
char buffer[512];
|
||||||
*
|
|
||||||
* " libpng version <version> - <date>\n"
|
|
||||||
* " translated __DATE__ __TIME__\n"
|
|
||||||
* " <file>, <line>: affirm 'condition' failed"
|
|
||||||
*
|
|
||||||
* In the STABLE versions the output is the same for the first two lines
|
|
||||||
* but the last line becomes:
|
|
||||||
*
|
|
||||||
* " <position>: affirm failed"
|
|
||||||
*
|
|
||||||
* If there is no number formatting the numbers just get replaced by
|
|
||||||
* some binhex (see the utility above).
|
|
||||||
*/
|
|
||||||
size_t pos;
|
|
||||||
char buffer[256];
|
|
||||||
|
|
||||||
pos = png_safecat(buffer, sizeof buffer, 0, PNG_HEADER_VERSION_STRING);
|
affirm_text(buffer, condition, position);
|
||||||
pos = png_safecat(buffer, sizeof buffer, pos,
|
|
||||||
" translated " __DATE__ " " __TIME__ "\n ");
|
|
||||||
# if PNG_AFFIRM_ERROR /* no 'condition' parameter: minimal text */
|
|
||||||
pos = affirm_number(buffer, sizeof buffer, pos, position,
|
|
||||||
PNG_NUMBER_FORMAT_x);
|
|
||||||
pos = png_safecat(buffer, sizeof buffer, pos, ": affirm failed");
|
|
||||||
# else /* !STABLE */
|
|
||||||
/* Break down 'position' into a file name and a line number: */
|
|
||||||
{
|
|
||||||
# define PNG_apply(f) { #f "\0", PNG_SRC_FILE_ ## f },
|
|
||||||
# define PNG_end { "", PNG_SRC_FILE_LAST }
|
|
||||||
static struct {
|
|
||||||
char filename[28]; /* GCC checks this size */
|
|
||||||
unsigned int base;
|
|
||||||
} fileinfo[] = { PNG_FILES };
|
|
||||||
# undef PNG_apply
|
|
||||||
# undef PNG_end
|
|
||||||
|
|
||||||
unsigned int i;
|
|
||||||
png_const_charp filename;
|
|
||||||
|
|
||||||
/* Do 'nfiles' this way to avoid problems with g++ where it whines
|
|
||||||
* about (size_t) being larger than (int), even though this is a
|
|
||||||
* compile time constant:
|
|
||||||
*/
|
|
||||||
# define nfiles ((sizeof fileinfo)/(sizeof (fileinfo[0])))
|
|
||||||
for (i=0; i < nfiles && position > fileinfo[i].base; ++i) {}
|
|
||||||
|
|
||||||
if (i == 0 || i > nfiles)
|
|
||||||
filename = "UNKNOWN";
|
|
||||||
else
|
|
||||||
{
|
|
||||||
filename = fileinfo[i-1].filename;
|
|
||||||
position -= fileinfo[i-1].base;
|
|
||||||
}
|
|
||||||
# undef nfiles
|
|
||||||
|
|
||||||
pos = png_safecat(buffer, sizeof buffer, pos, filename);
|
|
||||||
pos = png_safecat(buffer, sizeof buffer, pos, ".c, ");
|
|
||||||
pos = affirm_number(buffer, sizeof buffer, pos, position,
|
|
||||||
PNG_NUMBER_FORMAT_u);
|
|
||||||
}
|
|
||||||
|
|
||||||
pos = png_safecat(buffer, sizeof buffer, pos, ": affirm '");
|
|
||||||
pos = png_safecat(buffer, sizeof buffer, pos, condition);
|
|
||||||
pos = png_safecat(buffer, sizeof buffer, pos, "' failed");
|
|
||||||
# endif /* !STABLE */
|
|
||||||
# else /* !AFFIRM_TEXT */
|
# else /* !AFFIRM_TEXT */
|
||||||
PNG_UNUSED(position)
|
PNG_UNUSED(position)
|
||||||
# if !PNG_AFFIRM_ERROR
|
# if !PNG_RELEASE_BUILD
|
||||||
PNG_UNUSED(condition)
|
PNG_UNUSED(condition)
|
||||||
# endif
|
# endif
|
||||||
# endif /* AFFIRM_TEXT */
|
# endif /* AFFIRM_TEXT */
|
||||||
@ -1114,29 +1137,27 @@ PNG_FUNCTION(void, png_affirm,(png_const_structrp png_ptr,
|
|||||||
/* Now in STABLE do a png_error, but in other builds output the message
|
/* Now in STABLE do a png_error, but in other builds output the message
|
||||||
* (if possible) then abort (PNG_ABORT).
|
* (if possible) then abort (PNG_ABORT).
|
||||||
*/
|
*/
|
||||||
# if PNG_AFFIRM_ERROR
|
# if PNG_RELEASE_BUILD
|
||||||
png_error(png_ptr, buffer/*only if ERROR_TEXT*/);
|
png_error(png_ptr, buffer/*macro parameter used only if ERROR_TEXT*/);
|
||||||
# else /* !AFFIRM_ERROR */
|
# else /* !AFFIRM_ERROR */
|
||||||
/* Use the app warning message mechanism is possible, this is an inline
|
/* Use console IO if possible; this is because there is no guarantee that
|
||||||
* expansion of png_warning without the extra formatting of the message
|
* the app 'warning' will output anything. For certain the simplified
|
||||||
* that png_default_warning does and with the case !WARNINGS && CONSOLE_IO
|
* API implementation just copies the message (truncated) to the image
|
||||||
* implemented.
|
* message buffer, which makes debugging much more difficult.
|
||||||
*
|
*
|
||||||
* Note that it is possible that neither WARNINGS nor CONSOLE_IO are
|
* Note that it is possible that neither WARNINGS nor CONSOLE_IO are
|
||||||
* supported; in that case no text will be output (and PNG_AFFIRM_TEXT
|
* supported; in that case no text will be output (and PNG_AFFIRM_TEXT
|
||||||
* will be false.)
|
* will be false.)
|
||||||
*/
|
*/
|
||||||
# ifdef PNG_WARNINGS_SUPPORTED
|
|
||||||
if (png_ptr != NULL && png_ptr->warning_fn != NULL)
|
|
||||||
png_ptr->warning_fn(png_constcast(png_structrp,png_ptr), buffer);
|
|
||||||
# ifdef PNG_CONSOLE_IO_SUPPORTED
|
|
||||||
else
|
|
||||||
# endif
|
|
||||||
# else
|
|
||||||
PNG_UNUSED(png_ptr)
|
|
||||||
# endif
|
|
||||||
# ifdef PNG_CONSOLE_IO_SUPPORTED
|
# ifdef PNG_CONSOLE_IO_SUPPORTED
|
||||||
fprintf(stderr, "%s\n", buffer);
|
fprintf(stderr, "%s\n", buffer);
|
||||||
|
PNG_UNUSED(png_ptr)
|
||||||
|
# elif defined PNG_WARNINGS_SUPPORTED
|
||||||
|
if (png_ptr != NULL && png_ptr->warning_fn != NULL)
|
||||||
|
png_ptr->warning_fn(png_constcast(png_structrp, png_ptr), buffer);
|
||||||
|
/* else no way to output the text */
|
||||||
|
# else
|
||||||
|
PNG_UNUSED(png_ptr)
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
PNG_ABORT
|
PNG_ABORT
|
||||||
@ -1153,7 +1174,7 @@ png_char_affirm(png_const_structrp png_ptr, unsigned int position, int c)
|
|||||||
if (c >= CHAR_MIN && c <= CHAR_MAX)
|
if (c >= CHAR_MIN && c <= CHAR_MAX)
|
||||||
return (char)/*SAFE*/c;
|
return (char)/*SAFE*/c;
|
||||||
|
|
||||||
# if PNG_AFFIRM_ERROR
|
# if PNG_RELEASE_BUILD
|
||||||
/* testing in RC: no condition */
|
/* testing in RC: no condition */
|
||||||
png_affirm(png_ptr, position);
|
png_affirm(png_ptr, position);
|
||||||
# else
|
# else
|
||||||
@ -1170,7 +1191,7 @@ png_byte_affirm(png_const_structrp png_ptr, unsigned int position, int b)
|
|||||||
if (b >= 0 && b <= 255)
|
if (b >= 0 && b <= 255)
|
||||||
return (png_byte)/*SAFE*/b;
|
return (png_byte)/*SAFE*/b;
|
||||||
|
|
||||||
# if PNG_AFFIRM_ERROR
|
# if PNG_RELEASE_BUILD
|
||||||
/* testing in RC: no condition */
|
/* testing in RC: no condition */
|
||||||
png_affirm(png_ptr, position);
|
png_affirm(png_ptr, position);
|
||||||
# else
|
# else
|
||||||
@ -1186,7 +1207,7 @@ png_u16_affirm(png_const_structrp png_ptr, unsigned int position, int b)
|
|||||||
if (b >= 0 && b <= 65535)
|
if (b >= 0 && b <= 65535)
|
||||||
return (png_uint_16)/*SAFE*/b;
|
return (png_uint_16)/*SAFE*/b;
|
||||||
|
|
||||||
# if PNG_AFFIRM_ERROR
|
# if PNG_RELEASE_BUILD
|
||||||
/* testing in RC: no condition */
|
/* testing in RC: no condition */
|
||||||
png_affirm(png_ptr, position);
|
png_affirm(png_ptr, position);
|
||||||
# else
|
# else
|
||||||
@ -1194,5 +1215,32 @@ png_u16_affirm(png_const_structrp png_ptr, unsigned int position, int b)
|
|||||||
# endif
|
# endif
|
||||||
}
|
}
|
||||||
#endif /* INT_MAX >= 65535 */
|
#endif /* INT_MAX >= 65535 */
|
||||||
|
|
||||||
|
void /* PRIVATE */
|
||||||
|
png_handled_affirm(png_const_structrp png_ptr, png_const_charp message,
|
||||||
|
unsigned int position)
|
||||||
|
{
|
||||||
|
# if PNG_RELEASE_BUILD
|
||||||
|
/* testing in RC: we want to return control to the caller, so do not
|
||||||
|
* use png_affirm.
|
||||||
|
*/
|
||||||
|
char buffer[512];
|
||||||
|
|
||||||
|
affirm_text(buffer, message, position);
|
||||||
|
|
||||||
|
# ifdef PNG_CONSOLE_IO_SUPPORTED
|
||||||
|
fprintf(stderr, "%s\n", buffer);
|
||||||
|
# elif defined PNG_WARNINGS_SUPPORTED
|
||||||
|
if (png_ptr != NULL && png_ptr->warning_fn != NULL)
|
||||||
|
png_ptr->warning_fn(png_constcast(png_structrp, png_ptr), buffer);
|
||||||
|
/* else no way to output the text */
|
||||||
|
# else
|
||||||
|
PNG_UNUSED(png_ptr)
|
||||||
|
# endif
|
||||||
|
# else
|
||||||
|
png_affirm(png_ptr, message, position);
|
||||||
|
# endif
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* RANGE_CHECK */
|
#endif /* RANGE_CHECK */
|
||||||
#endif /* READ || WRITE */
|
#endif /* READ || WRITE */
|
||||||
|
|||||||
159
pngpriv.h
159
pngpriv.h
@ -332,6 +332,15 @@
|
|||||||
# define PNG_DLL_EXPORT
|
# define PNG_DLL_EXPORT
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* This is a global switch to set the compilation for an installed system
|
||||||
|
* (a release build). It can be set for testing debug builds to ensure that
|
||||||
|
* they will compile when the build type is switched to RC or STABLE, the
|
||||||
|
* default is just to use PNG_LIBPNG_BUILD_BASE_TYPE.
|
||||||
|
*/
|
||||||
|
#ifndef PNG_RELEASE_BUILD
|
||||||
|
# define PNG_RELEASE_BUILD (PNG_LIBPNG_BUILD_BASE_TYPE >= PNG_LIBPNG_BUILD_RC)
|
||||||
|
#endif
|
||||||
|
|
||||||
/* The affirm mechanism results in a minimal png_error in released versions
|
/* The affirm mechanism results in a minimal png_error in released versions
|
||||||
* ('STABLE' versions) and a more descriptive abort in all other cases.
|
* ('STABLE' versions) and a more descriptive abort in all other cases.
|
||||||
* The macros rely on the naming convention throughout this code - png_ptr
|
* The macros rely on the naming convention throughout this code - png_ptr
|
||||||
@ -351,21 +360,20 @@
|
|||||||
*
|
*
|
||||||
* The following works out the value for two numeric #defines:
|
* The following works out the value for two numeric #defines:
|
||||||
*
|
*
|
||||||
* PNG_AFFIRM_ERROR: Set to 1 if affirm should png_error (or png_err) rather
|
* PNG_RELEASE_BUILD: Set to 1 if affirm should png_error (or png_err) rather
|
||||||
* than abort. The png_error text is the minimal (file
|
* than abort. The png_error text is the minimal (file
|
||||||
* location) text in this case, if it is produced. This
|
* location) text in this case, if it is produced. This
|
||||||
* flag indicates a STABLE (or RC) build.
|
* flag indicates a STABLE (or RC) build.
|
||||||
* PNG_AFFIRM_TEXT: Set to 1 if affirm text should be produced, either the
|
* PNG_AFFIRM_TEXT: Set to 1 if affirm text should be produced, either the
|
||||||
* minimal text or, if PNG_AFFIRM_ERROR is 0, the more
|
* minimal text or, if PNG_RELEASE_BUILD is 0, the more
|
||||||
* verbose text including the 'condition' string. This
|
* verbose text including the 'condition' string. This
|
||||||
* value depends on whether the build supports an
|
* value depends on whether the build supports an
|
||||||
* appropriate way of outputing the message.
|
* appropriate way of outputting the message.
|
||||||
*
|
*
|
||||||
* Note that these are not configurable: this is just the affirm code, there's
|
* Note that these are not configurable: this is just the affirm code; there's
|
||||||
* no reason to allow configuration of these options.
|
* no reason to allow configuration of these options.
|
||||||
*/
|
*/
|
||||||
#define PNG_AFFIRM_ERROR (PNG_LIBPNG_BUILD_BASE_TYPE >= PNG_LIBPNG_BUILD_RC)
|
#define PNG_AFFIRM_TEXT (PNG_RELEASE_BUILD ?\
|
||||||
#define PNG_AFFIRM_TEXT (PNG_AFFIRM_ERROR ?\
|
|
||||||
(defined PNG_ERROR_TEXT_SUPPORTED) :\
|
(defined PNG_ERROR_TEXT_SUPPORTED) :\
|
||||||
(defined PNG_WARNINGS_SUPPORTED) || (defined PNG_CONSOLE_IO_SUPPORTED))
|
(defined PNG_WARNINGS_SUPPORTED) || (defined PNG_CONSOLE_IO_SUPPORTED))
|
||||||
|
|
||||||
@ -375,7 +383,7 @@
|
|||||||
* png_affirm function; these macros do not assume that the png_structp is
|
* png_affirm function; these macros do not assume that the png_structp is
|
||||||
* called png_ptr.
|
* called png_ptr.
|
||||||
*/
|
*/
|
||||||
#if PNG_AFFIRM_ERROR
|
#if PNG_RELEASE_BUILD
|
||||||
# define png_affirmpp(pp, cond)\
|
# define png_affirmpp(pp, cond)\
|
||||||
do\
|
do\
|
||||||
if (!(cond)) png_affirm(pp, PNG_SRC_LINE);\
|
if (!(cond)) png_affirm(pp, PNG_SRC_LINE);\
|
||||||
@ -441,6 +449,53 @@
|
|||||||
PNG_apply(arm_filter_neon_intrinsics)\
|
PNG_apply(arm_filter_neon_intrinsics)\
|
||||||
PNG_end
|
PNG_end
|
||||||
|
|
||||||
|
/* GCC complains about assignments of an (int) expression to a (char) even when
|
||||||
|
* it can readily determine that the value is in range. This makes arithmetic
|
||||||
|
* on (char) or (png_byte) values tedious. The warning is not issued by
|
||||||
|
* default, but libpng coding rules require no warnings leading to excessive,
|
||||||
|
* ridiculous and dangerous expressions of the form:
|
||||||
|
*
|
||||||
|
* <char> = (char)(expression & 0xff)
|
||||||
|
*
|
||||||
|
* They are dangerous because they hide the warning, which might actually be
|
||||||
|
* valid, and therefore merely enable introduction of undetected overflows when
|
||||||
|
* code is modified.
|
||||||
|
*
|
||||||
|
* The following macros exist to reliably detect any overflow in non-release
|
||||||
|
* builds. The theory here is that we really want to know about overflows, not
|
||||||
|
* merely hide a basically flawed compiler warning by throwing unnecessary casts
|
||||||
|
* into the code. The warnings disappear in RC builds so that the released
|
||||||
|
* (STABLE) version just assigns the value (with, possibly, a warning if someone
|
||||||
|
* turns on the -Wconversion GCC warning.)
|
||||||
|
*
|
||||||
|
* Doing it this way ensures that the code meets two very important aims:
|
||||||
|
*
|
||||||
|
* 1) Overflows are detected in pre-release tests; previously versions of libpng
|
||||||
|
* have been released that really did have overflows in the RGB calculations.
|
||||||
|
* 2) In release builds GCC specific operations, which may reduce the ability
|
||||||
|
* of other compilers and even GCC to optimize the code, are avoided.
|
||||||
|
*
|
||||||
|
* There is one important extra consequence for pre-release code; it is
|
||||||
|
* performing a lot of checks in pixel arithmetic that the release code won't
|
||||||
|
* perform. As a consequence a build time option, RANGE_CHECK, is provided
|
||||||
|
* to allow the checks to be turned off in pre-release when building for
|
||||||
|
* performance testing. This is a standard "_SUPPORTED" option except that it
|
||||||
|
* cannot be set in the system configuration (pnglibconf.h, pnglibconf.dfa).
|
||||||
|
*
|
||||||
|
* A separate macro PNG_BYTE() is provided to safely convert an unsigned value
|
||||||
|
* to the PNG byte range 0..255. This handles the fact that, technically,
|
||||||
|
* an ANSI-C (unsigned char), hence a (png_byte), may be able to store values
|
||||||
|
* outside this range. Note that if you are building on a system where this is
|
||||||
|
* true libpng is almost certainly going to produce errors; it has never been
|
||||||
|
* tested on such a system. For the moment pngconf.h ensures that this will
|
||||||
|
* not happen.
|
||||||
|
*/
|
||||||
|
#if !PNG_RELEASE_BUILD
|
||||||
|
# ifndef PNG_NO_RANGE_CHECK /* Turn off even in pre-release */
|
||||||
|
# define PNG_RANGE_CHECK_SUPPORTED
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
/* SECURITY and SAFETY:
|
/* SECURITY and SAFETY:
|
||||||
*
|
*
|
||||||
* libpng is built with support for internal limits on image dimensions and
|
* libpng is built with support for internal limits on image dimensions and
|
||||||
@ -473,6 +528,15 @@
|
|||||||
# define PNG_UNUSED(param) (void)param;
|
# define PNG_UNUSED(param) (void)param;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* This is a convenience for parameters which are not used in release
|
||||||
|
* builds.
|
||||||
|
*/
|
||||||
|
#if PNG_RELEASE_BUILD
|
||||||
|
# define PNG_UNUSEDRC(param) (void)param;
|
||||||
|
#else
|
||||||
|
# define PNG_UNUSEDRC(param)
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Just a little check that someone hasn't tried to define something
|
/* Just a little check that someone hasn't tried to define something
|
||||||
* contradictory.
|
* contradictory.
|
||||||
*/
|
*/
|
||||||
@ -505,6 +569,7 @@
|
|||||||
*/
|
*/
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
# define png_voidcast(type, value) static_cast<type>(value)
|
# define png_voidcast(type, value) static_cast<type>(value)
|
||||||
|
# define png_upcast(type, value) static_cast<type>(value)
|
||||||
# define png_constcast(type, value) const_cast<type>(value)
|
# define png_constcast(type, value) const_cast<type>(value)
|
||||||
# define png_aligncast(type, value) \
|
# define png_aligncast(type, value) \
|
||||||
static_cast<type>(static_cast<void*>(value))
|
static_cast<type>(static_cast<void*>(value))
|
||||||
@ -512,6 +577,7 @@
|
|||||||
static_cast<type>(static_cast<const void*>(value))
|
static_cast<type>(static_cast<const void*>(value))
|
||||||
#else
|
#else
|
||||||
# define png_voidcast(type, value) (value)
|
# define png_voidcast(type, value) (value)
|
||||||
|
# define png_upcast(type, value) ((type)(value))
|
||||||
# define png_constcast(type, value) ((type)(value))
|
# define png_constcast(type, value) ((type)(value))
|
||||||
# define png_aligncast(type, value) ((void*)(value))
|
# define png_aligncast(type, value) ((void*)(value))
|
||||||
# define png_aligncastconst(type, value) ((const void*)(value))
|
# define png_aligncastconst(type, value) ((const void*)(value))
|
||||||
@ -693,8 +759,9 @@
|
|||||||
#if defined(PNG_SIMPLIFIED_READ_SUPPORTED) ||\
|
#if defined(PNG_SIMPLIFIED_READ_SUPPORTED) ||\
|
||||||
defined(PNG_SIMPLIFIED_WRITE_SUPPORTED)
|
defined(PNG_SIMPLIFIED_WRITE_SUPPORTED)
|
||||||
/* See below for the definitions of the tables used in these macros */
|
/* See below for the definitions of the tables used in these macros */
|
||||||
#define PNG_sRGB_FROM_LINEAR(linear) ((png_byte)((png_sRGB_base[(linear)>>15] +\
|
#define PNG_sRGB_FROM_LINEAR(pp, linear) png_check_byte(pp,\
|
||||||
((((linear)&0x7fff)*png_sRGB_delta[(linear)>>15])>>12)) >> 8))
|
(png_sRGB_base[(linear)>>15] +\
|
||||||
|
((((linear)&0x7fff)*png_sRGB_delta[(linear)>>15])>>12)) >> 8)
|
||||||
/* Given a value 'linear' in the range 0..255*65535 calculate the 8-bit sRGB
|
/* Given a value 'linear' in the range 0..255*65535 calculate the 8-bit sRGB
|
||||||
* encoded value with maximum error 0.646365. Note that the input is not a
|
* encoded value with maximum error 0.646365. Note that the input is not a
|
||||||
* 16-bit value; it has been multiplied by 255! */
|
* 16-bit value; it has been multiplied by 255! */
|
||||||
@ -826,7 +893,7 @@ extern "C" {
|
|||||||
* All of these functions must be declared with PNG_INTERNAL_FUNCTION.
|
* All of these functions must be declared with PNG_INTERNAL_FUNCTION.
|
||||||
*/
|
*/
|
||||||
/* Assert handling */
|
/* Assert handling */
|
||||||
#if PNG_AFFIRM_ERROR
|
#if PNG_RELEASE_BUILD
|
||||||
PNG_INTERNAL_FUNCTION(void, png_affirm,(png_const_structrp png_ptr,
|
PNG_INTERNAL_FUNCTION(void, png_affirm,(png_const_structrp png_ptr,
|
||||||
unsigned int position), PNG_NORETURN);
|
unsigned int position), PNG_NORETURN);
|
||||||
#else
|
#else
|
||||||
@ -834,6 +901,64 @@ PNG_INTERNAL_FUNCTION(void, png_affirm,(png_const_structrp png_ptr,
|
|||||||
png_const_charp condition, unsigned int position), PNG_NORETURN);
|
png_const_charp condition, unsigned int position), PNG_NORETURN);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Character/byte range checking. */
|
||||||
|
#ifdef PNG_RANGE_CHECK_SUPPORTED
|
||||||
|
PNG_INTERNAL_FUNCTION(char, png_char_affirm,(png_const_structrp png_ptr,
|
||||||
|
unsigned int position, int c), PNG_EMPTY);
|
||||||
|
|
||||||
|
PNG_INTERNAL_FUNCTION(png_byte, png_byte_affirm,(png_const_structrp png_ptr,
|
||||||
|
unsigned int position, int b), PNG_EMPTY);
|
||||||
|
|
||||||
|
PNG_INTERNAL_FUNCTION(void, png_handled_affirm,(png_const_structrp png_ptr,
|
||||||
|
png_const_charp message, unsigned int position), PNG_EMPTY);
|
||||||
|
/* This is not marked PNG_NORETURN because in PNG_RELEASE_BUILD it will
|
||||||
|
* disappear and control will pass through it.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if INT_MAX >= 65535
|
||||||
|
PNG_INTERNAL_FUNCTION(png_uint_16, png_u16_affirm,(png_const_structrp png_ptr,
|
||||||
|
unsigned int position, int u), PNG_EMPTY);
|
||||||
|
# define png_check_u16(pp, u) (png_u16_affirm((pp), PNG_SRC_LINE, (u)))
|
||||||
|
#else
|
||||||
|
/* (int) cannot hold a (png_uint_16) so the above function just won't
|
||||||
|
* compile correctly, for the moment just do this:
|
||||||
|
*/
|
||||||
|
# define png_check_u16(pp, u) (u)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
# define png_check_char(pp, c) (png_char_affirm((pp), PNG_SRC_LINE, (c)))
|
||||||
|
# define png_check_byte(pp, b) (png_byte_affirm((pp), PNG_SRC_LINE, (b)))
|
||||||
|
# define PNG_BYTE(b) ((png_byte)((b) & 0xff))
|
||||||
|
# define png_handled(pp, m) (png_handled_affirm((pp), (m), PNG_SRC_LINE))
|
||||||
|
#elif !(defined PNG_REMOVE_CASTS)
|
||||||
|
# define png_check_char(pp, c) ((char)(c))
|
||||||
|
# define png_check_byte(pp, b) ((png_byte)(b))
|
||||||
|
# define png_check_u16(pp, u) ((png_uint_16)(u))
|
||||||
|
# define png_handled(pp, m) ((void)0)
|
||||||
|
# define PNG_BYTE(b) ((png_byte)((b) & 0xff))
|
||||||
|
#else
|
||||||
|
/* This is somewhat trust-me-it-works: if PNG_REMOVE_CASTS is defined then
|
||||||
|
* the casts, which might otherwise change the values, are completely
|
||||||
|
* removed. Use this to test your compiler to see if it makes *any*
|
||||||
|
* difference (code size or speed.) Currently NOT SUPPORTED.
|
||||||
|
*
|
||||||
|
* It also makes the png_byte macro not do anything either (fine if UCHAR_MAX
|
||||||
|
* is exactly 255.)
|
||||||
|
*/
|
||||||
|
# define png_check_char(pp, c) (c)
|
||||||
|
# define png_check_byte(pp, b) (b)
|
||||||
|
# define png_check_u16(pp, u) (u)
|
||||||
|
# define png_handled(pp, m) ((void)0)
|
||||||
|
# define PNG_BYTE(b) (b)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Utility macro to mark a handled error condition ; when control reaches this
|
||||||
|
* there has been an arithmetic overflow but it is being handled. Use the
|
||||||
|
* png_check_ macros above where control should leave the code for
|
||||||
|
* safety/security reasons.
|
||||||
|
*/
|
||||||
|
#define handled(m) png_handled(png_ptr, (m))
|
||||||
|
|
||||||
/* Zlib support */
|
/* Zlib support */
|
||||||
#define PNG_UNEXPECTED_ZLIB_RETURN (-7)
|
#define PNG_UNEXPECTED_ZLIB_RETURN (-7)
|
||||||
PNG_INTERNAL_FUNCTION(void, png_zstream_error,(png_structrp png_ptr, int ret),
|
PNG_INTERNAL_FUNCTION(void, png_zstream_error,(png_structrp png_ptr, int ret),
|
||||||
@ -1821,12 +1946,12 @@ PNG_INTERNAL_FUNCTION(int,png_gamma_significant,(png_fixed_point gamma_value),
|
|||||||
* While the input is an 'unsigned' value it must actually be the
|
* While the input is an 'unsigned' value it must actually be the
|
||||||
* correct bit value - 0..255 or 0..65535 as required.
|
* correct bit value - 0..255 or 0..65535 as required.
|
||||||
*/
|
*/
|
||||||
PNG_INTERNAL_FUNCTION(png_uint_16,png_gamma_correct,(png_structrp png_ptr,
|
PNG_INTERNAL_FUNCTION(png_uint_16,png_gamma_16bit_correct,(
|
||||||
unsigned int value, png_fixed_point gamma_value),PNG_EMPTY);
|
png_const_structrp png_ptr, png_uint_32 value, png_fixed_point gamma_value),
|
||||||
PNG_INTERNAL_FUNCTION(png_uint_16,png_gamma_16bit_correct,(unsigned int value,
|
PNG_EMPTY);
|
||||||
png_fixed_point gamma_value),PNG_EMPTY);
|
PNG_INTERNAL_FUNCTION(png_byte,png_gamma_8bit_correct,(
|
||||||
PNG_INTERNAL_FUNCTION(png_byte,png_gamma_8bit_correct,(unsigned int value,
|
png_const_structrp png_ptr, png_uint_32 value, png_fixed_point gamma_value),
|
||||||
png_fixed_point gamma_value),PNG_EMPTY);
|
PNG_EMPTY);
|
||||||
PNG_INTERNAL_FUNCTION(void,png_destroy_gamma_table,(png_structrp png_ptr),
|
PNG_INTERNAL_FUNCTION(void,png_destroy_gamma_table,(png_structrp png_ptr),
|
||||||
PNG_EMPTY);
|
PNG_EMPTY);
|
||||||
PNG_INTERNAL_FUNCTION(void,png_build_gamma_tables,(png_structrp png_ptr,
|
PNG_INTERNAL_FUNCTION(void,png_build_gamma_tables,(png_structrp png_ptr,
|
||||||
|
|||||||
@ -64,7 +64,7 @@ png_create_read_struct_2,(png_const_charp user_png_ver, png_voidp error_ptr,
|
|||||||
/* In stable builds only warn if an application error can be completely
|
/* In stable builds only warn if an application error can be completely
|
||||||
* handled.
|
* handled.
|
||||||
*/
|
*/
|
||||||
# if PNG_LIBPNG_BUILD_BASE_TYPE >= PNG_LIBPNG_BUILD_RC
|
# if PNG_RELEASE_BUILD
|
||||||
png_ptr->flags |= PNG_FLAG_APP_WARNINGS_WARN;
|
png_ptr->flags |= PNG_FLAG_APP_WARNINGS_WARN;
|
||||||
# endif
|
# endif
|
||||||
# endif
|
# endif
|
||||||
|
|||||||
@ -325,7 +325,7 @@ png_inflate_claim(png_structrp png_ptr, png_uint_32 owner)
|
|||||||
* are minimal.
|
* are minimal.
|
||||||
*/
|
*/
|
||||||
(void)png_safecat(msg, (sizeof msg), 4, " using zstream");
|
(void)png_safecat(msg, (sizeof msg), 4, " using zstream");
|
||||||
# if PNG_LIBPNG_BUILD_BASE_TYPE >= PNG_LIBPNG_BUILD_RC
|
# if PNG_RELEASE_BUILD
|
||||||
png_chunk_warning(png_ptr, msg);
|
png_chunk_warning(png_ptr, msg);
|
||||||
png_ptr->zowner = 0;
|
png_ptr->zowner = 0;
|
||||||
# else
|
# else
|
||||||
|
|||||||
@ -544,7 +544,7 @@ png_create_write_struct_2,(png_const_charp user_png_ver, png_voidp error_ptr,
|
|||||||
/* App warnings are warnings in release (or release candidate) builds but
|
/* App warnings are warnings in release (or release candidate) builds but
|
||||||
* are errors during development.
|
* are errors during development.
|
||||||
*/
|
*/
|
||||||
#if PNG_LIBPNG_BUILD_BASE_TYPE >= PNG_LIBPNG_BUILD_RC
|
#if PNG_RELEASE_BUILD
|
||||||
png_ptr->flags |= PNG_FLAG_APP_WARNINGS_WARN;
|
png_ptr->flags |= PNG_FLAG_APP_WARNINGS_WARN;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@ -309,7 +309,7 @@ png_deflate_claim(png_structrp png_ptr, png_uint_32 owner,
|
|||||||
*/
|
*/
|
||||||
(void)png_safecat(msg, (sizeof msg), 10, " using zstream");
|
(void)png_safecat(msg, (sizeof msg), 10, " using zstream");
|
||||||
#endif
|
#endif
|
||||||
#if PNG_LIBPNG_BUILD_BASE_TYPE >= PNG_LIBPNG_BUILD_RC
|
#if PNG_RELEASE_BUILD
|
||||||
png_warning(png_ptr, msg);
|
png_warning(png_ptr, msg);
|
||||||
|
|
||||||
/* Attempt sane error recovery */
|
/* Attempt sane error recovery */
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user