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