Description: IBM zSystems DFLTCC: Do not update strm.adler for raw streams #1390
Commit d38dd92 ("IBM Z DFLTCC: Fix updating strm.adler with inflate()") broke libxml2, as can be seen with the repro from [1]:
$ echo "" | gzip >file.xml.gz
$ python3 -c 'import libxml2; libxml2.parseFile("file.xml.gz")'
file.xml.gz:1: parser error : Document is empty
This is because libxml2 expects strm.adler to be untouched for raw streams.
Fix this and a similar issue in deflate by adding state->wrap checks. Add tests.
[1] https://bugzilla.redhat.com/show_bug.cgi?id=2155328
[2] https://gitlab.gnome.org/GNOME/libxml2/-/blob/v2.10.3/xzlib.c#L607
Author: Ilya Leoshkevich
Origin: upstream, https://github.com/zlib-ng/zlib-ng/pull/1390/commits/cc06335176d4cd1dfceaf8b6bcb757ad73da73be
backport, https://launchpadlibrarian.net/645435525/1390.patch
Bug-Ubuntu: https://bugs.launchpad.net/bugs/2002511
Bug-RedHat: https://bugzilla.redhat.com/show_bug.cgi?id=2155328
Reviewed-by: Frank Heimes
Last-Update: 2023-01-11
---
This patch header follows DEP-3: http://dep.debian.net/deps/dep3/
--- a/contrib/s390/dfltcc.c
+++ b/contrib/s390/dfltcc.c
@@ -457,7 +457,10 @@
*strm->next_out = (Bytef)state->bi_buf;
/* Honor history and check value */
param->nt = 0;
- param->cv = state->wrap == 2 ? ZSWAP32(strm->adler) : strm->adler;
+ if (state->wrap == 1)
+ param->cv = strm->adler;
+ else if (state->wrap == 2)
+ param->cv = ZSWAP32(strm->adler);
/* When opening a block, choose a Huffman-Table Type */
if (!param->bcf) {
@@ -489,7 +492,10 @@
state->bi_buf = 0; /* Avoid accessing next_out */
else
state->bi_buf = *strm->next_out & ((1 << state->bi_valid) - 1);
- strm->adler = state->wrap == 2 ? ZSWAP32(param->cv) : param->cv;
+ if (state->wrap == 1)
+ strm->adler = param->cv;
+ else if (state->wrap == 2)
+ strm->adler = ZSWAP32(param->cv);
/* Unmask the input data */
strm->avail_in += masked_avail_in;
@@ -605,13 +611,14 @@
}
/* Translate stream to parameter block */
- param->cvt = state->flags ? CVT_CRC32 : CVT_ADLER32;
+ param->cvt = ((state->wrap & 4) && state->flags) ? CVT_CRC32 : CVT_ADLER32;
param->sbb = state->bits;
param->hl = state->whave; /* Software and hardware history formats match */
param->ho = (state->wnext - state->whave) & ((1 << HB_BITS) - 1);
if (param->hl)
param->nt = 0; /* Honor history for the first block */
- param->cv = state->flags ? ZSWAP32(state->check) : state->check;
+ if (state->wrap & 4)
+ param->cv = state->flags ? ZSWAP32(state->check) : state->check;
/* Inflate */
do {
@@ -624,7 +631,9 @@
state->bits = param->sbb;
state->whave = param->hl;
state->wnext = (param->ho + param->hl) & ((1 << HB_BITS) - 1);
- strm->adler = state->check = state->flags ? ZSWAP32(param->cv) : param->cv;
+ if (state->wrap & 4)
+ strm->adler = state->check = state->flags ?
+ ZSWAP32(param->cv) : param->cv;
if (cc == DFLTCC_CC_OP2_CORRUPT && param->oesc != 0) {
/* Report an error if stream is corrupted */
state->mode = BAD;