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)(&copy, &strm);
339                                                 assert(ret == Z_OK);
340         ret = PREFIX(inflateEnd)(&copy);        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     Z_UNUSED(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     Z_UNUSED(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)(&copy, &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     Z_UNUSED(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     Z_UNUSED(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     Z_UNUSED(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