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