Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions deps/zlib/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -375,8 +375,6 @@ component("zlib") {
# Must be after no_chromium_code for warning flags to be ordered correctly.
":zlib_warnings",
]

allow_circular_includes_from = deps
}

config("minizip_warnings") {
Expand Down
35 changes: 25 additions & 10 deletions deps/zlib/contrib/optimizations/inffast_chunk.c
Original file line number Diff line number Diff line change
Expand Up @@ -132,28 +132,35 @@ void ZLIB_INTERNAL inflate_fast_chunk_(z_streamp strm, unsigned start) {
} while (0)
#endif

#ifdef INFLATE_CHUNK_READ_64LE
REFILL();
#endif

/* decode literals and length/distances until end-of-block or not enough
input data or output space */
do {
#ifdef INFLATE_CHUNK_READ_64LE
REFILL();
#else
#ifndef INFLATE_CHUNK_READ_64LE
if (bits < 15) {
hold += (unsigned long)(*in++) << bits;
bits += 8;
hold += (unsigned long)(*in++) << bits;
bits += 8;
}
#endif
/* Worst case: previous iteration had 3 literals (56 - 20 (lits) - 15 (lit) = 21 bits)
or a match (56 - 15 (dist) - 13 (extra) = 28 bits), leaving bits >= lenbits (<= 10). */
Assert(bits >= state->lenbits, "inflate_fast: short lit/len index");
here = lcode + (hold & lmask);
#ifdef INFLATE_CHUNK_READ_64LE
if (here->op == 0) { /* literal */
REFILL();
if (here->op == 0) { /* literal */
Tracevv((stderr, here->val >= 0x20 && here->val < 0x7f ?
"inflate: literal '%c'\n" :
"inflate: literal 0x%02x\n", here->val));
*out++ = (unsigned char)(here->val);
hold >>= here->bits;
bits -= here->bits;
Assert(bits >= state->lenbits, "inflate_fast: short 2nd lit/len index");
here = lcode + (hold & lmask);
if (here->op == 0) { /* literal */
Tracevv((stderr, here->val >= 0x20 && here->val < 0x7f ?
Expand All @@ -162,6 +169,7 @@ void ZLIB_INTERNAL inflate_fast_chunk_(z_streamp strm, unsigned start) {
*out++ = (unsigned char)(here->val);
hold >>= here->bits;
bits -= here->bits;
Assert(bits >= state->lenbits, "inflate_fast: short 3rd lit/len index");
here = lcode + (hold & lmask);
}
}
Expand All @@ -187,6 +195,7 @@ void ZLIB_INTERNAL inflate_fast_chunk_(z_streamp strm, unsigned start) {
bits += 8;
}
#endif
Assert(bits >= op, "inflate_fast: short length extra bits");
len += (unsigned)hold & ((1U << op) - 1);
hold >>= op;
bits -= op;
Expand All @@ -200,7 +209,14 @@ void ZLIB_INTERNAL inflate_fast_chunk_(z_streamp strm, unsigned start) {
bits += 8;
}
#endif
/* Worst case: 56 - 20 (lits) - 15 (len) - 5 (extra) = 16 bits remain for distbits <= 9. */
Assert(bits >= state->distbits, "inflate_fast: short dist index");
here = dcode + (hold & dmask);
#ifdef INFLATE_CHUNK_READ_64LE
/* Refill after the table load so the two can overlap, and so the
distance code and its extra bits start from a full 56 bits. */
REFILL();
#endif
dodist:
op = (unsigned)(here->bits);
hold >>= op;
Expand All @@ -209,20 +225,17 @@ void ZLIB_INTERNAL inflate_fast_chunk_(z_streamp strm, unsigned start) {
if (op & 16) { /* distance base */
dist = (unsigned)(here->val);
op &= 15; /* number of extra bits */
/* we have two fast-path loads: 10+10 + 15+5 + 15 = 55,
but we may need to refill here in the worst case */
#ifndef INFLATE_CHUNK_READ_64LE
if (bits < op) {
#ifdef INFLATE_CHUNK_READ_64LE
REFILL();
#else
hold += (unsigned long)(*in++) << bits;
bits += 8;
if (bits < op) {
hold += (unsigned long)(*in++) << bits;
bits += 8;
}
#endif
}
#endif
Assert(bits >= op, "inflate_fast: short distance extra bits");
dist += (unsigned)hold & ((1U << op) - 1);
#ifdef INFLATE_STRICT
if (dist > dmax) {
Expand Down Expand Up @@ -313,6 +326,7 @@ void ZLIB_INTERNAL inflate_fast_chunk_(z_streamp strm, unsigned start) {
}
}
else if ((op & 64) == 0) { /* 2nd level distance code */
Assert(bits >= op, "inflate_fast: short 2nd level dist index");
here = dcode + here->val + (hold & ((1U << op) - 1));
goto dodist;
}
Expand All @@ -323,6 +337,7 @@ void ZLIB_INTERNAL inflate_fast_chunk_(z_streamp strm, unsigned start) {
}
}
else if ((op & 64) == 0) { /* 2nd level length code */
Assert(bits >= op, "inflate_fast: short 2nd level lit/len index");
here = lcode + here->val + (hold & ((1U << op) - 1));
goto dolen;
}
Expand Down
50 changes: 50 additions & 0 deletions deps/zlib/contrib/tests/utils_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1248,6 +1248,55 @@ TEST(ZlibTest, InflateCopySIGILLReproduction) {
}
}

TEST(ZlibTest, InflateChunkRefillDistanceBitBudget) {
// Tests the edge case where one fast-loop iteration uses 10 + 10 + 15 + 5 +
// 15 = 55 of the 56 bits a refill. There should be sufficient bits for the
// next iteration.
static const uint8_t kCompressed[] = {
0xcd, 0xef, 0x01, 0x82, 0x24, 0x49, 0x92, 0x24, 0x49, 0x22, 0xb1, 0xa8,
0x79, 0xf5, 0xec, 0x2f, 0x33, 0xf3, 0x17, 0xf7, 0x7a, 0xf8, 0xc6, 0x1d,
0x20, 0xb1, 0xa8, 0x79, 0x64, 0xf5, 0xec, 0xfd, 0xf3, 0xef, 0xff, 0x1f,
0xfc, 0xff, 0xfe, 0xfd, 0xe7, 0xdf, 0xff, 0x3f, 0xf8, 0xff, 0xfd, 0xfb,
0xcf, 0xbf, 0xff, 0x7f, 0xf0, 0xff, 0xfb, 0x17};
std::vector<uint8_t> output(402 + 512);
z_stream stream = {};
stream.next_in = const_cast<uint8_t*>(kCompressed);
stream.avail_in = sizeof(kCompressed);
stream.next_out = output.data();
stream.avail_out = output.size();

ASSERT_EQ(Z_OK, inflateInit2(&stream, -MAX_WBITS));
EXPECT_EQ(Z_STREAM_END, inflate(&stream, Z_FINISH));
EXPECT_EQ(402u, stream.total_out);
EXPECT_EQ(Z_OK, inflateEnd(&stream));
EXPECT_EQ('b', output[133]); // Decodes as 'a' if the refill is not reached.
}

TEST(ZlibTest, InflateChunkRefillLiteralBitBudget) {
// Test an edge case where an iteration ends at a literal. and returns to the
// top of the inflate loop.
static const uint8_t kCompressed[] = {
0x05, 0xe0, 0x81, 0x81, 0x04, 0x49, 0x92, 0x24, 0x49, 0xb2, 0xa8, 0x79,
0x64, 0xcf, 0x1e, 0x96, 0x55, 0x05, 0xc5, 0x3f, 0xf4, 0x44, 0xff, 0xfe,
0xf7, 0xcf, 0x3f, 0xff, 0xbf, 0x7f, 0xff, 0xfb, 0xe7, 0x9f, 0xff, 0xdf,
0xbf, 0xff, 0xfd, 0xf3, 0xcf, 0xff, 0xef, 0xdf, 0xff, 0xfe, 0xf9, 0xe7,
0xff, 0xf7, 0xef, 0x7f, 0xff, 0xfc, 0xf3, 0xff, 0xfb, 0xf7, 0xbf, 0x7f,
0xfe, 0xf9, 0xff, 0x01};
std::vector<uint8_t> output(30 + 512);
z_stream stream = {};
stream.next_in = const_cast<uint8_t*>(kCompressed);
stream.avail_in = sizeof(kCompressed);
stream.next_out = output.data();
stream.avail_out = output.size();

ASSERT_EQ(Z_OK, inflateInit2(&stream, -MAX_WBITS));
EXPECT_EQ(Z_STREAM_END, inflate(&stream, Z_FINISH));
EXPECT_EQ(30u, stream.total_out);
EXPECT_EQ(Z_OK, inflateEnd(&stream));
// Decodes as 'a' if the accumulator runs short before the next lookup.
EXPECT_EQ('b', output[5]);
}

// TODO(gustavoa): make these tests run standalone.
#ifndef CMAKE_STANDALONE_UNITTESTS

Expand Down Expand Up @@ -1513,3 +1562,4 @@ TEST(ZlibTest, Compare256ReachesMaxMatch) {
}

#endif

2 changes: 1 addition & 1 deletion src/zlib_version.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@
// Refer to tools/dep_updaters/update-zlib.sh
#ifndef SRC_ZLIB_VERSION_H_
#define SRC_ZLIB_VERSION_H_
#define ZLIB_VERSION "1.3.2.1-motley-285e94b"
#define ZLIB_VERSION "1.3.2.1-motley-456ae73"
#endif // SRC_ZLIB_VERSION_H_
Loading