summaryrefslogtreecommitdiff
path: root/contrib/puff/puff.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/puff/puff.c')
-rw-r--r--contrib/puff/puff.c252
1 files changed, 67 insertions, 185 deletions
diff --git a/contrib/puff/puff.c b/contrib/puff/puff.c
index 650694e..df8470c 100644
--- a/contrib/puff/puff.c
+++ b/contrib/puff/puff.c
@@ -2,7 +2,7 @@
2 * puff.c 2 * puff.c
3 * Copyright (C) 2002-2010 Mark Adler 3 * Copyright (C) 2002-2010 Mark Adler
4 * For conditions of distribution and use, see copyright notice in puff.h 4 * For conditions of distribution and use, see copyright notice in puff.h
5 * version 2.1, 4 Apr 2010 5 * version 2.2, 25 Apr 2010
6 * 6 *
7 * puff.c is a simple inflate written to be an unambiguous way to specify the 7 * puff.c is a simple inflate written to be an unambiguous way to specify the
8 * deflate format. It is not written for speed but rather simplicity. As a 8 * deflate format. It is not written for speed but rather simplicity. As a
@@ -49,9 +49,9 @@
49 * - Fix fixed codes table error 49 * - Fix fixed codes table error
50 * - Provide a scanning mode for determining size of 50 * - Provide a scanning mode for determining size of
51 * uncompressed data 51 * uncompressed data
52 * 1.3 20 Mar 2002 - Go back to lengths for puff() parameters [Jean-loup] 52 * 1.3 20 Mar 2002 - Go back to lengths for puff() parameters [Gailly]
53 * - Add a puff.h file for the interface 53 * - Add a puff.h file for the interface
54 * - Add braces in puff() for else do [Jean-loup] 54 * - Add braces in puff() for else do [Gailly]
55 * - Use indexes instead of pointers for readability 55 * - Use indexes instead of pointers for readability
56 * 1.4 31 Mar 2002 - Simplify construct() code set check 56 * 1.4 31 Mar 2002 - Simplify construct() code set check
57 * - Fix some comments 57 * - Fix some comments
@@ -69,13 +69,19 @@
69 * - Allow TEST code to read from piped stdin 69 * - Allow TEST code to read from piped stdin
70 * 2.1 4 Apr 2010 - Avoid variable initialization for happier compilers 70 * 2.1 4 Apr 2010 - Avoid variable initialization for happier compilers
71 * - Avoid unsigned comparisons for even happier compilers 71 * - Avoid unsigned comparisons for even happier compilers
72 * 2.2 25 Apr 2010 - Fix bug in variable initializations [Oberhumer]
73 * - Add const where appropriate [Oberhumer]
74 * - Split if's and ?'s for coverage testing
75 * - Break out test code to separate file
76 * - Move NIL to puff.h
77 * - Allow incomplete code only if single code length is 1
78 * - Add full code coverage test to Makefile
72 */ 79 */
73 80
74#include <setjmp.h> /* for setjmp(), longjmp(), and jmp_buf */ 81#include <setjmp.h> /* for setjmp(), longjmp(), and jmp_buf */
75#include "puff.h" /* prototype for puff() */ 82#include "puff.h" /* prototype for puff() */
76 83
77#define local static /* for local function definitions */ 84#define local static /* for local function definitions */
78#define NIL ((unsigned char *)0) /* for no output option */
79 85
80/* 86/*
81 * Maximums for allocations and loops. It is not useful to change these -- 87 * Maximums for allocations and loops. It is not useful to change these --
@@ -95,7 +101,7 @@ struct state {
95 unsigned long outcnt; /* bytes written to out so far */ 101 unsigned long outcnt; /* bytes written to out so far */
96 102
97 /* input state */ 103 /* input state */
98 unsigned char *in; /* input buffer */ 104 const unsigned char *in; /* input buffer */
99 unsigned long inlen; /* available input at in */ 105 unsigned long inlen; /* available input at in */
100 unsigned long incnt; /* bytes read so far */ 106 unsigned long incnt; /* bytes read so far */
101 int bitbuf; /* bit buffer */ 107 int bitbuf; /* bit buffer */
@@ -123,7 +129,8 @@ local int bits(struct state *s, int need)
123 /* load at least need bits into val */ 129 /* load at least need bits into val */
124 val = s->bitbuf; 130 val = s->bitbuf;
125 while (s->bitcnt < need) { 131 while (s->bitcnt < need) {
126 if (s->incnt == s->inlen) longjmp(s->env, 1); /* out of input */ 132 if (s->incnt == s->inlen)
133 longjmp(s->env, 1); /* out of input */
127 val |= (long)(s->in[s->incnt++]) << s->bitcnt; /* load eight bits */ 134 val |= (long)(s->in[s->incnt++]) << s->bitcnt; /* load eight bits */
128 s->bitcnt += 8; 135 s->bitcnt += 8;
129 } 136 }
@@ -162,7 +169,8 @@ local int stored(struct state *s)
162 s->bitcnt = 0; 169 s->bitcnt = 0;
163 170
164 /* get length and check against its one's complement */ 171 /* get length and check against its one's complement */
165 if (s->incnt + 4 > s->inlen) return 2; /* not enough input */ 172 if (s->incnt + 4 > s->inlen)
173 return 2; /* not enough input */
166 len = s->in[s->incnt++]; 174 len = s->in[s->incnt++];
167 len |= s->in[s->incnt++] << 8; 175 len |= s->in[s->incnt++] << 8;
168 if (s->in[s->incnt++] != (~len & 0xff) || 176 if (s->in[s->incnt++] != (~len & 0xff) ||
@@ -170,7 +178,8 @@ local int stored(struct state *s)
170 return -2; /* didn't match complement! */ 178 return -2; /* didn't match complement! */
171 179
172 /* copy len bytes from in to out */ 180 /* copy len bytes from in to out */
173 if (s->incnt + len > s->inlen) return 2; /* not enough input */ 181 if (s->incnt + len > s->inlen)
182 return 2; /* not enough input */
174 if (s->out != NIL) { 183 if (s->out != NIL) {
175 if (s->outcnt + len > s->outlen) 184 if (s->outcnt + len > s->outlen)
176 return 1; /* not enough output space */ 185 return 1; /* not enough output space */
@@ -222,7 +231,7 @@ struct huffman {
222 * in the deflate format. See the format notes for fixed() and dynamic(). 231 * in the deflate format. See the format notes for fixed() and dynamic().
223 */ 232 */
224#ifdef SLOW 233#ifdef SLOW
225local int decode(struct state *s, struct huffman *h) 234local int decode(struct state *s, const struct huffman *h)
226{ 235{
227 int len; /* current number of bits in code */ 236 int len; /* current number of bits in code */
228 int code; /* len bits being decoded */ 237 int code; /* len bits being decoded */
@@ -250,7 +259,7 @@ local int decode(struct state *s, struct huffman *h)
250 * a few percent larger. 259 * a few percent larger.
251 */ 260 */
252#else /* !SLOW */ 261#else /* !SLOW */
253local int decode(struct state *s, struct huffman *h) 262local int decode(struct state *s, const struct huffman *h)
254{ 263{
255 int len; /* current number of bits in code */ 264 int len; /* current number of bits in code */
256 int code; /* len bits being decoded */ 265 int code; /* len bits being decoded */
@@ -283,10 +292,13 @@ local int decode(struct state *s, struct huffman *h)
283 len++; 292 len++;
284 } 293 }
285 left = (MAXBITS+1) - len; 294 left = (MAXBITS+1) - len;
286 if (left == 0) break; 295 if (left == 0)
287 if (s->incnt == s->inlen) longjmp(s->env, 1); /* out of input */ 296 break;
297 if (s->incnt == s->inlen)
298 longjmp(s->env, 1); /* out of input */
288 bitbuf = s->in[s->incnt++]; 299 bitbuf = s->in[s->incnt++];
289 if (left > 8) left = 8; 300 if (left > 8)
301 left = 8;
290 } 302 }
291 return -10; /* ran out of codes */ 303 return -10; /* ran out of codes */
292} 304}
@@ -324,7 +336,7 @@ local int decode(struct state *s, struct huffman *h)
324 * - Within a given code length, the symbols are kept in ascending order for 336 * - Within a given code length, the symbols are kept in ascending order for
325 * the code bits definition. 337 * the code bits definition.
326 */ 338 */
327local int construct(struct huffman *h, short *length, int n) 339local int construct(struct huffman *h, const short *length, int n)
328{ 340{
329 int symbol; /* current symbol when stepping through length[] */ 341 int symbol; /* current symbol when stepping through length[] */
330 int len; /* current length when stepping through h->count[] */ 342 int len; /* current length when stepping through h->count[] */
@@ -344,7 +356,8 @@ local int construct(struct huffman *h, short *length, int n)
344 for (len = 1; len <= MAXBITS; len++) { 356 for (len = 1; len <= MAXBITS; len++) {
345 left <<= 1; /* one more bit, double codes left */ 357 left <<= 1; /* one more bit, double codes left */
346 left -= h->count[len]; /* deduct count from possible codes */ 358 left -= h->count[len]; /* deduct count from possible codes */
347 if (left < 0) return left; /* over-subscribed--return negative */ 359 if (left < 0)
360 return left; /* over-subscribed--return negative */
348 } /* left > 0 means incomplete */ 361 } /* left > 0 means incomplete */
349 362
350 /* generate offsets into symbol table for each length for sorting */ 363 /* generate offsets into symbol table for each length for sorting */
@@ -420,8 +433,8 @@ local int construct(struct huffman *h, short *length, int n)
420 * defined to do the wrong thing in this case. 433 * defined to do the wrong thing in this case.
421 */ 434 */
422local int codes(struct state *s, 435local int codes(struct state *s,
423 struct huffman *lencode, 436 const struct huffman *lencode,
424 struct huffman *distcode) 437 const struct huffman *distcode)
425{ 438{
426 int symbol; /* decoded symbol */ 439 int symbol; /* decoded symbol */
427 int len; /* length for copy */ 440 int len; /* length for copy */
@@ -444,11 +457,13 @@ local int codes(struct state *s,
444 /* decode literals and length/distance pairs */ 457 /* decode literals and length/distance pairs */
445 do { 458 do {
446 symbol = decode(s, lencode); 459 symbol = decode(s, lencode);
447 if (symbol < 0) return symbol; /* invalid symbol */ 460 if (symbol < 0)
461 return symbol; /* invalid symbol */
448 if (symbol < 256) { /* literal: symbol is the byte */ 462 if (symbol < 256) { /* literal: symbol is the byte */
449 /* write out the literal */ 463 /* write out the literal */
450 if (s->out != NIL) { 464 if (s->out != NIL) {
451 if (s->outcnt == s->outlen) return 1; 465 if (s->outcnt == s->outlen)
466 return 1;
452 s->out[s->outcnt] = symbol; 467 s->out[s->outcnt] = symbol;
453 } 468 }
454 s->outcnt++; 469 s->outcnt++;
@@ -456,12 +471,14 @@ local int codes(struct state *s,
456 else if (symbol > 256) { /* length */ 471 else if (symbol > 256) { /* length */
457 /* get and compute length */ 472 /* get and compute length */
458 symbol -= 257; 473 symbol -= 257;
459 if (symbol >= 29) return -10; /* invalid fixed code */ 474 if (symbol >= 29)
475 return -10; /* invalid fixed code */
460 len = lens[symbol] + bits(s, lext[symbol]); 476 len = lens[symbol] + bits(s, lext[symbol]);
461 477
462 /* get and check distance */ 478 /* get and check distance */
463 symbol = decode(s, distcode); 479 symbol = decode(s, distcode);
464 if (symbol < 0) return symbol; /* invalid symbol */ 480 if (symbol < 0)
481 return symbol; /* invalid symbol */
465 dist = dists[symbol] + bits(s, dext[symbol]); 482 dist = dists[symbol] + bits(s, dext[symbol]);
466#ifndef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR 483#ifndef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
467 if (dist > s->outcnt) 484 if (dist > s->outcnt)
@@ -470,13 +487,15 @@ local int codes(struct state *s,
470 487
471 /* copy length bytes from distance bytes back */ 488 /* copy length bytes from distance bytes back */
472 if (s->out != NIL) { 489 if (s->out != NIL) {
473 if (s->outcnt + len > s->outlen) return 1; 490 if (s->outcnt + len > s->outlen)
491 return 1;
474 while (len--) { 492 while (len--) {
475 s->out[s->outcnt] = 493 s->out[s->outcnt] =
476#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR 494#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
477 dist > s->outcnt ? 0 : 495 dist > s->outcnt ?
496 0 :
478#endif 497#endif
479 s->out[s->outcnt - dist]; 498 s->out[s->outcnt - dist];
480 s->outcnt++; 499 s->outcnt++;
481 } 500 }
482 } 501 }
@@ -525,6 +544,12 @@ local int fixed(struct state *s)
525 int symbol; 544 int symbol;
526 short lengths[FIXLCODES]; 545 short lengths[FIXLCODES];
527 546
547 /* construct lencode and distcode */
548 lencode.count = lencnt;
549 lencode.symbol = lensym;
550 distcode.count = distcnt;
551 distcode.symbol = distsym;
552
528 /* literal/length table */ 553 /* literal/length table */
529 for (symbol = 0; symbol < 144; symbol++) 554 for (symbol = 0; symbol < 144; symbol++)
530 lengths[symbol] = 8; 555 lengths[symbol] = 8;
@@ -541,12 +566,6 @@ local int fixed(struct state *s)
541 lengths[symbol] = 5; 566 lengths[symbol] = 5;
542 construct(&distcode, lengths, MAXDCODES); 567 construct(&distcode, lengths, MAXDCODES);
543 568
544 /* construct lencode and distcode */
545 lencode.count = lencnt;
546 lencode.symbol = lensym;
547 distcode.count = distcnt;
548 distcode.symbol = distsym;
549
550 /* do this just once */ 569 /* do this just once */
551 virgin = 0; 570 virgin = 0;
552 } 571 }
@@ -675,7 +694,8 @@ local int dynamic(struct state *s)
675 694
676 /* build huffman table for code lengths codes (use lencode temporarily) */ 695 /* build huffman table for code lengths codes (use lencode temporarily) */
677 err = construct(&lencode, lengths, 19); 696 err = construct(&lencode, lengths, 19);
678 if (err != 0) return -4; /* require complete code set here */ 697 if (err != 0) /* require complete code set here */
698 return -4;
679 699
680 /* read length/literal and distance code length tables */ 700 /* read length/literal and distance code length tables */
681 index = 0; 701 index = 0;
@@ -689,7 +709,8 @@ local int dynamic(struct state *s)
689 else { /* repeat instruction */ 709 else { /* repeat instruction */
690 len = 0; /* assume repeating zeros */ 710 len = 0; /* assume repeating zeros */
691 if (symbol == 16) { /* repeat last length 3..6 times */ 711 if (symbol == 16) { /* repeat last length 3..6 times */
692 if (index == 0) return -5; /* no last length! */ 712 if (index == 0)
713 return -5; /* no last length! */
693 len = lengths[index - 1]; /* last length */ 714 len = lengths[index - 1]; /* last length */
694 symbol = 3 + bits(s, 2); 715 symbol = 3 + bits(s, 2);
695 } 716 }
@@ -710,13 +731,13 @@ local int dynamic(struct state *s)
710 731
711 /* build huffman table for literal/length codes */ 732 /* build huffman table for literal/length codes */
712 err = construct(&lencode, lengths, nlen); 733 err = construct(&lencode, lengths, nlen);
713 if (err < 0 || (err > 0 && nlen - lencode.count[0] != 1)) 734 if (err && (err < 0 || nlen != lencode.count[0] + lencode.count[1]))
714 return -7; /* only allow incomplete codes if just one code */ 735 return -7; /* incomplete code ok only for single length 1 code */
715 736
716 /* build huffman table for distance codes */ 737 /* build huffman table for distance codes */
717 err = construct(&distcode, lengths + nlen, ndist); 738 err = construct(&distcode, lengths + nlen, ndist);
718 if (err < 0 || (err > 0 && ndist - distcode.count[0] != 1)) 739 if (err && (err < 0 || ndist != distcode.count[0] + distcode.count[1]))
719 return -8; /* only allow incomplete codes if just one code */ 740 return -8; /* incomplete code ok only for single length 1 code */
720 741
721 /* decode data until end-of-block code */ 742 /* decode data until end-of-block code */
722 return codes(s, &lencode, &distcode); 743 return codes(s, &lencode, &distcode);
@@ -768,7 +789,7 @@ local int dynamic(struct state *s)
768 */ 789 */
769int puff(unsigned char *dest, /* pointer to destination pointer */ 790int puff(unsigned char *dest, /* pointer to destination pointer */
770 unsigned long *destlen, /* amount of output space */ 791 unsigned long *destlen, /* amount of output space */
771 unsigned char *source, /* pointer to source data pointer */ 792 const unsigned char *source, /* pointer to source data pointer */
772 unsigned long *sourcelen) /* amount of input available */ 793 unsigned long *sourcelen) /* amount of input available */
773{ 794{
774 struct state s; /* input/output state */ 795 struct state s; /* input/output state */
@@ -795,11 +816,15 @@ int puff(unsigned char *dest, /* pointer to destination pointer */
795 do { 816 do {
796 last = bits(&s, 1); /* one if last block */ 817 last = bits(&s, 1); /* one if last block */
797 type = bits(&s, 2); /* block type 0..3 */ 818 type = bits(&s, 2); /* block type 0..3 */
798 err = type == 0 ? stored(&s) : 819 err = type == 0 ?
799 (type == 1 ? fixed(&s) : 820 stored(&s) :
800 (type == 2 ? dynamic(&s) : 821 (type == 1 ?
801 -1)); /* type == 3, invalid */ 822 fixed(&s) :
802 if (err != 0) break; /* return with error */ 823 (type == 2 ?
824 dynamic(&s) :
825 -1)); /* type == 3, invalid */
826 if (err != 0)
827 break; /* return with error */
803 } while (!last); 828 } while (!last);
804 } 829 }
805 830
@@ -810,146 +835,3 @@ int puff(unsigned char *dest, /* pointer to destination pointer */
810 } 835 }
811 return err; 836 return err;
812} 837}
813
814#ifdef TEST
815/* Examples of how to use puff().
816
817 Usage: puff [-w] [-nnn] file
818 ... | puff [-w] [-nnn]
819
820 where file is the input file with deflate data, nnn is the number of bytes
821 of input to skip before inflating (e.g. to skip a zlib or gzip header), and
822 -w is used to write the decompressed data to stdout */
823
824#include <stdio.h>
825#include <stdlib.h>
826
827/* Return size times approximately the cube root of 2, keeping the result as 1,
828 3, or 5 times a power of 2 -- the result is always > size, until the result
829 is the maximum value of an unsigned long, where it remains. This is useful
830 to keep reallocations less than ~33% over the actual data. */
831local size_t bythirds(size_t size)
832{
833 int n;
834 size_t m;
835
836 m = size;
837 for (n = 0; m; n++)
838 m >>= 1;
839 if (n < 3)
840 return size + 1;
841 n -= 3;
842 m = size >> n;
843 m += m == 6 ? 2 : 1;
844 m <<= n;
845 return m > size ? m : (size_t)(-1);
846}
847
848/* Read the input file *name, or stdin if name is NULL, into allocated memory.
849 Reallocate to larger buffers until the entire file is read in. Return a
850 pointer to the allocated data, or NULL if there was a memory allocation
851 failure. *len is the number of bytes of data read from the input file (even
852 if load() returns NULL). If the input file was empty or could not be opened
853 or read, *len is zero. */
854local void *load(char *name, size_t *len)
855{
856 size_t size;
857 void *buf, *swap;
858 FILE *in;
859
860 *len = 0;
861 buf = malloc(size = 4096);
862 if (buf == NULL)
863 return NULL;
864 in = name == NULL ? stdin : fopen(name, "rb");
865 if (in != NULL) {
866 for (;;) {
867 *len += fread((char *)buf + *len, 1, size - *len, in);
868 if (*len < size) break;
869 size = bythirds(size);
870 if (size == *len || (swap = realloc(buf, size)) == NULL) {
871 free(buf);
872 buf = NULL;
873 break;
874 }
875 buf = swap;
876 }
877 fclose(in);
878 }
879 return buf;
880}
881
882int main(int argc, char **argv)
883{
884 int ret, put = 0;
885 unsigned skip = 0;
886 char *arg, *name = NULL;
887 unsigned char *source = NULL, *dest;
888 size_t len = 0;
889 unsigned long sourcelen, destlen;
890
891 /* process arguments */
892 while (arg = *++argv, --argc)
893 if (arg[0] == '-') {
894 if (arg[1] == 'w' && arg[2] == 0)
895 put = 1;
896 else if (arg[1] >= '0' && arg[1] <= '9')
897 skip = (unsigned)atoi(arg + 1);
898 else {
899 fprintf(stderr, "invalid option %s\n", arg);
900 return 3;
901 }
902 }
903 else if (name != NULL) {
904 fprintf(stderr, "only one file name allowed\n");
905 return 3;
906 }
907 else
908 name = arg;
909 source = load(name, &len);
910 if (source == NULL) {
911 fprintf(stderr, "memory allocation failure\n");
912 return 4;
913 }
914 if (len == 0) {
915 fprintf(stderr, "could not read %s, or it was empty\n",
916 name == NULL ? "<stdin>" : name);
917 free(source);
918 return 3;
919 }
920 if (skip >= len) {
921 fprintf(stderr, "skip request of %d leaves no input\n", skip);
922 free(source);
923 return 3;
924 }
925
926 /* test inflate data with offset skip */
927 len -= skip;
928 sourcelen = (unsigned long)len;
929 ret = puff(NIL, &destlen, source + skip, &sourcelen);
930 if (ret)
931 fprintf(stderr, "puff() failed with return code %d\n", ret);
932 else {
933 fprintf(stderr, "puff() succeeded uncompressing %lu bytes\n", destlen);
934 if (sourcelen < len) fprintf(stderr, "%lu compressed bytes unused\n",
935 len - sourcelen);
936 }
937
938 /* if requested, inflate again and write decompressd data to stdout */
939 if (put) {
940 dest = malloc(destlen);
941 if (dest == NULL) {
942 fprintf(stderr, "memory allocation failure\n");
943 free(source);
944 return 4;
945 }
946 puff(dest, &destlen, source + skip, &sourcelen);
947 fwrite(dest, 1, destlen, stdout);
948 free(dest);
949 }
950
951 /* clean up */
952 free(source);
953 return ret;
954}
955#endif