1b33c96954667ba382fa595baf7b31290bfdd517vboxsync/* infcover.c -- test zlib's inflate routines with full code coverage
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync * Copyright (C) 2011 Mark Adler
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync * For conditions of distribution and use, see copyright notice in zlib.h
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync */
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync/* to use, do: ./configure --cover && make cover */
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync#include <stdio.h>
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync#include <stdlib.h>
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync#include <string.h>
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync#include <assert.h>
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync#include "zlib.h"
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync/* get definition of internal structure so we can mess with it (see pull()),
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync and so we can call inflate_trees() (see cover5()) */
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync#define ZLIB_INTERNAL
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync#include "inftrees.h"
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync#include "inflate.h"
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync#define local static
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync/* -- memory tracking routines -- */
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync/*
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync These memory tracking routines are provided to zlib and track all of zlib's
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync allocations and deallocations, check for LIFO operations, keep a current
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync and high water mark of total bytes requested, optionally set a limit on the
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync total memory that can be allocated, and when done check for memory leaks.
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync They are used as follows:
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync z_stream strm;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync mem_setup(&strm) initializes the memory tracking and sets the
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync zalloc, zfree, and opaque members of strm to use
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync memory tracking for all zlib operations on strm
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync mem_limit(&strm, limit) sets a limit on the total bytes requested -- a
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync request that exceeds this limit will result in an
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync allocation failure (returns NULL) -- setting the
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync limit to zero means no limit, which is the default
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync after mem_setup()
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync mem_used(&strm, "msg") prints to stderr "msg" and the total bytes used
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync mem_high(&strm, "msg") prints to stderr "msg" and the high water mark
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync mem_done(&strm, "msg") ends memory tracking, releases all allocations
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync for the tracking as well as leaked zlib blocks, if
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync any. If there was anything unusual, such as leaked
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync blocks, non-FIFO frees, or frees of addresses not
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync allocated, then "msg" and information about the
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync problem is printed to stderr. If everything is
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync normal, nothing is printed. mem_done resets the
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync strm members to Z_NULL to use the default memory
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync allocation routines on the next zlib initialization
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync using strm.
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync */
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync/* these items are strung together in a linked list, one for each allocation */
1b33c96954667ba382fa595baf7b31290bfdd517vboxsyncstruct mem_item {
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync void *ptr; /* pointer to allocated memory */
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync size_t size; /* requested size of allocation */
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync struct mem_item *next; /* pointer to next item in list, or NULL */
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync};
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync/* this structure is at the root of the linked list, and tracks statistics */
1b33c96954667ba382fa595baf7b31290bfdd517vboxsyncstruct mem_zone {
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync struct mem_item *first; /* pointer to first item in list, or NULL */
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync size_t total, highwater; /* total allocations, and largest total */
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync size_t limit; /* memory allocation limit, or 0 if no limit */
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync int notlifo, rogue; /* counts of non-LIFO frees and rogue frees */
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync};
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync/* memory allocation routine to pass to zlib */
1b33c96954667ba382fa595baf7b31290bfdd517vboxsynclocal void *mem_alloc(void *mem, unsigned count, unsigned size)
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync{
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync void *ptr;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync struct mem_item *item;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync struct mem_zone *zone = mem;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync size_t len = count * (size_t)size;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync /* induced allocation failure */
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync if (zone == NULL || (zone->limit && zone->total + len > zone->limit))
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync return NULL;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync /* perform allocation using the standard library, fill memory with a
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync non-zero value to make sure that the code isn't depending on zeros */
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync ptr = malloc(len);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync if (ptr == NULL)
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync return NULL;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync memset(ptr, 0xa5, len);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync /* create a new item for the list */
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync item = malloc(sizeof(struct mem_item));
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync if (item == NULL) {
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync free(ptr);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync return NULL;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync }
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync item->ptr = ptr;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync item->size = len;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync /* insert item at the beginning of the list */
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync item->next = zone->first;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync zone->first = item;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync /* update the statistics */
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync zone->total += item->size;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync if (zone->total > zone->highwater)
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync zone->highwater = zone->total;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync /* return the allocated memory */
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync return ptr;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync}
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync/* memory free routine to pass to zlib */
1b33c96954667ba382fa595baf7b31290bfdd517vboxsynclocal void mem_free(void *mem, void *ptr)
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync{
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync struct mem_item *item, *next;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync struct mem_zone *zone = mem;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync /* if no zone, just do a free */
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync if (zone == NULL) {
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync free(ptr);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync return;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync }
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync /* point next to the item that matches ptr, or NULL if not found -- remove
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync the item from the linked list if found */
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync next = zone->first;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync if (next) {
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync if (next->ptr == ptr)
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync zone->first = next->next; /* first one is it, remove from list */
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync else {
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync do { /* search the linked list */
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync item = next;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync next = item->next;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync } while (next != NULL && next->ptr != ptr);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync if (next) { /* if found, remove from linked list */
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync item->next = next->next;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync zone->notlifo++; /* not a LIFO free */
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync }
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync }
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync }
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync /* if found, update the statistics and free the item */
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync if (next) {
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync zone->total -= next->size;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync free(next);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync }
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync /* if not found, update the rogue count */
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync else
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync zone->rogue++;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync /* in any case, do the requested free with the standard library function */
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync free(ptr);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync}
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync/* set up a controlled memory allocation space for monitoring, set the stream
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync parameters to the controlled routines, with opaque pointing to the space */
1b33c96954667ba382fa595baf7b31290bfdd517vboxsynclocal void mem_setup(z_stream *strm)
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync{
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync struct mem_zone *zone;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync zone = malloc(sizeof(struct mem_zone));
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync assert(zone != NULL);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync zone->first = NULL;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync zone->total = 0;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync zone->highwater = 0;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync zone->limit = 0;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync zone->notlifo = 0;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync zone->rogue = 0;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync strm->opaque = zone;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync strm->zalloc = mem_alloc;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync strm->zfree = mem_free;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync}
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync/* set a limit on the total memory allocation, or 0 to remove the limit */
1b33c96954667ba382fa595baf7b31290bfdd517vboxsynclocal void mem_limit(z_stream *strm, size_t limit)
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync{
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync struct mem_zone *zone = strm->opaque;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync zone->limit = limit;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync}
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync/* show the current total requested allocations in bytes */
1b33c96954667ba382fa595baf7b31290bfdd517vboxsynclocal void mem_used(z_stream *strm, char *prefix)
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync{
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync struct mem_zone *zone = strm->opaque;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync fprintf(stderr, "%s: %lu allocated\n", prefix, zone->total);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync}
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync/* show the high water allocation in bytes */
1b33c96954667ba382fa595baf7b31290bfdd517vboxsynclocal void mem_high(z_stream *strm, char *prefix)
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync{
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync struct mem_zone *zone = strm->opaque;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync fprintf(stderr, "%s: %lu high water mark\n", prefix, zone->highwater);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync}
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync/* release the memory allocation zone -- if there are any surprises, notify */
1b33c96954667ba382fa595baf7b31290bfdd517vboxsynclocal void mem_done(z_stream *strm, char *prefix)
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync{
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync int count = 0;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync struct mem_item *item, *next;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync struct mem_zone *zone = strm->opaque;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync /* show high water mark */
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync mem_high(strm, prefix);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync /* free leftover allocations and item structures, if any */
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync item = zone->first;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync while (item != NULL) {
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync free(item->ptr);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync next = item->next;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync free(item);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync item = next;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync count++;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync }
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync /* issue alerts about anything unexpected */
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync if (count || zone->total)
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync fprintf(stderr, "** %s: %lu bytes in %d blocks not freed\n",
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync prefix, zone->total, count);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync if (zone->notlifo)
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync fprintf(stderr, "** %s: %d frees not LIFO\n", prefix, zone->notlifo);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync if (zone->rogue)
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync fprintf(stderr, "** %s: %d frees not recognized\n",
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync prefix, zone->rogue);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync /* free the zone and delete from the stream */
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync free(zone);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync strm->opaque = Z_NULL;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync strm->zalloc = Z_NULL;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync strm->zfree = Z_NULL;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync}
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync/* -- inflate test routines -- */
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync/* Decode a hexadecimal string, set *len to length, in[] to the bytes. This
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync decodes liberally, in that hex digits can be adjacent, in which case two in
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync a row writes a byte. Or they can delimited by any non-hex character, where
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync the delimiters are ignored except when a single hex digit is followed by a
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync delimiter in which case that single digit writes a byte. The returned
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync data is allocated and must eventually be freed. NULL is returned if out of
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync memory. If the length is not needed, then len can be NULL. */
1b33c96954667ba382fa595baf7b31290bfdd517vboxsynclocal unsigned char *h2b(const char *hex, unsigned *len)
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync{
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync unsigned char *in;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync unsigned next, val;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync in = malloc((strlen(hex) + 1) >> 1);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync if (in == NULL)
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync return NULL;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync next = 0;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync val = 1;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync do {
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync if (*hex >= '0' && *hex <= '9')
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync val = (val << 4) + *hex - '0';
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync else if (*hex >= 'A' && *hex <= 'F')
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync val = (val << 4) + *hex - 'A' + 10;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync else if (*hex >= 'a' && *hex <= 'f')
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync val = (val << 4) + *hex - 'a' + 10;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync else if (val != 1 && val < 32) /* one digit followed by delimiter */
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync val += 240; /* make it look like two digits */
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync if (val > 255) { /* have two digits */
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync in[next++] = val & 0xff; /* save the decoded byte */
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync val = 1; /* start over */
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync }
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync } while (*hex++); /* go through the loop with the terminating null */
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync if (len != NULL)
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync *len = next;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync in = reallocf(in, next);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync return in;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync}
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync/* generic inflate() run, where hex is the hexadecimal input data, what is the
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync text to include in an error message, step is how much input data to feed
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync inflate() on each call, or zero to feed it all, win is the window bits
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync parameter to inflateInit2(), len is the size of the output buffer, and err
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync is the error code expected from the first inflate() call (the second
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync inflate() call is expected to return Z_STREAM_END). If win is 47, then
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync header information is collected with inflateGetHeader(). If a zlib stream
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync is looking for a dictionary, then an empty dictionary is provided.
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync inflate() is run until all of the input data is consumed. */
1b33c96954667ba382fa595baf7b31290bfdd517vboxsynclocal void inf(char *hex, char *what, unsigned step, int win, unsigned len,
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync int err)
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync{
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync int ret;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync unsigned have;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync unsigned char *in, *out;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync z_stream strm, copy;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync gz_header head;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync mem_setup(&strm);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync strm.avail_in = 0;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync strm.next_in = Z_NULL;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync ret = inflateInit2(&strm, win);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync if (ret != Z_OK) {
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync mem_done(&strm, what);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync return;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync }
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync out = malloc(len); assert(out != NULL);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync if (win == 47) {
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync head.extra = out;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync head.extra_max = len;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync head.name = out;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync head.name_max = len;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync head.comment = out;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync head.comm_max = len;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync ret = inflateGetHeader(&strm, &head); assert(ret == Z_OK);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync }
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync in = h2b(hex, &have); assert(in != NULL);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync if (step == 0 || step > have)
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync step = have;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync strm.avail_in = step;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync have -= step;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync strm.next_in = in;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync do {
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync strm.avail_out = len;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync strm.next_out = out;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync ret = inflate(&strm, Z_NO_FLUSH); assert(err == 9 || ret == err);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync if (ret != Z_OK && ret != Z_BUF_ERROR && ret != Z_NEED_DICT)
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync break;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync if (ret == Z_NEED_DICT) {
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync ret = inflateSetDictionary(&strm, in, 1);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync assert(ret == Z_DATA_ERROR);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync mem_limit(&strm, 1);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync ret = inflateSetDictionary(&strm, out, 0);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync assert(ret == Z_MEM_ERROR);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync mem_limit(&strm, 0);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync ((struct inflate_state *)strm.state)->mode = DICT;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync ret = inflateSetDictionary(&strm, out, 0);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync assert(ret == Z_OK);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync ret = inflate(&strm, Z_NO_FLUSH); assert(ret == Z_BUF_ERROR);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync }
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync ret = inflateCopy(&copy, &strm); assert(ret == Z_OK);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync ret = inflateEnd(&copy); assert(ret == Z_OK);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync err = 9; /* don't care next time around */
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync have += strm.avail_in;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync strm.avail_in = step > have ? have : step;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync have -= strm.avail_in;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync } while (strm.avail_in);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync free(in);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync free(out);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync ret = inflateReset2(&strm, -8); assert(ret == Z_OK);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync ret = inflateEnd(&strm); assert(ret == Z_OK);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync mem_done(&strm, what);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync}
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync/* cover all of the lines in inflate.c up to inflate() */
1b33c96954667ba382fa595baf7b31290bfdd517vboxsynclocal void cover_support(void)
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync{
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync int ret;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync z_stream strm;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync mem_setup(&strm);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync strm.avail_in = 0;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync strm.next_in = Z_NULL;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync ret = inflateInit(&strm); assert(ret == Z_OK);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync mem_used(&strm, "inflate init");
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync ret = inflatePrime(&strm, 5, 31); assert(ret == Z_OK);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync ret = inflatePrime(&strm, -1, 0); assert(ret == Z_OK);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync ret = inflateSetDictionary(&strm, Z_NULL, 0);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync assert(ret == Z_STREAM_ERROR);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync ret = inflateEnd(&strm); assert(ret == Z_OK);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync mem_done(&strm, "prime");
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync inf("63 0", "force window allocation", 0, -15, 1, Z_OK);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync inf("63 18 5", "force window replacement", 0, -8, 259, Z_OK);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync inf("63 18 68 30 d0 0 0", "force split window update", 4, -8, 259, Z_OK);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync inf("3 0", "use fixed blocks", 0, -15, 1, Z_STREAM_END);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync inf("", "bad window size", 0, 1, 0, Z_STREAM_ERROR);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync mem_setup(&strm);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync strm.avail_in = 0;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync strm.next_in = Z_NULL;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync ret = inflateInit_(&strm, ZLIB_VERSION - 1, (int)sizeof(z_stream));
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync assert(ret == Z_VERSION_ERROR);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync mem_done(&strm, "wrong version");
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync strm.avail_in = 0;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync strm.next_in = Z_NULL;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync ret = inflateInit(&strm); assert(ret == Z_OK);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync ret = inflateEnd(&strm); assert(ret == Z_OK);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync fputs("inflate built-in memory routines\n", stderr);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync}
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync/* cover all inflate() header and trailer cases and code after inflate() */
1b33c96954667ba382fa595baf7b31290bfdd517vboxsynclocal void cover_wrap(void)
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync{
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync int ret;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync z_stream strm, copy;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync unsigned char dict[257];
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync ret = inflate(Z_NULL, 0); assert(ret == Z_STREAM_ERROR);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync ret = inflateEnd(Z_NULL); assert(ret == Z_STREAM_ERROR);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync ret = inflateCopy(Z_NULL, Z_NULL); assert(ret == Z_STREAM_ERROR);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync fputs("inflate bad parameters\n", stderr);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync inf("1f 8b 0 0", "bad gzip method", 0, 31, 0, Z_DATA_ERROR);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync inf("1f 8b 8 80", "bad gzip flags", 0, 31, 0, Z_DATA_ERROR);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync inf("77 85", "bad zlib method", 0, 15, 0, Z_DATA_ERROR);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync inf("8 99", "set window size from header", 0, 0, 0, Z_OK);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync inf("78 9c", "bad zlib window size", 0, 8, 0, Z_DATA_ERROR);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync inf("78 9c 63 0 0 0 1 0 1", "check adler32", 0, 15, 1, Z_STREAM_END);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync inf("1f 8b 8 1e 0 0 0 0 0 0 1 0 0 0 0 0 0", "bad header crc", 0, 47, 1,
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync Z_DATA_ERROR);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync 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",
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync 0, 47, 0, Z_STREAM_END);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync inf("78 90", "bad zlib header check", 0, 47, 0, Z_DATA_ERROR);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync inf("8 b8 0 0 0 1", "need dictionary", 0, 8, 0, Z_NEED_DICT);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync inf("78 9c 63 0", "compute adler32", 0, 15, 1, Z_OK);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync mem_setup(&strm);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync strm.avail_in = 0;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync strm.next_in = Z_NULL;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync ret = inflateInit2(&strm, -8);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync strm.avail_in = 2;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync strm.next_in = (void *)"\x63";
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync strm.avail_out = 1;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync strm.next_out = (void *)&ret;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync mem_limit(&strm, 1);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync ret = inflate(&strm, Z_NO_FLUSH); assert(ret == Z_MEM_ERROR);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync ret = inflate(&strm, Z_NO_FLUSH); assert(ret == Z_MEM_ERROR);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync mem_limit(&strm, 0);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync memset(dict, 0, 257);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync ret = inflateSetDictionary(&strm, dict, 257);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync assert(ret == Z_OK);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync mem_limit(&strm, (sizeof(struct inflate_state) << 1) + 256);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync ret = inflatePrime(&strm, 16, 0); assert(ret == Z_OK);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync strm.avail_in = 2;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync strm.next_in = (void *)"\x80";
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync ret = inflateSync(&strm); assert(ret == Z_DATA_ERROR);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync ret = inflate(&strm, Z_NO_FLUSH); assert(ret == Z_STREAM_ERROR);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync strm.avail_in = 4;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync strm.next_in = (void *)"\0\0\xff\xff";
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync ret = inflateSync(&strm); assert(ret == Z_OK);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync (void)inflateSyncPoint(&strm);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync ret = inflateCopy(&copy, &strm); assert(ret == Z_MEM_ERROR);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync mem_limit(&strm, 0);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync ret = inflateUndermine(&strm, 1); assert(ret == Z_DATA_ERROR);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync (void)inflateMark(&strm);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync ret = inflateEnd(&strm); assert(ret == Z_OK);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync mem_done(&strm, "miscellaneous, force memory errors");
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync}
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync/* input and output functions for inflateBack() */
1b33c96954667ba382fa595baf7b31290bfdd517vboxsynclocal unsigned pull(void *desc, unsigned char **buf)
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync{
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync static unsigned int next = 0;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync static unsigned char dat[] = {0x63, 0, 2, 0};
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync struct inflate_state *state;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync if (desc == Z_NULL) {
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync next = 0;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync return 0; /* no input (already provided at next_in) */
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync }
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync state = (void *)((z_stream *)desc)->state;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync if (state != Z_NULL)
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync state->mode = SYNC; /* force an otherwise impossible situation */
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync return next < sizeof(dat) ? (*buf = dat + next++, 1) : 0;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync}
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsynclocal int push(void *desc, unsigned char *buf, unsigned len)
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync{
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync buf += len;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync return desc != Z_NULL; /* force error if desc not null */
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync}
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync/* cover inflateBack() up to common deflate data cases and after those */
1b33c96954667ba382fa595baf7b31290bfdd517vboxsynclocal void cover_back(void)
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync{
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync int ret;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync z_stream strm;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync unsigned char win[32768];
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync ret = inflateBackInit_(Z_NULL, 0, win, 0, 0);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync assert(ret == Z_VERSION_ERROR);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync ret = inflateBackInit(Z_NULL, 0, win); assert(ret == Z_STREAM_ERROR);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync ret = inflateBack(Z_NULL, Z_NULL, Z_NULL, Z_NULL, Z_NULL);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync assert(ret == Z_STREAM_ERROR);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync ret = inflateBackEnd(Z_NULL); assert(ret == Z_STREAM_ERROR);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync fputs("inflateBack bad parameters\n", stderr);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync mem_setup(&strm);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync ret = inflateBackInit(&strm, 15, win); assert(ret == Z_OK);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync strm.avail_in = 2;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync strm.next_in = (void *)"\x03";
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync ret = inflateBack(&strm, pull, Z_NULL, push, Z_NULL);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync assert(ret == Z_STREAM_END);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync /* force output error */
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync strm.avail_in = 3;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync strm.next_in = (void *)"\x63\x00";
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync ret = inflateBack(&strm, pull, Z_NULL, push, &strm);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync assert(ret == Z_BUF_ERROR);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync /* force mode error by mucking with state */
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync ret = inflateBack(&strm, pull, &strm, push, Z_NULL);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync assert(ret == Z_STREAM_ERROR);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync ret = inflateBackEnd(&strm); assert(ret == Z_OK);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync mem_done(&strm, "inflateBack bad state");
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync ret = inflateBackInit(&strm, 15, win); assert(ret == Z_OK);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync ret = inflateBackEnd(&strm); assert(ret == Z_OK);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync fputs("inflateBack built-in memory routines\n", stderr);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync}
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync/* do a raw inflate of data in hexadecimal with both inflate and inflateBack */
1b33c96954667ba382fa595baf7b31290bfdd517vboxsynclocal int try(char *hex, char *id, int err)
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync{
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync int ret;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync unsigned len, size;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync unsigned char *in, *out, *win;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync char *prefix;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync z_stream strm;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync /* convert to hex */
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync in = h2b(hex, &len);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync assert(in != NULL);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync /* allocate work areas */
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync size = len << 3;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync out = malloc(size);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync assert(out != NULL);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync win = malloc(32768);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync assert(win != NULL);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync prefix = malloc(strlen(id) + 6);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync assert(prefix != NULL);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync /* first with inflate */
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync strcpy(prefix, id);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync strcat(prefix, "-late");
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync mem_setup(&strm);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync strm.avail_in = 0;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync strm.next_in = Z_NULL;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync ret = inflateInit2(&strm, err < 0 ? 47 : -15);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync assert(ret == Z_OK);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync strm.avail_in = len;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync strm.next_in = in;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync do {
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync strm.avail_out = size;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync strm.next_out = out;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync ret = inflate(&strm, Z_TREES);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync assert(ret != Z_STREAM_ERROR && ret != Z_MEM_ERROR);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync if (ret == Z_DATA_ERROR || ret == Z_NEED_DICT)
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync break;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync } while (strm.avail_in || strm.avail_out == 0);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync if (err) {
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync assert(ret == Z_DATA_ERROR);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync assert(strcmp(id, strm.msg) == 0);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync }
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync inflateEnd(&strm);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync mem_done(&strm, prefix);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync /* then with inflateBack */
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync if (err >= 0) {
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync strcpy(prefix, id);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync strcat(prefix, "-back");
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync mem_setup(&strm);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync ret = inflateBackInit(&strm, 15, win);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync assert(ret == Z_OK);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync strm.avail_in = len;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync strm.next_in = in;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync ret = inflateBack(&strm, pull, Z_NULL, push, Z_NULL);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync assert(ret != Z_STREAM_ERROR);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync if (err) {
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync assert(ret == Z_DATA_ERROR);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync assert(strcmp(id, strm.msg) == 0);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync }
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync inflateBackEnd(&strm);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync mem_done(&strm, prefix);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync }
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync /* clean up */
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync free(prefix);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync free(win);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync free(out);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync free(in);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync return ret;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync}
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync/* cover deflate data cases in both inflate() and inflateBack() */
1b33c96954667ba382fa595baf7b31290bfdd517vboxsynclocal void cover_inflate(void)
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync{
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync try("0 0 0 0 0", "invalid stored block lengths", 1);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync try("3 0", "fixed", 0);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync try("6", "invalid block type", 1);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync try("1 1 0 fe ff 0", "stored", 0);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync try("fc 0 0", "too many length or distance symbols", 1);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync try("4 0 fe ff", "invalid code lengths set", 1);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync try("4 0 24 49 0", "invalid bit length repeat", 1);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync try("4 0 24 e9 ff ff", "invalid bit length repeat", 1);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync try("4 0 24 e9 ff 6d", "invalid code -- missing end-of-block", 1);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync try("4 80 49 92 24 49 92 24 71 ff ff 93 11 0",
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync "invalid literal/lengths set", 1);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync try("4 80 49 92 24 49 92 24 f b4 ff ff c3 84", "invalid distances set", 1);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync try("4 c0 81 8 0 0 0 0 20 7f eb b 0 0", "invalid literal/length code", 1);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync try("2 7e ff ff", "invalid distance code", 1);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync try("c c0 81 0 0 0 0 0 90 ff 6b 4 0", "invalid distance too far back", 1);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync /* also trailer mismatch just in inflate() */
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync try("1f 8b 8 0 0 0 0 0 0 0 3 0 0 0 0 1", "incorrect data check", -1);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync try("1f 8b 8 0 0 0 0 0 0 0 3 0 0 0 0 0 0 0 0 1",
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync "incorrect length check", -1);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync try("5 c0 21 d 0 0 0 80 b0 fe 6d 2f 91 6c", "pull 17", 0);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync try("5 e0 81 91 24 cb b2 2c 49 e2 f 2e 8b 9a 47 56 9f fb fe ec d2 ff 1f",
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync "long code", 0);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync try("ed c0 1 1 0 0 0 40 20 ff 57 1b 42 2c 4f", "length extra", 0);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync 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",
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync "long distance and extra", 0);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync 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 "
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync "0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 6", "window end", 0);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync inf("2 8 20 80 0 3 0", "inflate_fast TYPE return", 0, -15, 258,
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync Z_STREAM_END);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync inf("63 18 5 40 c 0", "window wrap", 3, -8, 300, Z_OK);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync}
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync/* cover remaining lines in inftrees.c */
1b33c96954667ba382fa595baf7b31290bfdd517vboxsynclocal void cover_trees(void)
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync{
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync int ret;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync unsigned bits;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync unsigned short lens[16], work[16];
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync code *next, table[ENOUGH_DISTS];
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync /* we need to call inflate_table() directly in order to manifest not-
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync enough errors, since zlib insures that enough is always enough */
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync for (bits = 0; bits < 15; bits++)
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync lens[bits] = (unsigned short)(bits + 1);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync lens[15] = 15;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync next = table;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync bits = 15;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync ret = inflate_table(DISTS, lens, 16, &next, &bits, work);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync assert(ret == 1);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync next = table;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync bits = 1;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync ret = inflate_table(DISTS, lens, 16, &next, &bits, work);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync assert(ret == 1);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync fputs("inflate_table not enough errors\n", stderr);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync}
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync/* cover remaining inffast.c decoding and window copying */
1b33c96954667ba382fa595baf7b31290bfdd517vboxsynclocal void cover_fast(void)
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync{
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync inf("e5 e0 81 ad 6d cb b2 2c c9 01 1e 59 63 ae 7d ee fb 4d fd b5 35 41 68"
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync " ff 7f 0f 0 0 0", "fast length extra bits", 0, -8, 258, Z_DATA_ERROR);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync inf("25 fd 81 b5 6d 59 b6 6a 49 ea af 35 6 34 eb 8c b9 f6 b9 1e ef 67 49"
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync " 50 fe ff ff 3f 0 0", "fast distance extra bits", 0, -8, 258,
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync Z_DATA_ERROR);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync inf("3 7e 0 0 0 0 0", "fast invalid distance code", 0, -8, 258,
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync Z_DATA_ERROR);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync inf("1b 7 0 0 0 0 0", "fast invalid literal/length code", 0, -8, 258,
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync Z_DATA_ERROR);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync 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",
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync "fast 2nd level codes and too far back", 0, -8, 258, Z_DATA_ERROR);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync inf("63 18 5 8c 10 8 0 0 0 0", "very common case", 0, -8, 259, Z_OK);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync inf("63 60 60 18 c9 0 8 18 18 18 26 c0 28 0 29 0 0 0",
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync "contiguous and wrap around window", 6, -8, 259, Z_OK);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync inf("63 0 3 0 0 0 0 0", "copy direct from output", 0, -8, 259,
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync Z_STREAM_END);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync}
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsyncint main(void)
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync{
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync fprintf(stderr, "%s\n", zlibVersion());
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync cover_support();
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync cover_wrap();
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync cover_back();
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync cover_inflate();
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync cover_trees();
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync cover_fast();
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync return 0;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync}