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.si...@amd.com> Signed-off-by: Christophe Leroy <christophe.le...@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