[PATCH 3/6] zlib: Fix inflate_fast() when POSTINC macro is set

Christophe Leroy christophe.leroy at csgroup.eu
Tue Jul 9 12:31:15 CEST 2024


inflate_fast() implements possibility to be build with
POSTINC set or unset. That POSTINC macro was introduced by
commit e89516f031db ("zlib: split up to match original source tree")
but forced to #undef in zlib.h.

However, in the meantime that commit removed UP_UNALIGNED() macro
introduced by commit cd514aeb996e ("zlib: Optimize decompression")
that was meant to implement proper behaviour depending on POSTINC.

In addition, commit cd514aeb996e ("zlib: Optimize decompression") has
a bug for when POSTINC is set in the following pointer arithmetic:

	pat16 = *(sout-2+2*OFF)

The intension is to remove 2 bytes when OFF is 0, but sout being a
short, this leads to removing 4 bytes instead of 2. The bug in not
visible when OFF is set to 1 which has always been the case until now.

In preparation for followup patch that will activate POSTINC, add back
UP_UNALIGNED() macro and fix the above pointer calculation.

Fixes: cd514aeb996e ("zlib: Optimize decompression")
Cc: Michal Simek <michal.simek at amd.com>
Signed-off-by: Christophe Leroy <christophe.leroy at csgroup.eu>
---
 lib/zlib/inffast.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/lib/zlib/inffast.c b/lib/zlib/inffast.c
index bdaa6d0dc5..29ec72fce5 100644
--- a/lib/zlib/inffast.c
+++ b/lib/zlib/inffast.c
@@ -26,9 +26,11 @@
 #ifdef POSTINC
 #  define OFF 0
 #  define PUP(a) *(a)++
+#  define UP_UNALIGNED(a) get_unaligned((a)++)
 #else
 #  define OFF 1
 #  define PUP(a) *++(a)
+#  define UP_UNALIGNED(a) get_unaligned(++(a))
 #endif
 
 /*
@@ -270,14 +272,14 @@ void inflate_fast(z_streamp strm, unsigned start)
 			sfrom = (unsigned short *)(from - OFF);
 			loops = len >> 1;
 			do
-			    PUP(sout) = get_unaligned(++sfrom);
+			    PUP(sout) = UP_UNALIGNED(sfrom);
 			while (--loops);
 			out = (unsigned char *)sout + OFF;
 			from = (unsigned char *)sfrom + OFF;
 		    } else { /* dist == 1 or dist == 2 */
 			unsigned short pat16;
 
-			pat16 = *(sout-2+2*OFF);
+			pat16 = *(sout - 1 + OFF);
 			if (dist == 1)
 #if defined(__BIG_ENDIAN)
 			    pat16 = (pat16 & 0xff) | ((pat16 & 0xff ) << 8);
-- 
2.44.0



More information about the U-Boot mailing list