1 /* inflate.c -- zlib interface to inflate modules 2 * Copyright (C) 1995-1996 Mark Adler 3 * For conditions of distribution and use, see copyright notice in zlib.h 4 */ 5 6 #include "zutil.h" 7 #include "infblock.h" 8 9 struct inflate_blocks_state {int dummy;}; /* for buggy compilers */ 10 11 /* inflate private state */ 12 struct internal_state { 13 14 /* mode */ 15 enum { 16 METHOD, /* waiting for method byte */ 17 FLAG, /* waiting for flag byte */ 18 DICT4, /* four dictionary check bytes to go */ 19 DICT3, /* three dictionary check bytes to go */ 20 DICT2, /* two dictionary check bytes to go */ 21 DICT1, /* one dictionary check byte to go */ 22 DICT0, /* waiting for inflateSetDictionary */ 23 BLOCKS, /* decompressing blocks */ 24 CHECK4, /* four check bytes to go */ 25 CHECK3, /* three check bytes to go */ 26 CHECK2, /* two check bytes to go */ 27 CHECK1, /* one check byte to go */ 28 DONE, /* finished check, done */ 29 BAD} /* got an error--stay here */ 30 mode; /* current inflate mode */ 31 32 /* mode dependent information */ 33 union { 34 uInt method; /* if FLAGS, method byte */ 35 struct { 36 uLong was; /* computed check value */ 37 uLong need; /* stream check value */ 38 } check; /* if CHECK, check values to compare */ 39 uInt marker; /* if BAD, inflateSync's marker bytes count */ 40 } sub; /* submode */ 41 42 /* mode independent information */ 43 int nowrap; /* flag for no wrapper */ 44 uInt wbits; /* log2(window size) (8..15, defaults to 15) */ 45 inflate_blocks_statef 46 *blocks; /* current inflate_blocks state */ 47 48 }; 49 50 51 int inflateReset(z) 52 z_streamp z; 53 { 54 uLong c; 55 56 if (z == Z_NULL || z->state == Z_NULL) 57 return Z_STREAM_ERROR; 58 z->total_in = z->total_out = 0; 59 z->msg = Z_NULL; 60 z->state->mode = z->state->nowrap ? BLOCKS : METHOD; 61 inflate_blocks_reset(z->state->blocks, z, &c); 62 Trace((stderr, "inflate: reset\n")); 63 return Z_OK; 64 } 65 66 67 int inflateEnd(z) 68 z_streamp z; 69 { 70 uLong c; 71 72 if (z == Z_NULL || z->state == Z_NULL || z->zfree == Z_NULL) 73 return Z_STREAM_ERROR; 74 if (z->state->blocks != Z_NULL) 75 inflate_blocks_free(z->state->blocks, z, &c); 76 ZFREE(z, z->state); 77 z->state = Z_NULL; 78 Trace((stderr, "inflate: end\n")); 79 return Z_OK; 80 } 81 82 83 int inflateInit2_(z, w, version, stream_size) 84 z_streamp z; 85 int w; 86 const char *version; 87 int stream_size; 88 { 89 if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || 90 stream_size != sizeof(z_stream)) 91 return Z_VERSION_ERROR; 92 93 /* initialize state */ 94 if (z == Z_NULL) 95 return Z_STREAM_ERROR; 96 z->msg = Z_NULL; 97 if (z->zalloc == Z_NULL) 98 { 99 z->zalloc = zcalloc; 100 z->opaque = (voidpf)0; 101 } 102 if (z->zfree == Z_NULL) z->zfree = zcfree; 103 if ((z->state = (struct internal_state FAR *) 104 ZALLOC(z,1,sizeof(struct internal_state))) == Z_NULL) 105 return Z_MEM_ERROR; 106 z->state->blocks = Z_NULL; 107 108 /* handle undocumented nowrap option (no zlib header or check) */ 109 z->state->nowrap = 0; 110 if (w < 0) 111 { 112 w = - w; 113 z->state->nowrap = 1; 114 } 115 116 /* set window size */ 117 if (w < 8 || w > 15) 118 { 119 inflateEnd(z); 120 return Z_STREAM_ERROR; 121 } 122 z->state->wbits = (uInt)w; 123 124 /* create inflate_blocks state */ 125 if ((z->state->blocks = 126 inflate_blocks_new(z, z->state->nowrap ? Z_NULL : adler32, (uInt)1 << w)) 127 == Z_NULL) 128 { 129 inflateEnd(z); 130 return Z_MEM_ERROR; 131 } 132 Trace((stderr, "inflate: allocated\n")); 133 134 /* reset state */ 135 inflateReset(z); 136 return Z_OK; 137 } 138 139 140 int inflateInit_(z, version, stream_size) 141 z_streamp z; 142 const char *version; 143 int stream_size; 144 { 145 return inflateInit2_(z, DEF_WBITS, version, stream_size); 146 } 147 148 149 #define NEEDBYTE {if(z->avail_in==0)return r;r=Z_OK;} 150 #define NEXTBYTE (z->avail_in--,z->total_in++,*z->next_in++) 151 152 int inflate(z, f) 153 z_streamp z; 154 int f; 155 { 156 int r; 157 uInt b; 158 159 if (z == Z_NULL || z->state == Z_NULL || z->next_in == Z_NULL || f < 0) 160 return Z_STREAM_ERROR; 161 r = Z_BUF_ERROR; 162 while (1) switch (z->state->mode) 163 { 164 case METHOD: 165 NEEDBYTE 166 if (((z->state->sub.method = NEXTBYTE) & 0xf) != Z_DEFLATED) 167 { 168 z->state->mode = BAD; 169 z->msg = (char*)"unknown compression method"; 170 z->state->sub.marker = 5; /* can't try inflateSync */ 171 break; 172 } 173 if ((z->state->sub.method >> 4) + 8 > z->state->wbits) 174 { 175 z->state->mode = BAD; 176 z->msg = (char*)"invalid window size"; 177 z->state->sub.marker = 5; /* can't try inflateSync */ 178 break; 179 } 180 z->state->mode = FLAG; 181 case FLAG: 182 NEEDBYTE 183 b = NEXTBYTE; 184 if (((z->state->sub.method << 8) + b) % 31) 185 { 186 z->state->mode = BAD; 187 z->msg = (char*)"incorrect header check"; 188 z->state->sub.marker = 5; /* can't try inflateSync */ 189 break; 190 } 191 Trace((stderr, "inflate: zlib header ok\n")); 192 if (!(b & PRESET_DICT)) 193 { 194 z->state->mode = BLOCKS; 195 break; 196 } 197 z->state->mode = DICT4; 198 case DICT4: 199 NEEDBYTE 200 z->state->sub.check.need = (uLong)NEXTBYTE << 24; 201 z->state->mode = DICT3; 202 case DICT3: 203 NEEDBYTE 204 z->state->sub.check.need += (uLong)NEXTBYTE << 16; 205 z->state->mode = DICT2; 206 case DICT2: 207 NEEDBYTE 208 z->state->sub.check.need += (uLong)NEXTBYTE << 8; 209 z->state->mode = DICT1; 210 case DICT1: 211 NEEDBYTE 212 z->state->sub.check.need += (uLong)NEXTBYTE; 213 z->adler = z->state->sub.check.need; 214 z->state->mode = DICT0; 215 return Z_NEED_DICT; 216 case DICT0: 217 z->state->mode = BAD; 218 z->msg = (char*)"need dictionary"; 219 z->state->sub.marker = 0; /* can try inflateSync */ 220 return Z_STREAM_ERROR; 221 case BLOCKS: 222 r = inflate_blocks(z->state->blocks, z, r); 223 if (r == Z_DATA_ERROR) 224 { 225 z->state->mode = BAD; 226 z->state->sub.marker = 0; /* can try inflateSync */ 227 break; 228 } 229 if (r != Z_STREAM_END) 230 return r; 231 r = Z_OK; 232 inflate_blocks_reset(z->state->blocks, z, &z->state->sub.check.was); 233 if (z->state->nowrap) 234 { 235 z->state->mode = DONE; 236 break; 237 } 238 z->state->mode = CHECK4; 239 case CHECK4: 240 NEEDBYTE 241 z->state->sub.check.need = (uLong)NEXTBYTE << 24; 242 z->state->mode = CHECK3; 243 case CHECK3: 244 NEEDBYTE 245 z->state->sub.check.need += (uLong)NEXTBYTE << 16; 246 z->state->mode = CHECK2; 247 case CHECK2: 248 NEEDBYTE 249 z->state->sub.check.need += (uLong)NEXTBYTE << 8; 250 z->state->mode = CHECK1; 251 case CHECK1: 252 NEEDBYTE 253 z->state->sub.check.need += (uLong)NEXTBYTE; 254 255 if (z->state->sub.check.was != z->state->sub.check.need) 256 { 257 z->state->mode = BAD; 258 z->msg = (char*)"incorrect data check"; 259 z->state->sub.marker = 5; /* can't try inflateSync */ 260 break; 261 } 262 Trace((stderr, "inflate: zlib check ok\n")); 263 z->state->mode = DONE; 264 case DONE: 265 return Z_STREAM_END; 266 case BAD: 267 return Z_DATA_ERROR; 268 default: 269 return Z_STREAM_ERROR; 270 } 271 } 272 273 274 int inflateSetDictionary(z, dictionary, dictLength) 275 z_streamp z; 276 const Bytef *dictionary; 277 uInt dictLength; 278 { 279 uInt length = dictLength; 280 281 if (z == Z_NULL || z->state == Z_NULL || z->state->mode != DICT0) 282 return Z_STREAM_ERROR; 283 284 if (adler32(1L, dictionary, dictLength) != z->adler) return Z_DATA_ERROR; 285 z->adler = 1L; 286 287 if (length >= ((uInt)1<<z->state->wbits)) 288 { 289 length = (1<<z->state->wbits)-1; 290 dictionary += dictLength - length; 291 } 292 inflate_set_dictionary(z->state->blocks, dictionary, length); 293 z->state->mode = BLOCKS; 294 return Z_OK; 295 } 296 297 298 int inflateSync(z) 299 z_streamp z; 300 { 301 uInt n; /* number of bytes to look at */ 302 Bytef *p; /* pointer to bytes */ 303 uInt m; /* number of marker bytes found in a row */ 304 uLong r, w; /* temporaries to save total_in and total_out */ 305 306 /* set up */ 307 if (z == Z_NULL || z->state == Z_NULL) 308 return Z_STREAM_ERROR; 309 if (z->state->mode != BAD) 310 { 311 z->state->mode = BAD; 312 z->state->sub.marker = 0; 313 } 314 if ((n = z->avail_in) == 0) 315 return Z_BUF_ERROR; 316 p = z->next_in; 317 m = z->state->sub.marker; 318 319 /* search */ 320 while (n && m < 4) 321 { 322 if (*p == (Byte)(m < 2 ? 0 : 0xff)) 323 m++; 324 else if (*p) 325 m = 0; 326 else 327 m = 4 - m; 328 p++, n--; 329 } 330 331 /* restore */ 332 z->total_in += p - z->next_in; 333 z->next_in = p; 334 z->avail_in = n; 335 z->state->sub.marker = m; 336 337 /* return no joy or set up to restart on a new block */ 338 if (m != 4) 339 return Z_DATA_ERROR; 340 r = z->total_in; w = z->total_out; 341 inflateReset(z); 342 z->total_in = r; z->total_out = w; 343 z->state->mode = BLOCKS; 344 return Z_OK; 345 } 346