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