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