]>
git.ipfire.org Git - thirdparty/strongswan.git/blob - linux/lib/zlib/inflate.c
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
6 #include <zlib/zutil.h>
9 struct inflate_blocks_state
{int dummy
;}; /* for buggy compilers */
12 METHOD
, /* waiting for method byte */
13 FLAG
, /* waiting for flag byte */
14 DICT4
, /* four dictionary check bytes to go */
15 DICT3
, /* three dictionary check bytes to go */
16 DICT2
, /* two dictionary check bytes to go */
17 DICT1
, /* one dictionary check byte to go */
18 DICT0
, /* waiting for inflateSetDictionary */
19 BLOCKS
, /* decompressing blocks */
20 CHECK4
, /* four check bytes to go */
21 CHECK3
, /* three check bytes to go */
22 CHECK2
, /* two check bytes to go */
23 CHECK1
, /* one check byte to go */
24 DONE
, /* finished check, done */
25 BAD
} /* got an error--stay here */
28 /* inflate private state */
29 struct internal_state
{
32 inflate_mode mode
; /* current inflate mode */
34 /* mode dependent information */
36 uInt method
; /* if FLAGS, method byte */
38 uLong was
; /* computed check value */
39 uLong need
; /* stream check value */
40 } check
; /* if CHECK, check values to compare */
41 uInt marker
; /* if BAD, inflateSync's marker bytes count */
44 /* mode independent information */
45 int nowrap
; /* flag for no wrapper */
46 uInt wbits
; /* log2(window size) (8..15, defaults to 15) */
48 *blocks
; /* current inflate_blocks state */
53 int ZEXPORT
inflateReset(z
)
56 if (z
== Z_NULL
|| z
->state
== Z_NULL
)
57 return Z_STREAM_ERROR
;
58 z
->total_in
= z
->total_out
= 0;
60 z
->state
->mode
= z
->state
->nowrap
? BLOCKS
: METHOD
;
61 inflate_blocks_reset(z
->state
->blocks
, z
, Z_NULL
);
62 Tracev((stderr
, "inflate: reset\n"));
67 int ZEXPORT
inflateEnd(z
)
70 if (z
== Z_NULL
|| z
->state
== Z_NULL
|| z
->zfree
== Z_NULL
)
71 return Z_STREAM_ERROR
;
72 if (z
->state
->blocks
!= Z_NULL
)
73 inflate_blocks_free(z
->state
->blocks
, z
);
76 Tracev((stderr
, "inflate: end\n"));
81 int ZEXPORT
inflateInit2_(z
, w
, version
, stream_size
)
87 if (version
== Z_NULL
|| version
[0] != ZLIB_VERSION
[0] ||
88 stream_size
!= sizeof(z_stream
))
89 return Z_VERSION_ERROR
;
91 /* initialize state */
93 return Z_STREAM_ERROR
;
95 if (z
->zalloc
== Z_NULL
)
97 return Z_STREAM_ERROR
;
98 /* z->zalloc = zcalloc;
99 z->opaque = (voidpf)0;
102 if (z
->zfree
== Z_NULL
) return Z_STREAM_ERROR
; /* z->zfree = zcfree; */
103 if ((z
->state
= (struct internal_state FAR
*)
104 ZALLOC(z
,1,sizeof(struct internal_state
))) == Z_NULL
)
106 z
->state
->blocks
= Z_NULL
;
108 /* handle undocumented nowrap option (no zlib header or check) */
109 z
->state
->nowrap
= 0;
113 z
->state
->nowrap
= 1;
116 /* set window size */
120 return Z_STREAM_ERROR
;
122 z
->state
->wbits
= (uInt
)w
;
124 /* create inflate_blocks state */
125 if ((z
->state
->blocks
=
126 inflate_blocks_new(z
, z
->state
->nowrap
? Z_NULL
: adler32
, (uInt
)1 << w
))
132 Tracev((stderr
, "inflate: allocated\n"));
140 int ZEXPORT
inflateInit_(z
, version
, stream_size
)
145 return inflateInit2_(z
, DEF_WBITS
, version
, stream_size
);
149 #define NEEDBYTE {if(z->avail_in==0)return r;r=f;}
150 #define NEXTBYTE (z->avail_in--,z->total_in++,*z->next_in++)
152 int ZEXPORT
inflate(z
, f
)
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
;
163 while (1) switch (z
->state
->mode
)
167 if (((z
->state
->sub
.method
= NEXTBYTE
) & 0xf) != Z_DEFLATED
)
169 z
->state
->mode
= BAD
;
170 z
->msg
= (char*)"unknown compression method";
171 z
->state
->sub
.marker
= 5; /* can't try inflateSync */
174 if ((z
->state
->sub
.method
>> 4) + 8 > z
->state
->wbits
)
176 z
->state
->mode
= BAD
;
177 z
->msg
= (char*)"invalid window size";
178 z
->state
->sub
.marker
= 5; /* can't try inflateSync */
181 z
->state
->mode
= FLAG
;
185 if (((z
->state
->sub
.method
<< 8) + b
) % 31)
187 z
->state
->mode
= BAD
;
188 z
->msg
= (char*)"incorrect header check";
189 z
->state
->sub
.marker
= 5; /* can't try inflateSync */
192 Tracev((stderr
, "inflate: zlib header ok\n"));
193 if (!(b
& PRESET_DICT
))
195 z
->state
->mode
= BLOCKS
;
198 z
->state
->mode
= DICT4
;
201 z
->state
->sub
.check
.need
= (uLong
)NEXTBYTE
<< 24;
202 z
->state
->mode
= DICT3
;
205 z
->state
->sub
.check
.need
+= (uLong
)NEXTBYTE
<< 16;
206 z
->state
->mode
= DICT2
;
209 z
->state
->sub
.check
.need
+= (uLong
)NEXTBYTE
<< 8;
210 z
->state
->mode
= DICT1
;
213 z
->state
->sub
.check
.need
+= (uLong
)NEXTBYTE
;
214 z
->adler
= z
->state
->sub
.check
.need
;
215 z
->state
->mode
= 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
;
223 r
= inflate_blocks(z
->state
->blocks
, z
, r
);
224 if (r
== Z_DATA_ERROR
)
226 z
->state
->mode
= BAD
;
227 z
->state
->sub
.marker
= 0; /* can try inflateSync */
232 if (r
!= Z_STREAM_END
)
235 inflate_blocks_reset(z
->state
->blocks
, z
, &z
->state
->sub
.check
.was
);
236 if (z
->state
->nowrap
)
238 z
->state
->mode
= DONE
;
241 z
->state
->mode
= CHECK4
;
244 z
->state
->sub
.check
.need
= (uLong
)NEXTBYTE
<< 24;
245 z
->state
->mode
= CHECK3
;
248 z
->state
->sub
.check
.need
+= (uLong
)NEXTBYTE
<< 16;
249 z
->state
->mode
= CHECK2
;
252 z
->state
->sub
.check
.need
+= (uLong
)NEXTBYTE
<< 8;
253 z
->state
->mode
= CHECK1
;
256 z
->state
->sub
.check
.need
+= (uLong
)NEXTBYTE
;
258 if (z
->state
->sub
.check
.was
!= z
->state
->sub
.check
.need
)
260 z
->state
->mode
= BAD
;
261 z
->msg
= (char*)"incorrect data check";
262 z
->state
->sub
.marker
= 5; /* can't try inflateSync */
265 Tracev((stderr
, "inflate: zlib check ok\n"));
266 z
->state
->mode
= DONE
;
272 return Z_STREAM_ERROR
;
274 #ifdef NEED_DUMMY_RETURN
275 return Z_STREAM_ERROR
; /* Some dumb compilers complain without this */
280 int ZEXPORT
inflateSetDictionary(z
, dictionary
, dictLength
)
282 const Bytef
*dictionary
;
285 uInt length
= dictLength
;
287 if (z
== Z_NULL
|| z
->state
== Z_NULL
|| z
->state
->mode
!= DICT0
)
288 return Z_STREAM_ERROR
;
290 if (adler32(1L, dictionary
, dictLength
) != z
->adler
) return Z_DATA_ERROR
;
293 if (length
>= ((uInt
)1<<z
->state
->wbits
))
295 length
= (1<<z
->state
->wbits
)-1;
296 dictionary
+= dictLength
- length
;
298 inflate_set_dictionary(z
->state
->blocks
, dictionary
, length
);
299 z
->state
->mode
= BLOCKS
;
304 int ZEXPORT
inflateSync(z
)
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 */
313 if (z
== Z_NULL
|| z
->state
== Z_NULL
)
314 return Z_STREAM_ERROR
;
315 if (z
->state
->mode
!= BAD
)
317 z
->state
->mode
= BAD
;
318 z
->state
->sub
.marker
= 0;
320 if ((n
= z
->avail_in
) == 0)
323 m
= z
->state
->sub
.marker
;
328 static const Byte mark
[4] = {0, 0, 0xff, 0xff};
339 z
->total_in
+= p
- z
->next_in
;
342 z
->state
->sub
.marker
= m
;
344 /* return no joy or set up to restart on a new block */
347 r
= z
->total_in
; w
= z
->total_out
;
349 z
->total_in
= r
; z
->total_out
= w
;
350 z
->state
->mode
= BLOCKS
;
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.
362 int ZEXPORT
inflateSyncPoint(z
)
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
);