test: add limit configuration tests

nocompile-limits.dfa: turns off all limits including run-time limits

nolimits.dfa: makes the compile time limits unlimited while leaving on
    the run-time limits.

Fixes compiler warnings exposed by these tests. These are just warnings,
there were no bugs other than a failure to handle systems with a 16-bit
at the appropriate time which would result in a later failure on malloc.

png.c: png_icc_check_length: in-line code was still used in place of
    png_chunk_max when checking the current chunk allocation limit.  The
    in-line code did not handle PNG_MAXSEG_64K and, anyway, issued
    compiler warnings in the 'nocompile-limits' case.  Changed to use
    png_malloc_max.

pngrutil.c: eliminated an erroneous 'truncation' warning with GCC-14 by
    using a safe cast.

pngtest.c: failed to check for PNG_USER_LIMITS_SUPPORTED around API
    calls which don't exist without PNG_USER_LIMITS.

Signed-off-by: John Bowler <jbowler@acm.org>
This commit is contained in:
John Bowler 2025-01-31 09:46:21 -08:00
parent 68e090e700
commit 812c34c13c
5 changed files with 46 additions and 16 deletions

View File

@ -0,0 +1,21 @@
# nolimits.dfa
# Build time configuration of libpng
#
# Author: John Bowler
# Copyright: (c) John Bowler, 2025
#
# Usage rights:
# To the extent possible under law, the author has waived all copyright and
# related or neighboring rights to this work. This work is published from:
# United States.
#
# Build libpng without any limits and without run-time settable limits. Turning
# USER_LIMITS off reduces libpng code size by allowing compile-time elimination
# of some checking code.
#
option USER_LIMITS off
@# define PNG_USER_WIDTH_MAX PNG_UINT_31_MAX
@# define PNG_USER_HEIGHT_MAX PNG_UINT_31_MAX
@# define PNG_USER_CHUNK_CACHE_MAX 0
@# define PNG_USER_CHUNK_MALLOC_MAX 0

View File

@ -0,0 +1,19 @@
# nolimits.dfa
# Build time configuration of libpng
#
# Author: John Bowler
# Copyright: (c) John Bowler, 2025
#
# Usage rights:
# To the extent possible under law, the author has waived all copyright and
# related or neighboring rights to this work. This work is published from:
# United States.
#
# Build libpng without any limits. With these settigs run-time limits are still
# possible.
#
@# define PNG_USER_WIDTH_MAX PNG_UINT_31_MAX
@# define PNG_USER_HEIGHT_MAX PNG_UINT_31_MAX
@# define PNG_USER_CHUNK_CACHE_MAX 0
@# define PNG_USER_CHUNK_MALLOC_MAX 0

18
png.c
View File

@ -1600,21 +1600,9 @@ png_icc_check_length(png_const_structrp png_ptr, png_const_charp name,
* the caller supplies the profile buffer so libpng doesn't allocate it. See
* the call to icc_check_length below (the write case).
*/
# ifdef PNG_SET_USER_LIMITS_SUPPORTED
else if (png_ptr->user_chunk_malloc_max > 0 &&
png_ptr->user_chunk_malloc_max < profile_length)
return png_icc_profile_error(png_ptr, name, profile_length,
"exceeds application limits");
# elif PNG_USER_CHUNK_MALLOC_MAX > 0
else if (PNG_USER_CHUNK_MALLOC_MAX < profile_length)
return png_icc_profile_error(png_ptr, name, profile_length,
"exceeds libpng limits");
# else /* !SET_USER_LIMITS */
/* This will get compiled out on all 32-bit and better systems. */
else if (PNG_SIZE_MAX < profile_length)
return png_icc_profile_error(png_ptr, name, profile_length,
"exceeds system limits");
# endif /* !SET_USER_LIMITS */
if (profile_length > png_chunk_max(png_ptr))
return png_icc_profile_error(png_ptr, name, profile_length,
"profile too long");
return 1;
}

View File

@ -4228,7 +4228,7 @@ png_read_IDAT_data(png_structrp png_ptr, png_bytep output,
avail_in = png_ptr->IDAT_read_size;
if (avail_in > png_chunk_max(png_ptr))
avail_in = png_chunk_max(png_ptr);
avail_in = (uInt)/*SAFE*/png_chunk_max(png_ptr);
if (avail_in > png_ptr->idat_size)
avail_in = (uInt)png_ptr->idat_size;

View File

@ -2137,6 +2137,7 @@ main(int argc, char *argv[])
fprintf(STDERR, " libpng FAILS test\n");
dummy_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
#ifdef PNG_USER_LIMITS_SUPPORTED
fprintf(STDERR, " Default limits:\n");
fprintf(STDERR, " width_max = %lu\n",
(unsigned long) png_get_user_width_max(dummy_ptr));
@ -2152,6 +2153,7 @@ main(int argc, char *argv[])
else
fprintf(STDERR, " malloc_max = %lu\n",
(unsigned long) png_get_chunk_malloc_max(dummy_ptr));
#endif
png_destroy_read_struct(&dummy_ptr, NULL, NULL);
return (ierror != 0);