• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2020 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the Chromium source repository LICENSE file.
4 
5 #include "infcover.h"
6 
7 #include <cstddef>
8 #include <vector>
9 
10 #include "compression_utils_portable.h"
11 #include "gtest.h"
12 #include "zlib.h"
13 
TestPayloads(size_t input_size,zlib_internal::WrapperType type)14 void TestPayloads(size_t input_size, zlib_internal::WrapperType type) {
15   std::vector<unsigned char> input;
16   input.reserve(input_size);
17   for (size_t i = 1; i <= input_size; ++i)
18     input.push_back(i & 0xff);
19 
20   // If it is big enough for GZIP, will work for other wrappers.
21   std::vector<unsigned char> compressed(
22       zlib_internal::GzipExpectedCompressedSize(input.size()));
23   std::vector<unsigned char> decompressed(input.size());
24 
25   // Libcores's java/util/zip/Deflater default settings: ZLIB,
26   // DEFAULT_COMPRESSION and DEFAULT_STRATEGY.
27   unsigned long compressed_size = static_cast<unsigned long>(compressed.size());
28   int result = zlib_internal::CompressHelper(
29       type, compressed.data(), &compressed_size, input.data(), input.size(),
30       Z_DEFAULT_COMPRESSION, nullptr, nullptr);
31   ASSERT_EQ(result, Z_OK);
32 
33   unsigned long decompressed_size =
34       static_cast<unsigned long>(decompressed.size());
35   result = zlib_internal::UncompressHelper(type, decompressed.data(),
36                                            &decompressed_size,
37                                            compressed.data(), compressed_size);
38   ASSERT_EQ(result, Z_OK);
39   EXPECT_EQ(input, decompressed);
40 }
41 
TEST(ZlibTest,ZlibWrapper)42 TEST(ZlibTest, ZlibWrapper) {
43   // Minimal ZLIB wrapped short stream size is about 8 bytes.
44   for (size_t i = 1; i < 1024; ++i)
45     TestPayloads(i, zlib_internal::WrapperType::ZLIB);
46 }
47 
TEST(ZlibTest,GzipWrapper)48 TEST(ZlibTest, GzipWrapper) {
49   // GZIP should be 12 bytes bigger than ZLIB wrapper.
50   for (size_t i = 1; i < 1024; ++i)
51     TestPayloads(i, zlib_internal::WrapperType::GZIP);
52 }
53 
TEST(ZlibTest,RawWrapper)54 TEST(ZlibTest, RawWrapper) {
55   // RAW has no wrapper (V8 Blobs is a known user), size
56   // should be payload_size + 2 for short payloads.
57   for (size_t i = 1; i < 1024; ++i)
58     TestPayloads(i, zlib_internal::WrapperType::ZRAW);
59 }
60 
TEST(ZlibTest,InflateCover)61 TEST(ZlibTest, InflateCover) {
62   cover_support();
63   cover_wrap();
64   cover_back();
65   cover_inflate();
66   // TODO(cavalcantii): enable this last test.
67   // cover_trees();
68   cover_fast();
69 }
70 
TEST(ZlibTest,DeflateStored)71 TEST(ZlibTest, DeflateStored) {
72   const int no_compression = 0;
73   const zlib_internal::WrapperType type = zlib_internal::WrapperType::GZIP;
74   std::vector<unsigned char> input(1 << 10, 42);
75   std::vector<unsigned char> compressed(
76       zlib_internal::GzipExpectedCompressedSize(input.size()));
77   std::vector<unsigned char> decompressed(input.size());
78   unsigned long compressed_size = static_cast<unsigned long>(compressed.size());
79   int result = zlib_internal::CompressHelper(
80       type, compressed.data(), &compressed_size, input.data(), input.size(),
81       no_compression, nullptr, nullptr);
82   ASSERT_EQ(result, Z_OK);
83 
84   unsigned long decompressed_size =
85       static_cast<unsigned long>(decompressed.size());
86   result = zlib_internal::UncompressHelper(type, decompressed.data(),
87                                            &decompressed_size,
88                                            compressed.data(), compressed_size);
89   ASSERT_EQ(result, Z_OK);
90   EXPECT_EQ(input, decompressed);
91 }
92 
TEST(ZlibTest,StreamingInflate)93 TEST(ZlibTest, StreamingInflate) {
94   uint8_t comp_buf[4096], decomp_buf[4096];
95   z_stream comp_strm, decomp_strm;
96   int ret;
97 
98   std::vector<uint8_t> src;
99   for (size_t i = 0; i < 1000; i++) {
100     for (size_t j = 0; j < 40; j++) {
101       src.push_back(j);
102     }
103   }
104 
105   // Deflate src into comp_buf.
106   comp_strm.zalloc = Z_NULL;
107   comp_strm.zfree = Z_NULL;
108   comp_strm.opaque = Z_NULL;
109   ret = deflateInit(&comp_strm, Z_BEST_COMPRESSION);
110   ASSERT_EQ(ret, Z_OK);
111   comp_strm.next_out = comp_buf;
112   comp_strm.avail_out = sizeof(comp_buf);
113   comp_strm.next_in = src.data();
114   comp_strm.avail_in = src.size();
115   ret = deflate(&comp_strm, Z_FINISH);
116   ASSERT_EQ(ret, Z_STREAM_END);
117   size_t comp_sz = sizeof(comp_buf) - comp_strm.avail_out;
118 
119   // Inflate comp_buf one 4096-byte buffer at a time.
120   decomp_strm.zalloc = Z_NULL;
121   decomp_strm.zfree = Z_NULL;
122   decomp_strm.opaque = Z_NULL;
123   ret = inflateInit(&decomp_strm);
124   ASSERT_EQ(ret, Z_OK);
125   decomp_strm.next_in = comp_buf;
126   decomp_strm.avail_in = comp_sz;
127 
128   while (decomp_strm.avail_in > 0) {
129     decomp_strm.next_out = decomp_buf;
130     decomp_strm.avail_out = sizeof(decomp_buf);
131     ret = inflate(&decomp_strm, Z_FINISH);
132     ASSERT_TRUE(ret == Z_OK || ret == Z_STREAM_END || ret == Z_BUF_ERROR);
133 
134     // Verify the output bytes.
135     size_t num_out = sizeof(decomp_buf) - decomp_strm.avail_out;
136     for (size_t i = 0; i < num_out; i++) {
137       EXPECT_EQ(decomp_buf[i], src[decomp_strm.total_out - num_out + i]);
138     }
139   }
140 
141   // Cleanup memory (i.e. makes ASAN bot happy).
142   ret = deflateEnd(&comp_strm);
143   EXPECT_EQ(ret, Z_OK);
144   ret = inflateEnd(&decomp_strm);
145   EXPECT_EQ(ret, Z_OK);
146 }
147 
TEST(ZlibTest,CRCHashBitsCollision)148 TEST(ZlibTest, CRCHashBitsCollision) {
149   // The CRC32c of the hex sequences 2a,14,14,14 and 2a,14,db,14 have the same
150   // lower 9 bits. Since longest_match doesn't check match[2], a bad match could
151   // be chosen when the number of hash bits is <= 9. For this reason, the number
152   // of hash bits must be set higher, regardless of the memlevel parameter, when
153   // using CRC32c hashing for string matching. See https://crbug.com/1113596
154 
155   std::vector<uint8_t> src = {
156       // Random byte; zlib doesn't match at offset 0.
157       123,
158 
159       // This will look like 5-byte match.
160       0x2a,
161       0x14,
162       0xdb,
163       0x14,
164       0x15,
165 
166       // Offer a 4-byte match to bump the next expected match length to 5.
167       0x2a,
168       0x14,
169       0x14,
170       0x14,
171 
172       0x2a,
173       0x14,
174       0x14,
175       0x14,
176       0x15,
177   };
178 
179   z_stream stream;
180   stream.zalloc = nullptr;
181   stream.zfree = nullptr;
182 
183   // Using a low memlevel to try to reduce the number of hash bits. Negative
184   // windowbits means raw deflate, i.e. without the zlib header.
185   int ret = deflateInit2(&stream, /*comp level*/ 2, /*method*/ Z_DEFLATED,
186                          /*windowbits*/ -15, /*memlevel*/ 2,
187                          /*strategy*/ Z_DEFAULT_STRATEGY);
188   ASSERT_EQ(ret, Z_OK);
189   std::vector<uint8_t> compressed(100, '\0');
190   stream.next_out = compressed.data();
191   stream.avail_out = compressed.size();
192   stream.next_in = src.data();
193   stream.avail_in = src.size();
194   ret = deflate(&stream, Z_FINISH);
195   ASSERT_EQ(ret, Z_STREAM_END);
196   compressed.resize(compressed.size() - stream.avail_out);
197   deflateEnd(&stream);
198 
199   ret = inflateInit2(&stream, /*windowbits*/ -15);
200   ASSERT_EQ(ret, Z_OK);
201   std::vector<uint8_t> decompressed(src.size(), '\0');
202   stream.next_in = compressed.data();
203   stream.avail_in = compressed.size();
204   stream.next_out = decompressed.data();
205   stream.avail_out = decompressed.size();
206   ret = inflate(&stream, Z_FINISH);
207   ASSERT_EQ(ret, Z_STREAM_END);
208   EXPECT_EQ(0U, stream.avail_out);
209   inflateEnd(&stream);
210 
211   EXPECT_EQ(src, decompressed);
212 }
213 
TEST(ZlibTest,CRCHashAssert)214 TEST(ZlibTest, CRCHashAssert) {
215   // The CRC32c of the hex sequences ff,ff,5e,6f and ff,ff,13,ff have the same
216   // lower 15 bits. This means longest_match's assert that match[2] == scan[2]
217   // won't hold. However, such hash collisions are only possible when one of the
218   // other four bytes also mismatch. This tests that zlib's assert handles this
219   // case.
220 
221   std::vector<uint8_t> src = {
222       // Random byte; zlib doesn't match at offset 0.
223       123,
224 
225       // This has the same hash as the last byte sequence, and the first two and
226       // last two bytes match; though the third and the fourth don't.
227       0xff,
228       0xff,
229       0x5e,
230       0x6f,
231       0x12,
232       0x34,
233 
234       // Offer a 5-byte match to bump the next expected match length to 6
235       // (because the two first and two last bytes need to match).
236       0xff,
237       0xff,
238       0x13,
239       0xff,
240       0x12,
241 
242       0xff,
243       0xff,
244       0x13,
245       0xff,
246       0x12,
247       0x34,
248   };
249 
250   z_stream stream;
251   stream.zalloc = nullptr;
252   stream.zfree = nullptr;
253 
254   int ret = deflateInit2(&stream, /*comp level*/ 5, /*method*/ Z_DEFLATED,
255                          /*windowbits*/ -15, /*memlevel*/ 8,
256                          /*strategy*/ Z_DEFAULT_STRATEGY);
257   ASSERT_EQ(ret, Z_OK);
258   std::vector<uint8_t> compressed(100, '\0');
259   stream.next_out = compressed.data();
260   stream.avail_out = compressed.size();
261   stream.next_in = src.data();
262   stream.avail_in = src.size();
263   ret = deflate(&stream, Z_FINISH);
264   ASSERT_EQ(ret, Z_STREAM_END);
265   compressed.resize(compressed.size() - stream.avail_out);
266   deflateEnd(&stream);
267 
268   ret = inflateInit2(&stream, /*windowbits*/ -15);
269   ASSERT_EQ(ret, Z_OK);
270   std::vector<uint8_t> decompressed(src.size(), '\0');
271   stream.next_in = compressed.data();
272   stream.avail_in = compressed.size();
273   stream.next_out = decompressed.data();
274   stream.avail_out = decompressed.size();
275   ret = inflate(&stream, Z_FINISH);
276   ASSERT_EQ(ret, Z_STREAM_END);
277   EXPECT_EQ(0U, stream.avail_out);
278   inflateEnd(&stream);
279 
280   EXPECT_EQ(src, decompressed);
281 }
282 
283 // Fuzzer generated.
284 static const uint8_t checkMatchCrashData[] = {
285     0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc5, 0x00, 0x00, 0x00, 0x00, 0x00,
286     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
287     0x00, 0x00, 0x58, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
288     0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00,
289     0x6e, 0x6e, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x6e, 0x01, 0x39, 0x6e, 0x6e,
290     0x00, 0x00, 0x00, 0x00, 0xf7, 0xff, 0x00, 0x00, 0x00, 0x00, 0x6e, 0x6e,
291     0x00, 0x00, 0x0a, 0x9a, 0x00, 0x00, 0x6e, 0x6e, 0x6e, 0x2a, 0x00, 0x00,
292     0x00, 0xd5, 0xf0, 0x00, 0x81, 0x02, 0xf3, 0xfd, 0xff, 0xab, 0xf3, 0x6e,
293     0x7e, 0x04, 0x5b, 0xf6, 0x2a, 0x2c, 0xf8, 0x00, 0x54, 0xf3, 0xa5, 0x0e,
294     0xfd, 0x6e, 0xff, 0x00, 0xfd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
295     0x00, 0xa4, 0x0b, 0xa5, 0x2a, 0x0d, 0x10, 0x01, 0x26, 0xf6, 0x04, 0x0e,
296     0xff, 0x6e, 0x6e, 0x6e, 0x76, 0x00, 0x00, 0x87, 0x01, 0xfe, 0x0d, 0xb6,
297     0x6e, 0x6e, 0xf7, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
298     0x00, 0x00, 0xfd, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x29, 0x00, 0x9b,
299     0x02, 0x00, 0x00, 0x00, 0x00, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a,
300     0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x6e, 0xff, 0xff, 0x00,
301     0x00, 0xd5, 0xf0, 0x00, 0xff, 0x40, 0x7e, 0x0b, 0xa5, 0x10, 0x67, 0x01,
302     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00,
303     0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00,
304     0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x40, 0x7e, 0x0b, 0xa5, 0x10, 0x67,
305     0x7e, 0x32, 0x6e, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x40, 0x0b, 0xa5,
306     0x10, 0x67, 0x01, 0xfe, 0x0d, 0xb6, 0x2a, 0x00, 0x00, 0x58, 0x00, 0x00,
307     0x00, 0x00, 0x00, 0x00, 0x6e, 0xfd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
308     0x00, 0x00, 0x3d, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00,
309     0x00, 0x00, 0x00, 0x00, 0xd6, 0x2d, 0x2d, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a,
310     0x8a, 0x8a, 0x8a, 0x8a, 0x66, 0x8a, 0x8a, 0x8a, 0xee, 0x1d, 0x00, 0x00,
311     0x00, 0x02, 0x00, 0x00, 0x00, 0xee, 0x0a, 0x00, 0x00, 0x00, 0x54, 0x40,
312     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
313     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
314     0x00, 0x00, 0x00, 0xf3, 0x00, 0x00, 0xff, 0xff, 0x23, 0x7e, 0x00, 0x1e,
315     0x00, 0x00, 0xd5, 0xf0, 0x00, 0xff, 0x40, 0x0b, 0xa5, 0x10, 0x67, 0x01,
316     0xfe, 0x0d, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a,
317     0x8a, 0x8a, 0x8a, 0x2d, 0x6e, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x0e,
318     0xfb, 0x00, 0x10, 0x24, 0x00, 0x00, 0xfb, 0xff, 0x00, 0x00, 0xff, 0x1f,
319     0xb3, 0x00, 0x04, 0x3d, 0x00, 0xee, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
320     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00,
321     0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00,
322     0x01, 0x45, 0x3d, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x11, 0x21, 0x00, 0x1e,
323     0x00, 0x0c, 0xb3, 0xfe, 0x0e, 0xee, 0x02, 0x00, 0x1d, 0x00, 0x00, 0x00,
324     0x00, 0x00, 0x6e, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x6e, 0x00,
325     0x00, 0x87, 0x00, 0x33, 0x38, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x00, 0x00,
326     0x00, 0x38, 0x00, 0x00, 0xff, 0xff, 0xff, 0x04, 0x3f, 0xff, 0xff, 0xff,
327     0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0xff, 0x00, 0x31, 0x13, 0x13, 0x13,
328     0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xab, 0x30, 0x83, 0x33,
329     0x00, 0x00, 0x01, 0x05, 0x00, 0x00, 0xff, 0xff, 0x7d, 0xff, 0x00, 0x01,
330     0x10, 0x0d, 0x2a, 0xa5, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x11,
331     0x21, 0x00, 0xa5, 0x00, 0x68, 0x68, 0x68, 0x67, 0x00, 0x00, 0xff, 0xff,
332     0x02, 0x00, 0x00, 0x68, 0x68, 0x68, 0x68, 0x00, 0x00, 0xfa, 0xff, 0xff,
333     0x03, 0x01, 0xff, 0x02, 0x00, 0x00, 0x68, 0x68, 0x68, 0x68, 0x0a, 0x10,
334     0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff,
335     0x06, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
336     0x00, 0x00, 0xfa, 0xff, 0xff, 0x08, 0xff, 0xff, 0xff, 0x00, 0x06, 0x04,
337     0x00, 0xf8, 0xff, 0xff, 0x00, 0x01, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00,
338     0x00, 0xff, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
339     0x78, 0x00, 0x00, 0x01, 0x00, 0xff, 0xff, 0xff, 0x00, 0x06, 0x04, 0x6e,
340     0x7e, 0x87, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00,
341     0x00, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87, 0x6e, 0x6e, 0x6e,
342     0x00, 0x01, 0x38, 0xd5, 0xf0, 0x00, 0x00, 0x2a, 0xfe, 0x04, 0x5b, 0x0d,
343     0xfd, 0x6e, 0x92, 0x28, 0xf9, 0xfb, 0xff, 0x07, 0xd2, 0xd6, 0x2d, 0x2d,
344     0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a,
345     0x8a, 0x8a, 0xc2, 0x91, 0x00, 0x5b, 0xef, 0xde, 0xf2, 0x6e, 0x6e, 0xfd,
346     0x0c, 0x02, 0x91, 0x62, 0x91, 0xfd, 0x6e, 0x6e, 0xd3, 0x06, 0x00, 0x00,
347     0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x00,
348     0xd5, 0xf0, 0x00, 0xff, 0x00, 0x00, 0x31, 0x13, 0x13, 0x13, 0x04, 0x00,
349     0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x04, 0x00, 0x13, 0x0a, 0x00, 0x00,
350     0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x6e, 0x00, 0x00, 0x01,
351     0x00, 0x00, 0x09, 0x00, 0x6a, 0x24, 0x26, 0x30, 0x01, 0x2e, 0x2a, 0xfe,
352     0x04, 0x5b, 0x0d, 0xfd, 0x6e, 0x6e, 0xd7, 0x06, 0x6e, 0x6e, 0x6e, 0x00,
353     0x00, 0xb1, 0xb1, 0xb1, 0xb1, 0x00, 0x00, 0x00, 0x6e, 0x5b, 0x00, 0x00,
354     0x58, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
355     0x58, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00,
356     0x00, 0x00, 0x00, 0x01, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
357     0x00, 0x00, 0x58, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
358     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
359     0x1e, 0x00, 0x00, 0x00, 0x87, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38,
360     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6b, 0x00, 0x00, 0x00, 0x00,
361     0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
362     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
363     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
364     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x0b,
365     0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x24, 0x2a, 0x6e, 0x5c, 0x24,
366     0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
367     0x00, 0x00, 0x87, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xeb,
368     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
369     0x00, 0x00, 0x40, 0x00, 0x40, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00,
370     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00,
371     0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
372     0x05, 0x00, 0x00, 0x00, 0x5d, 0x10, 0x6e, 0x6e, 0xa5, 0x2f, 0x00, 0x00,
373     0x95, 0x87, 0x00, 0x6e};
374 
TEST(ZlibTest,CheckMatchCrash)375 TEST(ZlibTest, CheckMatchCrash) {
376   // See https://crbug.com/1113142.
377   z_stream stream;
378   stream.zalloc = nullptr;
379   stream.zfree = nullptr;
380 
381   // Low windowbits to hit window sliding also with a relatively small input.
382   int ret = deflateInit2(&stream, /*comp level*/ 5, /*method*/ Z_DEFLATED,
383                          /*windowbits*/ -9, /*memlevel*/ 8,
384                          /*strategy*/ Z_DEFAULT_STRATEGY);
385   ASSERT_EQ(ret, Z_OK);
386 
387   uint8_t compressed[sizeof(checkMatchCrashData) * 2];
388   stream.next_out = compressed;
389   stream.avail_out = sizeof(compressed);
390 
391   for (size_t i = 0; i < sizeof(checkMatchCrashData); i++) {
392     ASSERT_GT(stream.avail_out, 0U);
393     stream.next_in = (uint8_t*)&checkMatchCrashData[i];
394     stream.avail_in = 1;
395     ret = deflate(&stream, Z_NO_FLUSH);
396     ASSERT_EQ(ret, Z_OK);
397   }
398 
399   stream.next_in = nullptr;
400   stream.avail_in = 0;
401   ASSERT_GT(stream.avail_out, 0U);
402   ret = deflate(&stream, Z_FINISH);
403   ASSERT_EQ(ret, Z_STREAM_END);
404   size_t compressed_sz = sizeof(compressed) - stream.avail_out;
405   deflateEnd(&stream);
406 
407   uint8_t decompressed[sizeof(checkMatchCrashData)];
408   ret = inflateInit2(&stream, -15);
409   ASSERT_EQ(ret, Z_OK);
410   stream.next_in = compressed;
411   stream.avail_in = compressed_sz;
412   stream.next_out = decompressed;
413   stream.avail_out = sizeof(decompressed);
414   ret = inflate(&stream, Z_FINISH);
415   ASSERT_EQ(ret, Z_STREAM_END);
416   inflateEnd(&stream);
417   ASSERT_EQ(
418       memcmp(checkMatchCrashData, decompressed, sizeof(checkMatchCrashData)),
419       0);
420 }
421 
TEST(ZlibTest,DeflateRLEUninitUse)422 TEST(ZlibTest, DeflateRLEUninitUse) {
423   // MSan would complain about use of uninitialized values in deflate_rle if the
424   // window isn't zero-initialized. See crbug.com/1137613. Similar problems
425   // exist in other places in zlib, e.g. longest_match (crbug.com/1144420) but
426   // we don't have as nice test cases.
427 
428   int level = 9;
429   int windowBits = 9;
430   int memLevel = 8;
431   int strategy = Z_RLE;
432   const std::vector<uint8_t> src{
433       0x31, 0x64, 0x38, 0x32, 0x30, 0x32, 0x30, 0x36, 0x65, 0x35, 0x38, 0x35,
434       0x32, 0x61, 0x30, 0x36, 0x65, 0x35, 0x32, 0x66, 0x30, 0x34, 0x38, 0x37,
435       0x61, 0x31, 0x38, 0x36, 0x37, 0x37, 0x31, 0x39, 0x0a, 0x65, 0x62, 0x00,
436       0x9f, 0xff, 0xc6, 0xc6, 0xc6, 0xff, 0x09, 0x00, 0x62, 0x00, 0x9f, 0xff,
437       0xc6, 0xc6, 0xc6, 0xff, 0x09, 0x00, 0x62, 0x00, 0x9f, 0xff, 0xc6, 0xc6,
438       0xc6, 0xff, 0x09, 0x00, 0x62, 0x00, 0x9f, 0xff, 0xc6, 0xc6, 0xc6, 0x95,
439       0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x0e, 0x0a, 0x54, 0x52,
440       0x58, 0x56, 0xab, 0x26, 0x13, 0x53, 0x5a, 0xb5, 0x30, 0xbb, 0x96, 0x44,
441       0x80, 0xe6, 0xc5, 0x0a, 0xd0, 0x47, 0x7a, 0xa0, 0x4e, 0xbe, 0x30, 0xdc,
442       0xa1, 0x08, 0x54, 0xe1, 0x51, 0xd1, 0xea, 0xef, 0xdb, 0xa1, 0x2d, 0xb4,
443       0xb9, 0x58, 0xb1, 0x2f, 0xf0, 0xae, 0xbc, 0x07, 0xd1, 0xba, 0x7f, 0x14,
444       0xa4, 0xde, 0x99, 0x7f, 0x4d, 0x3e, 0x25, 0xd9, 0xef, 0xee, 0x4f, 0x38,
445       0x7b, 0xaf, 0x3f, 0x6b, 0x53, 0x5a, 0xcb, 0x1f, 0x97, 0xb5, 0x43, 0xa3,
446       0xe8, 0xff, 0x09, 0x00, 0x62, 0x00, 0x9f, 0xff, 0xc6, 0xc6, 0xc6, 0xff,
447       0x09, 0x00, 0x62, 0x00, 0x9f, 0xff, 0xc6, 0xc6, 0xc6, 0xff, 0x09, 0x00,
448       0x62, 0x00, 0x9f, 0xff, 0xc6, 0xc6, 0xc6, 0xff, 0x09, 0x00, 0x62, 0x00,
449       0x9f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
450       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
451       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
452       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
453       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
454       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
455       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
456       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
457       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
458       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
459       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
460       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
461       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
462       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
463       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
464       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
465       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
466       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
467       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
468       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
469       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
470       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x3c,
471       0x73, 0x70, 0x23, 0x87, 0xec, 0xf8, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00,
472       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
473       0xc1, 0x00, 0x00, 0x9f, 0xc6, 0xc6, 0xff, 0x09, 0x00, 0x62, 0x00, 0x9f,
474       0xff, 0xc6, 0xc6, 0xc6, 0xff, 0x09, 0x00, 0x62, 0x00, 0x9f, 0xff, 0x00,
475       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
476       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
477       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
478       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
479       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
480       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
481       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
482       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
483       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
484       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
485       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
486       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
487       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
488       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
489       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
490       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
491       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
492       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
493       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
494       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
495       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
496       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00,
497   };
498 
499   z_stream stream;
500   stream.zalloc = Z_NULL;
501   stream.zfree = Z_NULL;
502 
503   // Compress the data one byte at a time to exercise the streaming code.
504   int ret =
505       deflateInit2(&stream, level, Z_DEFLATED, windowBits, memLevel, strategy);
506   ASSERT_EQ(ret, Z_OK);
507   std::vector<uint8_t> compressed(src.size() * 2 + 1000);
508   stream.next_out = compressed.data();
509   stream.avail_out = compressed.size();
510   for (uint8_t b : src) {
511     stream.next_in = &b;
512     stream.avail_in = 1;
513     ret = deflate(&stream, Z_NO_FLUSH);
514     ASSERT_EQ(ret, Z_OK);
515   }
516   stream.next_in = Z_NULL;
517   stream.avail_in = 0;
518   ret = deflate(&stream, Z_FINISH);
519   ASSERT_EQ(ret, Z_STREAM_END);
520   deflateEnd(&stream);
521 }
522