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