1/* inflate.c -- zlib interface to inflate modules 2 * Copyright (C) 1995-2002 Mark Adler 3 * For conditions of distribution and use, see copyright notice in zlib.h 4 */ 5/* $Id: inflate.c 14574 2005-10-29 16:27:43Z bonefish $ */ 6 7#include "zutil.h" 8#include "infblock.h" 9 10/* PDFlib GmbH: conflicts with Visual Studio.NET 11struct inflate_blocks_state {int dummy;}; *//* for buggy compilers */ 12 13typedef enum { 14 METHOD, /* waiting for method byte */ 15 FLAG, /* waiting for flag byte */ 16 DICT4, /* four dictionary check bytes to go */ 17 DICT3, /* three dictionary check bytes to go */ 18 DICT2, /* two dictionary check bytes to go */ 19 DICT1, /* one dictionary check byte to go */ 20 DICT0, /* waiting for inflateSetDictionary */ 21 BLOCKS, /* decompressing blocks */ 22 CHECK4, /* four check bytes to go */ 23 CHECK3, /* three check bytes to go */ 24 CHECK2, /* two check bytes to go */ 25 CHECK1, /* one check byte to go */ 26 DONE, /* finished check, done */ 27 BAD} /* got an error--stay here */ 28inflate_mode; 29 30/* inflate private state */ 31struct internal_state { 32 33 /* mode */ 34 inflate_mode mode; /* current inflate mode */ 35 36 /* mode dependent information */ 37 union { 38 uInt method; /* if FLAGS, method byte */ 39 struct { 40 uLong was; /* computed check value */ 41 uLong need; /* stream check value */ 42 } check; /* if CHECK, check values to compare */ 43 uInt marker; /* if BAD, inflateSync's marker bytes count */ 44 } sub; /* submode */ 45 46 /* mode independent information */ 47 int nowrap; /* flag for no wrapper */ 48 uInt wbits; /* log2(window size) (8..15, defaults to 15) */ 49 inflate_blocks_statef 50 *blocks; /* current inflate_blocks state */ 51 52}; 53 54 55int ZEXPORT inflateReset( 56z_streamp z) 57{ 58 if (z == Z_NULL || z->state == Z_NULL) 59 return Z_STREAM_ERROR; 60 z->total_in = z->total_out = 0; 61 z->msg = Z_NULL; 62 z->state->mode = z->state->nowrap ? BLOCKS : METHOD; 63 inflate_blocks_reset(z->state->blocks, z, Z_NULL); 64 Tracev((stderr, "inflate: reset\n")); 65 return Z_OK; 66} 67 68 69int ZEXPORT inflateEnd( 70z_streamp z) 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); 76 ZFREE(z, z->state); 77 z->state = Z_NULL; 78 Tracev((stderr, "inflate: end\n")); 79 return Z_OK; 80} 81 82 83int ZEXPORT inflateInit2_( 84z_streamp z, 85int w, 86const char *version, 87int 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 Tracev((stderr, "inflate: allocated\n")); 133 134 /* reset state */ 135 inflateReset(z); 136 return Z_OK; 137} 138 139 140int ZEXPORT inflateInit_( 141z_streamp z, 142const char *version, 143int 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=f;} 150#define NEXTBYTE (z->avail_in--,z->total_in++,*z->next_in++) 151 152int ZEXPORT inflate( 153z_streamp z, 154int f) 155{ 156 int r; 157 uInt b; 158 159 if (z == Z_NULL || z->state == Z_NULL || z->next_in == Z_NULL) 160 return Z_STREAM_ERROR; 161 f = f == Z_FINISH ? Z_BUF_ERROR : Z_OK; 162 r = Z_BUF_ERROR; 163 while (1) switch (z->state->mode) 164 { 165 case METHOD: 166 NEEDBYTE 167 if (((z->state->sub.method = NEXTBYTE) & 0xf) != Z_DEFLATED) 168 { 169 z->state->mode = BAD; 170 z->msg = (char*)"unknown compression method"; 171 z->state->sub.marker = 5; /* can't try inflateSync */ 172 break; 173 } 174 if ((z->state->sub.method >> 4) + 8 > z->state->wbits) 175 { 176 z->state->mode = BAD; 177 z->msg = (char*)"invalid window size"; 178 z->state->sub.marker = 5; /* can't try inflateSync */ 179 break; 180 } 181 z->state->mode = FLAG; 182 case FLAG: 183 NEEDBYTE 184 b = NEXTBYTE; 185 if (((z->state->sub.method << 8) + b) % 31) 186 { 187 z->state->mode = BAD; 188 z->msg = (char*)"incorrect header check"; 189 z->state->sub.marker = 5; /* can't try inflateSync */ 190 break; 191 } 192 Tracev((stderr, "inflate: zlib header ok\n")); 193 if (!(b & PRESET_DICT)) 194 { 195 z->state->mode = BLOCKS; 196 break; 197 } 198 z->state->mode = DICT4; 199 case DICT4: 200 NEEDBYTE 201 z->state->sub.check.need = (uLong)NEXTBYTE << 24; 202 z->state->mode = DICT3; 203 case DICT3: 204 NEEDBYTE 205 z->state->sub.check.need += (uLong)NEXTBYTE << 16; 206 z->state->mode = DICT2; 207 case DICT2: 208 NEEDBYTE 209 z->state->sub.check.need += (uLong)NEXTBYTE << 8; 210 z->state->mode = DICT1; 211 case DICT1: 212 NEEDBYTE 213 z->state->sub.check.need += (uLong)NEXTBYTE; 214 z->adler = z->state->sub.check.need; 215 z->state->mode = DICT0; 216 return Z_NEED_DICT; 217 case DICT0: 218 z->state->mode = BAD; 219 z->msg = (char*)"need dictionary"; 220 z->state->sub.marker = 0; /* can try inflateSync */ 221 return Z_STREAM_ERROR; 222 case BLOCKS: 223 r = inflate_blocks(z->state->blocks, z, r); 224 if (r == Z_DATA_ERROR) 225 { 226 z->state->mode = BAD; 227 z->state->sub.marker = 0; /* can try inflateSync */ 228 break; 229 } 230 if (r == Z_OK) 231 r = f; 232 if (r != Z_STREAM_END) 233 return r; 234 r = f; 235 inflate_blocks_reset(z->state->blocks, z, &z->state->sub.check.was); 236 if (z->state->nowrap) 237 { 238 z->state->mode = DONE; 239 break; 240 } 241 z->state->mode = CHECK4; 242 case CHECK4: 243 NEEDBYTE 244 z->state->sub.check.need = (uLong)NEXTBYTE << 24; 245 z->state->mode = CHECK3; 246 case CHECK3: 247 NEEDBYTE 248 z->state->sub.check.need += (uLong)NEXTBYTE << 16; 249 z->state->mode = CHECK2; 250 case CHECK2: 251 NEEDBYTE 252 z->state->sub.check.need += (uLong)NEXTBYTE << 8; 253 z->state->mode = CHECK1; 254 case CHECK1: 255 NEEDBYTE 256 z->state->sub.check.need += (uLong)NEXTBYTE; 257 258 if (z->state->sub.check.was != z->state->sub.check.need) 259 { 260 z->state->mode = BAD; 261 z->msg = (char*)"incorrect data check"; 262 z->state->sub.marker = 5; /* can't try inflateSync */ 263 break; 264 } 265 Tracev((stderr, "inflate: zlib check ok\n")); 266 z->state->mode = DONE; 267 case DONE: 268 return Z_STREAM_END; 269 case BAD: 270 return Z_DATA_ERROR; 271 default: 272 return Z_STREAM_ERROR; 273 } 274#ifdef NEED_DUMMY_RETURN 275 return Z_STREAM_ERROR; /* Some dumb compilers complain without this */ 276#endif 277} 278 279 280int ZEXPORT inflateSetDictionary( 281z_streamp z, 282const Bytef *dictionary, 283uInt dictLength) 284{ 285 uInt length = dictLength; 286 287 if (z == Z_NULL || z->state == Z_NULL || z->state->mode != DICT0) 288 return Z_STREAM_ERROR; 289 290 if (adler32(1L, dictionary, dictLength) != z->adler) return Z_DATA_ERROR; 291 z->adler = 1L; 292 293 if (length >= ((uInt)1<<z->state->wbits)) 294 { 295 length = (1<<z->state->wbits)-1; 296 dictionary += dictLength - length; 297 } 298 inflate_set_dictionary(z->state->blocks, dictionary, length); 299 z->state->mode = BLOCKS; 300 return Z_OK; 301} 302 303 304int ZEXPORT inflateSync( 305z_streamp z) 306{ 307 uInt n; /* number of bytes to look at */ 308 Bytef *p; /* pointer to bytes */ 309 uInt m; /* number of marker bytes found in a row */ 310 uLong r, w; /* temporaries to save total_in and total_out */ 311 312 /* set up */ 313 if (z == Z_NULL || z->state == Z_NULL) 314 return Z_STREAM_ERROR; 315 if (z->state->mode != BAD) 316 { 317 z->state->mode = BAD; 318 z->state->sub.marker = 0; 319 } 320 if ((n = z->avail_in) == 0) 321 return Z_BUF_ERROR; 322 p = z->next_in; 323 m = z->state->sub.marker; 324 325 /* search */ 326 while (n && m < 4) 327 { 328 static const Byte mark[4] = {0, 0, 0xff, 0xff}; 329 if (*p == mark[m]) 330 m++; 331 else if (*p) 332 m = 0; 333 else 334 m = 4 - m; 335 p++, n--; 336 } 337 338 /* restore */ 339 z->total_in += p - z->next_in; 340 z->next_in = p; 341 z->avail_in = n; 342 z->state->sub.marker = m; 343 344 /* return no joy or set up to restart on a new block */ 345 if (m != 4) 346 return Z_DATA_ERROR; 347 r = z->total_in; w = z->total_out; 348 inflateReset(z); 349 z->total_in = r; z->total_out = w; 350 z->state->mode = BLOCKS; 351 return Z_OK; 352} 353 354 355/* Returns true if inflate is currently at the end of a block generated 356 * by Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP 357 * implementation to provide an additional safety check. PPP uses Z_SYNC_FLUSH 358 * but removes the length bytes of the resulting empty stored block. When 359 * decompressing, PPP checks that at the end of input packet, inflate is 360 * waiting for these length bytes. 361 */ 362int ZEXPORT inflateSyncPoint( 363z_streamp z) 364{ 365 if (z == Z_NULL || z->state == Z_NULL || z->state->blocks == Z_NULL) 366 return Z_STREAM_ERROR; 367 return inflate_blocks_sync_point(z->state->blocks); 368} 369