1 /* inflate.c -- zlib interface to inflate modules 2 * Copyright (C) 1995-1998 Mark Adler 3 * For conditions of distribution and use, see copyright notice in zlib.h 4 */ 5 6 #include <linux/zutil.h> 7 #include "infblock.h" 8 #include "infutil.h" 9 10 int zlib_inflate_workspacesize(void) 11 { 12 return sizeof(struct inflate_workspace); 13 } 14 15 16 int zlib_inflateReset( 17 z_streamp z 18 ) 19 { 20 if (z == NULL || z->state == NULL || z->workspace == NULL) 21 return Z_STREAM_ERROR; 22 z->total_in = z->total_out = 0; 23 z->msg = NULL; 24 z->state->mode = z->state->nowrap ? BLOCKS : METHOD; 25 zlib_inflate_blocks_reset(z->state->blocks, z, NULL); 26 return Z_OK; 27 } 28 29 30 int zlib_inflateEnd( 31 z_streamp z 32 ) 33 { 34 if (z == NULL || z->state == NULL || z->workspace == NULL) 35 return Z_STREAM_ERROR; 36 if (z->state->blocks != NULL) 37 zlib_inflate_blocks_free(z->state->blocks, z); 38 z->state = NULL; 39 return Z_OK; 40 } 41 42 43 int zlib_inflateInit2_( 44 z_streamp z, 45 int w, 46 const char *version, 47 int stream_size 48 ) 49 { 50 if (version == NULL || version[0] != ZLIB_VERSION[0] || 51 stream_size != sizeof(z_stream) || z->workspace == NULL) 52 return Z_VERSION_ERROR; 53 54 /* initialize state */ 55 z->msg = NULL; 56 z->state = &WS(z)->internal_state; 57 z->state->blocks = NULL; 58 59 /* handle undocumented nowrap option (no zlib header or check) */ 60 z->state->nowrap = 0; 61 if (w < 0) 62 { 63 w = - w; 64 z->state->nowrap = 1; 65 } 66 67 /* set window size */ 68 if (w < 8 || w > 15) 69 { 70 zlib_inflateEnd(z); 71 return Z_STREAM_ERROR; 72 } 73 z->state->wbits = (uInt)w; 74 75 /* create inflate_blocks state */ 76 if ((z->state->blocks = 77 zlib_inflate_blocks_new(z, z->state->nowrap ? NULL : zlib_adler32, (uInt)1 << w)) 78 == NULL) 79 { 80 zlib_inflateEnd(z); 81 return Z_MEM_ERROR; 82 } 83 84 /* reset state */ 85 zlib_inflateReset(z); 86 return Z_OK; 87 } 88 89 90 /* 91 * At the end of a Deflate-compressed PPP packet, we expect to have seen 92 * a `stored' block type value but not the (zero) length bytes. 93 */ 94 static int zlib_inflate_packet_flush(inflate_blocks_statef *s) 95 { 96 if (s->mode != LENS) 97 return Z_DATA_ERROR; 98 s->mode = TYPE; 99 return Z_OK; 100 } 101 102 103 int zlib_inflateInit_( 104 z_streamp z, 105 const char *version, 106 int stream_size 107 ) 108 { 109 return zlib_inflateInit2_(z, DEF_WBITS, version, stream_size); 110 } 111 112 #undef NEEDBYTE 113 #undef NEXTBYTE 114 #define NEEDBYTE {if(z->avail_in==0)goto empty;r=trv;} 115 #define NEXTBYTE (z->avail_in--,z->total_in++,*z->next_in++) 116 117 int zlib_inflate( 118 z_streamp z, 119 int f 120 ) 121 { 122 int r, trv; 123 uInt b; 124 125 if (z == NULL || z->state == NULL || z->next_in == NULL) 126 return Z_STREAM_ERROR; 127 trv = f == Z_FINISH ? Z_BUF_ERROR : Z_OK; 128 r = Z_BUF_ERROR; 129 while (1) switch (z->state->mode) 130 { 131 case METHOD: 132 NEEDBYTE 133 if (((z->state->sub.method = NEXTBYTE) & 0xf) != Z_DEFLATED) 134 { 135 z->state->mode = I_BAD; 136 z->msg = (char*)"unknown compression method"; 137 z->state->sub.marker = 5; /* can't try inflateSync */ 138 break; 139 } 140 if ((z->state->sub.method >> 4) + 8 > z->state->wbits) 141 { 142 z->state->mode = I_BAD; 143 z->msg = (char*)"invalid window size"; 144 z->state->sub.marker = 5; /* can't try inflateSync */ 145 break; 146 } 147 z->state->mode = FLAG; 148 case FLAG: 149 NEEDBYTE 150 b = NEXTBYTE; 151 if (((z->state->sub.method << 8) + b) % 31) 152 { 153 z->state->mode = I_BAD; 154 z->msg = (char*)"incorrect header check"; 155 z->state->sub.marker = 5; /* can't try inflateSync */ 156 break; 157 } 158 if (!(b & PRESET_DICT)) 159 { 160 z->state->mode = BLOCKS; 161 break; 162 } 163 z->state->mode = DICT4; 164 case DICT4: 165 NEEDBYTE 166 z->state->sub.check.need = (uLong)NEXTBYTE << 24; 167 z->state->mode = DICT3; 168 case DICT3: 169 NEEDBYTE 170 z->state->sub.check.need += (uLong)NEXTBYTE << 16; 171 z->state->mode = DICT2; 172 case DICT2: 173 NEEDBYTE 174 z->state->sub.check.need += (uLong)NEXTBYTE << 8; 175 z->state->mode = DICT1; 176 case DICT1: 177 NEEDBYTE 178 z->state->sub.check.need += (uLong)NEXTBYTE; 179 z->adler = z->state->sub.check.need; 180 z->state->mode = DICT0; 181 return Z_NEED_DICT; 182 case DICT0: 183 z->state->mode = I_BAD; 184 z->msg = (char*)"need dictionary"; 185 z->state->sub.marker = 0; /* can try inflateSync */ 186 return Z_STREAM_ERROR; 187 case BLOCKS: 188 r = zlib_inflate_blocks(z->state->blocks, z, r); 189 if (f == Z_PACKET_FLUSH && z->avail_in == 0 && z->avail_out != 0) 190 r = zlib_inflate_packet_flush(z->state->blocks); 191 if (r == Z_DATA_ERROR) 192 { 193 z->state->mode = I_BAD; 194 z->state->sub.marker = 0; /* can try inflateSync */ 195 break; 196 } 197 if (r == Z_OK) 198 r = trv; 199 if (r != Z_STREAM_END) 200 return r; 201 r = trv; 202 zlib_inflate_blocks_reset(z->state->blocks, z, &z->state->sub.check.was); 203 if (z->state->nowrap) 204 { 205 z->state->mode = I_DONE; 206 break; 207 } 208 z->state->mode = CHECK4; 209 case CHECK4: 210 NEEDBYTE 211 z->state->sub.check.need = (uLong)NEXTBYTE << 24; 212 z->state->mode = CHECK3; 213 case CHECK3: 214 NEEDBYTE 215 z->state->sub.check.need += (uLong)NEXTBYTE << 16; 216 z->state->mode = CHECK2; 217 case CHECK2: 218 NEEDBYTE 219 z->state->sub.check.need += (uLong)NEXTBYTE << 8; 220 z->state->mode = CHECK1; 221 case CHECK1: 222 NEEDBYTE 223 z->state->sub.check.need += (uLong)NEXTBYTE; 224 225 if (z->state->sub.check.was != z->state->sub.check.need) 226 { 227 z->state->mode = I_BAD; 228 z->msg = (char*)"incorrect data check"; 229 z->state->sub.marker = 5; /* can't try inflateSync */ 230 break; 231 } 232 z->state->mode = I_DONE; 233 case I_DONE: 234 return Z_STREAM_END; 235 case I_BAD: 236 return Z_DATA_ERROR; 237 default: 238 return Z_STREAM_ERROR; 239 } 240 empty: 241 if (f != Z_PACKET_FLUSH) 242 return r; 243 z->state->mode = I_BAD; 244 z->msg = (char *)"need more for packet flush"; 245 z->state->sub.marker = 0; /* can try inflateSync */ 246 return Z_DATA_ERROR; 247 } 248