]> git.cworth.org Git - gzip/blobdiff - inflate.c
Avoid creating an undersized buffer for the hufts table.
[gzip] / inflate.c
index e903f8deb4808ba1114f3812a0022f64a0488260..2f4954be020fd9a9eaf0da4015ca8ee465e6dcc5 100644 (file)
--- a/inflate.c
+++ b/inflate.c
@@ -1,4 +1,23 @@
-/* inflate.c -- Not copyrighted 1992 by Mark Adler
+/* Inflate deflated data
+
+   Copyright (C) 1997, 1998, 1999, 2002, 2006 Free Software
+   Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
+
+/* Not copyrighted 1992 by Mark Adler
    version c10p1, 10 January 1993 */
 
 /* You can do whatever you like with this source file, though I would
@@ -43,8 +62,8 @@
    chunks), otherwise the dynamic method is used.  In the latter case, the
    codes are customized to the probabilities in the current block, and so
    can code it much better than the pre-determined fixed codes.
-   The Huffman codes themselves are decoded using a mutli-level table
+
+   The Huffman codes themselves are decoded using a multi-level table
    lookup, in order to maximize the speed of decoding plus the speed of
    building the decoding tables.  See the comments below that precede the
    lbits and dbits tuning parameters.
  */
 
 #ifdef RCSID
-static char rcsid[] = "$Id: inflate.c,v 0.14 1993/06/10 13:27:04 jloup Exp $";
+static char rcsid[] = "$Id: inflate.c,v 1.6 2006/12/20 23:30:17 eggert Exp $";
 #endif
 
 #include <config.h>
@@ -174,7 +193,7 @@ static ush cpdext[] = {         /* Extra bits for distance codes */
 
 /* Macros for inflate() bit peeking and grabbing.
    The usage is:
-   
+
         NEEDBITS(j)
         x = b & mask_bits[j];
         DUMPBITS(j)
@@ -184,6 +203,7 @@ static ush cpdext[] = {         /* Extra bits for distance codes */
    for the number of bits in b.  Normally, b and k are register
    variables for speed, and are initialized at the beginning of a
    routine that uses these macros from a global bit buffer and count.
+   The macros also use the variable w, which is a cached copy of wp.
 
    If we assume that EOB will be the longest code, then we will never
    ask for bits with NEEDBITS that are beyond the end of the stream.
@@ -211,12 +231,14 @@ ush mask_bits[] = {
     0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff
 };
 
+#define GETBYTE() (inptr < insize ? inbuf[inptr++] : (wp = w, fill_inbuf(0)))
+
 #ifdef CRYPT
   uch cc;
 #  define NEXTBYTE() \
-     (decrypt ? (cc = get_byte(), zdecode(cc), cc) : get_byte())
+     (decrypt ? (cc = GETBYTE(), zdecode(cc), cc) : GETBYTE())
 #else
-#  define NEXTBYTE()  (uch)get_byte()
+#  define NEXTBYTE()  (uch)GETBYTE()
 #endif
 #define NEEDBITS(n) {while(k<(n)){b|=((ulg)NEXTBYTE())<<k;k+=8;}}
 #define DUMPBITS(n) {b>>=(n);k-=(n);}
@@ -306,15 +328,24 @@ int *m;                 /* maximum lookup bits, returns actual */
   memzero(c, sizeof(c));
   p = b;  i = n;
   do {
-    Tracecv(*p, (stderr, (n-i >= ' ' && n-i <= '~' ? "%c %d\n" : "0x%x %d\n"), 
+    Tracecv(*p, (stderr, (n-i >= ' ' && n-i <= '~' ? "%c %d\n" : "0x%x %d\n"),
            n-i, *p));
     c[*p]++;                    /* assume all entries <= BMAX */
     p++;                      /* Can't combine with above line (Solaris bug) */
   } while (--i);
   if (c[0] == n)                /* null input--all zero length codes */
   {
-    *t = (struct huft *)NULL;
-    *m = 0;
+    q = (struct huft *) malloc (3 * sizeof *q);
+    if (!q)
+      return 3;
+    hufts += 3;
+    q[0].v.t = (struct huft *) NULL;
+    q[1].e = 99;    /* invalid code marker */
+    q[1].b = 1;
+    q[2].e = 99;    /* invalid code marker */
+    q[2].b = 1;
+    *t = q + 1;
+    *m = 1;
     return 0;
   }
 
@@ -483,7 +514,7 @@ struct huft *t;         /* table to free */
     q = (--p)->v.t;
     free((char*)p);
     p = q;
-  } 
+  }
   return 0;
 }
 
@@ -709,6 +740,7 @@ int inflate_dynamic()
   unsigned l;           /* last length */
   unsigned m;           /* mask for bit lengths table */
   unsigned n;           /* number of lengths to get */
+  unsigned w;           /* current window position */
   struct huft *tl;      /* literal/length code table */
   struct huft *td;      /* distance code table */
   int bl;               /* lookup bits for tl */
@@ -728,6 +760,7 @@ int inflate_dynamic()
   /* make local bit buffer */
   b = bb;
   k = bk;
+  w = wp;
 
 
   /* read in table lengths */
@@ -832,7 +865,7 @@ int inflate_dynamic()
   if ((i = huft_build(ll, nl, 257, cplens, cplext, &tl, &bl)) != 0)
   {
     if (i == 1) {
-      fprintf(stderr, " incomplete literal tree\n");
+      Trace ((stderr, " incomplete literal tree\n"));
       huft_free(tl);
     }
     return i;                   /* incomplete code set */
@@ -841,7 +874,7 @@ int inflate_dynamic()
   if ((i = huft_build(ll + nl, nd, 0, cpdist, cpdext, &td, &bd)) != 0)
   {
     if (i == 1) {
-      fprintf(stderr, " incomplete distance tree\n");
+      Trace ((stderr, " incomplete distance tree\n"));
 #ifdef PKZIP_BUG_WORKAROUND
       i = 0;
     }
@@ -872,6 +905,7 @@ int *e;                 /* last block flag */
 /* decompress an inflated block */
 {
   unsigned t;           /* block type */
+  unsigned w;           /* current window position */
   register ulg b;       /* bit buffer */
   register unsigned k;  /* number of bits in bit buffer */
 
@@ -879,6 +913,7 @@ int *e;                 /* last block flag */
   /* make local bit buffer */
   b = bb;
   k = bk;
+  w = wp;
 
 
   /* read in last block bit */
@@ -950,8 +985,6 @@ int inflate()
 
 
   /* return success */
-#ifdef DEBUG
-  fprintf(stderr, "<%u> ", h);
-#endif /* DEBUG */
+  Trace ((stderr, "<%u> ", h));
   return 0;
 }