]>
git.saurik.com Git - apple/security.git/blob - SecurityServer/MacYarrow/zlib/inflate.c
2 * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
4 * The contents of this file constitute Original Code as defined in and are
5 * subject to the Apple Public Source License Version 1.2 (the 'License').
6 * You may not use this file except in compliance with the License. Please obtain
7 * a copy of the License at http://www.apple.com/publicsource and read it before
10 * This Original Code and all software distributed under the License are
11 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS
12 * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT
13 * LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
14 * PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please see the License for the
15 * specific language governing rights and limitations under the License.
19 /* inflate.c -- zlib interface to inflate modules
20 * Copyright (C) 1995-1998 Mark Adler
21 * For conditions of distribution and use, see copyright notice in zlib.h
27 struct inflate_blocks_state
{int dummy
;}; /* for buggy compilers */
30 METHOD
, /* waiting for method byte */
31 FLAG
, /* waiting for flag byte */
32 DICT4
, /* four dictionary check bytes to go */
33 DICT3
, /* three dictionary check bytes to go */
34 DICT2
, /* two dictionary check bytes to go */
35 DICT1
, /* one dictionary check byte to go */
36 DICT0
, /* waiting for inflateSetDictionary */
37 BLOCKS
, /* decompressing blocks */
38 CHECK4
, /* four check bytes to go */
39 CHECK3
, /* three check bytes to go */
40 CHECK2
, /* two check bytes to go */
41 CHECK1
, /* one check byte to go */
42 DONE
, /* finished check, done */
43 BAD
} /* got an error--stay here */
46 /* inflate private state */
47 struct internal_state
{
50 inflate_mode mode
; /* current inflate mode */
52 /* mode dependent information */
54 uInt method
; /* if FLAGS, method byte */
56 uLong was
; /* computed check value */
57 uLong need
; /* stream check value */
58 } check
; /* if CHECK, check values to compare */
59 uInt marker
; /* if BAD, inflateSync's marker bytes count */
62 /* mode independent information */
63 int nowrap
; /* flag for no wrapper */
64 uInt wbits
; /* log2(window size) (8..15, defaults to 15) */
66 *blocks
; /* current inflate_blocks state */
71 int ZEXPORT
inflateReset(z
)
74 if (z
== Z_NULL
|| z
->state
== Z_NULL
)
75 return Z_STREAM_ERROR
;
76 z
->total_in
= z
->total_out
= 0;
78 z
->state
->mode
= z
->state
->nowrap
? BLOCKS
: METHOD
;
79 inflate_blocks_reset(z
->state
->blocks
, z
, Z_NULL
);
80 Tracev((stderr
, "inflate: reset\n"));
85 int ZEXPORT
inflateEnd(z
)
88 if (z
== Z_NULL
|| z
->state
== Z_NULL
|| z
->zfree
== Z_NULL
)
89 return Z_STREAM_ERROR
;
90 if (z
->state
->blocks
!= Z_NULL
)
91 inflate_blocks_free(z
->state
->blocks
, z
);
94 Tracev((stderr
, "inflate: end\n"));
99 int ZEXPORT
inflateInit2_(z
, w
, version
, stream_size
)
105 if (version
== Z_NULL
|| version
[0] != ZLIB_VERSION
[0] ||
106 stream_size
!= sizeof(z_stream
))
107 return Z_VERSION_ERROR
;
109 /* initialize state */
111 return Z_STREAM_ERROR
;
113 if (z
->zalloc
== Z_NULL
)
116 z
->opaque
= (voidpf
)0;
118 if (z
->zfree
== Z_NULL
) z
->zfree
= zcfree
;
119 if ((z
->state
= (struct internal_state FAR
*)
120 ZALLOC(z
,1,sizeof(struct internal_state
))) == Z_NULL
)
122 z
->state
->blocks
= Z_NULL
;
124 /* handle undocumented nowrap option (no zlib header or check) */
125 z
->state
->nowrap
= 0;
129 z
->state
->nowrap
= 1;
132 /* set window size */
136 return Z_STREAM_ERROR
;
138 z
->state
->wbits
= (uInt
)w
;
140 /* create inflate_blocks state */
141 if ((z
->state
->blocks
=
142 inflate_blocks_new(z
, z
->state
->nowrap
? Z_NULL
: adler32
, (uInt
)1 << w
))
148 Tracev((stderr
, "inflate: allocated\n"));
156 int ZEXPORT
inflateInit_(z
, version
, stream_size
)
161 return inflateInit2_(z
, DEF_WBITS
, version
, stream_size
);
165 #define NEEDBYTE {if(z->avail_in==0)return r;r=f;}
166 #define NEXTBYTE (z->avail_in--,z->total_in++,*z->next_in++)
168 int ZEXPORT
inflate(z
, f
)
175 if (z
== Z_NULL
|| z
->state
== Z_NULL
|| z
->next_in
== Z_NULL
)
176 return Z_STREAM_ERROR
;
177 f
= f
== Z_FINISH
? Z_BUF_ERROR
: Z_OK
;
179 while (1) switch (z
->state
->mode
)
183 if (((z
->state
->sub
.method
= NEXTBYTE
) & 0xf) != Z_DEFLATED
)
185 z
->state
->mode
= BAD
;
186 z
->msg
= (char*)"unknown compression method";
187 z
->state
->sub
.marker
= 5; /* can't try inflateSync */
190 if ((z
->state
->sub
.method
>> 4) + 8 > z
->state
->wbits
)
192 z
->state
->mode
= BAD
;
193 z
->msg
= (char*)"invalid window size";
194 z
->state
->sub
.marker
= 5; /* can't try inflateSync */
197 z
->state
->mode
= FLAG
;
201 if (((z
->state
->sub
.method
<< 8) + b
) % 31)
203 z
->state
->mode
= BAD
;
204 z
->msg
= (char*)"incorrect header check";
205 z
->state
->sub
.marker
= 5; /* can't try inflateSync */
208 Tracev((stderr
, "inflate: zlib header ok\n"));
209 if (!(b
& PRESET_DICT
))
211 z
->state
->mode
= BLOCKS
;
214 z
->state
->mode
= DICT4
;
217 z
->state
->sub
.check
.need
= (uLong
)NEXTBYTE
<< 24;
218 z
->state
->mode
= DICT3
;
221 z
->state
->sub
.check
.need
+= (uLong
)NEXTBYTE
<< 16;
222 z
->state
->mode
= DICT2
;
225 z
->state
->sub
.check
.need
+= (uLong
)NEXTBYTE
<< 8;
226 z
->state
->mode
= DICT1
;
229 z
->state
->sub
.check
.need
+= (uLong
)NEXTBYTE
;
230 z
->adler
= z
->state
->sub
.check
.need
;
231 z
->state
->mode
= DICT0
;
234 z
->state
->mode
= BAD
;
235 z
->msg
= (char*)"need dictionary";
236 z
->state
->sub
.marker
= 0; /* can try inflateSync */
237 return Z_STREAM_ERROR
;
239 r
= inflate_blocks(z
->state
->blocks
, z
, r
);
240 if (r
== Z_DATA_ERROR
)
242 z
->state
->mode
= BAD
;
243 z
->state
->sub
.marker
= 0; /* can try inflateSync */
248 if (r
!= Z_STREAM_END
)
251 inflate_blocks_reset(z
->state
->blocks
, z
, &z
->state
->sub
.check
.was
);
252 if (z
->state
->nowrap
)
254 z
->state
->mode
= DONE
;
257 z
->state
->mode
= CHECK4
;
260 z
->state
->sub
.check
.need
= (uLong
)NEXTBYTE
<< 24;
261 z
->state
->mode
= CHECK3
;
264 z
->state
->sub
.check
.need
+= (uLong
)NEXTBYTE
<< 16;
265 z
->state
->mode
= CHECK2
;
268 z
->state
->sub
.check
.need
+= (uLong
)NEXTBYTE
<< 8;
269 z
->state
->mode
= CHECK1
;
272 z
->state
->sub
.check
.need
+= (uLong
)NEXTBYTE
;
274 if (z
->state
->sub
.check
.was
!= z
->state
->sub
.check
.need
)
276 z
->state
->mode
= BAD
;
277 z
->msg
= (char*)"incorrect data check";
278 z
->state
->sub
.marker
= 5; /* can't try inflateSync */
281 Tracev((stderr
, "inflate: zlib check ok\n"));
282 z
->state
->mode
= DONE
;
288 return Z_STREAM_ERROR
;
290 #ifdef NEED_DUMMY_RETURN
291 return Z_STREAM_ERROR
; /* Some dumb compilers complain without this */
296 int ZEXPORT
inflateSetDictionary(z
, dictionary
, dictLength
)
298 const Bytef
*dictionary
;
301 uInt length
= dictLength
;
303 if (z
== Z_NULL
|| z
->state
== Z_NULL
|| z
->state
->mode
!= DICT0
)
304 return Z_STREAM_ERROR
;
306 if (adler32(1L, dictionary
, dictLength
) != z
->adler
) return Z_DATA_ERROR
;
309 if (length
>= ((uInt
)1<<z
->state
->wbits
))
311 length
= (1<<z
->state
->wbits
)-1;
312 dictionary
+= dictLength
- length
;
314 inflate_set_dictionary(z
->state
->blocks
, dictionary
, length
);
315 z
->state
->mode
= BLOCKS
;
320 int ZEXPORT
inflateSync(z
)
323 uInt n
; /* number of bytes to look at */
324 Bytef
*p
; /* pointer to bytes */
325 uInt m
; /* number of marker bytes found in a row */
326 uLong r
, w
; /* temporaries to save total_in and total_out */
329 if (z
== Z_NULL
|| z
->state
== Z_NULL
)
330 return Z_STREAM_ERROR
;
331 if (z
->state
->mode
!= BAD
)
333 z
->state
->mode
= BAD
;
334 z
->state
->sub
.marker
= 0;
336 if ((n
= z
->avail_in
) == 0)
339 m
= z
->state
->sub
.marker
;
344 static const Byte mark
[4] = {0, 0, 0xff, 0xff};
355 z
->total_in
+= p
- z
->next_in
;
358 z
->state
->sub
.marker
= m
;
360 /* return no joy or set up to restart on a new block */
363 r
= z
->total_in
; w
= z
->total_out
;
365 z
->total_in
= r
; z
->total_out
= w
;
366 z
->state
->mode
= BLOCKS
;
371 /* Returns true if inflate is currently at the end of a block generated
372 * by Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP
373 * implementation to provide an additional safety check. PPP uses Z_SYNC_FLUSH
374 * but removes the length bytes of the resulting empty stored block. When
375 * decompressing, PPP checks that at the end of input packet, inflate is
376 * waiting for these length bytes.
378 int ZEXPORT
inflateSyncPoint(z
)
381 if (z
== Z_NULL
|| z
->state
== Z_NULL
|| z
->state
->blocks
== Z_NULL
)
382 return Z_STREAM_ERROR
;
383 return inflate_blocks_sync_point(z
->state
->blocks
);