jdk/src/java.base/share/native/libzip/zlib-1.2.8/gzread.c
changeset 43806 36e9a4583949
parent 43805 9051877afb06
child 43807 82f979ff031f
equal deleted inserted replaced
43805:9051877afb06 43806:36e9a4583949
     1 /*
       
     2  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       
     3  *
       
     4  * This code is free software; you can redistribute it and/or modify it
       
     5  * under the terms of the GNU General Public License version 2 only, as
       
     6  * published by the Free Software Foundation.  Oracle designates this
       
     7  * particular file as subject to the "Classpath" exception as provided
       
     8  * by Oracle in the LICENSE file that accompanied this code.
       
     9  *
       
    10  * This code is distributed in the hope that it will be useful, but WITHOUT
       
    11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       
    12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       
    13  * version 2 for more details (a copy is included in the LICENSE file that
       
    14  * accompanied this code).
       
    15  *
       
    16  * You should have received a copy of the GNU General Public License version
       
    17  * 2 along with this work; if not, write to the Free Software Foundation,
       
    18  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
       
    19  *
       
    20  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
       
    21  * or visit www.oracle.com if you need additional information or have any
       
    22  * questions.
       
    23  */
       
    24 
       
    25 /* gzread.c -- zlib functions for reading gzip files
       
    26  * Copyright (C) 2004, 2005, 2010, 2011, 2012, 2013 Mark Adler
       
    27  * For conditions of distribution and use, see copyright notice in zlib.h
       
    28  */
       
    29 
       
    30 #include "gzguts.h"
       
    31 
       
    32 /* Local functions */
       
    33 local int gz_load OF((gz_statep, unsigned char *, unsigned, unsigned *));
       
    34 local int gz_avail OF((gz_statep));
       
    35 local int gz_look OF((gz_statep));
       
    36 local int gz_decomp OF((gz_statep));
       
    37 local int gz_fetch OF((gz_statep));
       
    38 local int gz_skip OF((gz_statep, z_off64_t));
       
    39 
       
    40 /* Use read() to load a buffer -- return -1 on error, otherwise 0.  Read from
       
    41    state->fd, and update state->eof, state->err, and state->msg as appropriate.
       
    42    This function needs to loop on read(), since read() is not guaranteed to
       
    43    read the number of bytes requested, depending on the type of descriptor. */
       
    44 local int gz_load(state, buf, len, have)
       
    45     gz_statep state;
       
    46     unsigned char *buf;
       
    47     unsigned len;
       
    48     unsigned *have;
       
    49 {
       
    50     int ret;
       
    51 
       
    52     *have = 0;
       
    53     do {
       
    54         ret = read(state->fd, buf + *have, len - *have);
       
    55         if (ret <= 0)
       
    56             break;
       
    57         *have += ret;
       
    58     } while (*have < len);
       
    59     if (ret < 0) {
       
    60         gz_error(state, Z_ERRNO, zstrerror());
       
    61         return -1;
       
    62     }
       
    63     if (ret == 0)
       
    64         state->eof = 1;
       
    65     return 0;
       
    66 }
       
    67 
       
    68 /* Load up input buffer and set eof flag if last data loaded -- return -1 on
       
    69    error, 0 otherwise.  Note that the eof flag is set when the end of the input
       
    70    file is reached, even though there may be unused data in the buffer.  Once
       
    71    that data has been used, no more attempts will be made to read the file.
       
    72    If strm->avail_in != 0, then the current data is moved to the beginning of
       
    73    the input buffer, and then the remainder of the buffer is loaded with the
       
    74    available data from the input file. */
       
    75 local int gz_avail(state)
       
    76     gz_statep state;
       
    77 {
       
    78     unsigned got;
       
    79     z_streamp strm = &(state->strm);
       
    80 
       
    81     if (state->err != Z_OK && state->err != Z_BUF_ERROR)
       
    82         return -1;
       
    83     if (state->eof == 0) {
       
    84         if (strm->avail_in) {       /* copy what's there to the start */
       
    85             unsigned char *p = state->in;
       
    86             unsigned const char *q = strm->next_in;
       
    87             unsigned n = strm->avail_in;
       
    88             do {
       
    89                 *p++ = *q++;
       
    90             } while (--n);
       
    91         }
       
    92         if (gz_load(state, state->in + strm->avail_in,
       
    93                     state->size - strm->avail_in, &got) == -1)
       
    94             return -1;
       
    95         strm->avail_in += got;
       
    96         strm->next_in = state->in;
       
    97     }
       
    98     return 0;
       
    99 }
       
   100 
       
   101 /* Look for gzip header, set up for inflate or copy.  state->x.have must be 0.
       
   102    If this is the first time in, allocate required memory.  state->how will be
       
   103    left unchanged if there is no more input data available, will be set to COPY
       
   104    if there is no gzip header and direct copying will be performed, or it will
       
   105    be set to GZIP for decompression.  If direct copying, then leftover input
       
   106    data from the input buffer will be copied to the output buffer.  In that
       
   107    case, all further file reads will be directly to either the output buffer or
       
   108    a user buffer.  If decompressing, the inflate state will be initialized.
       
   109    gz_look() will return 0 on success or -1 on failure. */
       
   110 local int gz_look(state)
       
   111     gz_statep state;
       
   112 {
       
   113     z_streamp strm = &(state->strm);
       
   114 
       
   115     /* allocate read buffers and inflate memory */
       
   116     if (state->size == 0) {
       
   117         /* allocate buffers */
       
   118         state->in = (unsigned char *)malloc(state->want);
       
   119         state->out = (unsigned char *)malloc(state->want << 1);
       
   120         if (state->in == NULL || state->out == NULL) {
       
   121             if (state->out != NULL)
       
   122                 free(state->out);
       
   123             if (state->in != NULL)
       
   124                 free(state->in);
       
   125             gz_error(state, Z_MEM_ERROR, "out of memory");
       
   126             return -1;
       
   127         }
       
   128         state->size = state->want;
       
   129 
       
   130         /* allocate inflate memory */
       
   131         state->strm.zalloc = Z_NULL;
       
   132         state->strm.zfree = Z_NULL;
       
   133         state->strm.opaque = Z_NULL;
       
   134         state->strm.avail_in = 0;
       
   135         state->strm.next_in = Z_NULL;
       
   136         if (inflateInit2(&(state->strm), 15 + 16) != Z_OK) {    /* gunzip */
       
   137             free(state->out);
       
   138             free(state->in);
       
   139             state->size = 0;
       
   140             gz_error(state, Z_MEM_ERROR, "out of memory");
       
   141             return -1;
       
   142         }
       
   143     }
       
   144 
       
   145     /* get at least the magic bytes in the input buffer */
       
   146     if (strm->avail_in < 2) {
       
   147         if (gz_avail(state) == -1)
       
   148             return -1;
       
   149         if (strm->avail_in == 0)
       
   150             return 0;
       
   151     }
       
   152 
       
   153     /* look for gzip magic bytes -- if there, do gzip decoding (note: there is
       
   154        a logical dilemma here when considering the case of a partially written
       
   155        gzip file, to wit, if a single 31 byte is written, then we cannot tell
       
   156        whether this is a single-byte file, or just a partially written gzip
       
   157        file -- for here we assume that if a gzip file is being written, then
       
   158        the header will be written in a single operation, so that reading a
       
   159        single byte is sufficient indication that it is not a gzip file) */
       
   160     if (strm->avail_in > 1 &&
       
   161             strm->next_in[0] == 31 && strm->next_in[1] == 139) {
       
   162         inflateReset(strm);
       
   163         state->how = GZIP;
       
   164         state->direct = 0;
       
   165         return 0;
       
   166     }
       
   167 
       
   168     /* no gzip header -- if we were decoding gzip before, then this is trailing
       
   169        garbage.  Ignore the trailing garbage and finish. */
       
   170     if (state->direct == 0) {
       
   171         strm->avail_in = 0;
       
   172         state->eof = 1;
       
   173         state->x.have = 0;
       
   174         return 0;
       
   175     }
       
   176 
       
   177     /* doing raw i/o, copy any leftover input to output -- this assumes that
       
   178        the output buffer is larger than the input buffer, which also assures
       
   179        space for gzungetc() */
       
   180     state->x.next = state->out;
       
   181     if (strm->avail_in) {
       
   182         memcpy(state->x.next, strm->next_in, strm->avail_in);
       
   183         state->x.have = strm->avail_in;
       
   184         strm->avail_in = 0;
       
   185     }
       
   186     state->how = COPY;
       
   187     state->direct = 1;
       
   188     return 0;
       
   189 }
       
   190 
       
   191 /* Decompress from input to the provided next_out and avail_out in the state.
       
   192    On return, state->x.have and state->x.next point to the just decompressed
       
   193    data.  If the gzip stream completes, state->how is reset to LOOK to look for
       
   194    the next gzip stream or raw data, once state->x.have is depleted.  Returns 0
       
   195    on success, -1 on failure. */
       
   196 local int gz_decomp(state)
       
   197     gz_statep state;
       
   198 {
       
   199     int ret = Z_OK;
       
   200     unsigned had;
       
   201     z_streamp strm = &(state->strm);
       
   202 
       
   203     /* fill output buffer up to end of deflate stream */
       
   204     had = strm->avail_out;
       
   205     do {
       
   206         /* get more input for inflate() */
       
   207         if (strm->avail_in == 0 && gz_avail(state) == -1)
       
   208             return -1;
       
   209         if (strm->avail_in == 0) {
       
   210             gz_error(state, Z_BUF_ERROR, "unexpected end of file");
       
   211             break;
       
   212         }
       
   213 
       
   214         /* decompress and handle errors */
       
   215         ret = inflate(strm, Z_NO_FLUSH);
       
   216         if (ret == Z_STREAM_ERROR || ret == Z_NEED_DICT) {
       
   217             gz_error(state, Z_STREAM_ERROR,
       
   218                      "internal error: inflate stream corrupt");
       
   219             return -1;
       
   220         }
       
   221         if (ret == Z_MEM_ERROR) {
       
   222             gz_error(state, Z_MEM_ERROR, "out of memory");
       
   223             return -1;
       
   224         }
       
   225         if (ret == Z_DATA_ERROR) {              /* deflate stream invalid */
       
   226             gz_error(state, Z_DATA_ERROR,
       
   227                      strm->msg == NULL ? "compressed data error" : strm->msg);
       
   228             return -1;
       
   229         }
       
   230     } while (strm->avail_out && ret != Z_STREAM_END);
       
   231 
       
   232     /* update available output */
       
   233     state->x.have = had - strm->avail_out;
       
   234     state->x.next = strm->next_out - state->x.have;
       
   235 
       
   236     /* if the gzip stream completed successfully, look for another */
       
   237     if (ret == Z_STREAM_END)
       
   238         state->how = LOOK;
       
   239 
       
   240     /* good decompression */
       
   241     return 0;
       
   242 }
       
   243 
       
   244 /* Fetch data and put it in the output buffer.  Assumes state->x.have is 0.
       
   245    Data is either copied from the input file or decompressed from the input
       
   246    file depending on state->how.  If state->how is LOOK, then a gzip header is
       
   247    looked for to determine whether to copy or decompress.  Returns -1 on error,
       
   248    otherwise 0.  gz_fetch() will leave state->how as COPY or GZIP unless the
       
   249    end of the input file has been reached and all data has been processed.  */
       
   250 local int gz_fetch(state)
       
   251     gz_statep state;
       
   252 {
       
   253     z_streamp strm = &(state->strm);
       
   254 
       
   255     do {
       
   256         switch(state->how) {
       
   257         case LOOK:      /* -> LOOK, COPY (only if never GZIP), or GZIP */
       
   258             if (gz_look(state) == -1)
       
   259                 return -1;
       
   260             if (state->how == LOOK)
       
   261                 return 0;
       
   262             break;
       
   263         case COPY:      /* -> COPY */
       
   264             if (gz_load(state, state->out, state->size << 1, &(state->x.have))
       
   265                     == -1)
       
   266                 return -1;
       
   267             state->x.next = state->out;
       
   268             return 0;
       
   269         case GZIP:      /* -> GZIP or LOOK (if end of gzip stream) */
       
   270             strm->avail_out = state->size << 1;
       
   271             strm->next_out = state->out;
       
   272             if (gz_decomp(state) == -1)
       
   273                 return -1;
       
   274         }
       
   275     } while (state->x.have == 0 && (!state->eof || strm->avail_in));
       
   276     return 0;
       
   277 }
       
   278 
       
   279 /* Skip len uncompressed bytes of output.  Return -1 on error, 0 on success. */
       
   280 local int gz_skip(state, len)
       
   281     gz_statep state;
       
   282     z_off64_t len;
       
   283 {
       
   284     unsigned n;
       
   285 
       
   286     /* skip over len bytes or reach end-of-file, whichever comes first */
       
   287     while (len)
       
   288         /* skip over whatever is in output buffer */
       
   289         if (state->x.have) {
       
   290             n = GT_OFF(state->x.have) || (z_off64_t)state->x.have > len ?
       
   291                 (unsigned)len : state->x.have;
       
   292             state->x.have -= n;
       
   293             state->x.next += n;
       
   294             state->x.pos += n;
       
   295             len -= n;
       
   296         }
       
   297 
       
   298         /* output buffer empty -- return if we're at the end of the input */
       
   299         else if (state->eof && state->strm.avail_in == 0)
       
   300             break;
       
   301 
       
   302         /* need more data to skip -- load up output buffer */
       
   303         else {
       
   304             /* get more output, looking for header if required */
       
   305             if (gz_fetch(state) == -1)
       
   306                 return -1;
       
   307         }
       
   308     return 0;
       
   309 }
       
   310 
       
   311 /* -- see zlib.h -- */
       
   312 int ZEXPORT gzread(file, buf, len)
       
   313     gzFile file;
       
   314     voidp buf;
       
   315     unsigned len;
       
   316 {
       
   317     unsigned got, n;
       
   318     gz_statep state;
       
   319     z_streamp strm;
       
   320 
       
   321     /* get internal structure */
       
   322     if (file == NULL)
       
   323         return -1;
       
   324     state = (gz_statep)file;
       
   325     strm = &(state->strm);
       
   326 
       
   327     /* check that we're reading and that there's no (serious) error */
       
   328     if (state->mode != GZ_READ ||
       
   329             (state->err != Z_OK && state->err != Z_BUF_ERROR))
       
   330         return -1;
       
   331 
       
   332     /* since an int is returned, make sure len fits in one, otherwise return
       
   333        with an error (this avoids the flaw in the interface) */
       
   334     if ((int)len < 0) {
       
   335         gz_error(state, Z_DATA_ERROR, "requested length does not fit in int");
       
   336         return -1;
       
   337     }
       
   338 
       
   339     /* if len is zero, avoid unnecessary operations */
       
   340     if (len == 0)
       
   341         return 0;
       
   342 
       
   343     /* process a skip request */
       
   344     if (state->seek) {
       
   345         state->seek = 0;
       
   346         if (gz_skip(state, state->skip) == -1)
       
   347             return -1;
       
   348     }
       
   349 
       
   350     /* get len bytes to buf, or less than len if at the end */
       
   351     got = 0;
       
   352     do {
       
   353         /* first just try copying data from the output buffer */
       
   354         if (state->x.have) {
       
   355             n = state->x.have > len ? len : state->x.have;
       
   356             memcpy(buf, state->x.next, n);
       
   357             state->x.next += n;
       
   358             state->x.have -= n;
       
   359         }
       
   360 
       
   361         /* output buffer empty -- return if we're at the end of the input */
       
   362         else if (state->eof && strm->avail_in == 0) {
       
   363             state->past = 1;        /* tried to read past end */
       
   364             break;
       
   365         }
       
   366 
       
   367         /* need output data -- for small len or new stream load up our output
       
   368            buffer */
       
   369         else if (state->how == LOOK || len < (state->size << 1)) {
       
   370             /* get more output, looking for header if required */
       
   371             if (gz_fetch(state) == -1)
       
   372                 return -1;
       
   373             continue;       /* no progress yet -- go back to copy above */
       
   374             /* the copy above assures that we will leave with space in the
       
   375                output buffer, allowing at least one gzungetc() to succeed */
       
   376         }
       
   377 
       
   378         /* large len -- read directly into user buffer */
       
   379         else if (state->how == COPY) {      /* read directly */
       
   380             if (gz_load(state, (unsigned char *)buf, len, &n) == -1)
       
   381                 return -1;
       
   382         }
       
   383 
       
   384         /* large len -- decompress directly into user buffer */
       
   385         else {  /* state->how == GZIP */
       
   386             strm->avail_out = len;
       
   387             strm->next_out = (unsigned char *)buf;
       
   388             if (gz_decomp(state) == -1)
       
   389                 return -1;
       
   390             n = state->x.have;
       
   391             state->x.have = 0;
       
   392         }
       
   393 
       
   394         /* update progress */
       
   395         len -= n;
       
   396         buf = (char *)buf + n;
       
   397         got += n;
       
   398         state->x.pos += n;
       
   399     } while (len);
       
   400 
       
   401     /* return number of bytes read into user buffer (will fit in int) */
       
   402     return (int)got;
       
   403 }
       
   404 
       
   405 /* -- see zlib.h -- */
       
   406 #ifdef Z_PREFIX_SET
       
   407 #  undef z_gzgetc
       
   408 #else
       
   409 #  undef gzgetc
       
   410 #endif
       
   411 int ZEXPORT gzgetc(file)
       
   412     gzFile file;
       
   413 {
       
   414     int ret;
       
   415     unsigned char buf[1];
       
   416     gz_statep state;
       
   417 
       
   418     /* get internal structure */
       
   419     if (file == NULL)
       
   420         return -1;
       
   421     state = (gz_statep)file;
       
   422 
       
   423     /* check that we're reading and that there's no (serious) error */
       
   424     if (state->mode != GZ_READ ||
       
   425         (state->err != Z_OK && state->err != Z_BUF_ERROR))
       
   426         return -1;
       
   427 
       
   428     /* try output buffer (no need to check for skip request) */
       
   429     if (state->x.have) {
       
   430         state->x.have--;
       
   431         state->x.pos++;
       
   432         return *(state->x.next)++;
       
   433     }
       
   434 
       
   435     /* nothing there -- try gzread() */
       
   436     ret = gzread(file, buf, 1);
       
   437     return ret < 1 ? -1 : buf[0];
       
   438 }
       
   439 
       
   440 int ZEXPORT gzgetc_(file)
       
   441 gzFile file;
       
   442 {
       
   443     return gzgetc(file);
       
   444 }
       
   445 
       
   446 /* -- see zlib.h -- */
       
   447 int ZEXPORT gzungetc(c, file)
       
   448     int c;
       
   449     gzFile file;
       
   450 {
       
   451     gz_statep state;
       
   452 
       
   453     /* get internal structure */
       
   454     if (file == NULL)
       
   455         return -1;
       
   456     state = (gz_statep)file;
       
   457 
       
   458     /* check that we're reading and that there's no (serious) error */
       
   459     if (state->mode != GZ_READ ||
       
   460         (state->err != Z_OK && state->err != Z_BUF_ERROR))
       
   461         return -1;
       
   462 
       
   463     /* process a skip request */
       
   464     if (state->seek) {
       
   465         state->seek = 0;
       
   466         if (gz_skip(state, state->skip) == -1)
       
   467             return -1;
       
   468     }
       
   469 
       
   470     /* can't push EOF */
       
   471     if (c < 0)
       
   472         return -1;
       
   473 
       
   474     /* if output buffer empty, put byte at end (allows more pushing) */
       
   475     if (state->x.have == 0) {
       
   476         state->x.have = 1;
       
   477         state->x.next = state->out + (state->size << 1) - 1;
       
   478         state->x.next[0] = c;
       
   479         state->x.pos--;
       
   480         state->past = 0;
       
   481         return c;
       
   482     }
       
   483 
       
   484     /* if no room, give up (must have already done a gzungetc()) */
       
   485     if (state->x.have == (state->size << 1)) {
       
   486         gz_error(state, Z_DATA_ERROR, "out of room to push characters");
       
   487         return -1;
       
   488     }
       
   489 
       
   490     /* slide output data if needed and insert byte before existing data */
       
   491     if (state->x.next == state->out) {
       
   492         unsigned char *src = state->out + state->x.have;
       
   493         unsigned char *dest = state->out + (state->size << 1);
       
   494         while (src > state->out)
       
   495             *--dest = *--src;
       
   496         state->x.next = dest;
       
   497     }
       
   498     state->x.have++;
       
   499     state->x.next--;
       
   500     state->x.next[0] = c;
       
   501     state->x.pos--;
       
   502     state->past = 0;
       
   503     return c;
       
   504 }
       
   505 
       
   506 /* -- see zlib.h -- */
       
   507 char * ZEXPORT gzgets(file, buf, len)
       
   508     gzFile file;
       
   509     char *buf;
       
   510     int len;
       
   511 {
       
   512     unsigned left, n;
       
   513     char *str;
       
   514     unsigned char *eol;
       
   515     gz_statep state;
       
   516 
       
   517     /* check parameters and get internal structure */
       
   518     if (file == NULL || buf == NULL || len < 1)
       
   519         return NULL;
       
   520     state = (gz_statep)file;
       
   521 
       
   522     /* check that we're reading and that there's no (serious) error */
       
   523     if (state->mode != GZ_READ ||
       
   524         (state->err != Z_OK && state->err != Z_BUF_ERROR))
       
   525         return NULL;
       
   526 
       
   527     /* process a skip request */
       
   528     if (state->seek) {
       
   529         state->seek = 0;
       
   530         if (gz_skip(state, state->skip) == -1)
       
   531             return NULL;
       
   532     }
       
   533 
       
   534     /* copy output bytes up to new line or len - 1, whichever comes first --
       
   535        append a terminating zero to the string (we don't check for a zero in
       
   536        the contents, let the user worry about that) */
       
   537     str = buf;
       
   538     left = (unsigned)len - 1;
       
   539     if (left) do {
       
   540         /* assure that something is in the output buffer */
       
   541         if (state->x.have == 0 && gz_fetch(state) == -1)
       
   542             return NULL;                /* error */
       
   543         if (state->x.have == 0) {       /* end of file */
       
   544             state->past = 1;            /* read past end */
       
   545             break;                      /* return what we have */
       
   546         }
       
   547 
       
   548         /* look for end-of-line in current output buffer */
       
   549         n = state->x.have > left ? left : state->x.have;
       
   550         eol = (unsigned char *)memchr(state->x.next, '\n', n);
       
   551         if (eol != NULL)
       
   552             n = (unsigned)(eol - state->x.next) + 1;
       
   553 
       
   554         /* copy through end-of-line, or remainder if not found */
       
   555         memcpy(buf, state->x.next, n);
       
   556         state->x.have -= n;
       
   557         state->x.next += n;
       
   558         state->x.pos += n;
       
   559         left -= n;
       
   560         buf += n;
       
   561     } while (left && eol == NULL);
       
   562 
       
   563     /* return terminated string, or if nothing, end of file */
       
   564     if (buf == str)
       
   565         return NULL;
       
   566     buf[0] = 0;
       
   567     return str;
       
   568 }
       
   569 
       
   570 /* -- see zlib.h -- */
       
   571 int ZEXPORT gzdirect(file)
       
   572     gzFile file;
       
   573 {
       
   574     gz_statep state;
       
   575 
       
   576     /* get internal structure */
       
   577     if (file == NULL)
       
   578         return 0;
       
   579     state = (gz_statep)file;
       
   580 
       
   581     /* if the state is not known, but we can find out, then do so (this is
       
   582        mainly for right after a gzopen() or gzdopen()) */
       
   583     if (state->mode == GZ_READ && state->how == LOOK && state->x.have == 0)
       
   584         (void)gz_look(state);
       
   585 
       
   586     /* return 1 if transparent, 0 if processing a gzip stream */
       
   587     return state->direct;
       
   588 }
       
   589 
       
   590 /* -- see zlib.h -- */
       
   591 int ZEXPORT gzclose_r(file)
       
   592     gzFile file;
       
   593 {
       
   594     int ret, err;
       
   595     gz_statep state;
       
   596 
       
   597     /* get internal structure */
       
   598     if (file == NULL)
       
   599         return Z_STREAM_ERROR;
       
   600     state = (gz_statep)file;
       
   601 
       
   602     /* check that we're reading */
       
   603     if (state->mode != GZ_READ)
       
   604         return Z_STREAM_ERROR;
       
   605 
       
   606     /* free memory and close file */
       
   607     if (state->size) {
       
   608         inflateEnd(&(state->strm));
       
   609         free(state->out);
       
   610         free(state->in);
       
   611     }
       
   612     err = state->err == Z_BUF_ERROR ? Z_BUF_ERROR : Z_OK;
       
   613     gz_error(state, Z_OK, NULL);
       
   614     free(state->path);
       
   615     ret = close(state->fd);
       
   616     free(state);
       
   617     return ret ? Z_ERRNO : err;
       
   618 }