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)(©, &strm);
333 assert(ret == Z_OK);
334 ret = PREFIX(inflateEnd)(©); 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)(©, &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