Path: blob/master/src/java.base/share/native/libzip/zlib/inflate.c
41153 views
/*1* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.2*3* This code is free software; you can redistribute it and/or modify it4* under the terms of the GNU General Public License version 2 only, as5* published by the Free Software Foundation. Oracle designates this6* particular file as subject to the "Classpath" exception as provided7* by Oracle in the LICENSE file that accompanied this code.8*9* This code is distributed in the hope that it will be useful, but WITHOUT10* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or11* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License12* version 2 for more details (a copy is included in the LICENSE file that13* accompanied this code).14*15* You should have received a copy of the GNU General Public License version16* 2 along with this work; if not, write to the Free Software Foundation,17* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.18*19* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA20* or visit www.oracle.com if you need additional information or have any21* questions.22*/2324/* inflate.c -- zlib decompression25* Copyright (C) 1995-2016 Mark Adler26* For conditions of distribution and use, see copyright notice in zlib.h27*/2829/*30* Change history:31*32* 1.2.beta0 24 Nov 200233* - First version -- complete rewrite of inflate to simplify code, avoid34* creation of window when not needed, minimize use of window when it is35* needed, make inffast.c even faster, implement gzip decoding, and to36* improve code readability and style over the previous zlib inflate code37*38* 1.2.beta1 25 Nov 200239* - Use pointers for available input and output checking in inffast.c40* - Remove input and output counters in inffast.c41* - Change inffast.c entry and loop from avail_in >= 7 to >= 642* - Remove unnecessary second byte pull from length extra in inffast.c43* - Unroll direct copy to three copies per loop in inffast.c44*45* 1.2.beta2 4 Dec 200246* - Change external routine names to reduce potential conflicts47* - Correct filename to inffixed.h for fixed tables in inflate.c48* - Make hbuf[] unsigned char to match parameter type in inflate.c49* - Change strm->next_out[-state->offset] to *(strm->next_out - state->offset)50* to avoid negation problem on Alphas (64 bit) in inflate.c51*52* 1.2.beta3 22 Dec 200253* - Add comments on state->bits assertion in inffast.c54* - Add comments on op field in inftrees.h55* - Fix bug in reuse of allocated window after inflateReset()56* - Remove bit fields--back to byte structure for speed57* - Remove distance extra == 0 check in inflate_fast()--only helps for lengths58* - Change post-increments to pre-increments in inflate_fast(), PPC biased?59* - Add compile time option, POSTINC, to use post-increments instead (Intel?)60* - Make MATCH copy in inflate() much faster for when inflate_fast() not used61* - Use local copies of stream next and avail values, as well as local bit62* buffer and bit count in inflate()--for speed when inflate_fast() not used63*64* 1.2.beta4 1 Jan 200365* - Split ptr - 257 statements in inflate_table() to avoid compiler warnings66* - Move a comment on output buffer sizes from inffast.c to inflate.c67* - Add comments in inffast.c to introduce the inflate_fast() routine68* - Rearrange window copies in inflate_fast() for speed and simplification69* - Unroll last copy for window match in inflate_fast()70* - Use local copies of window variables in inflate_fast() for speed71* - Pull out common wnext == 0 case for speed in inflate_fast()72* - Make op and len in inflate_fast() unsigned for consistency73* - Add FAR to lcode and dcode declarations in inflate_fast()74* - Simplified bad distance check in inflate_fast()75* - Added inflateBackInit(), inflateBack(), and inflateBackEnd() in new76* source file infback.c to provide a call-back interface to inflate for77* programs like gzip and unzip -- uses window as output buffer to avoid78* window copying79*80* 1.2.beta5 1 Jan 200381* - Improved inflateBack() interface to allow the caller to provide initial82* input in strm.83* - Fixed stored blocks bug in inflateBack()84*85* 1.2.beta6 4 Jan 200386* - Added comments in inffast.c on effectiveness of POSTINC87* - Typecasting all around to reduce compiler warnings88* - Changed loops from while (1) or do {} while (1) to for (;;), again to89* make compilers happy90* - Changed type of window in inflateBackInit() to unsigned char *91*92* 1.2.beta7 27 Jan 200393* - Changed many types to unsigned or unsigned short to avoid warnings94* - Added inflateCopy() function95*96* 1.2.0 9 Mar 200397* - Changed inflateBack() interface to provide separate opaque descriptors98* for the in() and out() functions99* - Changed inflateBack() argument and in_func typedef to swap the length100* and buffer address return values for the input function101* - Check next_in and next_out for Z_NULL on entry to inflate()102*103* The history for versions after 1.2.0 are in ChangeLog in zlib distribution.104*/105106#include "zutil.h"107#include "inftrees.h"108#include "inflate.h"109#include "inffast.h"110111#ifdef MAKEFIXED112# ifndef BUILDFIXED113# define BUILDFIXED114# endif115#endif116117/* function prototypes */118local int inflateStateCheck OF((z_streamp strm));119local void fixedtables OF((struct inflate_state FAR *state));120local int updatewindow OF((z_streamp strm, const unsigned char FAR *end,121unsigned copy));122#ifdef BUILDFIXED123void makefixed OF((void));124#endif125local unsigned syncsearch OF((unsigned FAR *have, const unsigned char FAR *buf,126unsigned len));127128local int inflateStateCheck(strm)129z_streamp strm;130{131struct inflate_state FAR *state;132if (strm == Z_NULL ||133strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0)134return 1;135state = (struct inflate_state FAR *)strm->state;136if (state == Z_NULL || state->strm != strm ||137state->mode < HEAD || state->mode > SYNC)138return 1;139return 0;140}141142int ZEXPORT inflateResetKeep(strm)143z_streamp strm;144{145struct inflate_state FAR *state;146147if (inflateStateCheck(strm)) return Z_STREAM_ERROR;148state = (struct inflate_state FAR *)strm->state;149strm->total_in = strm->total_out = state->total = 0;150strm->msg = Z_NULL;151if (state->wrap) /* to support ill-conceived Java test suite */152strm->adler = state->wrap & 1;153state->mode = HEAD;154state->last = 0;155state->havedict = 0;156state->dmax = 32768U;157state->head = Z_NULL;158state->hold = 0;159state->bits = 0;160state->lencode = state->distcode = state->next = state->codes;161state->sane = 1;162state->back = -1;163Tracev((stderr, "inflate: reset\n"));164return Z_OK;165}166167int ZEXPORT inflateReset(strm)168z_streamp strm;169{170struct inflate_state FAR *state;171172if (inflateStateCheck(strm)) return Z_STREAM_ERROR;173state = (struct inflate_state FAR *)strm->state;174state->wsize = 0;175state->whave = 0;176state->wnext = 0;177return inflateResetKeep(strm);178}179180int ZEXPORT inflateReset2(strm, windowBits)181z_streamp strm;182int windowBits;183{184int wrap;185struct inflate_state FAR *state;186187/* get the state */188if (inflateStateCheck(strm)) return Z_STREAM_ERROR;189state = (struct inflate_state FAR *)strm->state;190191/* extract wrap request from windowBits parameter */192if (windowBits < 0) {193wrap = 0;194windowBits = -windowBits;195}196else {197wrap = (windowBits >> 4) + 5;198#ifdef GUNZIP199if (windowBits < 48)200windowBits &= 15;201#endif202}203204/* set number of window bits, free window if different */205if (windowBits && (windowBits < 8 || windowBits > 15))206return Z_STREAM_ERROR;207if (state->window != Z_NULL && state->wbits != (unsigned)windowBits) {208ZFREE(strm, state->window);209state->window = Z_NULL;210}211212/* update state and reset the rest of it */213state->wrap = wrap;214state->wbits = (unsigned)windowBits;215return inflateReset(strm);216}217218int ZEXPORT inflateInit2_(strm, windowBits, version, stream_size)219z_streamp strm;220int windowBits;221const char *version;222int stream_size;223{224int ret;225struct inflate_state FAR *state;226227if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||228stream_size != (int)(sizeof(z_stream)))229return Z_VERSION_ERROR;230if (strm == Z_NULL) return Z_STREAM_ERROR;231strm->msg = Z_NULL; /* in case we return an error */232if (strm->zalloc == (alloc_func)0) {233#ifdef Z_SOLO234return Z_STREAM_ERROR;235#else236strm->zalloc = zcalloc;237strm->opaque = (voidpf)0;238#endif239}240if (strm->zfree == (free_func)0)241#ifdef Z_SOLO242return Z_STREAM_ERROR;243#else244strm->zfree = zcfree;245#endif246state = (struct inflate_state FAR *)247ZALLOC(strm, 1, sizeof(struct inflate_state));248if (state == Z_NULL) return Z_MEM_ERROR;249Tracev((stderr, "inflate: allocated\n"));250strm->state = (struct internal_state FAR *)state;251state->strm = strm;252state->window = Z_NULL;253state->mode = HEAD; /* to pass state test in inflateReset2() */254ret = inflateReset2(strm, windowBits);255if (ret != Z_OK) {256ZFREE(strm, state);257strm->state = Z_NULL;258}259return ret;260}261262int ZEXPORT inflateInit_(strm, version, stream_size)263z_streamp strm;264const char *version;265int stream_size;266{267return inflateInit2_(strm, DEF_WBITS, version, stream_size);268}269270int ZEXPORT inflatePrime(strm, bits, value)271z_streamp strm;272int bits;273int value;274{275struct inflate_state FAR *state;276277if (inflateStateCheck(strm)) return Z_STREAM_ERROR;278state = (struct inflate_state FAR *)strm->state;279if (bits < 0) {280state->hold = 0;281state->bits = 0;282return Z_OK;283}284if (bits > 16 || state->bits + (uInt)bits > 32) return Z_STREAM_ERROR;285value &= (1L << bits) - 1;286state->hold += (unsigned)value << state->bits;287state->bits += (uInt)bits;288return Z_OK;289}290291/*292Return state with length and distance decoding tables and index sizes set to293fixed code decoding. Normally this returns fixed tables from inffixed.h.294If BUILDFIXED is defined, then instead this routine builds the tables the295first time it's called, and returns those tables the first time and296thereafter. This reduces the size of the code by about 2K bytes, in297exchange for a little execution time. However, BUILDFIXED should not be298used for threaded applications, since the rewriting of the tables and virgin299may not be thread-safe.300*/301local void fixedtables(state)302struct inflate_state FAR *state;303{304#ifdef BUILDFIXED305static int virgin = 1;306static code *lenfix, *distfix;307static code fixed[544];308309/* build fixed huffman tables if first call (may not be thread safe) */310if (virgin) {311unsigned sym, bits;312static code *next;313314/* literal/length table */315sym = 0;316while (sym < 144) state->lens[sym++] = 8;317while (sym < 256) state->lens[sym++] = 9;318while (sym < 280) state->lens[sym++] = 7;319while (sym < 288) state->lens[sym++] = 8;320next = fixed;321lenfix = next;322bits = 9;323inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work);324325/* distance table */326sym = 0;327while (sym < 32) state->lens[sym++] = 5;328distfix = next;329bits = 5;330inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work);331332/* do this just once */333virgin = 0;334}335#else /* !BUILDFIXED */336# include "inffixed.h"337#endif /* BUILDFIXED */338state->lencode = lenfix;339state->lenbits = 9;340state->distcode = distfix;341state->distbits = 5;342}343344#ifdef MAKEFIXED345#include <stdio.h>346347/*348Write out the inffixed.h that is #include'd above. Defining MAKEFIXED also349defines BUILDFIXED, so the tables are built on the fly. makefixed() writes350those tables to stdout, which would be piped to inffixed.h. A small program351can simply call makefixed to do this:352353void makefixed(void);354355int main(void)356{357makefixed();358return 0;359}360361Then that can be linked with zlib built with MAKEFIXED defined and run:362363a.out > inffixed.h364*/365void makefixed()366{367unsigned low, size;368struct inflate_state state;369370fixedtables(&state);371puts(" /* inffixed.h -- table for decoding fixed codes");372puts(" * Generated automatically by makefixed().");373puts(" */");374puts("");375puts(" /* WARNING: this file should *not* be used by applications.");376puts(" It is part of the implementation of this library and is");377puts(" subject to change. Applications should only use zlib.h.");378puts(" */");379puts("");380size = 1U << 9;381printf(" static const code lenfix[%u] = {", size);382low = 0;383for (;;) {384if ((low % 7) == 0) printf("\n ");385printf("{%u,%u,%d}", (low & 127) == 99 ? 64 : state.lencode[low].op,386state.lencode[low].bits, state.lencode[low].val);387if (++low == size) break;388putchar(',');389}390puts("\n };");391size = 1U << 5;392printf("\n static const code distfix[%u] = {", size);393low = 0;394for (;;) {395if ((low % 6) == 0) printf("\n ");396printf("{%u,%u,%d}", state.distcode[low].op, state.distcode[low].bits,397state.distcode[low].val);398if (++low == size) break;399putchar(',');400}401puts("\n };");402}403#endif /* MAKEFIXED */404405/*406Update the window with the last wsize (normally 32K) bytes written before407returning. If window does not exist yet, create it. This is only called408when a window is already in use, or when output has been written during this409inflate call, but the end of the deflate stream has not been reached yet.410It is also called to create a window for dictionary data when a dictionary411is loaded.412413Providing output buffers larger than 32K to inflate() should provide a speed414advantage, since only the last 32K of output is copied to the sliding window415upon return from inflate(), and since all distances after the first 32K of416output will fall in the output data, making match copies simpler and faster.417The advantage may be dependent on the size of the processor's data caches.418*/419local int updatewindow(strm, end, copy)420z_streamp strm;421const Bytef *end;422unsigned copy;423{424struct inflate_state FAR *state;425unsigned dist;426427state = (struct inflate_state FAR *)strm->state;428429/* if it hasn't been done already, allocate space for the window */430if (state->window == Z_NULL) {431state->window = (unsigned char FAR *)432ZALLOC(strm, 1U << state->wbits,433sizeof(unsigned char));434if (state->window == Z_NULL) return 1;435}436437/* if window not in use yet, initialize */438if (state->wsize == 0) {439state->wsize = 1U << state->wbits;440state->wnext = 0;441state->whave = 0;442}443444/* copy state->wsize or less output bytes into the circular window */445if (copy >= state->wsize) {446zmemcpy(state->window, end - state->wsize, state->wsize);447state->wnext = 0;448state->whave = state->wsize;449}450else {451dist = state->wsize - state->wnext;452if (dist > copy) dist = copy;453zmemcpy(state->window + state->wnext, end - copy, dist);454copy -= dist;455if (copy) {456zmemcpy(state->window, end - copy, copy);457state->wnext = copy;458state->whave = state->wsize;459}460else {461state->wnext += dist;462if (state->wnext == state->wsize) state->wnext = 0;463if (state->whave < state->wsize) state->whave += dist;464}465}466return 0;467}468469/* Macros for inflate(): */470471/* check function to use adler32() for zlib or crc32() for gzip */472#ifdef GUNZIP473# define UPDATE(check, buf, len) \474(state->flags ? crc32(check, buf, len) : adler32(check, buf, len))475#else476# define UPDATE(check, buf, len) adler32(check, buf, len)477#endif478479/* check macros for header crc */480#ifdef GUNZIP481# define CRC2(check, word) \482do { \483hbuf[0] = (unsigned char)(word); \484hbuf[1] = (unsigned char)((word) >> 8); \485check = crc32(check, hbuf, 2); \486} while (0)487488# define CRC4(check, word) \489do { \490hbuf[0] = (unsigned char)(word); \491hbuf[1] = (unsigned char)((word) >> 8); \492hbuf[2] = (unsigned char)((word) >> 16); \493hbuf[3] = (unsigned char)((word) >> 24); \494check = crc32(check, hbuf, 4); \495} while (0)496#endif497498/* Load registers with state in inflate() for speed */499#define LOAD() \500do { \501put = strm->next_out; \502left = strm->avail_out; \503next = strm->next_in; \504have = strm->avail_in; \505hold = state->hold; \506bits = state->bits; \507} while (0)508509/* Restore state from registers in inflate() */510#define RESTORE() \511do { \512strm->next_out = put; \513strm->avail_out = left; \514strm->next_in = next; \515strm->avail_in = have; \516state->hold = hold; \517state->bits = bits; \518} while (0)519520/* Clear the input bit accumulator */521#define INITBITS() \522do { \523hold = 0; \524bits = 0; \525} while (0)526527/* Get a byte of input into the bit accumulator, or return from inflate()528if there is no input available. */529#define PULLBYTE() \530do { \531if (have == 0) goto inf_leave; \532have--; \533hold += (unsigned long)(*next++) << bits; \534bits += 8; \535} while (0)536537/* Assure that there are at least n bits in the bit accumulator. If there is538not enough available input to do that, then return from inflate(). */539#define NEEDBITS(n) \540do { \541while (bits < (unsigned)(n)) \542PULLBYTE(); \543} while (0)544545/* Return the low n bits of the bit accumulator (n < 16) */546#define BITS(n) \547((unsigned)hold & ((1U << (n)) - 1))548549/* Remove n bits from the bit accumulator */550#define DROPBITS(n) \551do { \552hold >>= (n); \553bits -= (unsigned)(n); \554} while (0)555556/* Remove zero to seven bits as needed to go to a byte boundary */557#define BYTEBITS() \558do { \559hold >>= bits & 7; \560bits -= bits & 7; \561} while (0)562563/*564inflate() uses a state machine to process as much input data and generate as565much output data as possible before returning. The state machine is566structured roughly as follows:567568for (;;) switch (state) {569...570case STATEn:571if (not enough input data or output space to make progress)572return;573... make progress ...574state = STATEm;575break;576...577}578579so when inflate() is called again, the same case is attempted again, and580if the appropriate resources are provided, the machine proceeds to the581next state. The NEEDBITS() macro is usually the way the state evaluates582whether it can proceed or should return. NEEDBITS() does the return if583the requested bits are not available. The typical use of the BITS macros584is:585586NEEDBITS(n);587... do something with BITS(n) ...588DROPBITS(n);589590where NEEDBITS(n) either returns from inflate() if there isn't enough591input left to load n bits into the accumulator, or it continues. BITS(n)592gives the low n bits in the accumulator. When done, DROPBITS(n) drops593the low n bits off the accumulator. INITBITS() clears the accumulator594and sets the number of available bits to zero. BYTEBITS() discards just595enough bits to put the accumulator on a byte boundary. After BYTEBITS()596and a NEEDBITS(8), then BITS(8) would return the next byte in the stream.597598NEEDBITS(n) uses PULLBYTE() to get an available byte of input, or to return599if there is no input available. The decoding of variable length codes uses600PULLBYTE() directly in order to pull just enough bytes to decode the next601code, and no more.602603Some states loop until they get enough input, making sure that enough604state information is maintained to continue the loop where it left off605if NEEDBITS() returns in the loop. For example, want, need, and keep606would all have to actually be part of the saved state in case NEEDBITS()607returns:608609case STATEw:610while (want < need) {611NEEDBITS(n);612keep[want++] = BITS(n);613DROPBITS(n);614}615state = STATEx;616case STATEx:617618As shown above, if the next state is also the next case, then the break619is omitted.620621A state may also return if there is not enough output space available to622complete that state. Those states are copying stored data, writing a623literal byte, and copying a matching string.624625When returning, a "goto inf_leave" is used to update the total counters,626update the check value, and determine whether any progress has been made627during that inflate() call in order to return the proper return code.628Progress is defined as a change in either strm->avail_in or strm->avail_out.629When there is a window, goto inf_leave will update the window with the last630output written. If a goto inf_leave occurs in the middle of decompression631and there is no window currently, goto inf_leave will create one and copy632output to the window for the next call of inflate().633634In this implementation, the flush parameter of inflate() only affects the635return code (per zlib.h). inflate() always writes as much as possible to636strm->next_out, given the space available and the provided input--the effect637documented in zlib.h of Z_SYNC_FLUSH. Furthermore, inflate() always defers638the allocation of and copying into a sliding window until necessary, which639provides the effect documented in zlib.h for Z_FINISH when the entire input640stream available. So the only thing the flush parameter actually does is:641when flush is set to Z_FINISH, inflate() cannot return Z_OK. Instead it642will return Z_BUF_ERROR if it has not reached the end of the stream.643*/644645int ZEXPORT inflate(strm, flush)646z_streamp strm;647int flush;648{649struct inflate_state FAR *state;650z_const unsigned char FAR *next; /* next input */651unsigned char FAR *put; /* next output */652unsigned have, left; /* available input and output */653unsigned long hold; /* bit buffer */654unsigned bits; /* bits in bit buffer */655unsigned in, out; /* save starting available input and output */656unsigned copy; /* number of stored or match bytes to copy */657unsigned char FAR *from; /* where to copy match bytes from */658code here; /* current decoding table entry */659code last; /* parent table entry */660unsigned len; /* length to copy for repeats, bits to drop */661int ret; /* return code */662#ifdef GUNZIP663unsigned char hbuf[4]; /* buffer for gzip header crc calculation */664#endif665static const unsigned short order[19] = /* permutation of code lengths */666{16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};667668if (inflateStateCheck(strm) || strm->next_out == Z_NULL ||669(strm->next_in == Z_NULL && strm->avail_in != 0))670return Z_STREAM_ERROR;671672state = (struct inflate_state FAR *)strm->state;673if (state->mode == TYPE) state->mode = TYPEDO; /* skip check */674LOAD();675in = have;676out = left;677ret = Z_OK;678for (;;)679switch (state->mode) {680case HEAD:681if (state->wrap == 0) {682state->mode = TYPEDO;683break;684}685NEEDBITS(16);686#ifdef GUNZIP687if ((state->wrap & 2) && hold == 0x8b1f) { /* gzip header */688if (state->wbits == 0)689state->wbits = 15;690state->check = crc32(0L, Z_NULL, 0);691CRC2(state->check, hold);692INITBITS();693state->mode = FLAGS;694break;695}696state->flags = 0; /* expect zlib header */697if (state->head != Z_NULL)698state->head->done = -1;699if (!(state->wrap & 1) || /* check if zlib header allowed */700#else701if (702#endif703((BITS(8) << 8) + (hold >> 8)) % 31) {704strm->msg = (char *)"incorrect header check";705state->mode = BAD;706break;707}708if (BITS(4) != Z_DEFLATED) {709strm->msg = (char *)"unknown compression method";710state->mode = BAD;711break;712}713DROPBITS(4);714len = BITS(4) + 8;715if (state->wbits == 0)716state->wbits = len;717if (len > 15 || len > state->wbits) {718strm->msg = (char *)"invalid window size";719state->mode = BAD;720break;721}722state->dmax = 1U << len;723Tracev((stderr, "inflate: zlib header ok\n"));724strm->adler = state->check = adler32(0L, Z_NULL, 0);725state->mode = hold & 0x200 ? DICTID : TYPE;726INITBITS();727break;728#ifdef GUNZIP729case FLAGS:730NEEDBITS(16);731state->flags = (int)(hold);732if ((state->flags & 0xff) != Z_DEFLATED) {733strm->msg = (char *)"unknown compression method";734state->mode = BAD;735break;736}737if (state->flags & 0xe000) {738strm->msg = (char *)"unknown header flags set";739state->mode = BAD;740break;741}742if (state->head != Z_NULL)743state->head->text = (int)((hold >> 8) & 1);744if ((state->flags & 0x0200) && (state->wrap & 4))745CRC2(state->check, hold);746INITBITS();747state->mode = TIME;748case TIME:749NEEDBITS(32);750if (state->head != Z_NULL)751state->head->time = hold;752if ((state->flags & 0x0200) && (state->wrap & 4))753CRC4(state->check, hold);754INITBITS();755state->mode = OS;756case OS:757NEEDBITS(16);758if (state->head != Z_NULL) {759state->head->xflags = (int)(hold & 0xff);760state->head->os = (int)(hold >> 8);761}762if ((state->flags & 0x0200) && (state->wrap & 4))763CRC2(state->check, hold);764INITBITS();765state->mode = EXLEN;766case EXLEN:767if (state->flags & 0x0400) {768NEEDBITS(16);769state->length = (unsigned)(hold);770if (state->head != Z_NULL)771state->head->extra_len = (unsigned)hold;772if ((state->flags & 0x0200) && (state->wrap & 4))773CRC2(state->check, hold);774INITBITS();775}776else if (state->head != Z_NULL)777state->head->extra = Z_NULL;778state->mode = EXTRA;779case EXTRA:780if (state->flags & 0x0400) {781copy = state->length;782if (copy > have) copy = have;783if (copy) {784if (state->head != Z_NULL &&785state->head->extra != Z_NULL) {786len = state->head->extra_len - state->length;787zmemcpy(state->head->extra + len, next,788len + copy > state->head->extra_max ?789state->head->extra_max - len : copy);790}791if ((state->flags & 0x0200) && (state->wrap & 4))792state->check = crc32(state->check, next, copy);793have -= copy;794next += copy;795state->length -= copy;796}797if (state->length) goto inf_leave;798}799state->length = 0;800state->mode = NAME;801case NAME:802if (state->flags & 0x0800) {803if (have == 0) goto inf_leave;804copy = 0;805do {806len = (unsigned)(next[copy++]);807if (state->head != Z_NULL &&808state->head->name != Z_NULL &&809state->length < state->head->name_max)810state->head->name[state->length++] = (Bytef)len;811} while (len && copy < have);812if ((state->flags & 0x0200) && (state->wrap & 4))813state->check = crc32(state->check, next, copy);814have -= copy;815next += copy;816if (len) goto inf_leave;817}818else if (state->head != Z_NULL)819state->head->name = Z_NULL;820state->length = 0;821state->mode = COMMENT;822case COMMENT:823if (state->flags & 0x1000) {824if (have == 0) goto inf_leave;825copy = 0;826do {827len = (unsigned)(next[copy++]);828if (state->head != Z_NULL &&829state->head->comment != Z_NULL &&830state->length < state->head->comm_max)831state->head->comment[state->length++] = (Bytef)len;832} while (len && copy < have);833if ((state->flags & 0x0200) && (state->wrap & 4))834state->check = crc32(state->check, next, copy);835have -= copy;836next += copy;837if (len) goto inf_leave;838}839else if (state->head != Z_NULL)840state->head->comment = Z_NULL;841state->mode = HCRC;842case HCRC:843if (state->flags & 0x0200) {844NEEDBITS(16);845if ((state->wrap & 4) && hold != (state->check & 0xffff)) {846strm->msg = (char *)"header crc mismatch";847state->mode = BAD;848break;849}850INITBITS();851}852if (state->head != Z_NULL) {853state->head->hcrc = (int)((state->flags >> 9) & 1);854state->head->done = 1;855}856strm->adler = state->check = crc32(0L, Z_NULL, 0);857state->mode = TYPE;858break;859#endif860case DICTID:861NEEDBITS(32);862strm->adler = state->check = ZSWAP32(hold);863INITBITS();864state->mode = DICT;865case DICT:866if (state->havedict == 0) {867RESTORE();868return Z_NEED_DICT;869}870strm->adler = state->check = adler32(0L, Z_NULL, 0);871state->mode = TYPE;872case TYPE:873if (flush == Z_BLOCK || flush == Z_TREES) goto inf_leave;874case TYPEDO:875if (state->last) {876BYTEBITS();877state->mode = CHECK;878break;879}880NEEDBITS(3);881state->last = BITS(1);882DROPBITS(1);883switch (BITS(2)) {884case 0: /* stored block */885Tracev((stderr, "inflate: stored block%s\n",886state->last ? " (last)" : ""));887state->mode = STORED;888break;889case 1: /* fixed block */890fixedtables(state);891Tracev((stderr, "inflate: fixed codes block%s\n",892state->last ? " (last)" : ""));893state->mode = LEN_; /* decode codes */894if (flush == Z_TREES) {895DROPBITS(2);896goto inf_leave;897}898break;899case 2: /* dynamic block */900Tracev((stderr, "inflate: dynamic codes block%s\n",901state->last ? " (last)" : ""));902state->mode = TABLE;903break;904case 3:905strm->msg = (char *)"invalid block type";906state->mode = BAD;907}908DROPBITS(2);909break;910case STORED:911BYTEBITS(); /* go to byte boundary */912NEEDBITS(32);913if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) {914strm->msg = (char *)"invalid stored block lengths";915state->mode = BAD;916break;917}918state->length = (unsigned)hold & 0xffff;919Tracev((stderr, "inflate: stored length %u\n",920state->length));921INITBITS();922state->mode = COPY_;923if (flush == Z_TREES) goto inf_leave;924case COPY_:925state->mode = COPY;926case COPY:927copy = state->length;928if (copy) {929if (copy > have) copy = have;930if (copy > left) copy = left;931if (copy == 0) goto inf_leave;932zmemcpy(put, next, copy);933have -= copy;934next += copy;935left -= copy;936put += copy;937state->length -= copy;938break;939}940Tracev((stderr, "inflate: stored end\n"));941state->mode = TYPE;942break;943case TABLE:944NEEDBITS(14);945state->nlen = BITS(5) + 257;946DROPBITS(5);947state->ndist = BITS(5) + 1;948DROPBITS(5);949state->ncode = BITS(4) + 4;950DROPBITS(4);951#ifndef PKZIP_BUG_WORKAROUND952if (state->nlen > 286 || state->ndist > 30) {953strm->msg = (char *)"too many length or distance symbols";954state->mode = BAD;955break;956}957#endif958Tracev((stderr, "inflate: table sizes ok\n"));959state->have = 0;960state->mode = LENLENS;961case LENLENS:962while (state->have < state->ncode) {963NEEDBITS(3);964state->lens[order[state->have++]] = (unsigned short)BITS(3);965DROPBITS(3);966}967while (state->have < 19)968state->lens[order[state->have++]] = 0;969state->next = state->codes;970state->lencode = (const code FAR *)(state->next);971state->lenbits = 7;972ret = inflate_table(CODES, state->lens, 19, &(state->next),973&(state->lenbits), state->work);974if (ret) {975strm->msg = (char *)"invalid code lengths set";976state->mode = BAD;977break;978}979Tracev((stderr, "inflate: code lengths ok\n"));980state->have = 0;981state->mode = CODELENS;982case CODELENS:983while (state->have < state->nlen + state->ndist) {984for (;;) {985here = state->lencode[BITS(state->lenbits)];986if ((unsigned)(here.bits) <= bits) break;987PULLBYTE();988}989if (here.val < 16) {990DROPBITS(here.bits);991state->lens[state->have++] = here.val;992}993else {994if (here.val == 16) {995NEEDBITS(here.bits + 2);996DROPBITS(here.bits);997if (state->have == 0) {998strm->msg = (char *)"invalid bit length repeat";999state->mode = BAD;1000break;1001}1002len = state->lens[state->have - 1];1003copy = 3 + BITS(2);1004DROPBITS(2);1005}1006else if (here.val == 17) {1007NEEDBITS(here.bits + 3);1008DROPBITS(here.bits);1009len = 0;1010copy = 3 + BITS(3);1011DROPBITS(3);1012}1013else {1014NEEDBITS(here.bits + 7);1015DROPBITS(here.bits);1016len = 0;1017copy = 11 + BITS(7);1018DROPBITS(7);1019}1020if (state->have + copy > state->nlen + state->ndist) {1021strm->msg = (char *)"invalid bit length repeat";1022state->mode = BAD;1023break;1024}1025while (copy--)1026state->lens[state->have++] = (unsigned short)len;1027}1028}10291030/* handle error breaks in while */1031if (state->mode == BAD) break;10321033/* check for end-of-block code (better have one) */1034if (state->lens[256] == 0) {1035strm->msg = (char *)"invalid code -- missing end-of-block";1036state->mode = BAD;1037break;1038}10391040/* build code tables -- note: do not change the lenbits or distbits1041values here (9 and 6) without reading the comments in inftrees.h1042concerning the ENOUGH constants, which depend on those values */1043state->next = state->codes;1044state->lencode = (const code FAR *)(state->next);1045state->lenbits = 9;1046ret = inflate_table(LENS, state->lens, state->nlen, &(state->next),1047&(state->lenbits), state->work);1048if (ret) {1049strm->msg = (char *)"invalid literal/lengths set";1050state->mode = BAD;1051break;1052}1053state->distcode = (const code FAR *)(state->next);1054state->distbits = 6;1055ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist,1056&(state->next), &(state->distbits), state->work);1057if (ret) {1058strm->msg = (char *)"invalid distances set";1059state->mode = BAD;1060break;1061}1062Tracev((stderr, "inflate: codes ok\n"));1063state->mode = LEN_;1064if (flush == Z_TREES) goto inf_leave;1065case LEN_:1066state->mode = LEN;1067case LEN:1068if (have >= 6 && left >= 258) {1069RESTORE();1070inflate_fast(strm, out);1071LOAD();1072if (state->mode == TYPE)1073state->back = -1;1074break;1075}1076state->back = 0;1077for (;;) {1078here = state->lencode[BITS(state->lenbits)];1079if ((unsigned)(here.bits) <= bits) break;1080PULLBYTE();1081}1082if (here.op && (here.op & 0xf0) == 0) {1083last = here;1084for (;;) {1085here = state->lencode[last.val +1086(BITS(last.bits + last.op) >> last.bits)];1087if ((unsigned)(last.bits + here.bits) <= bits) break;1088PULLBYTE();1089}1090DROPBITS(last.bits);1091state->back += last.bits;1092}1093DROPBITS(here.bits);1094state->back += here.bits;1095state->length = (unsigned)here.val;1096if ((int)(here.op) == 0) {1097Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ?1098"inflate: literal '%c'\n" :1099"inflate: literal 0x%02x\n", here.val));1100state->mode = LIT;1101break;1102}1103if (here.op & 32) {1104Tracevv((stderr, "inflate: end of block\n"));1105state->back = -1;1106state->mode = TYPE;1107break;1108}1109if (here.op & 64) {1110strm->msg = (char *)"invalid literal/length code";1111state->mode = BAD;1112break;1113}1114state->extra = (unsigned)(here.op) & 15;1115state->mode = LENEXT;1116case LENEXT:1117if (state->extra) {1118NEEDBITS(state->extra);1119state->length += BITS(state->extra);1120DROPBITS(state->extra);1121state->back += state->extra;1122}1123Tracevv((stderr, "inflate: length %u\n", state->length));1124state->was = state->length;1125state->mode = DIST;1126case DIST:1127for (;;) {1128here = state->distcode[BITS(state->distbits)];1129if ((unsigned)(here.bits) <= bits) break;1130PULLBYTE();1131}1132if ((here.op & 0xf0) == 0) {1133last = here;1134for (;;) {1135here = state->distcode[last.val +1136(BITS(last.bits + last.op) >> last.bits)];1137if ((unsigned)(last.bits + here.bits) <= bits) break;1138PULLBYTE();1139}1140DROPBITS(last.bits);1141state->back += last.bits;1142}1143DROPBITS(here.bits);1144state->back += here.bits;1145if (here.op & 64) {1146strm->msg = (char *)"invalid distance code";1147state->mode = BAD;1148break;1149}1150state->offset = (unsigned)here.val;1151state->extra = (unsigned)(here.op) & 15;1152state->mode = DISTEXT;1153case DISTEXT:1154if (state->extra) {1155NEEDBITS(state->extra);1156state->offset += BITS(state->extra);1157DROPBITS(state->extra);1158state->back += state->extra;1159}1160#ifdef INFLATE_STRICT1161if (state->offset > state->dmax) {1162strm->msg = (char *)"invalid distance too far back";1163state->mode = BAD;1164break;1165}1166#endif1167Tracevv((stderr, "inflate: distance %u\n", state->offset));1168state->mode = MATCH;1169case MATCH:1170if (left == 0) goto inf_leave;1171copy = out - left;1172if (state->offset > copy) { /* copy from window */1173copy = state->offset - copy;1174if (copy > state->whave) {1175if (state->sane) {1176strm->msg = (char *)"invalid distance too far back";1177state->mode = BAD;1178break;1179}1180#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR1181Trace((stderr, "inflate.c too far\n"));1182copy -= state->whave;1183if (copy > state->length) copy = state->length;1184if (copy > left) copy = left;1185left -= copy;1186state->length -= copy;1187do {1188*put++ = 0;1189} while (--copy);1190if (state->length == 0) state->mode = LEN;1191break;1192#endif1193}1194if (copy > state->wnext) {1195copy -= state->wnext;1196from = state->window + (state->wsize - copy);1197}1198else1199from = state->window + (state->wnext - copy);1200if (copy > state->length) copy = state->length;1201}1202else { /* copy from output */1203from = put - state->offset;1204copy = state->length;1205}1206if (copy > left) copy = left;1207left -= copy;1208state->length -= copy;1209do {1210*put++ = *from++;1211} while (--copy);1212if (state->length == 0) state->mode = LEN;1213break;1214case LIT:1215if (left == 0) goto inf_leave;1216*put++ = (unsigned char)(state->length);1217left--;1218state->mode = LEN;1219break;1220case CHECK:1221if (state->wrap) {1222NEEDBITS(32);1223out -= left;1224strm->total_out += out;1225state->total += out;1226if ((state->wrap & 4) && out)1227strm->adler = state->check =1228UPDATE(state->check, put - out, out);1229out = left;1230if ((state->wrap & 4) && (1231#ifdef GUNZIP1232state->flags ? hold :1233#endif1234ZSWAP32(hold)) != state->check) {1235strm->msg = (char *)"incorrect data check";1236state->mode = BAD;1237break;1238}1239INITBITS();1240Tracev((stderr, "inflate: check matches trailer\n"));1241}1242#ifdef GUNZIP1243state->mode = LENGTH;1244case LENGTH:1245if (state->wrap && state->flags) {1246NEEDBITS(32);1247if (hold != (state->total & 0xffffffffUL)) {1248strm->msg = (char *)"incorrect length check";1249state->mode = BAD;1250break;1251}1252INITBITS();1253Tracev((stderr, "inflate: length matches trailer\n"));1254}1255#endif1256state->mode = DONE;1257case DONE:1258ret = Z_STREAM_END;1259goto inf_leave;1260case BAD:1261ret = Z_DATA_ERROR;1262goto inf_leave;1263case MEM:1264return Z_MEM_ERROR;1265case SYNC:1266default:1267return Z_STREAM_ERROR;1268}12691270/*1271Return from inflate(), updating the total counts and the check value.1272If there was no progress during the inflate() call, return a buffer1273error. Call updatewindow() to create and/or update the window state.1274Note: a memory error from inflate() is non-recoverable.1275*/1276inf_leave:1277RESTORE();1278if (state->wsize || (out != strm->avail_out && state->mode < BAD &&1279(state->mode < CHECK || flush != Z_FINISH)))1280if (updatewindow(strm, strm->next_out, out - strm->avail_out)) {1281state->mode = MEM;1282return Z_MEM_ERROR;1283}1284in -= strm->avail_in;1285out -= strm->avail_out;1286strm->total_in += in;1287strm->total_out += out;1288state->total += out;1289if ((state->wrap & 4) && out)1290strm->adler = state->check =1291UPDATE(state->check, strm->next_out - out, out);1292strm->data_type = (int)state->bits + (state->last ? 64 : 0) +1293(state->mode == TYPE ? 128 : 0) +1294(state->mode == LEN_ || state->mode == COPY_ ? 256 : 0);1295if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK)1296ret = Z_BUF_ERROR;1297return ret;1298}12991300int ZEXPORT inflateEnd(strm)1301z_streamp strm;1302{1303struct inflate_state FAR *state;1304if (inflateStateCheck(strm))1305return Z_STREAM_ERROR;1306state = (struct inflate_state FAR *)strm->state;1307if (state->window != Z_NULL) ZFREE(strm, state->window);1308ZFREE(strm, strm->state);1309strm->state = Z_NULL;1310Tracev((stderr, "inflate: end\n"));1311return Z_OK;1312}13131314int ZEXPORT inflateGetDictionary(strm, dictionary, dictLength)1315z_streamp strm;1316Bytef *dictionary;1317uInt *dictLength;1318{1319struct inflate_state FAR *state;13201321/* check state */1322if (inflateStateCheck(strm)) return Z_STREAM_ERROR;1323state = (struct inflate_state FAR *)strm->state;13241325/* copy dictionary */1326if (state->whave && dictionary != Z_NULL) {1327zmemcpy(dictionary, state->window + state->wnext,1328state->whave - state->wnext);1329zmemcpy(dictionary + state->whave - state->wnext,1330state->window, state->wnext);1331}1332if (dictLength != Z_NULL)1333*dictLength = state->whave;1334return Z_OK;1335}13361337int ZEXPORT inflateSetDictionary(strm, dictionary, dictLength)1338z_streamp strm;1339const Bytef *dictionary;1340uInt dictLength;1341{1342struct inflate_state FAR *state;1343unsigned long dictid;1344int ret;13451346/* check state */1347if (inflateStateCheck(strm)) return Z_STREAM_ERROR;1348state = (struct inflate_state FAR *)strm->state;1349if (state->wrap != 0 && state->mode != DICT)1350return Z_STREAM_ERROR;13511352/* check for correct dictionary identifier */1353if (state->mode == DICT) {1354dictid = adler32(0L, Z_NULL, 0);1355dictid = adler32(dictid, dictionary, dictLength);1356if (dictid != state->check)1357return Z_DATA_ERROR;1358}13591360/* copy dictionary to window using updatewindow(), which will amend the1361existing dictionary if appropriate */1362ret = updatewindow(strm, dictionary + dictLength, dictLength);1363if (ret) {1364state->mode = MEM;1365return Z_MEM_ERROR;1366}1367state->havedict = 1;1368Tracev((stderr, "inflate: dictionary set\n"));1369return Z_OK;1370}13711372int ZEXPORT inflateGetHeader(strm, head)1373z_streamp strm;1374gz_headerp head;1375{1376struct inflate_state FAR *state;13771378/* check state */1379if (inflateStateCheck(strm)) return Z_STREAM_ERROR;1380state = (struct inflate_state FAR *)strm->state;1381if ((state->wrap & 2) == 0) return Z_STREAM_ERROR;13821383/* save header structure */1384state->head = head;1385head->done = 0;1386return Z_OK;1387}13881389/*1390Search buf[0..len-1] for the pattern: 0, 0, 0xff, 0xff. Return when found1391or when out of input. When called, *have is the number of pattern bytes1392found in order so far, in 0..3. On return *have is updated to the new1393state. If on return *have equals four, then the pattern was found and the1394return value is how many bytes were read including the last byte of the1395pattern. If *have is less than four, then the pattern has not been found1396yet and the return value is len. In the latter case, syncsearch() can be1397called again with more data and the *have state. *have is initialized to1398zero for the first call.1399*/1400local unsigned syncsearch(have, buf, len)1401unsigned FAR *have;1402const unsigned char FAR *buf;1403unsigned len;1404{1405unsigned got;1406unsigned next;14071408got = *have;1409next = 0;1410while (next < len && got < 4) {1411if ((int)(buf[next]) == (got < 2 ? 0 : 0xff))1412got++;1413else if (buf[next])1414got = 0;1415else1416got = 4 - got;1417next++;1418}1419*have = got;1420return next;1421}14221423int ZEXPORT inflateSync(strm)1424z_streamp strm;1425{1426unsigned len; /* number of bytes to look at or looked at */1427unsigned long in, out; /* temporary to save total_in and total_out */1428unsigned char buf[4]; /* to restore bit buffer to byte string */1429struct inflate_state FAR *state;14301431/* check parameters */1432if (inflateStateCheck(strm)) return Z_STREAM_ERROR;1433state = (struct inflate_state FAR *)strm->state;1434if (strm->avail_in == 0 && state->bits < 8) return Z_BUF_ERROR;14351436/* if first time, start search in bit buffer */1437if (state->mode != SYNC) {1438state->mode = SYNC;1439state->hold <<= state->bits & 7;1440state->bits -= state->bits & 7;1441len = 0;1442while (state->bits >= 8) {1443buf[len++] = (unsigned char)(state->hold);1444state->hold >>= 8;1445state->bits -= 8;1446}1447state->have = 0;1448syncsearch(&(state->have), buf, len);1449}14501451/* search available input */1452len = syncsearch(&(state->have), strm->next_in, strm->avail_in);1453strm->avail_in -= len;1454strm->next_in += len;1455strm->total_in += len;14561457/* return no joy or set up to restart inflate() on a new block */1458if (state->have != 4) return Z_DATA_ERROR;1459in = strm->total_in; out = strm->total_out;1460inflateReset(strm);1461strm->total_in = in; strm->total_out = out;1462state->mode = TYPE;1463return Z_OK;1464}14651466/*1467Returns true if inflate is currently at the end of a block generated by1468Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP1469implementation to provide an additional safety check. PPP uses1470Z_SYNC_FLUSH but removes the length bytes of the resulting empty stored1471block. When decompressing, PPP checks that at the end of input packet,1472inflate is waiting for these length bytes.1473*/1474int ZEXPORT inflateSyncPoint(strm)1475z_streamp strm;1476{1477struct inflate_state FAR *state;14781479if (inflateStateCheck(strm)) return Z_STREAM_ERROR;1480state = (struct inflate_state FAR *)strm->state;1481return state->mode == STORED && state->bits == 0;1482}14831484int ZEXPORT inflateCopy(dest, source)1485z_streamp dest;1486z_streamp source;1487{1488struct inflate_state FAR *state;1489struct inflate_state FAR *copy;1490unsigned char FAR *window;1491unsigned wsize;14921493/* check input */1494if (inflateStateCheck(source) || dest == Z_NULL)1495return Z_STREAM_ERROR;1496state = (struct inflate_state FAR *)source->state;14971498/* allocate space */1499copy = (struct inflate_state FAR *)1500ZALLOC(source, 1, sizeof(struct inflate_state));1501if (copy == Z_NULL) return Z_MEM_ERROR;1502window = Z_NULL;1503if (state->window != Z_NULL) {1504window = (unsigned char FAR *)1505ZALLOC(source, 1U << state->wbits, sizeof(unsigned char));1506if (window == Z_NULL) {1507ZFREE(source, copy);1508return Z_MEM_ERROR;1509}1510}15111512/* copy state */1513zmemcpy((voidpf)dest, (voidpf)source, sizeof(z_stream));1514zmemcpy((voidpf)copy, (voidpf)state, sizeof(struct inflate_state));1515copy->strm = dest;1516if (state->lencode >= state->codes &&1517state->lencode <= state->codes + ENOUGH - 1) {1518copy->lencode = copy->codes + (state->lencode - state->codes);1519copy->distcode = copy->codes + (state->distcode - state->codes);1520}1521copy->next = copy->codes + (state->next - state->codes);1522if (window != Z_NULL) {1523wsize = 1U << state->wbits;1524zmemcpy(window, state->window, wsize);1525}1526copy->window = window;1527dest->state = (struct internal_state FAR *)copy;1528return Z_OK;1529}15301531int ZEXPORT inflateUndermine(strm, subvert)1532z_streamp strm;1533int subvert;1534{1535struct inflate_state FAR *state;15361537if (inflateStateCheck(strm)) return Z_STREAM_ERROR;1538state = (struct inflate_state FAR *)strm->state;1539#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR1540state->sane = !subvert;1541return Z_OK;1542#else1543(void)subvert;1544state->sane = 1;1545return Z_DATA_ERROR;1546#endif1547}15481549int ZEXPORT inflateValidate(strm, check)1550z_streamp strm;1551int check;1552{1553struct inflate_state FAR *state;15541555if (inflateStateCheck(strm)) return Z_STREAM_ERROR;1556state = (struct inflate_state FAR *)strm->state;1557if (check)1558state->wrap |= 4;1559else1560state->wrap &= ~4;1561return Z_OK;1562}15631564long ZEXPORT inflateMark(strm)1565z_streamp strm;1566{1567struct inflate_state FAR *state;15681569if (inflateStateCheck(strm))1570return -(1L << 16);1571state = (struct inflate_state FAR *)strm->state;1572return (long)(((unsigned long)((long)state->back)) << 16) +1573(state->mode == COPY ? state->length :1574(state->mode == MATCH ? state->was - state->length : 0));1575}15761577unsigned long ZEXPORT inflateCodesUsed(strm)1578z_streamp strm;1579{1580struct inflate_state FAR *state;1581if (inflateStateCheck(strm)) return (unsigned long)-1;1582state = (struct inflate_state FAR *)strm->state;1583return (unsigned long)(state->next - state->codes);1584}158515861587