summaryrefslogtreecommitdiff
path: root/inflate.c
diff options
context:
space:
mode:
Diffstat (limited to 'inflate.c')
-rw-r--r--inflate.c56
1 files changed, 33 insertions, 23 deletions
diff --git a/inflate.c b/inflate.c
index 478f46d..38d70cc 100644
--- a/inflate.c
+++ b/inflate.c
@@ -25,10 +25,6 @@ struct internal_state {
25 ERROR} /* got an error--stay here */ 25 ERROR} /* got an error--stay here */
26 mode; /* current inflate mode */ 26 mode; /* current inflate mode */
27 27
28 int no_header;
29 uInt w_size; /* LZ77 window size (32K by default) */
30 uInt w_bits; /* log2(w_size) (8..16) */
31
32 /* mode dependent information */ 28 /* mode dependent information */
33 union { 29 union {
34 uInt method; /* if FLAGS, method byte */ 30 uInt method; /* if FLAGS, method byte */
@@ -39,19 +35,26 @@ struct internal_state {
39 uLong need; /* stream check value */ 35 uLong need; /* stream check value */
40 } check; /* if CHECK, check values to compare */ 36 } check; /* if CHECK, check values to compare */
41 } sub; /* submode */ 37 } sub; /* submode */
38
39 /* mode independent information */
40 int nowrap; /* flag for no wrapper */
41 uInt wbits; /* log2(window size) (8..15, defaults to 15) */
42
42}; 43};
43 44
44 45
45int inflateInit (strm) 46int inflateInit(z)
46z_stream *strm; 47z_stream *z;
47{ 48{
48 return inflateInit2(strm, WBITS); 49 return inflateInit2(z, WBITS);
49} 50}
50 51
51int inflateInit2(z, windowBits) 52
53int inflateInit2(z, w)
52z_stream *z; 54z_stream *z;
53int windowBits; 55int w;
54{ 56{
57 /* initialize state */
55 if (z == Z_NULL) 58 if (z == Z_NULL)
56 return Z_STREAM_ERROR; 59 return Z_STREAM_ERROR;
57 if (z->zalloc == Z_NULL) z->zalloc = zcalloc; 60 if (z->zalloc == Z_NULL) z->zalloc = zcalloc;
@@ -63,19 +66,22 @@ int windowBits;
63 return Z_MEM_ERROR; 66 return Z_MEM_ERROR;
64 z->state->mode = METHOD; 67 z->state->mode = METHOD;
65 68
66 z->state->no_header = 0; 69 /* handle undocumented nowrap option (no zlib header or check) */
67 if (windowBits < 0) { /* undocumented feature: no zlib header */ 70 z->state->nowrap = 0;
68 windowBits = - windowBits; 71 if (w < 0)
69 z->state->no_header = 1; 72 {
70 z->state->sub.method = DEFLATED; 73 w = - w;
74 z->state->nowrap = 1;
71 z->state->mode = START; 75 z->state->mode = START;
72 } 76 }
73 if (windowBits < 8 || windowBits > 15) { 77
78 /* set window size */
79 if (w < 8 || w > 15)
80 {
74 inflateEnd(z); 81 inflateEnd(z);
75 return Z_STREAM_ERROR; 82 return Z_STREAM_ERROR;
76 } 83 }
77 z->state->w_bits = windowBits; 84 z->state->wbits = w;
78 z->state->w_size = 1<<windowBits;
79 return Z_OK; 85 return Z_OK;
80} 86}
81 87
@@ -103,7 +109,7 @@ int f;
103 z->msg = "unknown compression method"; 109 z->msg = "unknown compression method";
104 return Z_DATA_ERROR; 110 return Z_DATA_ERROR;
105 } 111 }
106 if ((z->state->sub.method >> 4) > z->state->w_bits) 112 if ((z->state->sub.method >> 4) + 8 > z->state->wbits)
107 { 113 {
108 z->state->mode = ERROR; 114 z->state->mode = ERROR;
109 z->msg = "invalid window size"; 115 z->msg = "invalid window size";
@@ -126,17 +132,21 @@ int f;
126 } 132 }
127 z->state->mode = START; 133 z->state->mode = START;
128 case START: 134 case START:
129 if ((z->state->sub.blocks = inflate_blocks_new(z,z->state->w_size)) 135 if ((z->state->sub.blocks = inflate_blocks_new(z,
130 == Z_NULL) 136 z->state->nowrap ? Z_NULL : adler32,
137 1<< z->state->wbits)) == Z_NULL)
131 return Z_MEM_ERROR; 138 return Z_MEM_ERROR;
132 z->state->mode = BLOCKS; 139 z->state->mode = BLOCKS;
133 case BLOCKS: 140 case BLOCKS:
134 if ((r = inflate_blocks(z->state->sub.blocks, z, r)) != Z_STREAM_END) 141 if ((r = inflate_blocks(z->state->sub.blocks, z, r)) != Z_STREAM_END)
135 return r; 142 return r;
136 inflate_blocks_free(z->state->sub.blocks, z, &c, &r); 143 inflate_blocks_free(z->state->sub.blocks, z, &c, &r);
137 if (z->state->no_header) { 144 if (z->state->nowrap)
138 z->state->mode = DONE; 145 {
139 return Z_STREAM_END; 146 if (r != -1)
147 z->msg = "inflate bug--took one too many bytes";
148 z->state->mode = r == -1 ? DONE : ERROR;
149 break;
140 } 150 }
141 z->state->sub.check.was = c; 151 z->state->sub.check.was = c;
142 if (r != -1) 152 if (r != -1)