Home | History | Annotate | Line # | Download | only in test
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(&copy, &strm);        assert(ret == Z_OK);
    336  1.1.1.1.4.2  pgoyette         ret = inflateEnd(&copy);                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(&copy, &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