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