From 812c34c13c27a963073e546c720f5a7b88b1ed00 Mon Sep 17 00:00:00 2001 From: John Bowler Date: Fri, 31 Jan 2025 09:46:21 -0800 Subject: [PATCH] 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 --- contrib/conftest/nocompile-limits.dfa | 21 +++++++++++++++++++++ contrib/conftest/nolimits.dfa | 19 +++++++++++++++++++ png.c | 18 +++--------------- pngrutil.c | 2 +- pngtest.c | 2 ++ 5 files changed, 46 insertions(+), 16 deletions(-) create mode 100644 contrib/conftest/nocompile-limits.dfa create mode 100644 contrib/conftest/nolimits.dfa diff --git a/contrib/conftest/nocompile-limits.dfa b/contrib/conftest/nocompile-limits.dfa new file mode 100644 index 0000000000..24e1e2e083 --- /dev/null +++ b/contrib/conftest/nocompile-limits.dfa @@ -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 diff --git a/contrib/conftest/nolimits.dfa b/contrib/conftest/nolimits.dfa new file mode 100644 index 0000000000..5b37fcf727 --- /dev/null +++ b/contrib/conftest/nolimits.dfa @@ -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 + diff --git a/png.c b/png.c index f261753bce..d28dbcbb17 100644 --- a/png.c +++ b/png.c @@ -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; } diff --git a/pngrutil.c b/pngrutil.c index e1354b70cb..d0f3ed35d2 100644 --- a/pngrutil.c +++ b/pngrutil.c @@ -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; diff --git a/pngtest.c b/pngtest.c index 6477f4b902..e126049f6b 100644 --- a/pngtest.c +++ b/pngtest.c @@ -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);