Back to index

avfs  1.0.1
inflate.c
Go to the documentation of this file.
00001 /* inflate.c -- zlib interface to inflate modules
00002  * Copyright (C) 1995-2002 Mark Adler
00003  * For conditions of distribution and use, see copyright notice in zlib.h 
00004  */
00005 
00006 #include "zutil.h"
00007 #include "infblock.h"
00008 
00009 #include <assert.h>
00010 
00011 struct inflate_blocks_state {int dummy;}; /* for buggy compilers */
00012 
00013 typedef enum {
00014       METHOD,   /* waiting for method byte */
00015       FLAG,     /* waiting for flag byte */
00016       DICT4,    /* four dictionary check bytes to go */
00017       DICT3,    /* three dictionary check bytes to go */
00018       DICT2,    /* two dictionary check bytes to go */
00019       DICT1,    /* one dictionary check byte to go */
00020       DICT0,    /* waiting for inflateSetDictionary */
00021       BLOCKS,   /* decompressing blocks */
00022       CHECK4,   /* four check bytes to go */
00023       CHECK3,   /* three check bytes to go */
00024       CHECK2,   /* two check bytes to go */
00025       CHECK1,   /* one check byte to go */
00026       DONE,     /* finished check, done */
00027       BAD}      /* got an error--stay here */
00028 inflate_mode;
00029 
00030 /* inflate private state */
00031 struct internal_state {
00032 
00033   /* mode */
00034   inflate_mode  mode;   /* current inflate mode */
00035 
00036   /* mode dependent information */
00037   union {
00038     uInt method;        /* if FLAGS, method byte */
00039     struct {
00040       uLong was;                /* computed check value */
00041       uLong need;               /* stream check value */
00042     } check;            /* if CHECK, check values to compare */
00043     uInt marker;        /* if BAD, inflateSync's marker bytes count */
00044   } sub;        /* submode */
00045 
00046   /* mode independent information */
00047   int  nowrap;          /* flag for no wrapper */
00048   uInt wbits;           /* log2(window size)  (8..15, defaults to 15) */
00049   inflate_blocks_statef 
00050     *blocks;            /* current inflate_blocks state */
00051 
00052 };
00053 
00054 
00055 int ZEXPORT inflateReset(z)
00056 z_streamp z;
00057 {
00058   if (z == Z_NULL || z->state == Z_NULL)
00059     return Z_STREAM_ERROR;
00060   z->total_in = z->total_out = 0;
00061   z->msg = Z_NULL;
00062   z->state->mode = z->state->nowrap ? BLOCKS : METHOD;
00063   inflate_blocks_reset(z->state->blocks, z, Z_NULL);
00064   Tracev((stderr, "inflate: reset\n"));
00065   return Z_OK;
00066 }
00067 
00068 
00069 int ZEXPORT inflateEnd(z)
00070 z_streamp z;
00071 {
00072   if (z == Z_NULL || z->state == Z_NULL || z->zfree == Z_NULL)
00073     return Z_STREAM_ERROR;
00074   if (z->state->blocks != Z_NULL)
00075     inflate_blocks_free(z->state->blocks, z);
00076   ZFREE(z, z->state);
00077   z->state = Z_NULL;
00078   Tracev((stderr, "inflate: end\n"));
00079   return Z_OK;
00080 }
00081 
00082 
00083 int ZEXPORT inflateInit2_(z, w, version, stream_size)
00084 z_streamp z;
00085 int w;
00086 const char *version;
00087 int stream_size;
00088 {
00089   if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
00090       stream_size != sizeof(z_stream))
00091       return Z_VERSION_ERROR;
00092 
00093   /* initialize state */
00094   if (z == Z_NULL)
00095     return Z_STREAM_ERROR;
00096   z->msg = Z_NULL;
00097   if (z->zalloc == Z_NULL)
00098   {
00099     z->zalloc = zcalloc;
00100     z->opaque = (voidpf)0;
00101   }
00102   if (z->zfree == Z_NULL) z->zfree = zcfree;
00103   if ((z->state = (struct internal_state FAR *)
00104        ZALLOC(z,1,sizeof(struct internal_state))) == Z_NULL)
00105     return Z_MEM_ERROR;
00106   z->state->blocks = Z_NULL;
00107 
00108   /* handle undocumented nowrap option (no zlib header or check) */
00109   z->state->nowrap = 0;
00110   if (w < 0)
00111   {
00112     w = - w;
00113     z->state->nowrap = 1;
00114   }
00115 
00116   /* set window size */
00117   if (w < 8 || w > 15)
00118   {
00119     inflateEnd(z);
00120     return Z_STREAM_ERROR;
00121   }
00122   z->state->wbits = (uInt)w;
00123 
00124   /* create inflate_blocks state */
00125   if ((z->state->blocks =
00126       inflate_blocks_new(z, z->state->nowrap ? Z_NULL : adler32, (uInt)1 << w))
00127       == Z_NULL)
00128   {
00129     inflateEnd(z);
00130     return Z_MEM_ERROR;
00131   }
00132   Tracev((stderr, "inflate: allocated\n"));
00133 
00134   /* reset state */
00135   inflateReset(z);
00136   return Z_OK;
00137 }
00138 
00139 
00140 int ZEXPORT inflateInit_(z, version, stream_size)
00141 z_streamp z;
00142 const char *version;
00143 int stream_size;
00144 {
00145   return inflateInit2_(z, DEF_WBITS, version, stream_size);
00146 }
00147 
00148 
00149 #define NEEDBYTE {if(z->avail_in==0)return r;r=f;}
00150 #define NEXTBYTE (z->avail_in--,z->total_in++,*z->next_in++)
00151 
00152 int ZEXPORT inflate(z, f)
00153 z_streamp z;
00154 int f;
00155 {
00156   int r;
00157   uInt b;
00158 
00159   if (z == Z_NULL || z->state == Z_NULL || z->next_in == Z_NULL)
00160     return Z_STREAM_ERROR;
00161   f = f == Z_FINISH ? Z_BUF_ERROR : Z_OK;
00162   r = Z_BUF_ERROR;
00163   while (1) switch (z->state->mode)
00164   {
00165     case METHOD:
00166       NEEDBYTE
00167       if (((z->state->sub.method = NEXTBYTE) & 0xf) != Z_DEFLATED)
00168       {
00169         z->state->mode = BAD;
00170         z->msg = (char*)"unknown compression method";
00171         z->state->sub.marker = 5;       /* can't try inflateSync */
00172         break;
00173       }
00174       if ((z->state->sub.method >> 4) + 8 > z->state->wbits)
00175       {
00176         z->state->mode = BAD;
00177         z->msg = (char*)"invalid window size";
00178         z->state->sub.marker = 5;       /* can't try inflateSync */
00179         break;
00180       }
00181       z->state->mode = FLAG;
00182     case FLAG:
00183       NEEDBYTE
00184       b = NEXTBYTE;
00185       if (((z->state->sub.method << 8) + b) % 31)
00186       {
00187         z->state->mode = BAD;
00188         z->msg = (char*)"incorrect header check";
00189         z->state->sub.marker = 5;       /* can't try inflateSync */
00190         break;
00191       }
00192       Tracev((stderr, "inflate: zlib header ok\n"));
00193       if (!(b & PRESET_DICT))
00194       {
00195         z->state->mode = BLOCKS;
00196         break;
00197       }
00198       z->state->mode = DICT4;
00199     case DICT4:
00200       NEEDBYTE
00201       z->state->sub.check.need = (uLong)NEXTBYTE << 24;
00202       z->state->mode = DICT3;
00203     case DICT3:
00204       NEEDBYTE
00205       z->state->sub.check.need += (uLong)NEXTBYTE << 16;
00206       z->state->mode = DICT2;
00207     case DICT2:
00208       NEEDBYTE
00209       z->state->sub.check.need += (uLong)NEXTBYTE << 8;
00210       z->state->mode = DICT1;
00211     case DICT1:
00212       NEEDBYTE
00213       z->state->sub.check.need += (uLong)NEXTBYTE;
00214       z->adler = z->state->sub.check.need;
00215       z->state->mode = DICT0;
00216       return Z_NEED_DICT;
00217     case DICT0:
00218       z->state->mode = BAD;
00219       z->msg = (char*)"need dictionary";
00220       z->state->sub.marker = 0;       /* can try inflateSync */
00221       return Z_STREAM_ERROR;
00222     case BLOCKS:
00223       r = inflate_blocks(z->state->blocks, z, r);
00224       if (r == Z_DATA_ERROR)
00225       {
00226         z->state->mode = BAD;
00227         z->state->sub.marker = 0;       /* can try inflateSync */
00228         break;
00229       }
00230       if (r == Z_OK)
00231         r = f;
00232       if (r != Z_STREAM_END)
00233         return r;
00234       r = f;
00235       inflate_blocks_reset(z->state->blocks, z, &z->state->sub.check.was);
00236       if (z->state->nowrap)
00237       {
00238         z->state->mode = DONE;
00239         break;
00240       }
00241       z->state->mode = CHECK4;
00242     case CHECK4:
00243       NEEDBYTE
00244       z->state->sub.check.need = (uLong)NEXTBYTE << 24;
00245       z->state->mode = CHECK3;
00246     case CHECK3:
00247       NEEDBYTE
00248       z->state->sub.check.need += (uLong)NEXTBYTE << 16;
00249       z->state->mode = CHECK2;
00250     case CHECK2:
00251       NEEDBYTE
00252       z->state->sub.check.need += (uLong)NEXTBYTE << 8;
00253       z->state->mode = CHECK1;
00254     case CHECK1:
00255       NEEDBYTE
00256       z->state->sub.check.need += (uLong)NEXTBYTE;
00257 
00258       if (z->state->sub.check.was != z->state->sub.check.need)
00259       {
00260         z->state->mode = BAD;
00261         z->msg = (char*)"incorrect data check";
00262         z->state->sub.marker = 5;       /* can't try inflateSync */
00263         break;
00264       }
00265       Tracev((stderr, "inflate: zlib check ok\n"));
00266       z->state->mode = DONE;
00267     case DONE:
00268       return Z_STREAM_END;
00269     case BAD:
00270       return Z_DATA_ERROR;
00271     default:
00272       return Z_STREAM_ERROR;
00273   }
00274 #ifdef NEED_DUMMY_RETURN
00275   return Z_STREAM_ERROR;  /* Some dumb compilers complain without this */
00276 #endif
00277 }
00278 
00279 
00280 int ZEXPORT inflateSetDictionary(z, dictionary, dictLength)
00281 z_streamp z;
00282 const Bytef *dictionary;
00283 uInt  dictLength;
00284 {
00285   uInt length = dictLength;
00286 
00287   if (z == Z_NULL || z->state == Z_NULL || z->state->mode != DICT0)
00288     return Z_STREAM_ERROR;
00289 
00290   if (adler32(1L, dictionary, dictLength) != z->adler) return Z_DATA_ERROR;
00291   z->adler = 1L;
00292 
00293   if (length >= ((uInt)1<<z->state->wbits))
00294   {
00295     length = (1<<z->state->wbits)-1;
00296     dictionary += dictLength - length;
00297   }
00298   inflate_set_dictionary(z->state->blocks, dictionary, length);
00299   z->state->mode = BLOCKS;
00300   return Z_OK;
00301 }
00302 
00303 
00304 int ZEXPORT inflateSync(z)
00305 z_streamp z;
00306 {
00307   uInt n;       /* number of bytes to look at */
00308   Bytef *p;     /* pointer to bytes */
00309   uInt m;       /* number of marker bytes found in a row */
00310   uLongLong r, w;   /* temporaries to save total_in and total_out */
00311 
00312   /* set up */
00313   if (z == Z_NULL || z->state == Z_NULL)
00314     return Z_STREAM_ERROR;
00315   if (z->state->mode != BAD)
00316   {
00317     z->state->mode = BAD;
00318     z->state->sub.marker = 0;
00319   }
00320   if ((n = z->avail_in) == 0)
00321     return Z_BUF_ERROR;
00322   p = z->next_in;
00323   m = z->state->sub.marker;
00324 
00325   /* search */
00326   while (n && m < 4)
00327   {
00328     static const Byte mark[4] = {0, 0, 0xff, 0xff};
00329     if (*p == mark[m])
00330       m++;
00331     else if (*p)
00332       m = 0;
00333     else
00334       m = 4 - m;
00335     p++, n--;
00336   }
00337 
00338   /* restore */
00339   z->total_in += p - z->next_in;
00340   z->next_in = p;
00341   z->avail_in = n;
00342   z->state->sub.marker = m;
00343 
00344   /* return no joy or set up to restart on a new block */
00345   if (m != 4)
00346     return Z_DATA_ERROR;
00347   r = z->total_in;  w = z->total_out;
00348   inflateReset(z);
00349   z->total_in = r;  z->total_out = w;
00350   z->state->mode = BLOCKS;
00351   return Z_OK;
00352 }
00353 
00354 
00355 /* Returns true if inflate is currently at the end of a block generated
00356  * by Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP
00357  * implementation to provide an additional safety check. PPP uses Z_SYNC_FLUSH
00358  * but removes the length bytes of the resulting empty stored block. When
00359  * decompressing, PPP checks that at the end of input packet, inflate is
00360  * waiting for these length bytes.
00361  */
00362 int ZEXPORT inflateSyncPoint(z)
00363 z_streamp z;
00364 {
00365   if (z == Z_NULL || z->state == Z_NULL || z->state->blocks == Z_NULL)
00366     return Z_STREAM_ERROR;
00367   return inflate_blocks_sync_point(z->state->blocks);
00368 }
00369 
00370 int inflateSave(z_streamp z, char **resultp)
00371 {
00372   int at;
00373   char *buf;
00374   z_stream zcpy = *z;
00375   struct internal_state statecpy = *z->state;
00376   
00377   buf = malloc(sizeof(z_stream) + sizeof(struct internal_state));
00378   if(buf == NULL)
00379     return Z_MEM_ERROR;
00380   
00381   at = 0;
00382 
00383   zcpy.next_in = NULL;
00384   zcpy.avail_in = 0;
00385   zcpy.next_out = NULL;
00386   zcpy.avail_out = 0;
00387   zcpy.msg = NULL;
00388   zcpy.state = NULL;
00389   zcpy.zalloc = NULL;
00390   zcpy.zfree = NULL;
00391   zcpy.opaque = NULL;
00392   memcpy(buf + at, &zcpy, sizeof(z_stream));
00393   at += sizeof(z_stream);
00394   
00395   statecpy.blocks = NULL;
00396   memcpy(buf + at, &statecpy, sizeof(struct internal_state));
00397   at += sizeof(struct internal_state);
00398   
00399   at = inflate_blocks_save(&buf, at, z->state->blocks, z,
00400                            (uInt)1 << z->state->wbits);
00401   if(at < 0) {
00402       free(buf);
00403       return at;
00404   }
00405 
00406   buf = realloc(buf, at + 2);
00407   buf[at++] = 'S';
00408   buf[at++] = 'Z';
00409 
00410   *resultp = buf;  
00411   return at;
00412 }
00413 
00414 int inflateRestore(z_streamp z, char *buf)
00415 {
00416   z_stream zcpy;
00417   
00418   memcpy(&zcpy, buf, sizeof(z_stream));
00419   buf += sizeof(z_stream);
00420 
00421   zcpy.next_in = z->next_in;
00422   zcpy.avail_in = z->avail_in;
00423   zcpy.next_out = z->next_out;
00424   zcpy.avail_out = z->avail_out;
00425   zcpy.zalloc = z->zalloc;
00426   zcpy.zfree = z->zfree;
00427   zcpy.opaque = z->opaque;
00428   *z = zcpy;
00429 
00430   z->msg = Z_NULL;
00431   if (z->zalloc == Z_NULL)
00432   {
00433     z->zalloc = zcalloc;
00434     z->opaque = (voidpf)0;
00435   }
00436   if (z->zfree == Z_NULL) z->zfree = zcfree;
00437   if ((z->state = (struct internal_state FAR *)
00438        ZALLOC(z,1,sizeof(struct internal_state))) == Z_NULL)
00439     return Z_MEM_ERROR;
00440 
00441   memcpy(z->state, buf, sizeof(struct internal_state));
00442   buf += sizeof(struct internal_state);
00443   
00444   if((z->state->blocks =
00445       inflate_blocks_restore(&buf, z, z->state->nowrap ? Z_NULL : adler32,
00446                              (uInt) 1 << z->state->wbits)) == Z_NULL)
00447   {
00448     inflateEnd(z);
00449     return Z_MEM_ERROR;
00450   }
00451 
00452   assert(buf[0] == 'S' && buf[1] == 'Z');
00453 
00454   return Z_OK;
00455 }