mirror of
https://github.com/GerbilSoft/zlib-ng.git
synced 2025-06-18 11:35:35 -04:00
IBM zSystems DFLTCC: Do not update strm.adler for raw streams
Commit d38dd9240f
("IBM Z DFLTCC: Fix updating strm.adler with
inflate()") broke libxml2, as can be seen with the repro from [1]:
$ echo "<a></a>" | 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
This commit is contained in:
parent
c4e7e231c8
commit
2ff9398fde
@ -240,7 +240,10 @@ again:
|
||||
*strm->next_out = (unsigned char)state->bi_buf;
|
||||
/* Honor history and check value */
|
||||
param->nt = 0;
|
||||
param->cv = state->wrap == 2 ? ZSWAP32(state->crc_fold.value) : strm->adler;
|
||||
if (state->wrap == 1)
|
||||
param->cv = strm->adler;
|
||||
else if (state->wrap == 2)
|
||||
param->cv = ZSWAP32(state->crc_fold.value);
|
||||
|
||||
/* When opening a block, choose a Huffman-Table Type */
|
||||
if (!param->bcf) {
|
||||
@ -271,10 +274,10 @@ again:
|
||||
state->bi_buf = 0; /* Avoid accessing next_out */
|
||||
else
|
||||
state->bi_buf = *strm->next_out & ((1 << state->bi_valid) - 1);
|
||||
if (state->wrap == 2)
|
||||
state->crc_fold.value = ZSWAP32(param->cv);
|
||||
else
|
||||
if (state->wrap == 1)
|
||||
strm->adler = param->cv;
|
||||
else if (state->wrap == 2)
|
||||
state->crc_fold.value = ZSWAP32(param->cv);
|
||||
|
||||
/* Unmask the input data */
|
||||
strm->avail_in += masked_avail_in;
|
||||
|
@ -92,11 +92,12 @@ dfltcc_inflate_action Z_INTERNAL PREFIX(dfltcc_inflate)(PREFIX3(streamp) strm, i
|
||||
}
|
||||
|
||||
/* 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;
|
||||
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 {
|
||||
@ -107,7 +108,8 @@ dfltcc_inflate_action Z_INTERNAL PREFIX(dfltcc_inflate)(PREFIX3(streamp) strm, i
|
||||
strm->msg = oesc_msg(dfltcc_state->msg, param->oesc);
|
||||
state->last = cc == DFLTCC_CC_OK;
|
||||
state->bits = param->sbb;
|
||||
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;
|
||||
|
@ -167,6 +167,7 @@ else()
|
||||
test_dict.cc
|
||||
test_inflate_adler32.cc
|
||||
test_large_buffers.cc
|
||||
test_raw.cc
|
||||
test_small_buffers.cc
|
||||
test_small_window.cc
|
||||
)
|
||||
|
@ -61,6 +61,9 @@ TEST(deflate, header) {
|
||||
EXPECT_EQ(err, Z_OK);
|
||||
}
|
||||
|
||||
/* Check CRC32. */
|
||||
EXPECT_EQ(c_stream.adler, 0xb56c3f9dU);
|
||||
|
||||
err = PREFIX(deflateEnd)(&c_stream);
|
||||
EXPECT_EQ(err, Z_OK);
|
||||
|
||||
|
58
test/test_raw.cc
Normal file
58
test/test_raw.cc
Normal file
@ -0,0 +1,58 @@
|
||||
/* test_raw.cc - Test raw streams. */
|
||||
|
||||
#include "zbuild.h"
|
||||
#ifdef ZLIB_COMPAT
|
||||
# include "zlib.h"
|
||||
#else
|
||||
# include "zlib-ng.h"
|
||||
#endif
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
TEST(raw, basic) {
|
||||
PREFIX3(stream) stream;
|
||||
int err;
|
||||
unsigned char plain[512];
|
||||
size_t i;
|
||||
unsigned char compr[sizeof(plain)];
|
||||
unsigned int compr_len;
|
||||
unsigned char plain_again[sizeof(plain)];
|
||||
|
||||
memset(&stream, 0, sizeof(stream));
|
||||
err = PREFIX(deflateInit2)(&stream, Z_BEST_SPEED, Z_DEFLATED, -15, 8, Z_DEFAULT_STRATEGY);
|
||||
EXPECT_EQ(err, Z_OK);
|
||||
|
||||
for (i = 0; i < sizeof(plain); i++)
|
||||
plain[i] = (unsigned char)i;
|
||||
stream.adler = 0x12345678;
|
||||
stream.next_in = plain;
|
||||
stream.avail_in = (uint32_t)sizeof(plain);
|
||||
stream.next_out = compr;
|
||||
stream.avail_out = (uint32_t)sizeof(compr);
|
||||
err = PREFIX(deflate)(&stream, Z_FINISH);
|
||||
EXPECT_EQ(err, Z_STREAM_END);
|
||||
EXPECT_EQ(stream.adler, 0x12345678);
|
||||
compr_len = sizeof(compr) - stream.avail_out;
|
||||
|
||||
err = PREFIX(deflateEnd)(&stream);
|
||||
EXPECT_EQ(err, Z_OK);
|
||||
|
||||
memset(&stream, 0, sizeof(stream));
|
||||
err = PREFIX(inflateInit2)(&stream, -15);
|
||||
EXPECT_EQ(err, Z_OK);
|
||||
|
||||
stream.adler = 0x87654321;
|
||||
stream.next_in = compr;
|
||||
stream.avail_in = compr_len;
|
||||
stream.next_out = plain_again;
|
||||
stream.avail_out = (unsigned int)sizeof(plain_again);
|
||||
|
||||
err = PREFIX(inflate)(&stream, Z_NO_FLUSH);
|
||||
EXPECT_EQ(err, Z_STREAM_END);
|
||||
EXPECT_EQ(stream.adler, 0x87654321);
|
||||
|
||||
err = PREFIX(inflateEnd)(&stream);
|
||||
EXPECT_EQ(err, Z_OK);
|
||||
|
||||
EXPECT_TRUE(memcmp(plain_again, plain, sizeof(plain)) == 0);
|
||||
}
|
Loading…
Reference in New Issue
Block a user