From dfc331f0bd8165dd41c0c5b0a666d490e5dc8a54 Mon Sep 17 00:00:00 2001 From: Dimitri Schoolwerth Date: Wed, 16 Dec 2020 17:09:22 +0100 Subject: [PATCH 1/5] Refactor check for zlib's inflateValidate presence No compile-time changes. Refactor a single and expanding statement checking for availability of inflateValidate into an option. --- pngrutil.c | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/pngrutil.c b/pngrutil.c index 356e8f1f2..aad1cc42a 100644 --- a/pngrutil.c +++ b/pngrutil.c @@ -18,6 +18,27 @@ #ifdef PNG_READ_SUPPORTED +#ifndef PNG_USE_ZLIB_INFLATE_VALIDATE + /* Check if zlib's inflateValidate can be used. */ +# if ZLIB_VERNUM >= 0x1290 && \ + defined(PNG_SET_OPTION_SUPPORTED) && defined(PNG_IGNORE_ADLER32) + /* Determine at compile-time whether inflateValidate is available by + * minimal supported OS version. + */ +# if defined(MAC_OS_X_VERSION_MIN_REQUIRED) && \ + MAC_OS_X_VERSION_MIN_REQUIRED < 101300 + /* Don't use if targeting pre-macOS 10.13. */ +# define PNG_USE_ZLIB_INFLATE_VALIDATE 0 +# endif +# else +# define PNG_USE_ZLIB_INFLATE_VALIDATE 0 +# endif /* ZLIB_VERNUM && PNG_SET_OPTION_SUPPORTED && PNG_IGNORE_ADLER32 */ + +# ifndef PNG_USE_ZLIB_INFLATE_VALIDATE +# define PNG_USE_ZLIB_INFLATE_VALIDATE 1 +# endif +#endif /* PNG_USE_ZLIB_INFLATE_VALIDATE */ + png_uint_32 PNGAPI png_get_uint_31(png_const_structrp png_ptr, png_const_bytep buf) { @@ -422,9 +443,7 @@ png_inflate_claim(png_structrp png_ptr, png_uint_32 owner) png_ptr->flags |= PNG_FLAG_ZSTREAM_INITIALIZED; } -#if ZLIB_VERNUM >= 0x1290 && \ - defined(PNG_SET_OPTION_SUPPORTED) && defined(PNG_IGNORE_ADLER32) && \ - !(defined(MAC_OS_X_VERSION_MIN_REQUIRED) && MAC_OS_X_VERSION_MIN_REQUIRED < 101300) +#if PNG_USE_ZLIB_INFLATE_VALIDATE if (((png_ptr->options >> PNG_IGNORE_ADLER32) & 3) == PNG_OPTION_ON) /* Turn off validation of the ADLER32 checksum in IDAT chunks */ ret = inflateValidate(&png_ptr->zstream, 0); From 759dc457a8c4188b9ba4fb07386d5067a493e996 Mon Sep 17 00:00:00 2001 From: Dimitri Schoolwerth Date: Thu, 17 Dec 2020 01:49:19 +0100 Subject: [PATCH 2/5] Fix continued undesired usage of inflateValidate Macro MAC_OS_X_VERSION_MIN_REQUIRED isn't present through, coincidental, inclusion of , which means inflateValidate can still be used resulting in a warning when targeting pre-10.13 and a crash if called pre-10.13 as described in (attempted fix) bda2970c65. Fix by including the needed header explicitly. --- pngrutil.c | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/pngrutil.c b/pngrutil.c index aad1cc42a..81195578e 100644 --- a/pngrutil.c +++ b/pngrutil.c @@ -22,14 +22,23 @@ /* Check if zlib's inflateValidate can be used. */ # if ZLIB_VERNUM >= 0x1290 && \ defined(PNG_SET_OPTION_SUPPORTED) && defined(PNG_IGNORE_ADLER32) - /* Determine at compile-time whether inflateValidate is available by - * minimal supported OS version. - */ -# if defined(MAC_OS_X_VERSION_MIN_REQUIRED) && \ - MAC_OS_X_VERSION_MIN_REQUIRED < 101300 - /* Don't use if targeting pre-macOS 10.13. */ -# define PNG_USE_ZLIB_INFLATE_VALIDATE 0 -# endif +# if defined(__APPLE__) && defined(__MACH__) + /* Determine at compile-time whether inflateValidate is available by + * minimal supported OS version. + */ + + /* For MAC_OS_X_VERSION_MIN_REQUIRED. + * Not using the preferred because it was introduced + * during the 10.5 SDK while this header has been available with Xcode + * since 1.0 (10.3 SDK). + */ +# include +# if defined(MAC_OS_X_VERSION_MIN_REQUIRED) && \ + MAC_OS_X_VERSION_MIN_REQUIRED < 101300 + /* Don't use if targeting pre-macOS 10.13. */ +# define PNG_USE_ZLIB_INFLATE_VALIDATE 0 +# endif +# endif /* __APPLE__ && __MACH__ */ # else # define PNG_USE_ZLIB_INFLATE_VALIDATE 0 # endif /* ZLIB_VERNUM && PNG_SET_OPTION_SUPPORTED && PNG_IGNORE_ADLER32 */ From fd4a538c678e632b5008e787fa7467496205e787 Mon Sep 17 00:00:00 2001 From: Dimitri Schoolwerth Date: Thu, 17 Dec 2020 02:16:30 +0100 Subject: [PATCH 3/5] Add iOS compile-time check for inflateValidate Don't use inflateValidate if targeting pre-iOS 11. --- pngrutil.c | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/pngrutil.c b/pngrutil.c index 81195578e..4fa820c98 100644 --- a/pngrutil.c +++ b/pngrutil.c @@ -27,16 +27,27 @@ * minimal supported OS version. */ - /* For MAC_OS_X_VERSION_MIN_REQUIRED. + /* For TARGET_OS_IPHONE / TARGET_OS_MAC */ +# include + + /* For IPHONE_OS_VERSION_MIN_REQUIRED / MAC_OS_X_VERSION_MIN_REQUIRED. * Not using the preferred because it was introduced * during the 10.5 SDK while this header has been available with Xcode * since 1.0 (10.3 SDK). */ # include -# if defined(MAC_OS_X_VERSION_MIN_REQUIRED) && \ - MAC_OS_X_VERSION_MIN_REQUIRED < 101300 - /* Don't use if targeting pre-macOS 10.13. */ -# define PNG_USE_ZLIB_INFLATE_VALIDATE 0 +# if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE +# if defined(IPHONE_OS_VERSION_MIN_REQUIRED) && \ + IPHONE_OS_VERSION_MIN_REQUIRED < 110000 + /* Don't use if targeting pre-iOS 11.0. */ +# define PNG_USE_ZLIB_INFLATE_VALIDATE 0 +# endif +# elif defined(TARGET_OS_MAC) && TARGET_OS_MAC +# if defined(MAC_OS_X_VERSION_MIN_REQUIRED) && \ + MAC_OS_X_VERSION_MIN_REQUIRED < 101300 + /* Don't use if targeting pre-macOS 10.13. */ +# define PNG_USE_ZLIB_INFLATE_VALIDATE 0 +# endif # endif # endif /* __APPLE__ && __MACH__ */ # else From e69f6b3e26822279f1bb3f2ba4def398f55f0349 Mon Sep 17 00:00:00 2001 From: Dimitri Schoolwerth Date: Thu, 17 Dec 2020 02:22:25 +0100 Subject: [PATCH 4/5] Add iOS/macOS run-time check for inflateValidate --- pngrutil.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/pngrutil.c b/pngrutil.c index 4fa820c98..8024ab84a 100644 --- a/pngrutil.c +++ b/pngrutil.c @@ -23,8 +23,9 @@ # if ZLIB_VERNUM >= 0x1290 && \ defined(PNG_SET_OPTION_SUPPORTED) && defined(PNG_IGNORE_ADLER32) # if defined(__APPLE__) && defined(__MACH__) - /* Determine at compile-time whether inflateValidate is available by - * minimal supported OS version. + /* Determine whether inflateValidate is available by checking: + * - at run-time by OS version (best with sys zlib usage) + * - at compile-time by minimal supported OS version */ /* For TARGET_OS_IPHONE / TARGET_OS_MAC */ @@ -36,7 +37,10 @@ * since 1.0 (10.3 SDK). */ # include -# if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE +# if defined(__clang__) && __has_builtin(__builtin_available) + /* Check at run-time for availability by OS version. */ +# define PNG_USE_ZLIB_INFLATE_VALIDATE 2 +# elif defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE # if defined(IPHONE_OS_VERSION_MIN_REQUIRED) && \ IPHONE_OS_VERSION_MIN_REQUIRED < 110000 /* Don't use if targeting pre-iOS 11.0. */ @@ -465,8 +469,11 @@ png_inflate_claim(png_structrp png_ptr, png_uint_32 owner) #if PNG_USE_ZLIB_INFLATE_VALIDATE if (((png_ptr->options >> PNG_IGNORE_ADLER32) & 3) == PNG_OPTION_ON) - /* Turn off validation of the ADLER32 checksum in IDAT chunks */ - ret = inflateValidate(&png_ptr->zstream, 0); +# if PNG_USE_ZLIB_INFLATE_VALIDATE == 2 + if (__builtin_available(macOS 10.13, iOS 11.0, *)) +# endif + /* Turn off validation of the ADLER32 checksum in IDAT chunks */ + ret = inflateValidate(&png_ptr->zstream, 0); #endif if (ret == Z_OK) From b825c1723ddfdf9f9dae132997f09af1433a65e7 Mon Sep 17 00:00:00 2001 From: Dimitri Schoolwerth Date: Thu, 17 Dec 2020 17:01:20 +0100 Subject: [PATCH 5/5] Try to use inflateValidate in case of static zlib When static linking zlib on iOS/macOS the usage of inflateValidate is still unnecessarily based on OS version checks. Detect at least the case where zlib functions are definitions (as a result of compiling zlib with a prefix), allowing for unrestricted inflateValidate usage. --- pngrutil.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/pngrutil.c b/pngrutil.c index 8024ab84a..01ade8863 100644 --- a/pngrutil.c +++ b/pngrutil.c @@ -24,6 +24,7 @@ defined(PNG_SET_OPTION_SUPPORTED) && defined(PNG_IGNORE_ADLER32) # if defined(__APPLE__) && defined(__MACH__) /* Determine whether inflateValidate is available by checking: + * - for static zlib linking (best, but flaky and unreliable detection) * - at run-time by OS version (best with sys zlib usage) * - at compile-time by minimal supported OS version */ @@ -37,7 +38,16 @@ * since 1.0 (10.3 SDK). */ # include -# if defined(__clang__) && __has_builtin(__builtin_available) +# ifdef inflateValidate + /* Without this (empty) check usage of inflateValidate is driven + * only by OS version while zlib with inflateValidate could be + * linked statically. + * If the system's zlib is being used inflateValidate is not a + * macro so by checking if inflateValidate is a macro the cases + * where zlib is compiled with a prefix are at least handled and + * inflateValidate can then be used regardless of OS version. + */ +# elif defined(__clang__) && __has_builtin(__builtin_available) /* Check at run-time for availability by OS version. */ # define PNG_USE_ZLIB_INFLATE_VALIDATE 2 # elif defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE @@ -52,7 +62,7 @@ /* Don't use if targeting pre-macOS 10.13. */ # define PNG_USE_ZLIB_INFLATE_VALIDATE 0 # endif -# endif +# endif /* inflateValidate */ # endif /* __APPLE__ && __MACH__ */ # else # define PNG_USE_ZLIB_INFLATE_VALIDATE 0