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