Index: cpukit/zlib/contrib/puff/puff.c
===================================================================
--- cpukit/zlib/contrib/puff/puff.c	(revision d42bd2f70e16488559a2353668701b455c980780)
+++ cpukit/zlib/contrib/puff/puff.c	(revision 64bad829488142fbe7b99218fe1146c676d10138)
@@ -1,7 +1,7 @@
 /*
  * puff.c
- * Copyright (C) 2002-2004 Mark Adler
+ * Copyright (C) 2002-2008 Mark Adler
  * For conditions of distribution and use, see copyright notice in puff.h
- * version 1.8, 9 Jan 2004
+ * version 2.0, 25 Jul 2008
  *
  * puff.c is a simple inflate written to be an unambiguous way to specify the
@@ -62,4 +62,10 @@
  *                      - Added zlib-like license
  * 1.8   9 Jan 2004     - Added some comments on no distance codes case
+ * 1.9  21 Feb 2008     - Fix bug on 16-bit integer architectures [Pohland]
+ *                      - Catch missing end-of-block symbol error
+ * 2.0  25 Jul 2008     - Add #define to permit distance too far back
+ *                      - Add option in TEST code for puff to write the data
+ *                      - Add option in TEST code to skip input bytes
+ *                      - Allow TEST code to read from piped stdin
  */
 
@@ -195,5 +201,5 @@
  * a negative value if there is an error.  If all of the lengths are zero, i.e.
  * an empty code, or if the code is incomplete and an invalid code is received,
- * then -9 is returned after reading MAXBITS bits.
+ * then -10 is returned after reading MAXBITS bits.
  *
  * Format notes:
@@ -227,5 +233,5 @@
         code |= bits(s, 1);             /* get next bit */
         count = h->count[len];
-        if (code < first + count)       /* if length len, return symbol */
+        if (code - count < first)       /* if length len, return symbol */
             return h->symbol[index + (code - first)];
         index += count;                 /* else update for next length */
@@ -234,5 +240,5 @@
         code <<= 1;
     }
-    return -9;                          /* ran out of codes */
+    return -10;                         /* ran out of codes */
 }
 
@@ -264,5 +270,5 @@
             bitbuf >>= 1;
             count = *next++;
-            if (code < first + count) { /* if length len, return symbol */
+            if (code - count < first) { /* if length len, return symbol */
                 s->bitbuf = bitbuf;
                 s->bitcnt = (s->bitcnt - len) & 7;
@@ -281,5 +287,5 @@
         if (left > 8) left = 8;
     }
-    return -9;                          /* ran out of codes */
+    return -10;                         /* ran out of codes */
 }
 #endif /* SLOW */
@@ -449,5 +455,5 @@
             /* get and compute length */
             symbol -= 257;
-            if (symbol >= 29) return -9;        /* invalid fixed code */
+            if (symbol >= 29) return -10;       /* invalid fixed code */
             len = lens[symbol] + bits(s, lext[symbol]);
 
@@ -456,6 +462,8 @@
             if (symbol < 0) return symbol;      /* invalid symbol */
             dist = dists[symbol] + bits(s, dext[symbol]);
+#ifndef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
             if (dist > s->outcnt)
-                return -10;     /* distance too far back */
+                return -11;     /* distance too far back */
+#endif
 
             /* copy length bytes from distance bytes back */
@@ -463,5 +471,9 @@
                 if (s->outcnt + len > s->outlen) return 1;
                 while (len--) {
-                    s->out[s->outcnt] = s->out[s->outcnt - dist];
+                    s->out[s->outcnt] =
+#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
+                        dist > s->outcnt ? 0 :
+#endif
+                        s->out[s->outcnt - dist];
                     s->outcnt++;
                 }
@@ -681,4 +693,8 @@
     }
 
+    /* check for end-of-block code -- there better be one! */
+    if (lengths[256] == 0)
+        return -9;
+
     /* build huffman table for literal/length codes */
     err = construct(&lencode, lengths, nlen);
@@ -725,6 +741,7 @@
  *  -7:  dynamic block code description: invalid literal/length code lengths
  *  -8:  dynamic block code description: invalid distance code lengths
- *  -9:  invalid literal/length or distance code in fixed or dynamic block
- * -10:  distance is too far back in fixed or dynamic block
+ *  -9:  dynamic block code description: missing end-of-block code
+ * -10:  invalid literal/length or distance code in fixed or dynamic block
+ * -11:  distance is too far back in fixed or dynamic block
  *
  * Format notes:
@@ -784,31 +801,68 @@
 
 #ifdef TEST
-/* Example of how to use puff() */
+/* Examples of how to use puff().
+
+   Usage: puff [-w] [-nnn] file
+          ... | puff [-w] [-nnn]
+
+   where file is the input file with deflate data, nnn is the number of bytes
+   of input to skip before inflating (e.g. to skip a zlib or gzip header), and
+   -w is used to write the decompressed data to stdout */
+
 #include <stdio.h>
 #include <stdlib.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-
-local unsigned char *yank(char *name, unsigned long *len)
-{
-    unsigned long size;
-    unsigned char *buf;
+
+/* Return size times approximately the cube root of 2, keeping the result as 1,
+   3, or 5 times a power of 2 -- the result is always > size, until the result
+   is the maximum value of an unsigned long, where it remains.  This is useful
+   to keep reallocations less than ~33% over the actual data. */
+local size_t bythirds(size_t size)
+{
+    int n;
+    size_t m;
+
+    m = size;
+    for (n = 0; m; n++)
+        m >>= 1;
+    if (n < 3)
+        return size + 1;
+    n -= 3;
+    m = size >> n;
+    m += m == 6 ? 2 : 1;
+    m <<= n;
+    return m > size ? m : (size_t)(-1);
+}
+
+/* Read the input file *name, or stdin if name is NULL, into allocated memory.
+   Reallocate to larger buffers until the entire file is read in.  Return a
+   pointer to the allocated data, or NULL if there was a memory allocation
+   failure.  *len is the number of bytes of data read from the input file (even
+   if load() returns NULL).  If the input file was empty or could not be opened
+   or read, *len is zero. */
+local void *load(char *name, size_t *len)
+{
+    size_t size;
+    void *buf, *swap;
     FILE *in;
-    struct stat s;
 
     *len = 0;
-    if (stat(name, &s)) return NULL;
-    if ((s.st_mode & S_IFMT) != S_IFREG) return NULL;
-    size = (unsigned long)(s.st_size);
-    if (size == 0 || (off_t)size != s.st_size) return NULL;
-    in = fopen(name, "r");
-    if (in == NULL) return NULL;
-    buf = malloc(size);
-    if (buf != NULL && fread(buf, 1, size, in) != size) {
-        free(buf);
-        buf = NULL;
-    }
-    fclose(in);
-    *len = size;
+    buf = malloc(size = 4096);
+    if (buf == NULL)
+        return NULL;
+    in = name == NULL ? stdin : fopen(name, "rb");
+    if (in != NULL) {
+        for (;;) {
+            *len += fread((char *)buf + *len, 1, size - *len, in);
+            if (*len < size) break;
+            size = bythirds(size);
+            if (size == *len || (swap = realloc(buf, size)) == NULL) {
+                free(buf);
+                buf = NULL;
+                break;
+            }
+            buf = swap;
+        }
+        fclose(in);
+    }
     return buf;
 }
@@ -816,20 +870,71 @@
 int main(int argc, char **argv)
 {
-    int ret;
-    unsigned char *source;
-    unsigned long len, sourcelen, destlen;
-
-    if (argc < 2) return 2;
-    source = yank(argv[1], &len);
-    if (source == NULL) return 2;
-    sourcelen = len;
-    ret = puff(NIL, &destlen, source, &sourcelen);
+    int ret, skip = 0, put = 0;
+    char *arg, *name = NULL;
+    unsigned char *source = NULL, *dest;
+    size_t len = 0;
+    unsigned long sourcelen, destlen;
+
+    /* process arguments */
+    while (arg = *++argv, --argc)
+        if (arg[0] == '-') {
+            if (arg[1] == 'w' && arg[2] == 0)
+                put = 1;
+            else if (arg[1] >= '0' && arg[1] <= '9')
+                skip = atoi(arg + 1);
+            else {
+                fprintf(stderr, "invalid option %s\n", arg);
+                return 3;
+            }
+        }
+        else if (name != NULL) {
+            fprintf(stderr, "only one file name allowed\n");
+            return 3;
+        }
+        else
+            name = arg;
+    source = load(name, &len);
+    if (source == NULL) {
+        fprintf(stderr, "memory allocation failure\n");
+        return 4;
+    }
+    if (len == 0) {
+        fprintf(stderr, "could not read %s, or it was empty\n",
+                name == NULL ? "<stdin>" : name);
+        free(source);
+        return 3;
+    }
+    if (skip >= len) {
+        fprintf(stderr, "skip request of %d leaves no input\n", skip);
+        free(source);
+        return 3;
+    }
+
+    /* test inflate data with offset skip */
+    len -= skip;
+    sourcelen = (unsigned long)len;
+    ret = puff(NIL, &destlen, source + skip, &sourcelen);
     if (ret)
-        printf("puff() failed with return code %d\n", ret);
+        fprintf(stderr, "puff() failed with return code %d\n", ret);
     else {
-        printf("puff() succeeded uncompressing %lu bytes\n", destlen);
-        if (sourcelen < len) printf("%lu compressed bytes unused\n",
-                                    len - sourcelen);
-    }
+        fprintf(stderr, "puff() succeeded uncompressing %lu bytes\n", destlen);
+        if (sourcelen < len) fprintf(stderr, "%lu compressed bytes unused\n",
+                                     len - sourcelen);
+    }
+
+    /* if requested, inflate again and write decompressd data to stdout */
+    if (put) {
+        dest = malloc(destlen);
+        if (dest == NULL) {
+            fprintf(stderr, "memory allocation failure\n");
+            free(source);
+            return 4;
+        }
+        puff(dest, &destlen, source + skip, &sourcelen);
+        fwrite(dest, 1, destlen, stdout);
+        free(dest);
+    }
+
+    /* clean up */
     free(source);
     return ret;
