blob: a8c51c7e43d2cf2bde0ecd270dd0357af05eb0a4 [file] [log] [blame]
Adenilson Cavalcanti699e86d2020-04-29 03:44:04 +00001/* infcover.c -- test zlib's inflate routines with full code coverage
2 * Copyright (C) 2011, 2016 Mark Adler
3 * For conditions of distribution and use, see copyright notice in zlib.h
4 */
5
6/* to use, do: ./configure --cover && make cover */
7// clang-format off
8#include "infcover.h"
9#include <stdio.h>
10#include <stdlib.h>
11#include <string.h>
12
13#include "zlib.h"
14
15/* get definition of internal structure so we can mess with it (see pull()),
16 and so we can call inflate_trees() (see cover5()) */
17#define ZLIB_INTERNAL
18#include "inftrees.h"
19#include "inflate.h"
20
21/* XXX: use C++ streams instead of printf/fputs/etc due to portability
22 * as type sizes can vary between platforms.
23 */
24#include <iostream>
25#define local static
26
27/* XXX: hacking C assert and plugging into GTest. */
28#include "testing/gtest/include/gtest/gtest.h"
29#if defined(assert)
30#undef assert
31#define assert EXPECT_TRUE
32#endif
33
34/* XXX: handle what is a reserved word in C++. */
35#define try try_f
36
37/* -- memory tracking routines -- */
38
39/*
40 These memory tracking routines are provided to zlib and track all of zlib's
41 allocations and deallocations, check for LIFO operations, keep a current
42 and high water mark of total bytes requested, optionally set a limit on the
43 total memory that can be allocated, and when done check for memory leaks.
44
45 They are used as follows:
46
47 z_stream strm;
48 mem_setup(&strm) initializes the memory tracking and sets the
49 zalloc, zfree, and opaque members of strm to use
50 memory tracking for all zlib operations on strm
51 mem_limit(&strm, limit) sets a limit on the total bytes requested -- a
52 request that exceeds this limit will result in an
53 allocation failure (returns NULL) -- setting the
54 limit to zero means no limit, which is the default
55 after mem_setup()
56 mem_used(&strm, "msg") prints to stderr "msg" and the total bytes used
57 mem_high(&strm, "msg") prints to stderr "msg" and the high water mark
58 mem_done(&strm, "msg") ends memory tracking, releases all allocations
59 for the tracking as well as leaked zlib blocks, if
60 any. If there was anything unusual, such as leaked
61 blocks, non-FIFO frees, or frees of addresses not
62 allocated, then "msg" and information about the
63 problem is printed to stderr. If everything is
64 normal, nothing is printed. mem_done resets the
65 strm members to Z_NULL to use the default memory
66 allocation routines on the next zlib initialization
67 using strm.
68 */
69
70/* these items are strung together in a linked list, one for each allocation */
71struct mem_item {
72 void *ptr; /* pointer to allocated memory */
73 size_t size; /* requested size of allocation */
74 struct mem_item *next; /* pointer to next item in list, or NULL */
75};
76
77/* this structure is at the root of the linked list, and tracks statistics */
78struct mem_zone {
79 struct mem_item *first; /* pointer to first item in list, or NULL */
80 size_t total, highwater; /* total allocations, and largest total */
81 size_t limit; /* memory allocation limit, or 0 if no limit */
82 int notlifo, rogue; /* counts of non-LIFO frees and rogue frees */
83};
84
85/* memory allocation routine to pass to zlib */
86local void *mem_alloc(void *mem, unsigned count, unsigned size)
87{
88 void *ptr;
89 struct mem_item *item;
90 struct mem_zone *zone = static_cast<struct mem_zone *>(mem);
91 size_t len = count * (size_t)size;
92
93 /* induced allocation failure */
94 if (zone == NULL || (zone->limit && zone->total + len > zone->limit))
95 return NULL;
96
97 /* perform allocation using the standard library, fill memory with a
98 non-zero value to make sure that the code isn't depending on zeros */
99 ptr = malloc(len);
100 if (ptr == NULL)
101 return NULL;
102 memset(ptr, 0xa5, len);
103
104 /* create a new item for the list */
105 item = static_cast<struct mem_item *>(malloc(sizeof(struct mem_item)));
106 if (item == NULL) {
107 free(ptr);
108 return NULL;
109 }
110 item->ptr = ptr;
111 item->size = len;
112
113 /* insert item at the beginning of the list */
114 item->next = zone->first;
115 zone->first = item;
116
117 /* update the statistics */
118 zone->total += item->size;
119 if (zone->total > zone->highwater)
120 zone->highwater = zone->total;
121
122 /* return the allocated memory */
123 return ptr;
124}
125
126/* memory free routine to pass to zlib */
127local void mem_free(void *mem, void *ptr)
128{
129 struct mem_item *item, *next;
130 struct mem_zone *zone = static_cast<struct mem_zone *>(mem);
131
132 /* if no zone, just do a free */
133 if (zone == NULL) {
134 free(ptr);
135 return;
136 }
137
138 /* point next to the item that matches ptr, or NULL if not found -- remove
139 the item from the linked list if found */
140 next = zone->first;
141 if (next) {
142 if (next->ptr == ptr)
143 zone->first = next->next; /* first one is it, remove from list */
144 else {
145 do { /* search the linked list */
146 item = next;
147 next = item->next;
148 } while (next != NULL && next->ptr != ptr);
149 if (next) { /* if found, remove from linked list */
150 item->next = next->next;
151 zone->notlifo++; /* not a LIFO free */
152 }
153
154 }
155 }
156
157 /* if found, update the statistics and free the item */
158 if (next) {
159 zone->total -= next->size;
160 free(next);
161 }
162
163 /* if not found, update the rogue count */
164 else
165 zone->rogue++;
166
167 /* in any case, do the requested free with the standard library function */
168 free(ptr);
169}
170
171/* set up a controlled memory allocation space for monitoring, set the stream
172 parameters to the controlled routines, with opaque pointing to the space */
173local void mem_setup(z_stream *strm)
174{
175 struct mem_zone *zone;
176
177 zone = static_cast<struct mem_zone *>(malloc(sizeof(struct mem_zone)));
178 assert(zone != NULL);
179 zone->first = NULL;
180 zone->total = 0;
181 zone->highwater = 0;
182 zone->limit = 0;
183 zone->notlifo = 0;
184 zone->rogue = 0;
185 strm->opaque = zone;
186 strm->zalloc = mem_alloc;
187 strm->zfree = mem_free;
188}
189
190/* set a limit on the total memory allocation, or 0 to remove the limit */
191local void mem_limit(z_stream *strm, size_t limit)
192{
193 struct mem_zone *zone = static_cast<struct mem_zone *>(strm->opaque);
194
195 zone->limit = limit;
196}
197
198/* show the current total requested allocations in bytes */
199local void mem_used(z_stream *strm, const char *prefix)
200{
201 struct mem_zone *zone = static_cast<struct mem_zone *>(strm->opaque);
202
203 std::cout << prefix << ": " << zone->total << " allocated" << std::endl;
204}
205
206/* show the high water allocation in bytes */
207local void mem_high(z_stream *strm, const char *prefix)
208{
209 struct mem_zone *zone = static_cast<struct mem_zone *>(strm->opaque);
210
211 std::cout << prefix << ": " << zone->highwater << " high water mark" << std::endl;
212}
213
214/* release the memory allocation zone -- if there are any surprises, notify */
215local void mem_done(z_stream *strm, const char *prefix)
216{
217 int count = 0;
218 struct mem_item *item, *next;
219 struct mem_zone *zone = static_cast<struct mem_zone *>(strm->opaque);
220
221 /* show high water mark */
222 mem_high(strm, prefix);
223
224 /* free leftover allocations and item structures, if any */
225 item = zone->first;
226 while (item != NULL) {
227 free(item->ptr);
228 next = item->next;
229 free(item);
230 item = next;
231 count++;
232 }
233
234 /* issue alerts about anything unexpected */
235 if (count || zone->total)
236 std::cout << "** " << prefix << ": "
237 << zone->total << " bytes in "
238 << count << " blocks not freed"
239 << std::endl;
240
241 if (zone->notlifo)
242 std::cout << "** " << prefix << ": "
243 << zone->notlifo << " frees not LIFO"
244 << std::endl;
245
246 if (zone->rogue)
247 std::cout << "** " << prefix << ": "
248 << zone->rogue << " frees not recognized"
249 << std::endl;
250
251 /* free the zone and delete from the stream */
252 free(zone);
253 strm->opaque = Z_NULL;
254 strm->zalloc = Z_NULL;
255 strm->zfree = Z_NULL;
256}
257
258/* -- inflate test routines -- */
259
260/* Decode a hexadecimal string, set *len to length, in[] to the bytes. This
261 decodes liberally, in that hex digits can be adjacent, in which case two in
262 a row writes a byte. Or they can be delimited by any non-hex character,
263 where the delimiters are ignored except when a single hex digit is followed
264 by a delimiter, where that single digit writes a byte. The returned data is
265 allocated and must eventually be freed. NULL is returned if out of memory.
266 If the length is not needed, then len can be NULL. */
267local unsigned char *h2b(const char *hex, unsigned *len)
268{
269 unsigned char *in, *re;
270 unsigned next, val;
271
272 in = static_cast<unsigned char *>(malloc((strlen(hex) + 1) >> 1));
273 if (in == NULL)
274 return NULL;
275 next = 0;
276 val = 1;
277 do {
278 if (*hex >= '0' && *hex <= '9')
279 val = (val << 4) + *hex - '0';
280 else if (*hex >= 'A' && *hex <= 'F')
281 val = (val << 4) + *hex - 'A' + 10;
282 else if (*hex >= 'a' && *hex <= 'f')
283 val = (val << 4) + *hex - 'a' + 10;
284 else if (val != 1 && val < 32) /* one digit followed by delimiter */
285 val += 240; /* make it look like two digits */
286 if (val > 255) { /* have two digits */
287 in[next++] = val & 0xff; /* save the decoded byte */
288 val = 1; /* start over */
289 }
290 } while (*hex++); /* go through the loop with the terminating null */
291 if (len != NULL)
292 *len = next;
293 re = static_cast<unsigned char *>(realloc(in, next));
294 return re == NULL ? in : re;
295}
296
297/* generic inflate() run, where hex is the hexadecimal input data, what is the
298 text to include in an error message, step is how much input data to feed
299 inflate() on each call, or zero to feed it all, win is the window bits
300 parameter to inflateInit2(), len is the size of the output buffer, and err
301 is the error code expected from the first inflate() call (the second
302 inflate() call is expected to return Z_STREAM_END). If win is 47, then
303 header information is collected with inflateGetHeader(). If a zlib stream
304 is looking for a dictionary, then an empty dictionary is provided.
305 inflate() is run until all of the input data is consumed. */
306local void inf(const char *hex, const char *what, unsigned step, int win, unsigned len,
307 int err)
308{
309 int ret;
310 unsigned have;
311 unsigned char *in, *out;
312 z_stream strm, copy;
313 gz_header head;
314
315 mem_setup(&strm);
316 strm.avail_in = 0;
317 strm.next_in = Z_NULL;
318 ret = inflateInit2(&strm, win);
319 if (ret != Z_OK) {
320 mem_done(&strm, what);
321 return;
322 }
323 out = static_cast<unsigned char *>(malloc(len)); assert(out != NULL);
324 if (win == 47) {
325 head.extra = out;
326 head.extra_max = len;
327 head.name = out;
328 head.name_max = len;
329 head.comment = out;
330 head.comm_max = len;
331 ret = inflateGetHeader(&strm, &head); assert(ret == Z_OK);
332 }
333 in = h2b(hex, &have); assert(in != NULL);
334 if (step == 0 || step > have)
335 step = have;
336 strm.avail_in = step;
337 have -= step;
338 strm.next_in = in;
339 do {
340 strm.avail_out = len;
341 strm.next_out = out;
342 ret = inflate(&strm, Z_NO_FLUSH); assert(err == 9 || ret == err);
343 if (ret != Z_OK && ret != Z_BUF_ERROR && ret != Z_NEED_DICT)
344 break;
345 if (ret == Z_NEED_DICT) {
346 ret = inflateSetDictionary(&strm, in, 1);
347 assert(ret == Z_DATA_ERROR);
348 mem_limit(&strm, 1);
349 ret = inflateSetDictionary(&strm, out, 0);
350 assert(ret == Z_MEM_ERROR);
351 mem_limit(&strm, 0);
352 ((struct inflate_state *)strm.state)->mode = DICT;
353 ret = inflateSetDictionary(&strm, out, 0);
354 assert(ret == Z_OK);
355 ret = inflate(&strm, Z_NO_FLUSH); assert(ret == Z_BUF_ERROR);
356 }
357 ret = inflateCopy(&copy, &strm); assert(ret == Z_OK);
358 ret = inflateEnd(&copy); assert(ret == Z_OK);
359 err = 9; /* don't care next time around */
360 have += strm.avail_in;
361 strm.avail_in = step > have ? have : step;
362 have -= strm.avail_in;
363 } while (strm.avail_in);
364 free(in);
365 free(out);
366 ret = inflateReset2(&strm, -8); assert(ret == Z_OK);
367 ret = inflateEnd(&strm); assert(ret == Z_OK);
368 mem_done(&strm, what);
369}
370
371/* cover all of the lines in inflate.c up to inflate() */
372void cover_support(void)
373{
374 int ret;
375 z_stream strm;
376
377 mem_setup(&strm);
378 strm.avail_in = 0;
379 strm.next_in = Z_NULL;
380 ret = inflateInit(&strm); assert(ret == Z_OK);
381 mem_used(&strm, "inflate init");
382 ret = inflatePrime(&strm, 5, 31); assert(ret == Z_OK);
383 ret = inflatePrime(&strm, -1, 0); assert(ret == Z_OK);
384 ret = inflateSetDictionary(&strm, Z_NULL, 0);
385 assert(ret == Z_STREAM_ERROR);
386 ret = inflateEnd(&strm); assert(ret == Z_OK);
387 mem_done(&strm, "prime");
388
389 inf("63 0", "force window allocation", 0, -15, 1, Z_OK);
390 inf("63 18 5", "force window replacement", 0, -8, 259, Z_OK);
391 inf("63 18 68 30 d0 0 0", "force split window update", 4, -8, 259, Z_OK);
392 inf("3 0", "use fixed blocks", 0, -15, 1, Z_STREAM_END);
393 inf("", "bad window size", 0, 1, 0, Z_STREAM_ERROR);
394
395 mem_setup(&strm);
396 strm.avail_in = 0;
397 strm.next_in = Z_NULL;
398 ret = inflateInit_(&strm, ZLIB_VERSION - 1, (int)sizeof(z_stream));
399 assert(ret == Z_VERSION_ERROR);
400 mem_done(&strm, "wrong version");
401
402 strm.avail_in = 0;
403 strm.next_in = Z_NULL;
404 ret = inflateInit(&strm); assert(ret == Z_OK);
405 ret = inflateEnd(&strm); assert(ret == Z_OK);
406 std::cout << "inflate built-in memory routines" << std::endl;;
407}
408
409/* cover all inflate() header and trailer cases and code after inflate() */
410void cover_wrap(void)
411{
412 int ret;
413 z_stream strm, copy;
414 unsigned char dict[257];
415
416 ret = inflate(Z_NULL, 0); assert(ret == Z_STREAM_ERROR);
417 ret = inflateEnd(Z_NULL); assert(ret == Z_STREAM_ERROR);
418 ret = inflateCopy(Z_NULL, Z_NULL); assert(ret == Z_STREAM_ERROR);
419 std::cout << "inflate bad parameters" << std::endl;
420
421 inf("1f 8b 0 0", "bad gzip method", 0, 31, 0, Z_DATA_ERROR);
422 inf("1f 8b 8 80", "bad gzip flags", 0, 31, 0, Z_DATA_ERROR);
423 inf("77 85", "bad zlib method", 0, 15, 0, Z_DATA_ERROR);
424 inf("8 99", "set window size from header", 0, 0, 0, Z_OK);
425 inf("78 9c", "bad zlib window size", 0, 8, 0, Z_DATA_ERROR);
426 inf("78 9c 63 0 0 0 1 0 1", "check adler32", 0, 15, 1, Z_STREAM_END);
427 inf("1f 8b 8 1e 0 0 0 0 0 0 1 0 0 0 0 0 0", "bad header crc", 0, 47, 1,
428 Z_DATA_ERROR);
429 inf("1f 8b 8 2 0 0 0 0 0 0 1d 26 3 0 0 0 0 0 0 0 0 0", "check gzip length",
430 0, 47, 0, Z_STREAM_END);
431 inf("78 90", "bad zlib header check", 0, 47, 0, Z_DATA_ERROR);
432 inf("8 b8 0 0 0 1", "need dictionary", 0, 8, 0, Z_NEED_DICT);
433 inf("78 9c 63 0", "compute adler32", 0, 15, 1, Z_OK);
434
435 mem_setup(&strm);
436 strm.avail_in = 0;
437 strm.next_in = Z_NULL;
438 ret = inflateInit2(&strm, -8);
439 strm.avail_in = 2;
440 strm.next_in = (Bytef *)"\x63";
441 strm.avail_out = 1;
442 strm.next_out = (Bytef *)&ret;
443 mem_limit(&strm, 1);
444 ret = inflate(&strm, Z_NO_FLUSH); assert(ret == Z_MEM_ERROR);
445 ret = inflate(&strm, Z_NO_FLUSH); assert(ret == Z_MEM_ERROR);
446 mem_limit(&strm, 0);
447 memset(dict, 0, 257);
448 ret = inflateSetDictionary(&strm, dict, 257);
449 assert(ret == Z_OK);
450 mem_limit(&strm, (sizeof(struct inflate_state) << 1) + 256);
451 ret = inflatePrime(&strm, 16, 0); assert(ret == Z_OK);
452 strm.avail_in = 2;
453 strm.next_in = (Bytef *)"\x80";
454 ret = inflateSync(&strm); assert(ret == Z_DATA_ERROR);
455 ret = inflate(&strm, Z_NO_FLUSH); assert(ret == Z_STREAM_ERROR);
456 strm.avail_in = 4;
457 strm.next_in = (Bytef *)"\0\0\xff\xff";
458 ret = inflateSync(&strm); assert(ret == Z_OK);
459 (void)inflateSyncPoint(&strm);
460 ret = inflateCopy(&copy, &strm); assert(ret == Z_MEM_ERROR);
461 mem_limit(&strm, 0);
462 ret = inflateUndermine(&strm, 1); assert(ret == Z_DATA_ERROR);
463 (void)inflateMark(&strm);
464 ret = inflateEnd(&strm); assert(ret == Z_OK);
465 mem_done(&strm, "miscellaneous, force memory errors");
466}
467
468/* input and output functions for inflateBack() */
469local unsigned pull(void *desc, unsigned char **buf)
470{
471 static unsigned int next = 0;
472 static unsigned char dat[] = {0x63, 0, 2, 0};
473 struct inflate_state *state;
474
475 if (desc == Z_NULL) {
476 next = 0;
477 return 0; /* no input (already provided at next_in) */
478 }
479 state = reinterpret_cast<struct inflate_state *>(((z_stream *)desc)->state);
480 if (state != Z_NULL)
481 state->mode = SYNC; /* force an otherwise impossible situation */
482 return next < sizeof(dat) ? (*buf = dat + next++, 1) : 0;
483}
484
485local int push(void *desc, unsigned char *buf, unsigned len)
486{
487 buf += len;
488 return desc != Z_NULL; /* force error if desc not null */
489}
490
491/* cover inflateBack() up to common deflate data cases and after those */
492void cover_back(void)
493{
494 int ret;
495 z_stream strm;
496 unsigned char win[32768];
497
498 ret = inflateBackInit_(Z_NULL, 0, win, 0, 0);
499 assert(ret == Z_VERSION_ERROR);
500 ret = inflateBackInit(Z_NULL, 0, win); assert(ret == Z_STREAM_ERROR);
501 ret = inflateBack(Z_NULL, Z_NULL, Z_NULL, Z_NULL, Z_NULL);
502 assert(ret == Z_STREAM_ERROR);
503 ret = inflateBackEnd(Z_NULL); assert(ret == Z_STREAM_ERROR);
504 std::cout << "inflateBack bad parameters" << std::endl;;
505
506 mem_setup(&strm);
507 ret = inflateBackInit(&strm, 15, win); assert(ret == Z_OK);
508 strm.avail_in = 2;
509 strm.next_in = (Bytef *)"\x03";
510 ret = inflateBack(&strm, pull, Z_NULL, push, Z_NULL);
511 assert(ret == Z_STREAM_END);
512 /* force output error */
513 strm.avail_in = 3;
514 strm.next_in = (Bytef *)"\x63\x00";
515 ret = inflateBack(&strm, pull, Z_NULL, push, &strm);
516 assert(ret == Z_BUF_ERROR);
517 /* force mode error by mucking with state */
518 ret = inflateBack(&strm, pull, &strm, push, Z_NULL);
519 assert(ret == Z_STREAM_ERROR);
520 ret = inflateBackEnd(&strm); assert(ret == Z_OK);
521 mem_done(&strm, "inflateBack bad state");
522
523 ret = inflateBackInit(&strm, 15, win); assert(ret == Z_OK);
524 ret = inflateBackEnd(&strm); assert(ret == Z_OK);
525 std::cout << "inflateBack built-in memory routines" << std::endl;;
526}
527
528/* do a raw inflate of data in hexadecimal with both inflate and inflateBack */
529local int try(const char *hex, const char *id, int err)
530{
531 int ret;
532 unsigned len, size;
533 unsigned char *in, *out, *win;
534 char *prefix;
535 z_stream strm;
536
537 /* convert to hex */
538 in = h2b(hex, &len);
539 assert(in != NULL);
540
541 /* allocate work areas */
542 size = len << 3;
543 out = static_cast<unsigned char *>(malloc(size));
544 assert(out != NULL);
545 win = static_cast<unsigned char *>(malloc(32768));
546 assert(win != NULL);
547 prefix = static_cast<char *>(malloc(strlen(id) + 6));
548 assert(prefix != NULL);
549
550 /* first with inflate */
551 strcpy(prefix, id);
552 strcat(prefix, "-late");
553 mem_setup(&strm);
554 strm.avail_in = 0;
555 strm.next_in = Z_NULL;
556 ret = inflateInit2(&strm, err < 0 ? 47 : -15);
557 assert(ret == Z_OK);
558 strm.avail_in = len;
559 strm.next_in = in;
560 do {
561 strm.avail_out = size;
562 strm.next_out = out;
563 ret = inflate(&strm, Z_TREES);
564 assert(ret != Z_STREAM_ERROR && ret != Z_MEM_ERROR);
565 if (ret == Z_DATA_ERROR || ret == Z_NEED_DICT)
566 break;
567 } while (strm.avail_in || strm.avail_out == 0);
568 if (err) {
569 assert(ret == Z_DATA_ERROR);
570 assert(strcmp(id, strm.msg) == 0);
571 }
572 inflateEnd(&strm);
573 mem_done(&strm, prefix);
574
575 /* then with inflateBack */
576 if (err >= 0) {
577 strcpy(prefix, id);
578 strcat(prefix, "-back");
579 mem_setup(&strm);
580 ret = inflateBackInit(&strm, 15, win);
581 assert(ret == Z_OK);
582 strm.avail_in = len;
583 strm.next_in = in;
584 ret = inflateBack(&strm, pull, Z_NULL, push, Z_NULL);
585 assert(ret != Z_STREAM_ERROR);
586 if (err) {
587 assert(ret == Z_DATA_ERROR);
588 assert(strcmp(id, strm.msg) == 0);
589 }
590 inflateBackEnd(&strm);
591 mem_done(&strm, prefix);
592 }
593
594 /* clean up */
595 free(prefix);
596 free(win);
597 free(out);
598 free(in);
599 return ret;
600}
601
602/* cover deflate data cases in both inflate() and inflateBack() */
603void cover_inflate(void)
604{
605 try("0 0 0 0 0", "invalid stored block lengths", 1);
606 try("3 0", "fixed", 0);
607 try("6", "invalid block type", 1);
608 try("1 1 0 fe ff 0", "stored", 0);
609 try("fc 0 0", "too many length or distance symbols", 1);
610 try("4 0 fe ff", "invalid code lengths set", 1);
611 try("4 0 24 49 0", "invalid bit length repeat", 1);
612 try("4 0 24 e9 ff ff", "invalid bit length repeat", 1);
613 try("4 0 24 e9 ff 6d", "invalid code -- missing end-of-block", 1);
614 try("4 80 49 92 24 49 92 24 71 ff ff 93 11 0",
615 "invalid literal/lengths set", 1);
616 try("4 80 49 92 24 49 92 24 f b4 ff ff c3 84", "invalid distances set", 1);
617 try("4 c0 81 8 0 0 0 0 20 7f eb b 0 0", "invalid literal/length code", 1);
618 try("2 7e ff ff", "invalid distance code", 1);
619 try("c c0 81 0 0 0 0 0 90 ff 6b 4 0", "invalid distance too far back", 1);
620
621 /* also trailer mismatch just in inflate() */
622 try("1f 8b 8 0 0 0 0 0 0 0 3 0 0 0 0 1", "incorrect data check", -1);
623 try("1f 8b 8 0 0 0 0 0 0 0 3 0 0 0 0 0 0 0 0 1",
624 "incorrect length check", -1);
625 try("5 c0 21 d 0 0 0 80 b0 fe 6d 2f 91 6c", "pull 17", 0);
626 try("5 e0 81 91 24 cb b2 2c 49 e2 f 2e 8b 9a 47 56 9f fb fe ec d2 ff 1f",
627 "long code", 0);
628 try("ed c0 1 1 0 0 0 40 20 ff 57 1b 42 2c 4f", "length extra", 0);
629 try("ed cf c1 b1 2c 47 10 c4 30 fa 6f 35 1d 1 82 59 3d fb be 2e 2a fc f c",
630 "long distance and extra", 0);
631 try("ed c0 81 0 0 0 0 80 a0 fd a9 17 a9 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 "
632 "0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 6", "window end", 0);
633 inf("2 8 20 80 0 3 0", "inflate_fast TYPE return", 0, -15, 258,
634 Z_STREAM_END);
635 inf("63 18 5 40 c 0", "window wrap", 3, -8, 300, Z_OK);
636}
637
638/* XXX(cavalcantii): fix linking error due inflate_table. */
639/* cover remaining lines in inftrees.c */
640/* void cover_trees(void) */
641/* { */
642/* int ret; */
643/* unsigned bits; */
644/* unsigned short lens[16], work[16]; */
645/* code *next, table[ENOUGH_DISTS]; */
646
647/* /\* we need to call inflate_table() directly in order to manifest not- */
648/* enough errors, since zlib insures that enough is always enough *\/ */
649/* for (bits = 0; bits < 15; bits++) */
650/* lens[bits] = (unsigned short)(bits + 1); */
651/* lens[15] = 15; */
652/* next = table; */
653/* bits = 15; */
654/* ret = inflate_table(DISTS, lens, 16, &next, &bits, work); */
655/* assert(ret == 1); */
656/* next = table; */
657/* bits = 1; */
658/* ret = inflate_table(DISTS, lens, 16, &next, &bits, work); */
659/* assert(ret == 1); */
660/* fputs("inflate_table not enough errors\n", stderr); */
661/* } */
662
663/* cover remaining inffast.c decoding and window copying */
664void cover_fast(void)
665{
666 inf("e5 e0 81 ad 6d cb b2 2c c9 01 1e 59 63 ae 7d ee fb 4d fd b5 35 41 68"
667 " ff 7f 0f 0 0 0", "fast length extra bits", 0, -8, 258, Z_DATA_ERROR);
668 inf("25 fd 81 b5 6d 59 b6 6a 49 ea af 35 6 34 eb 8c b9 f6 b9 1e ef 67 49"
669 " 50 fe ff ff 3f 0 0", "fast distance extra bits", 0, -8, 258,
670 Z_DATA_ERROR);
671 inf("3 7e 0 0 0 0 0", "fast invalid distance code", 0, -8, 258,
672 Z_DATA_ERROR);
673 inf("1b 7 0 0 0 0 0", "fast invalid literal/length code", 0, -8, 258,
674 Z_DATA_ERROR);
675 inf("d c7 1 ae eb 38 c 4 41 a0 87 72 de df fb 1f b8 36 b1 38 5d ff ff 0",
676 "fast 2nd level codes and too far back", 0, -8, 258, Z_DATA_ERROR);
677 inf("63 18 5 8c 10 8 0 0 0 0", "very common case", 0, -8, 259, Z_OK);
678 inf("63 60 60 18 c9 0 8 18 18 18 26 c0 28 0 29 0 0 0",
679 "contiguous and wrap around window", 6, -8, 259, Z_OK);
680 inf("63 0 3 0 0 0 0 0", "copy direct from output", 0, -8, 259,
681 Z_STREAM_END);
682}
683
684// clang-format on