Diff for /embedaddon/rsync/zlib/inflate.c between versions 1.1.1.1 and 1.1.1.2

version 1.1.1.1, 2012/02/17 15:09:30 version 1.1.1.2, 2013/10/14 07:51:14
Line 1 Line 1
 /* inflate.c -- zlib decompression  /* inflate.c -- zlib decompression
 * Copyright (C) 1995-2005 Mark Adler * Copyright (C) 1995-2012 Mark Adler
  * For conditions of distribution and use, see copyright notice in zlib.h   * For conditions of distribution and use, see copyright notice in zlib.h
  */   */
   
Line 45 Line 45
  * - Rearrange window copies in inflate_fast() for speed and simplification   * - Rearrange window copies in inflate_fast() for speed and simplification
  * - Unroll last copy for window match in inflate_fast()   * - Unroll last copy for window match in inflate_fast()
  * - Use local copies of window variables in inflate_fast() for speed   * - Use local copies of window variables in inflate_fast() for speed
 * - Pull out common write == 0 case for speed in inflate_fast() * - Pull out common wnext == 0 case for speed in inflate_fast()
  * - Make op and len in inflate_fast() unsigned for consistency   * - Make op and len in inflate_fast() unsigned for consistency
  * - Add FAR to lcode and dcode declarations in inflate_fast()   * - Add FAR to lcode and dcode declarations in inflate_fast()
  * - Simplified bad distance check in inflate_fast()   * - Simplified bad distance check in inflate_fast()
Line 93 Line 93
   
 /* function prototypes */  /* function prototypes */
 local void fixedtables OF((struct inflate_state FAR *state));  local void fixedtables OF((struct inflate_state FAR *state));
local int updatewindow OF((z_streamp strm, unsigned out));local int updatewindow OF((z_streamp strm, const unsigned char FAR *end,
                            unsigned copy));
 #ifdef BUILDFIXED  #ifdef BUILDFIXED
    void makefixed OF((void));     void makefixed OF((void));
 #endif  #endif
local unsigned syncsearch OF((unsigned FAR *have, unsigned char FAR *buf,local unsigned syncsearch OF((unsigned FAR *have, const unsigned char FAR *buf,
                               unsigned len));                                unsigned len));
   
int ZEXPORT inflateReset(strm)int ZEXPORT inflateResetKeep(strm)
 z_streamp strm;  z_streamp strm;
 {  {
     struct inflate_state FAR *state;      struct inflate_state FAR *state;
Line 109  z_streamp strm; Line 110  z_streamp strm;
     state = (struct inflate_state FAR *)strm->state;      state = (struct inflate_state FAR *)strm->state;
     strm->total_in = strm->total_out = state->total = 0;      strm->total_in = strm->total_out = state->total = 0;
     strm->msg = Z_NULL;      strm->msg = Z_NULL;
    strm->adler = 1;        /* to support ill-conceived Java test suite */    if (state->wrap)        /* to support ill-conceived Java test suite */
         strm->adler = state->wrap & 1;
     state->mode = HEAD;      state->mode = HEAD;
     state->last = 0;      state->last = 0;
     state->havedict = 0;      state->havedict = 0;
     state->dmax = 32768U;      state->dmax = 32768U;
     state->head = Z_NULL;      state->head = Z_NULL;
     state->wsize = 0;  
     state->whave = 0;  
     state->write = 0;  
     state->hold = 0;      state->hold = 0;
     state->bits = 0;      state->bits = 0;
     state->lencode = state->distcode = state->next = state->codes;      state->lencode = state->distcode = state->next = state->codes;
       state->sane = 1;
       state->back = -1;
     Tracev((stderr, "inflate: reset\n"));      Tracev((stderr, "inflate: reset\n"));
     return Z_OK;      return Z_OK;
 }  }
   
int ZEXPORT inflatePrime(strm, bits, value)int ZEXPORT inflateReset(strm)
 z_streamp strm;  z_streamp strm;
 int bits;  
 int value;  
 {  {
     struct inflate_state FAR *state;      struct inflate_state FAR *state;
   
     if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;      if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
     state = (struct inflate_state FAR *)strm->state;      state = (struct inflate_state FAR *)strm->state;
    if (bits > 16 || state->bits + bits > 32) return Z_STREAM_ERROR;    state->wsize = 0;
    value &= (1L << bits) - 1;    state->whave = 0;
    state->hold += value << state->bits;    state->wnext = 0;
    state->bits += bits;    return inflateResetKeep(strm);
    return Z_OK; 
 }  }
   
   int ZEXPORT inflateReset2(strm, windowBits)
   z_streamp strm;
   int windowBits;
   {
       int wrap;
       struct inflate_state FAR *state;
   
       /* get the state */
       if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
       state = (struct inflate_state FAR *)strm->state;
   
       /* extract wrap request from windowBits parameter */
       if (windowBits < 0) {
           wrap = 0;
           windowBits = -windowBits;
       }
       else {
           wrap = (windowBits >> 4) + 1;
   #ifdef GUNZIP
           if (windowBits < 48)
               windowBits &= 15;
   #endif
       }
   
       /* set number of window bits, free window if different */
       if (windowBits && (windowBits < 8 || windowBits > 15))
           return Z_STREAM_ERROR;
       if (state->window != Z_NULL && state->wbits != (unsigned)windowBits) {
           ZFREE(strm, state->window);
           state->window = Z_NULL;
       }
   
       /* update state and reset the rest of it */
       state->wrap = wrap;
       state->wbits = (unsigned)windowBits;
       return inflateReset(strm);
   }
   
 int ZEXPORT inflateInit2_(strm, windowBits, version, stream_size)  int ZEXPORT inflateInit2_(strm, windowBits, version, stream_size)
 z_streamp strm;  z_streamp strm;
 int windowBits;  int windowBits;
 const char *version;  const char *version;
 int stream_size;  int stream_size;
 {  {
       int ret;
     struct inflate_state FAR *state;      struct inflate_state FAR *state;
   
     if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||      if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
Line 155  int stream_size; Line 192  int stream_size;
     if (strm == Z_NULL) return Z_STREAM_ERROR;      if (strm == Z_NULL) return Z_STREAM_ERROR;
     strm->msg = Z_NULL;                 /* in case we return an error */      strm->msg = Z_NULL;                 /* in case we return an error */
     if (strm->zalloc == (alloc_func)0) {      if (strm->zalloc == (alloc_func)0) {
   #ifdef Z_SOLO
           return Z_STREAM_ERROR;
   #else
         strm->zalloc = zcalloc;          strm->zalloc = zcalloc;
         strm->opaque = (voidpf)0;          strm->opaque = (voidpf)0;
   #endif
     }      }
    if (strm->zfree == (free_func)0) strm->zfree = zcfree;    if (strm->zfree == (free_func)0)
 #ifdef Z_SOLO
         return Z_STREAM_ERROR;
 #else
         strm->zfree = zcfree;
 #endif
     state = (struct inflate_state FAR *)      state = (struct inflate_state FAR *)
             ZALLOC(strm, 1, sizeof(struct inflate_state));              ZALLOC(strm, 1, sizeof(struct inflate_state));
     if (state == Z_NULL) return Z_MEM_ERROR;      if (state == Z_NULL) return Z_MEM_ERROR;
     Tracev((stderr, "inflate: allocated\n"));      Tracev((stderr, "inflate: allocated\n"));
     strm->state = (struct internal_state FAR *)state;      strm->state = (struct internal_state FAR *)state;
    if (windowBits < 0) {    state->window = Z_NULL;
        state->wrap = 0;    ret = inflateReset2(strm, windowBits);
        windowBits = -windowBits;    if (ret != Z_OK) {
    } 
    else { 
        state->wrap = (windowBits >> 4) + 1; 
#ifdef GUNZIP 
        if (windowBits < 48) windowBits &= 15; 
#endif 
    } 
    if (windowBits < 8 || windowBits > 15) { 
         ZFREE(strm, state);          ZFREE(strm, state);
         strm->state = Z_NULL;          strm->state = Z_NULL;
         return Z_STREAM_ERROR;  
     }      }
    state->wbits = (unsigned)windowBits;    return ret;
    state->window = Z_NULL; 
    return inflateReset(strm); 
 }  }
   
 int ZEXPORT inflateInit_(strm, version, stream_size)  int ZEXPORT inflateInit_(strm, version, stream_size)
Line 192  int stream_size; Line 227  int stream_size;
     return inflateInit2_(strm, DEF_WBITS, version, stream_size);      return inflateInit2_(strm, DEF_WBITS, version, stream_size);
 }  }
   
   int ZEXPORT inflatePrime(strm, bits, value)
   z_streamp strm;
   int bits;
   int value;
   {
       struct inflate_state FAR *state;
   
       if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
       state = (struct inflate_state FAR *)strm->state;
       if (bits < 0) {
           state->hold = 0;
           state->bits = 0;
           return Z_OK;
       }
       if (bits > 16 || state->bits + bits > 32) return Z_STREAM_ERROR;
       value &= (1L << bits) - 1;
       state->hold += value << state->bits;
       state->bits += bits;
       return Z_OK;
   }
   
 /*  /*
    Return state with length and distance decoding tables and index sizes set to     Return state with length and distance decoding tables and index sizes set to
    fixed code decoding.  Normally this returns fixed tables from inffixed.h.     fixed code decoding.  Normally this returns fixed tables from inffixed.h.
Line 286  void makefixed() Line 342  void makefixed()
     low = 0;      low = 0;
     for (;;) {      for (;;) {
         if ((low % 7) == 0) printf("\n        ");          if ((low % 7) == 0) printf("\n        ");
        printf("{%u,%u,%d}", state.lencode[low].op, state.lencode[low].bits,        printf("{%u,%u,%d}", (low & 127) == 99 ? 64 : state.lencode[low].op,
               state.lencode[low].val);               state.lencode[low].bits, state.lencode[low].val);
         if (++low == size) break;          if (++low == size) break;
         putchar(',');          putchar(',');
     }      }
Line 320  void makefixed() Line 376  void makefixed()
    output will fall in the output data, making match copies simpler and faster.     output will fall in the output data, making match copies simpler and faster.
    The advantage may be dependent on the size of the processor's data caches.     The advantage may be dependent on the size of the processor's data caches.
  */   */
local int updatewindow(strm, out)local int updatewindow(strm, end, copy)
 z_streamp strm;  z_streamp strm;
unsigned out;const Bytef *end;
 unsigned copy;
 {  {
     struct inflate_state FAR *state;      struct inflate_state FAR *state;
    unsigned copy, dist;    unsigned dist;
   
     state = (struct inflate_state FAR *)strm->state;      state = (struct inflate_state FAR *)strm->state;
   
Line 340  unsigned out; Line 397  unsigned out;
     /* if window not in use yet, initialize */      /* if window not in use yet, initialize */
     if (state->wsize == 0) {      if (state->wsize == 0) {
         state->wsize = 1U << state->wbits;          state->wsize = 1U << state->wbits;
        state->write = 0;        state->wnext = 0;
         state->whave = 0;          state->whave = 0;
     }      }
   
     /* copy state->wsize or less output bytes into the circular window */      /* copy state->wsize or less output bytes into the circular window */
     copy = out - strm->avail_out;  
     if (copy >= state->wsize) {      if (copy >= state->wsize) {
        zmemcpy(state->window, strm->next_out - state->wsize, state->wsize);        zmemcpy(state->window, end - state->wsize, state->wsize);
        state->write = 0;        state->wnext = 0;
         state->whave = state->wsize;          state->whave = state->wsize;
     }      }
     else {      else {
        dist = state->wsize - state->write;        dist = state->wsize - state->wnext;
         if (dist > copy) dist = copy;          if (dist > copy) dist = copy;
        zmemcpy(state->window + state->write, strm->next_out - copy, dist);        zmemcpy(state->window + state->wnext, end - copy, dist);
         copy -= dist;          copy -= dist;
         if (copy) {          if (copy) {
            zmemcpy(state->window, strm->next_out - copy, copy);            zmemcpy(state->window, end - copy, copy);
            state->write = copy;            state->wnext = copy;
             state->whave = state->wsize;              state->whave = state->wsize;
         }          }
         else {          else {
            state->write += dist;            state->wnext += dist;
            if (state->write == state->wsize) state->write = 0;            if (state->wnext == state->wsize) state->wnext = 0;
             if (state->whave < state->wsize) state->whave += dist;              if (state->whave < state->wsize) state->whave += dist;
         }          }
     }      }
Line 464  unsigned out; Line 520  unsigned out;
         bits -= bits & 7; \          bits -= bits & 7; \
     } while (0)      } while (0)
   
 /* Reverse the bytes in a 32-bit value */  
 #define REVERSE(q) \  
     ((((q) >> 24) & 0xff) + (((q) >> 8) & 0xff00) + \  
      (((q) & 0xff00) << 8) + (((q) & 0xff) << 24))  
   
 /*  /*
    inflate() uses a state machine to process as much input data and generate as     inflate() uses a state machine to process as much input data and generate as
    much output data as possible before returning.  The state machine is     much output data as possible before returning.  The state machine is
Line 556  z_streamp strm; Line 607  z_streamp strm;
 int flush;  int flush;
 {  {
     struct inflate_state FAR *state;      struct inflate_state FAR *state;
    unsigned char FAR *next;    /* next input */    z_const unsigned char FAR *next;    /* next input */
     unsigned char FAR *put;     /* next output */      unsigned char FAR *put;     /* next output */
     unsigned have, left;        /* available input and output */      unsigned have, left;        /* available input and output */
     unsigned long hold;         /* bit buffer */      unsigned long hold;         /* bit buffer */
Line 564  int flush; Line 615  int flush;
     unsigned in, out;           /* save starting available input and output */      unsigned in, out;           /* save starting available input and output */
     unsigned copy;              /* number of stored or match bytes to copy */      unsigned copy;              /* number of stored or match bytes to copy */
     unsigned char FAR *from;    /* where to copy match bytes from */      unsigned char FAR *from;    /* where to copy match bytes from */
    code this;                  /* current decoding table entry */    code here;                  /* current decoding table entry */
     code last;                  /* parent table entry */      code last;                  /* parent table entry */
     unsigned len;               /* length to copy for repeats, bits to drop */      unsigned len;               /* length to copy for repeats, bits to drop */
     int ret;                    /* return code */      int ret;                    /* return code */
Line 619  int flush; Line 670  int flush;
             }              }
             DROPBITS(4);              DROPBITS(4);
             len = BITS(4) + 8;              len = BITS(4) + 8;
            if (len > state->wbits) {            if (state->wbits == 0)
                 state->wbits = len;
             else if (len > state->wbits) {
                 strm->msg = (char *)"invalid window size";                  strm->msg = (char *)"invalid window size";
                 state->mode = BAD;                  state->mode = BAD;
                 break;                  break;
Line 767  int flush; Line 820  int flush;
 #endif  #endif
         case DICTID:          case DICTID:
             NEEDBITS(32);              NEEDBITS(32);
            strm->adler = state->check = REVERSE(hold);            strm->adler = state->check = ZSWAP32(hold);
             INITBITS();              INITBITS();
             state->mode = DICT;              state->mode = DICT;
             /* FALL THROUGH */              /* FALL THROUGH */
Line 780  int flush; Line 833  int flush;
             state->mode = TYPE;              state->mode = TYPE;
             /* FALL THROUGH */              /* FALL THROUGH */
         case TYPE:          case TYPE:
            if (flush == Z_BLOCK) goto inf_leave;            if (flush == Z_BLOCK || flush == Z_TREES) goto inf_leave;
             /* FALL THROUGH */              /* FALL THROUGH */
         case TYPEDO:          case TYPEDO:
             if (state->last) {              if (state->last) {
Line 801  int flush; Line 854  int flush;
                 fixedtables(state);                  fixedtables(state);
                 Tracev((stderr, "inflate:     fixed codes block%s\n",                  Tracev((stderr, "inflate:     fixed codes block%s\n",
                         state->last ? " (last)" : ""));                          state->last ? " (last)" : ""));
                state->mode = LEN;              /* decode codes */                state->mode = LEN_;             /* decode codes */
                 if (flush == Z_TREES) {
                     DROPBITS(2);
                     goto inf_leave;
                 }
                 break;                  break;
             case 2:                             /* dynamic block */              case 2:                             /* dynamic block */
                 Tracev((stderr, "inflate:     dynamic codes block%s\n",                  Tracev((stderr, "inflate:     dynamic codes block%s\n",
Line 826  int flush; Line 883  int flush;
             Tracev((stderr, "inflate:       stored length %u\n",              Tracev((stderr, "inflate:       stored length %u\n",
                     state->length));                      state->length));
             INITBITS();              INITBITS();
               state->mode = COPY_;
               if (flush == Z_TREES) goto inf_leave;
           case COPY_:
             state->mode = COPY;              state->mode = COPY;
             /* FALL THROUGH */              /* FALL THROUGH */
         case COPY:          case COPY:
Line 873  int flush; Line 933  int flush;
             while (state->have < 19)              while (state->have < 19)
                 state->lens[order[state->have++]] = 0;                  state->lens[order[state->have++]] = 0;
             state->next = state->codes;              state->next = state->codes;
            state->lencode = (code const FAR *)(state->next);            state->lencode = (const code FAR *)(state->next);
             state->lenbits = 7;              state->lenbits = 7;
             ret = inflate_table(CODES, state->lens, 19, &(state->next),              ret = inflate_table(CODES, state->lens, 19, &(state->next),
                                 &(state->lenbits), state->work);                                  &(state->lenbits), state->work);
Line 889  int flush; Line 949  int flush;
         case CODELENS:          case CODELENS:
             while (state->have < state->nlen + state->ndist) {              while (state->have < state->nlen + state->ndist) {
                 for (;;) {                  for (;;) {
                    this = state->lencode[BITS(state->lenbits)];                    here = state->lencode[BITS(state->lenbits)];
                    if ((unsigned)(this.bits) <= bits) break;                    if ((unsigned)(here.bits) <= bits) break;
                     PULLBYTE();                      PULLBYTE();
                 }                  }
                if (this.val < 16) {                if (here.val < 16) {
                    NEEDBITS(this.bits);                    DROPBITS(here.bits);
                    DROPBITS(this.bits);                    state->lens[state->have++] = here.val;
                    state->lens[state->have++] = this.val; 
                 }                  }
                 else {                  else {
                    if (this.val == 16) {                    if (here.val == 16) {
                        NEEDBITS(this.bits + 2);                        NEEDBITS(here.bits + 2);
                        DROPBITS(this.bits);                        DROPBITS(here.bits);
                         if (state->have == 0) {                          if (state->have == 0) {
                             strm->msg = (char *)"invalid bit length repeat";                              strm->msg = (char *)"invalid bit length repeat";
                             state->mode = BAD;                              state->mode = BAD;
Line 911  int flush; Line 970  int flush;
                         copy = 3 + BITS(2);                          copy = 3 + BITS(2);
                         DROPBITS(2);                          DROPBITS(2);
                     }                      }
                    else if (this.val == 17) {                    else if (here.val == 17) {
                        NEEDBITS(this.bits + 3);                        NEEDBITS(here.bits + 3);
                        DROPBITS(this.bits);                        DROPBITS(here.bits);
                         len = 0;                          len = 0;
                         copy = 3 + BITS(3);                          copy = 3 + BITS(3);
                         DROPBITS(3);                          DROPBITS(3);
                     }                      }
                     else {                      else {
                        NEEDBITS(this.bits + 7);                        NEEDBITS(here.bits + 7);
                        DROPBITS(this.bits);                        DROPBITS(here.bits);
                         len = 0;                          len = 0;
                         copy = 11 + BITS(7);                          copy = 11 + BITS(7);
                         DROPBITS(7);                          DROPBITS(7);
Line 938  int flush; Line 997  int flush;
             /* handle error breaks in while */              /* handle error breaks in while */
             if (state->mode == BAD) break;              if (state->mode == BAD) break;
   
            /* build code tables */            /* check for end-of-block code (better have one) */
             if (state->lens[256] == 0) {
                 strm->msg = (char *)"invalid code -- missing end-of-block";
                 state->mode = BAD;
                 break;
             }
 
             /* build code tables -- note: do not change the lenbits or distbits
                values here (9 and 6) without reading the comments in inftrees.h
                concerning the ENOUGH constants, which depend on those values */
             state->next = state->codes;              state->next = state->codes;
            state->lencode = (code const FAR *)(state->next);            state->lencode = (const code FAR *)(state->next);
             state->lenbits = 9;              state->lenbits = 9;
             ret = inflate_table(LENS, state->lens, state->nlen, &(state->next),              ret = inflate_table(LENS, state->lens, state->nlen, &(state->next),
                                 &(state->lenbits), state->work);                                  &(state->lenbits), state->work);
Line 949  int flush; Line 1017  int flush;
                 state->mode = BAD;                  state->mode = BAD;
                 break;                  break;
             }              }
            state->distcode = (code const FAR *)(state->next);            state->distcode = (const code FAR *)(state->next);
             state->distbits = 6;              state->distbits = 6;
             ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist,              ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist,
                             &(state->next), &(state->distbits), state->work);                              &(state->next), &(state->distbits), state->work);
Line 959  int flush; Line 1027  int flush;
                 break;                  break;
             }              }
             Tracev((stderr, "inflate:       codes ok\n"));              Tracev((stderr, "inflate:       codes ok\n"));
               state->mode = LEN_;
               if (flush == Z_TREES) goto inf_leave;
               /* FALL THROUGH */
           case LEN_:
             state->mode = LEN;              state->mode = LEN;
             /* FALL THROUGH */              /* FALL THROUGH */
         case LEN:          case LEN:
Line 966  int flush; Line 1038  int flush;
                 RESTORE();                  RESTORE();
                 inflate_fast(strm, out);                  inflate_fast(strm, out);
                 LOAD();                  LOAD();
                   if (state->mode == TYPE)
                       state->back = -1;
                 break;                  break;
             }              }
               state->back = 0;
             for (;;) {              for (;;) {
                this = state->lencode[BITS(state->lenbits)];                here = state->lencode[BITS(state->lenbits)];
                if ((unsigned)(this.bits) <= bits) break;                if ((unsigned)(here.bits) <= bits) break;
                 PULLBYTE();                  PULLBYTE();
             }              }
            if (this.op && (this.op & 0xf0) == 0) {            if (here.op && (here.op & 0xf0) == 0) {
                last = this;                last = here;
                 for (;;) {                  for (;;) {
                    this = state->lencode[last.val +                    here = state->lencode[last.val +
                             (BITS(last.bits + last.op) >> last.bits)];                              (BITS(last.bits + last.op) >> last.bits)];
                    if ((unsigned)(last.bits + this.bits) <= bits) break;                    if ((unsigned)(last.bits + here.bits) <= bits) break;
                     PULLBYTE();                      PULLBYTE();
                 }                  }
                 DROPBITS(last.bits);                  DROPBITS(last.bits);
                   state->back += last.bits;
             }              }
            DROPBITS(this.bits);            DROPBITS(here.bits);
            state->length = (unsigned)this.val;            state->back += here.bits;
            if ((int)(this.op) == 0) {            state->length = (unsigned)here.val;
                Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ?            if ((int)(here.op) == 0) {
                 Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ?
                         "inflate:         literal '%c'\n" :                          "inflate:         literal '%c'\n" :
                        "inflate:         literal 0x%02x\n", this.val));                        "inflate:         literal 0x%02x\n", here.val));
                 state->mode = LIT;                  state->mode = LIT;
                 break;                  break;
             }              }
            if (this.op & 32) {            if (here.op & 32) {
                 Tracevv((stderr, "inflate:         end of block\n"));                  Tracevv((stderr, "inflate:         end of block\n"));
                   state->back = -1;
                 state->mode = TYPE;                  state->mode = TYPE;
                 break;                  break;
             }              }
            if (this.op & 64) {            if (here.op & 64) {
                 strm->msg = (char *)"invalid literal/length code";                  strm->msg = (char *)"invalid literal/length code";
                 state->mode = BAD;                  state->mode = BAD;
                 break;                  break;
             }              }
            state->extra = (unsigned)(this.op) & 15;            state->extra = (unsigned)(here.op) & 15;
             state->mode = LENEXT;              state->mode = LENEXT;
             /* FALL THROUGH */              /* FALL THROUGH */
         case LENEXT:          case LENEXT:
Line 1010  int flush; Line 1088  int flush;
                 NEEDBITS(state->extra);                  NEEDBITS(state->extra);
                 state->length += BITS(state->extra);                  state->length += BITS(state->extra);
                 DROPBITS(state->extra);                  DROPBITS(state->extra);
                   state->back += state->extra;
             }              }
             Tracevv((stderr, "inflate:         length %u\n", state->length));              Tracevv((stderr, "inflate:         length %u\n", state->length));
               state->was = state->length;
             state->mode = DIST;              state->mode = DIST;
             /* FALL THROUGH */              /* FALL THROUGH */
         case DIST:          case DIST:
             for (;;) {              for (;;) {
                this = state->distcode[BITS(state->distbits)];                here = state->distcode[BITS(state->distbits)];
                if ((unsigned)(this.bits) <= bits) break;                if ((unsigned)(here.bits) <= bits) break;
                 PULLBYTE();                  PULLBYTE();
             }              }
            if ((this.op & 0xf0) == 0) {            if ((here.op & 0xf0) == 0) {
                last = this;                last = here;
                 for (;;) {                  for (;;) {
                    this = state->distcode[last.val +                    here = state->distcode[last.val +
                             (BITS(last.bits + last.op) >> last.bits)];                              (BITS(last.bits + last.op) >> last.bits)];
                    if ((unsigned)(last.bits + this.bits) <= bits) break;                    if ((unsigned)(last.bits + here.bits) <= bits) break;
                     PULLBYTE();                      PULLBYTE();
                 }                  }
                 DROPBITS(last.bits);                  DROPBITS(last.bits);
                   state->back += last.bits;
             }              }
            DROPBITS(this.bits);            DROPBITS(here.bits);
            if (this.op & 64) {            state->back += here.bits;
             if (here.op & 64) {
                 strm->msg = (char *)"invalid distance code";                  strm->msg = (char *)"invalid distance code";
                 state->mode = BAD;                  state->mode = BAD;
                 break;                  break;
             }              }
            state->offset = (unsigned)this.val;            state->offset = (unsigned)here.val;
            state->extra = (unsigned)(this.op) & 15;            state->extra = (unsigned)(here.op) & 15;
             state->mode = DISTEXT;              state->mode = DISTEXT;
             /* FALL THROUGH */              /* FALL THROUGH */
         case DISTEXT:          case DISTEXT:
Line 1045  int flush; Line 1127  int flush;
                 NEEDBITS(state->extra);                  NEEDBITS(state->extra);
                 state->offset += BITS(state->extra);                  state->offset += BITS(state->extra);
                 DROPBITS(state->extra);                  DROPBITS(state->extra);
                   state->back += state->extra;
             }              }
 #ifdef INFLATE_STRICT  #ifdef INFLATE_STRICT
             if (state->offset > state->dmax) {              if (state->offset > state->dmax) {
Line 1053  int flush; Line 1136  int flush;
                 break;                  break;
             }              }
 #endif  #endif
             if (state->offset > state->whave + out - left) {  
                 strm->msg = (char *)"invalid distance too far back";  
                 state->mode = BAD;  
                 break;  
             }  
             Tracevv((stderr, "inflate:         distance %u\n", state->offset));              Tracevv((stderr, "inflate:         distance %u\n", state->offset));
             state->mode = MATCH;              state->mode = MATCH;
             /* FALL THROUGH */              /* FALL THROUGH */
Line 1066  int flush; Line 1144  int flush;
             copy = out - left;              copy = out - left;
             if (state->offset > copy) {         /* copy from window */              if (state->offset > copy) {         /* copy from window */
                 copy = state->offset - copy;                  copy = state->offset - copy;
                if (copy > state->write) {                if (copy > state->whave) {
                    copy -= state->write;                    if (state->sane) {
                         strm->msg = (char *)"invalid distance too far back";
                         state->mode = BAD;
                         break;
                     }
 #ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
                     Trace((stderr, "inflate.c too far\n"));
                     copy -= state->whave;
                     if (copy > state->length) copy = state->length;
                     if (copy > left) copy = left;
                     left -= copy;
                     state->length -= copy;
                     do {
                         *put++ = 0;
                     } while (--copy);
                     if (state->length == 0) state->mode = LEN;
                     break;
 #endif
                 }
                 if (copy > state->wnext) {
                     copy -= state->wnext;
                     from = state->window + (state->wsize - copy);                      from = state->window + (state->wsize - copy);
                 }                  }
                 else                  else
                    from = state->window + (state->write - copy);                    from = state->window + (state->wnext - copy);
                 if (copy > state->length) copy = state->length;                  if (copy > state->length) copy = state->length;
             }              }
             else {                              /* copy from output */              else {                              /* copy from output */
Line 1106  int flush; Line 1204  int flush;
 #ifdef GUNZIP  #ifdef GUNZIP
                      state->flags ? hold :                       state->flags ? hold :
 #endif  #endif
                     REVERSE(hold)) != state->check) {                     ZSWAP32(hold)) != state->check) {
                     strm->msg = (char *)"incorrect data check";                      strm->msg = (char *)"incorrect data check";
                     state->mode = BAD;                      state->mode = BAD;
                     break;                      break;
Line 1152  int flush; Line 1250  int flush;
      */       */
   inf_leave:    inf_leave:
     RESTORE();      RESTORE();
    if (state->wsize || (state->mode < CHECK && out != strm->avail_out))    if (state->wsize || (out != strm->avail_out && state->mode < BAD &&
        if (updatewindow(strm, out)) {            (state->mode < CHECK || flush != Z_FINISH)))
         if (updatewindow(strm, strm->next_out, out - strm->avail_out)) {
             state->mode = MEM;              state->mode = MEM;
             return Z_MEM_ERROR;              return Z_MEM_ERROR;
         }          }
Line 1166  int flush; Line 1265  int flush;
         strm->adler = state->check =          strm->adler = state->check =
             UPDATE(state->check, strm->next_out - out, out);              UPDATE(state->check, strm->next_out - out, out);
     strm->data_type = state->bits + (state->last ? 64 : 0) +      strm->data_type = state->bits + (state->last ? 64 : 0) +
                      (state->mode == TYPE ? 128 : 0);                      (state->mode == TYPE ? 128 : 0) +
                       (state->mode == LEN_ || state->mode == COPY_ ? 256 : 0);
     if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK)      if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK)
         ret = Z_BUF_ERROR;          ret = Z_BUF_ERROR;
     return ret;      return ret;
Line 1186  z_streamp strm; Line 1286  z_streamp strm;
     return Z_OK;      return Z_OK;
 }  }
   
   int ZEXPORT inflateGetDictionary(strm, dictionary, dictLength)
   z_streamp strm;
   Bytef *dictionary;
   uInt *dictLength;
   {
       struct inflate_state FAR *state;
   
       /* check state */
       if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
       state = (struct inflate_state FAR *)strm->state;
   
       /* copy dictionary */
       if (state->whave && dictionary != Z_NULL) {
           zmemcpy(dictionary, state->window + state->wnext,
                   state->whave - state->wnext);
           zmemcpy(dictionary + state->whave - state->wnext,
                   state->window, state->wnext);
       }
       if (dictLength != Z_NULL)
           *dictLength = state->whave;
       return Z_OK;
   }
   
 int ZEXPORT inflateSetDictionary(strm, dictionary, dictLength)  int ZEXPORT inflateSetDictionary(strm, dictionary, dictLength)
 z_streamp strm;  z_streamp strm;
 const Bytef *dictionary;  const Bytef *dictionary;
 uInt dictLength;  uInt dictLength;
 {  {
     struct inflate_state FAR *state;      struct inflate_state FAR *state;
    unsigned long id;    unsigned long dictid;
     int ret;
   
     /* check state */      /* check state */
     if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;      if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
Line 1200  uInt dictLength; Line 1324  uInt dictLength;
     if (state->wrap != 0 && state->mode != DICT)      if (state->wrap != 0 && state->mode != DICT)
         return Z_STREAM_ERROR;          return Z_STREAM_ERROR;
   
    /* check for correct dictionary id */    /* check for correct dictionary identifier */
     if (state->mode == DICT) {      if (state->mode == DICT) {
        id = adler32(0L, Z_NULL, 0);        dictid = adler32(0L, Z_NULL, 0);
        id = adler32(id, dictionary, dictLength);        dictid = adler32(dictid, dictionary, dictLength);
        if (id != state->check)        if (dictid != state->check)
             return Z_DATA_ERROR;              return Z_DATA_ERROR;
     }      }
   
    /* copy dictionary to window */    /* copy dictionary to window using updatewindow(), which will amend the
    if (updatewindow(strm, strm->avail_out)) {       existing dictionary if appropriate */
     ret = updatewindow(strm, dictionary + dictLength, dictLength);
     if (ret) {
         state->mode = MEM;          state->mode = MEM;
         return Z_MEM_ERROR;          return Z_MEM_ERROR;
     }      }
     if (dictLength > state->wsize) {  
         zmemcpy(state->window, dictionary + dictLength - state->wsize,  
                 state->wsize);  
         state->whave = state->wsize;  
     }  
     else {  
         zmemcpy(state->window + state->wsize - dictLength, dictionary,  
                 dictLength);  
         state->whave = dictLength;  
     }  
     state->havedict = 1;      state->havedict = 1;
     Tracev((stderr, "inflate:   dictionary set\n"));      Tracev((stderr, "inflate:   dictionary set\n"));
     return Z_OK;      return Z_OK;
Line 1258  gz_headerp head; Line 1374  gz_headerp head;
  */   */
 local unsigned syncsearch(have, buf, len)  local unsigned syncsearch(have, buf, len)
 unsigned FAR *have;  unsigned FAR *have;
unsigned char FAR *buf;const unsigned char FAR *buf;
 unsigned len;  unsigned len;
 {  {
     unsigned got;      unsigned got;
Line 1370  z_streamp source; Line 1486  z_streamp source;
     }      }
   
     /* copy state */      /* copy state */
    zmemcpy(dest, source, sizeof(z_stream));    zmemcpy((voidpf)dest, (voidpf)source, sizeof(z_stream));
    zmemcpy(copy, state, sizeof(struct inflate_state));    zmemcpy((voidpf)copy, (voidpf)state, sizeof(struct inflate_state));
     if (state->lencode >= state->codes &&      if (state->lencode >= state->codes &&
         state->lencode <= state->codes + ENOUGH - 1) {          state->lencode <= state->codes + ENOUGH - 1) {
         copy->lencode = copy->codes + (state->lencode - state->codes);          copy->lencode = copy->codes + (state->lencode - state->codes);
Line 1385  z_streamp source; Line 1501  z_streamp source;
     copy->window = window;      copy->window = window;
     dest->state = (struct internal_state FAR *)copy;      dest->state = (struct internal_state FAR *)copy;
     return Z_OK;      return Z_OK;
   }
   
   int ZEXPORT inflateUndermine(strm, subvert)
   z_streamp strm;
   int subvert;
   {
       struct inflate_state FAR *state;
   
       if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
       state = (struct inflate_state FAR *)strm->state;
       state->sane = !subvert;
   #ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
       return Z_OK;
   #else
       state->sane = 1;
       return Z_DATA_ERROR;
   #endif
   }
   
   long ZEXPORT inflateMark(strm)
   z_streamp strm;
   {
       struct inflate_state FAR *state;
   
       if (strm == Z_NULL || strm->state == Z_NULL) return -1L << 16;
       state = (struct inflate_state FAR *)strm->state;
       return ((long)(state->back) << 16) +
           (state->mode == COPY ? state->length :
               (state->mode == MATCH ? state->was - state->length : 0));
 }  }

Removed from v.1.1.1.1  
changed lines
  Added in v.1.1.1.2


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>