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