Changeset 23c71a8 in rtems


Ignore:
Timestamp:
Mar 18, 2011, 10:11:13 AM (9 years ago)
Author:
Ralf Corsepius <ralf.corsepius@…>
Branches:
4.11, master
Children:
e8f3eb9
Parents:
593898f
Message:

Import from zlib-1.2.4

File:
1 edited

Legend:

Unmodified
Added
Removed
  • cpukit/zlib/inflate.c

    r593898f r23c71a8  
    11/* inflate.c -- zlib decompression
    2  * Copyright (C) 1995-2005 Mark Adler
     2 * Copyright (C) 1995-2010 Mark Adler
    33 * For conditions of distribution and use, see copyright notice in zlib.h
    44 */
     
    4646 * - Unroll last copy for window match in inflate_fast()
    4747 * - Use local copies of window variables in inflate_fast() for speed
    48  * - Pull out common write == 0 case for speed in inflate_fast()
     48 * - Pull out common wnext == 0 case for speed in inflate_fast()
    4949 * - Make op and len in inflate_fast() unsigned for consistency
    5050 * - Add FAR to lcode and dcode declarations in inflate_fast()
     
    118118    state->wsize = 0;
    119119    state->whave = 0;
    120     state->write = 0;
     120    state->wnext = 0;
    121121    state->hold = 0;
    122122    state->bits = 0;
    123123    state->lencode = state->distcode = state->next = state->codes;
     124    state->sane = 1;
     125    state->back = -1;
    124126    Tracev((stderr, "inflate: reset\n"));
    125127    return Z_OK;
    126128}
    127129
    128 int ZEXPORT inflatePrime(strm, bits, value)
     130int ZEXPORT inflateReset2(strm, windowBits)
    129131z_streamp strm;
    130 int bits;
    131 int value;
    132 {
     132int windowBits;
     133{
     134    int wrap;
    133135    struct inflate_state FAR *state;
    134136
     137    /* get the state */
    135138    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
    136139    state = (struct inflate_state FAR *)strm->state;
    137     if (bits > 16 || state->bits + bits > 32) return Z_STREAM_ERROR;
    138     value &= (1L << bits) - 1;
    139     state->hold += value << state->bits;
    140     state->bits += bits;
    141     return Z_OK;
     140
     141    /* extract wrap request from windowBits parameter */
     142    if (windowBits < 0) {
     143        wrap = 0;
     144        windowBits = -windowBits;
     145    }
     146    else {
     147        wrap = (windowBits >> 4) + 1;
     148#ifdef GUNZIP
     149        if (windowBits < 48)
     150            windowBits &= 15;
     151#endif
     152    }
     153
     154    /* set number of window bits, free window if different */
     155    if (windowBits && (windowBits < 8 || windowBits > 15))
     156        return Z_STREAM_ERROR;
     157    if (state->window != Z_NULL && state->wbits != (unsigned)windowBits) {
     158        ZFREE(strm, state->window);
     159        state->window = Z_NULL;
     160    }
     161
     162    /* update state and reset the rest of it */
     163    state->wrap = wrap;
     164    state->wbits = (unsigned)windowBits;
     165    return inflateReset(strm);
    142166}
    143167
     
    148172int stream_size;
    149173{
     174    int ret;
    150175    struct inflate_state FAR *state;
    151176
     
    165190    Tracev((stderr, "inflate: allocated\n"));
    166191    strm->state = (struct internal_state FAR *)state;
    167     if (windowBits < 0) {
    168         state->wrap = 0;
    169         windowBits = -windowBits;
    170     }
    171     else {
    172         state->wrap = (windowBits >> 4) + 1;
    173 #ifdef GUNZIP
    174         if (windowBits < 48) windowBits &= 15;
    175 #endif
    176     }
    177     if (windowBits < 8 || windowBits > 15) {
     192    state->window = Z_NULL;
     193    ret = inflateReset2(strm, windowBits);
     194    if (ret != Z_OK) {
    178195        ZFREE(strm, state);
    179196        strm->state = Z_NULL;
    180         return Z_STREAM_ERROR;
    181     }
    182     state->wbits = (unsigned)windowBits;
    183     state->window = Z_NULL;
    184     return inflateReset(strm);
     197    }
     198    return ret;
    185199}
    186200
     
    191205{
    192206    return inflateInit2_(strm, DEF_WBITS, version, stream_size);
     207}
     208
     209int ZEXPORT inflatePrime(strm, bits, value)
     210z_streamp strm;
     211int bits;
     212int value;
     213{
     214    struct inflate_state FAR *state;
     215
     216    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
     217    state = (struct inflate_state FAR *)strm->state;
     218    if (bits < 0) {
     219        state->hold = 0;
     220        state->bits = 0;
     221        return Z_OK;
     222    }
     223    if (bits > 16 || state->bits + bits > 32) return Z_STREAM_ERROR;
     224    value &= (1L << bits) - 1;
     225    state->hold += value << state->bits;
     226    state->bits += bits;
     227    return Z_OK;
    193228}
    194229
     
    341376    if (state->wsize == 0) {
    342377        state->wsize = 1U << state->wbits;
    343         state->write = 0;
     378        state->wnext = 0;
    344379        state->whave = 0;
    345380    }
     
    349384    if (copy >= state->wsize) {
    350385        zmemcpy(state->window, strm->next_out - state->wsize, state->wsize);
    351         state->write = 0;
     386        state->wnext = 0;
    352387        state->whave = state->wsize;
    353388    }
    354389    else {
    355         dist = state->wsize - state->write;
     390        dist = state->wsize - state->wnext;
    356391        if (dist > copy) dist = copy;
    357         zmemcpy(state->window + state->write, strm->next_out - copy, dist);
     392        zmemcpy(state->window + state->wnext, strm->next_out - copy, dist);
    358393        copy -= dist;
    359394        if (copy) {
    360395            zmemcpy(state->window, strm->next_out - copy, copy);
    361             state->write = copy;
     396            state->wnext = copy;
    362397            state->whave = state->wsize;
    363398        }
    364399        else {
    365             state->write += dist;
    366             if (state->write == state->wsize) state->write = 0;
     400            state->wnext += dist;
     401            if (state->wnext == state->wsize) state->wnext = 0;
    367402            if (state->whave < state->wsize) state->whave += dist;
    368403        }
     
    565600    unsigned copy;              /* number of stored or match bytes to copy */
    566601    unsigned char FAR *from;    /* where to copy match bytes from */
    567     code this;                  /* current decoding table entry */
     602    code here;                  /* current decoding table entry */
    568603    code last;                  /* parent table entry */
    569604    unsigned len;               /* length to copy for repeats, bits to drop */
     
    620655            DROPBITS(4);
    621656            len = BITS(4) + 8;
    622             if (len > state->wbits) {
     657            if (state->wbits == 0)
     658                state->wbits = len;
     659            else if (len > state->wbits) {
    623660                strm->msg = (char *)"invalid window size";
    624661                state->mode = BAD;
     
    772809            state->mode = TYPE;
    773810        case TYPE:
    774             if (flush == Z_BLOCK) goto inf_leave;
     811            if (flush == Z_BLOCK || flush == Z_TREES) goto inf_leave;
    775812        case TYPEDO:
    776813            if (state->last) {
     
    792829                Tracev((stderr, "inflate:     fixed codes block%s\n",
    793830                        state->last ? " (last)" : ""));
    794                 state->mode = LEN;              /* decode codes */
     831                state->mode = LEN_;             /* decode codes */
     832                if (flush == Z_TREES) {
     833                    DROPBITS(2);
     834                    goto inf_leave;
     835                }
    795836                break;
    796837            case 2:                             /* dynamic block */
     
    817858                    state->length));
    818859            INITBITS();
     860            state->mode = COPY_;
     861            if (flush == Z_TREES) goto inf_leave;
     862        case COPY_:
    819863            state->mode = COPY;
    820864        case COPY:
     
    877921            while (state->have < state->nlen + state->ndist) {
    878922                for (;;) {
    879                     this = state->lencode[BITS(state->lenbits)];
    880                     if ((unsigned)(this.bits) <= bits) break;
     923                    here = state->lencode[BITS(state->lenbits)];
     924                    if ((unsigned)(here.bits) <= bits) break;
    881925                    PULLBYTE();
    882926                }
    883                 if (this.val < 16) {
    884                     NEEDBITS(this.bits);
    885                     DROPBITS(this.bits);
    886                     state->lens[state->have++] = this.val;
     927                if (here.val < 16) {
     928                    NEEDBITS(here.bits);
     929                    DROPBITS(here.bits);
     930                    state->lens[state->have++] = here.val;
    887931                }
    888932                else {
    889                     if (this.val == 16) {
    890                         NEEDBITS(this.bits + 2);
    891                         DROPBITS(this.bits);
     933                    if (here.val == 16) {
     934                        NEEDBITS(here.bits + 2);
     935                        DROPBITS(here.bits);
    892936                        if (state->have == 0) {
    893937                            strm->msg = (char *)"invalid bit length repeat";
     
    899943                        DROPBITS(2);
    900944                    }
    901                     else if (this.val == 17) {
    902                         NEEDBITS(this.bits + 3);
    903                         DROPBITS(this.bits);
     945                    else if (here.val == 17) {
     946                        NEEDBITS(here.bits + 3);
     947                        DROPBITS(here.bits);
    904948                        len = 0;
    905949                        copy = 3 + BITS(3);
     
    907951                    }
    908952                    else {
    909                         NEEDBITS(this.bits + 7);
    910                         DROPBITS(this.bits);
     953                        NEEDBITS(here.bits + 7);
     954                        DROPBITS(here.bits);
    911955                        len = 0;
    912956                        copy = 11 + BITS(7);
     
    926970            if (state->mode == BAD) break;
    927971
    928             /* build code tables */
     972            /* check for end-of-block code (better have one) */
     973            if (state->lens[256] == 0) {
     974                strm->msg = (char *)"invalid code -- missing end-of-block";
     975                state->mode = BAD;
     976                break;
     977            }
     978
     979            /* build code tables -- note: do not change the lenbits or distbits
     980               values here (9 and 6) without reading the comments in inftrees.h
     981               concerning the ENOUGH constants, which depend on those values */
    929982            state->next = state->codes;
    930983            state->lencode = (code const FAR *)(state->next);
     
    9471000            }
    9481001            Tracev((stderr, "inflate:       codes ok\n"));
     1002            state->mode = LEN_;
     1003            if (flush == Z_TREES) goto inf_leave;
     1004        case LEN_:
    9491005            state->mode = LEN;
    9501006        case LEN:
     
    9531009                inflate_fast(strm, out);
    9541010                LOAD();
    955                 break;
    956             }
     1011                if (state->mode == TYPE)
     1012                    state->back = -1;
     1013                break;
     1014            }
     1015            state->back = 0;
    9571016            for (;;) {
    958                 this = state->lencode[BITS(state->lenbits)];
    959                 if ((unsigned)(this.bits) <= bits) break;
     1017                here = state->lencode[BITS(state->lenbits)];
     1018                if ((unsigned)(here.bits) <= bits) break;
    9601019                PULLBYTE();
    9611020            }
    962             if (this.op && (this.op & 0xf0) == 0) {
    963                 last = this;
     1021            if (here.op && (here.op & 0xf0) == 0) {
     1022                last = here;
    9641023                for (;;) {
    965                     this = state->lencode[last.val +
     1024                    here = state->lencode[last.val +
    9661025                            (BITS(last.bits + last.op) >> last.bits)];
    967                     if ((unsigned)(last.bits + this.bits) <= bits) break;
     1026                    if ((unsigned)(last.bits + here.bits) <= bits) break;
    9681027                    PULLBYTE();
    9691028                }
    9701029                DROPBITS(last.bits);
    971             }
    972             DROPBITS(this.bits);
    973             state->length = (unsigned)this.val;
    974             if ((int)(this.op) == 0) {
    975                 Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ?
     1030                state->back += last.bits;
     1031            }
     1032            DROPBITS(here.bits);
     1033            state->back += here.bits;
     1034            state->length = (unsigned)here.val;
     1035            if ((int)(here.op) == 0) {
     1036                Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ?
    9761037                        "inflate:         literal '%c'\n" :
    977                         "inflate:         literal 0x%02x\n", this.val));
     1038                        "inflate:         literal 0x%02x\n", here.val));
    9781039                state->mode = LIT;
    9791040                break;
    9801041            }
    981             if (this.op & 32) {
     1042            if (here.op & 32) {
    9821043                Tracevv((stderr, "inflate:         end of block\n"));
     1044                state->back = -1;
    9831045                state->mode = TYPE;
    9841046                break;
    9851047            }
    986             if (this.op & 64) {
     1048            if (here.op & 64) {
    9871049                strm->msg = (char *)"invalid literal/length code";
    9881050                state->mode = BAD;
    9891051                break;
    9901052            }
    991             state->extra = (unsigned)(this.op) & 15;
     1053            state->extra = (unsigned)(here.op) & 15;
    9921054            state->mode = LENEXT;
    9931055        case LENEXT:
     
    9961058                state->length += BITS(state->extra);
    9971059                DROPBITS(state->extra);
     1060                state->back += state->extra;
    9981061            }
    9991062            Tracevv((stderr, "inflate:         length %u\n", state->length));
     1063            state->was = state->length;
    10001064            state->mode = DIST;
    10011065        case DIST:
    10021066            for (;;) {
    1003                 this = state->distcode[BITS(state->distbits)];
    1004                 if ((unsigned)(this.bits) <= bits) break;
     1067                here = state->distcode[BITS(state->distbits)];
     1068                if ((unsigned)(here.bits) <= bits) break;
    10051069                PULLBYTE();
    10061070            }
    1007             if ((this.op & 0xf0) == 0) {
    1008                 last = this;
     1071            if ((here.op & 0xf0) == 0) {
     1072                last = here;
    10091073                for (;;) {
    1010                     this = state->distcode[last.val +
     1074                    here = state->distcode[last.val +
    10111075                            (BITS(last.bits + last.op) >> last.bits)];
    1012                     if ((unsigned)(last.bits + this.bits) <= bits) break;
     1076                    if ((unsigned)(last.bits + here.bits) <= bits) break;
    10131077                    PULLBYTE();
    10141078                }
    10151079                DROPBITS(last.bits);
    1016             }
    1017             DROPBITS(this.bits);
    1018             if (this.op & 64) {
     1080                state->back += last.bits;
     1081            }
     1082            DROPBITS(here.bits);
     1083            state->back += here.bits;
     1084            if (here.op & 64) {
    10191085                strm->msg = (char *)"invalid distance code";
    10201086                state->mode = BAD;
    10211087                break;
    10221088            }
    1023             state->offset = (unsigned)this.val;
    1024             state->extra = (unsigned)(this.op) & 15;
     1089            state->offset = (unsigned)here.val;
     1090            state->extra = (unsigned)(here.op) & 15;
    10251091            state->mode = DISTEXT;
    10261092        case DISTEXT:
     
    10291095                state->offset += BITS(state->extra);
    10301096                DROPBITS(state->extra);
     1097                state->back += state->extra;
    10311098            }
    10321099#ifdef INFLATE_STRICT
     
    10371104            }
    10381105#endif
    1039             if (state->offset > state->whave + out - left) {
    1040                 strm->msg = (char *)"invalid distance too far back";
    1041                 state->mode = BAD;
    1042                 break;
    1043             }
    10441106            Tracevv((stderr, "inflate:         distance %u\n", state->offset));
    10451107            state->mode = MATCH;
     
    10491111            if (state->offset > copy) {         /* copy from window */
    10501112                copy = state->offset - copy;
    1051                 if (copy > state->write) {
    1052                     copy -= state->write;
     1113                if (copy > state->whave) {
     1114                    if (state->sane) {
     1115                        strm->msg = (char *)"invalid distance too far back";
     1116                        state->mode = BAD;
     1117                        break;
     1118                    }
     1119#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
     1120                    Trace((stderr, "inflate.c too far\n"));
     1121                    copy -= state->whave;
     1122                    if (copy > state->length) copy = state->length;
     1123                    if (copy > left) copy = left;
     1124                    left -= copy;
     1125                    state->length -= copy;
     1126                    do {
     1127                        *put++ = 0;
     1128                    } while (--copy);
     1129                    if (state->length == 0) state->mode = LEN;
     1130                    break;
     1131#endif
     1132                }
     1133                if (copy > state->wnext) {
     1134                    copy -= state->wnext;
    10531135                    from = state->window + (state->wsize - copy);
    10541136                }
    10551137                else
    1056                     from = state->window + (state->write - copy);
     1138                    from = state->window + (state->wnext - copy);
    10571139                if (copy > state->length) copy = state->length;
    10581140            }
     
    11471229            UPDATE(state->check, strm->next_out - out, out);
    11481230    strm->data_type = state->bits + (state->last ? 64 : 0) +
    1149                       (state->mode == TYPE ? 128 : 0);
     1231                      (state->mode == TYPE ? 128 : 0) +
     1232                      (state->mode == LEN_ || state->mode == COPY_ ? 256 : 0);
    11501233    if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK)
    11511234        ret = Z_BUF_ERROR;
     
    13671450    return Z_OK;
    13681451}
     1452
     1453int ZEXPORT inflateUndermine(strm, subvert)
     1454z_streamp strm;
     1455int subvert;
     1456{
     1457    struct inflate_state FAR *state;
     1458
     1459    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
     1460    state = (struct inflate_state FAR *)strm->state;
     1461    state->sane = !subvert;
     1462#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
     1463    return Z_OK;
     1464#else
     1465    state->sane = 1;
     1466    return Z_DATA_ERROR;
     1467#endif
     1468}
     1469
     1470long ZEXPORT inflateMark(strm)
     1471z_streamp strm;
     1472{
     1473    struct inflate_state FAR *state;
     1474
     1475    if (strm == Z_NULL || strm->state == Z_NULL) return -1L << 16;
     1476    state = (struct inflate_state FAR *)strm->state;
     1477    return ((long)(state->back) << 16) +
     1478        (state->mode == COPY ? state->length :
     1479            (state->mode == MATCH ? state->was - state->length : 0));
     1480}
Note: See TracChangeset for help on using the changeset viewer.