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