Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:24:11

0001 /* gzread.c -- zlib functions for reading gzip files
0002  * Copyright (C) 2004-2017 Mark Adler
0003  * For conditions of distribution and use, see copyright notice in zlib.h
0004  */
0005 
0006 #include "gzguts.h"
0007 
0008 /* Local functions */
0009 local int gz_load OF((gz_statep, unsigned char *, unsigned, unsigned *));
0010 local int gz_avail OF((gz_statep));
0011 local int gz_look OF((gz_statep));
0012 local int gz_decomp OF((gz_statep));
0013 local int gz_fetch OF((gz_statep));
0014 local int gz_skip OF((gz_statep, z_off64_t));
0015 local z_size_t gz_read OF((gz_statep, voidp, z_size_t));
0016 
0017 /* Use read() to load a buffer -- return -1 on error, otherwise 0.  Read from
0018    state->fd, and update state->eof, state->err, and state->msg as appropriate.
0019    This function needs to loop on read(), since read() is not guaranteed to
0020    read the number of bytes requested, depending on the type of descriptor. */
0021 local int gz_load(state, buf, len, have)
0022     gz_statep state;
0023     unsigned char *buf;
0024     unsigned len;
0025     unsigned *have;
0026 {
0027     int ret;
0028     unsigned get, max = ((unsigned)-1 >> 2) + 1;
0029 
0030     *have = 0;
0031     do {
0032         get = len - *have;
0033         if (get > max)
0034             get = max;
0035         ret = read(state->fd, buf + *have, get);
0036         if (ret <= 0)
0037             break;
0038         *have += (unsigned)ret;
0039     } while (*have < len);
0040     if (ret < 0) {
0041         gz_error(state, Z_ERRNO, zstrerror());
0042         return -1;
0043     }
0044     if (ret == 0)
0045         state->eof = 1;
0046     return 0;
0047 }
0048 
0049 /* Load up input buffer and set eof flag if last data loaded -- return -1 on
0050    error, 0 otherwise.  Note that the eof flag is set when the end of the input
0051    file is reached, even though there may be unused data in the buffer.  Once
0052    that data has been used, no more attempts will be made to read the file.
0053    If strm->avail_in != 0, then the current data is moved to the beginning of
0054    the input buffer, and then the remainder of the buffer is loaded with the
0055    available data from the input file. */
0056 local int gz_avail(state)
0057     gz_statep state;
0058 {
0059     unsigned got;
0060     z_streamp strm = &(state->strm);
0061 
0062     if (state->err != Z_OK && state->err != Z_BUF_ERROR)
0063         return -1;
0064     if (state->eof == 0) {
0065         if (strm->avail_in) {       /* copy what's there to the start */
0066             unsigned char *p = state->in;
0067             unsigned const char *q = strm->next_in;
0068             unsigned n = strm->avail_in;
0069             do {
0070                 *p++ = *q++;
0071             } while (--n);
0072         }
0073         if (gz_load(state, state->in + strm->avail_in,
0074                     state->size - strm->avail_in, &got) == -1)
0075             return -1;
0076         strm->avail_in += got;
0077         strm->next_in = state->in;
0078     }
0079     return 0;
0080 }
0081 
0082 /* Look for gzip header, set up for inflate or copy.  state->x.have must be 0.
0083    If this is the first time in, allocate required memory.  state->how will be
0084    left unchanged if there is no more input data available, will be set to COPY
0085    if there is no gzip header and direct copying will be performed, or it will
0086    be set to GZIP for decompression.  If direct copying, then leftover input
0087    data from the input buffer will be copied to the output buffer.  In that
0088    case, all further file reads will be directly to either the output buffer or
0089    a user buffer.  If decompressing, the inflate state will be initialized.
0090    gz_look() will return 0 on success or -1 on failure. */
0091 local int gz_look(state)
0092     gz_statep state;
0093 {
0094     z_streamp strm = &(state->strm);
0095 
0096     /* allocate read buffers and inflate memory */
0097     if (state->size == 0) {
0098         /* allocate buffers */
0099         state->in = (unsigned char *)malloc(state->want);
0100         state->out = (unsigned char *)malloc(state->want << 1);
0101         if (state->in == NULL || state->out == NULL) {
0102             free(state->out);
0103             free(state->in);
0104             gz_error(state, Z_MEM_ERROR, "out of memory");
0105             return -1;
0106         }
0107         state->size = state->want;
0108 
0109         /* allocate inflate memory */
0110         state->strm.zalloc = Z_NULL;
0111         state->strm.zfree = Z_NULL;
0112         state->strm.opaque = Z_NULL;
0113         state->strm.avail_in = 0;
0114         state->strm.next_in = Z_NULL;
0115         if (inflateInit2(&(state->strm), 15 + 16) != Z_OK) {    /* gunzip */
0116             free(state->out);
0117             free(state->in);
0118             state->size = 0;
0119             gz_error(state, Z_MEM_ERROR, "out of memory");
0120             return -1;
0121         }
0122     }
0123 
0124     /* get at least the magic bytes in the input buffer */
0125     if (strm->avail_in < 2) {
0126         if (gz_avail(state) == -1)
0127             return -1;
0128         if (strm->avail_in == 0)
0129             return 0;
0130     }
0131 
0132     /* look for gzip magic bytes -- if there, do gzip decoding (note: there is
0133        a logical dilemma here when considering the case of a partially written
0134        gzip file, to wit, if a single 31 byte is written, then we cannot tell
0135        whether this is a single-byte file, or just a partially written gzip
0136        file -- for here we assume that if a gzip file is being written, then
0137        the header will be written in a single operation, so that reading a
0138        single byte is sufficient indication that it is not a gzip file) */
0139     if (strm->avail_in > 1 &&
0140             strm->next_in[0] == 31 && strm->next_in[1] == 139) {
0141         inflateReset(strm);
0142         state->how = GZIP;
0143         state->direct = 0;
0144         return 0;
0145     }
0146 
0147     /* no gzip header -- if we were decoding gzip before, then this is trailing
0148        garbage.  Ignore the trailing garbage and finish. */
0149     if (state->direct == 0) {
0150         strm->avail_in = 0;
0151         state->eof = 1;
0152         state->x.have = 0;
0153         return 0;
0154     }
0155 
0156     /* doing raw i/o, copy any leftover input to output -- this assumes that
0157        the output buffer is larger than the input buffer, which also assures
0158        space for gzungetc() */
0159     state->x.next = state->out;
0160     memcpy(state->x.next, strm->next_in, strm->avail_in);
0161     state->x.have = strm->avail_in;
0162     strm->avail_in = 0;
0163     state->how = COPY;
0164     state->direct = 1;
0165     return 0;
0166 }
0167 
0168 /* Decompress from input to the provided next_out and avail_out in the state.
0169    On return, state->x.have and state->x.next point to the just decompressed
0170    data.  If the gzip stream completes, state->how is reset to LOOK to look for
0171    the next gzip stream or raw data, once state->x.have is depleted.  Returns 0
0172    on success, -1 on failure. */
0173 local int gz_decomp(state)
0174     gz_statep state;
0175 {
0176     int ret = Z_OK;
0177     unsigned had;
0178     z_streamp strm = &(state->strm);
0179 
0180     /* fill output buffer up to end of deflate stream */
0181     had = strm->avail_out;
0182     do {
0183         /* get more input for inflate() */
0184         if (strm->avail_in == 0 && gz_avail(state) == -1)
0185             return -1;
0186         if (strm->avail_in == 0) {
0187             gz_error(state, Z_BUF_ERROR, "unexpected end of file");
0188             break;
0189         }
0190 
0191         /* decompress and handle errors */
0192         ret = inflate(strm, Z_NO_FLUSH);
0193         if (ret == Z_STREAM_ERROR || ret == Z_NEED_DICT) {
0194             gz_error(state, Z_STREAM_ERROR,
0195                      "internal error: inflate stream corrupt");
0196             return -1;
0197         }
0198         if (ret == Z_MEM_ERROR) {
0199             gz_error(state, Z_MEM_ERROR, "out of memory");
0200             return -1;
0201         }
0202         if (ret == Z_DATA_ERROR) {              /* deflate stream invalid */
0203             gz_error(state, Z_DATA_ERROR,
0204                      strm->msg == NULL ? "compressed data error" : strm->msg);
0205             return -1;
0206         }
0207     } while (strm->avail_out && ret != Z_STREAM_END);
0208 
0209     /* update available output */
0210     state->x.have = had - strm->avail_out;
0211     state->x.next = strm->next_out - state->x.have;
0212 
0213     /* if the gzip stream completed successfully, look for another */
0214     if (ret == Z_STREAM_END)
0215         state->how = LOOK;
0216 
0217     /* good decompression */
0218     return 0;
0219 }
0220 
0221 /* Fetch data and put it in the output buffer.  Assumes state->x.have is 0.
0222    Data is either copied from the input file or decompressed from the input
0223    file depending on state->how.  If state->how is LOOK, then a gzip header is
0224    looked for to determine whether to copy or decompress.  Returns -1 on error,
0225    otherwise 0.  gz_fetch() will leave state->how as COPY or GZIP unless the
0226    end of the input file has been reached and all data has been processed.  */
0227 local int gz_fetch(state)
0228     gz_statep state;
0229 {
0230     z_streamp strm = &(state->strm);
0231 
0232     do {
0233         switch(state->how) {
0234         case LOOK:      /* -> LOOK, COPY (only if never GZIP), or GZIP */
0235             if (gz_look(state) == -1)
0236                 return -1;
0237             if (state->how == LOOK)
0238                 return 0;
0239             break;
0240         case COPY:      /* -> COPY */
0241             if (gz_load(state, state->out, state->size << 1, &(state->x.have))
0242                     == -1)
0243                 return -1;
0244             state->x.next = state->out;
0245             return 0;
0246         case GZIP:      /* -> GZIP or LOOK (if end of gzip stream) */
0247             strm->avail_out = state->size << 1;
0248             strm->next_out = state->out;
0249             if (gz_decomp(state) == -1)
0250                 return -1;
0251         }
0252     } while (state->x.have == 0 && (!state->eof || strm->avail_in));
0253     return 0;
0254 }
0255 
0256 /* Skip len uncompressed bytes of output.  Return -1 on error, 0 on success. */
0257 local int gz_skip(state, len)
0258     gz_statep state;
0259     z_off64_t len;
0260 {
0261     unsigned n;
0262 
0263     /* skip over len bytes or reach end-of-file, whichever comes first */
0264     while (len)
0265         /* skip over whatever is in output buffer */
0266         if (state->x.have) {
0267             n = GT_OFF(state->x.have) || (z_off64_t)state->x.have > len ?
0268                 (unsigned)len : state->x.have;
0269             state->x.have -= n;
0270             state->x.next += n;
0271             state->x.pos += n;
0272             len -= n;
0273         }
0274 
0275         /* output buffer empty -- return if we're at the end of the input */
0276         else if (state->eof && state->strm.avail_in == 0)
0277             break;
0278 
0279         /* need more data to skip -- load up output buffer */
0280         else {
0281             /* get more output, looking for header if required */
0282             if (gz_fetch(state) == -1)
0283                 return -1;
0284         }
0285     return 0;
0286 }
0287 
0288 /* Read len bytes into buf from file, or less than len up to the end of the
0289    input.  Return the number of bytes read.  If zero is returned, either the
0290    end of file was reached, or there was an error.  state->err must be
0291    consulted in that case to determine which. */
0292 local z_size_t gz_read(state, buf, len)
0293     gz_statep state;
0294     voidp buf;
0295     z_size_t len;
0296 {
0297     z_size_t got;
0298     unsigned n;
0299 
0300     /* if len is zero, avoid unnecessary operations */
0301     if (len == 0)
0302         return 0;
0303 
0304     /* process a skip request */
0305     if (state->seek) {
0306         state->seek = 0;
0307         if (gz_skip(state, state->skip) == -1)
0308             return 0;
0309     }
0310 
0311     /* get len bytes to buf, or less than len if at the end */
0312     got = 0;
0313     do {
0314         /* set n to the maximum amount of len that fits in an unsigned int */
0315         n = (unsigned)-1;
0316         if (n > len)
0317             n = (unsigned)len;
0318 
0319         /* first just try copying data from the output buffer */
0320         if (state->x.have) {
0321             if (state->x.have < n)
0322                 n = state->x.have;
0323             memcpy(buf, state->x.next, n);
0324             state->x.next += n;
0325             state->x.have -= n;
0326         }
0327 
0328         /* output buffer empty -- return if we're at the end of the input */
0329         else if (state->eof && state->strm.avail_in == 0) {
0330             state->past = 1;        /* tried to read past end */
0331             break;
0332         }
0333 
0334         /* need output data -- for small len or new stream load up our output
0335            buffer */
0336         else if (state->how == LOOK || n < (state->size << 1)) {
0337             /* get more output, looking for header if required */
0338             if (gz_fetch(state) == -1)
0339                 return 0;
0340             continue;       /* no progress yet -- go back to copy above */
0341             /* the copy above assures that we will leave with space in the
0342                output buffer, allowing at least one gzungetc() to succeed */
0343         }
0344 
0345         /* large len -- read directly into user buffer */
0346         else if (state->how == COPY) {      /* read directly */
0347             if (gz_load(state, (unsigned char *)buf, n, &n) == -1)
0348                 return 0;
0349         }
0350 
0351         /* large len -- decompress directly into user buffer */
0352         else {  /* state->how == GZIP */
0353             state->strm.avail_out = n;
0354             state->strm.next_out = (unsigned char *)buf;
0355             if (gz_decomp(state) == -1)
0356                 return 0;
0357             n = state->x.have;
0358             state->x.have = 0;
0359         }
0360 
0361         /* update progress */
0362         len -= n;
0363         buf = (char *)buf + n;
0364         got += n;
0365         state->x.pos += n;
0366     } while (len);
0367 
0368     /* return number of bytes read into user buffer */
0369     return got;
0370 }
0371 
0372 /* -- see zlib.h -- */
0373 int ZEXPORT gzread(file, buf, len)
0374     gzFile file;
0375     voidp buf;
0376     unsigned len;
0377 {
0378     gz_statep state;
0379 
0380     /* get internal structure */
0381     if (file == NULL)
0382         return -1;
0383     state = (gz_statep)file;
0384 
0385     /* check that we're reading and that there's no (serious) error */
0386     if (state->mode != GZ_READ ||
0387             (state->err != Z_OK && state->err != Z_BUF_ERROR))
0388         return -1;
0389 
0390     /* since an int is returned, make sure len fits in one, otherwise return
0391        with an error (this avoids a flaw in the interface) */
0392     if ((int)len < 0) {
0393         gz_error(state, Z_STREAM_ERROR, "request does not fit in an int");
0394         return -1;
0395     }
0396 
0397     /* read len or fewer bytes to buf */
0398     len = (unsigned)gz_read(state, buf, len);
0399 
0400     /* check for an error */
0401     if (len == 0 && state->err != Z_OK && state->err != Z_BUF_ERROR)
0402         return -1;
0403 
0404     /* return the number of bytes read (this is assured to fit in an int) */
0405     return (int)len;
0406 }
0407 
0408 /* -- see zlib.h -- */
0409 z_size_t ZEXPORT gzfread(buf, size, nitems, file)
0410     voidp buf;
0411     z_size_t size;
0412     z_size_t nitems;
0413     gzFile file;
0414 {
0415     z_size_t len;
0416     gz_statep state;
0417 
0418     /* get internal structure */
0419     if (file == NULL)
0420         return 0;
0421     state = (gz_statep)file;
0422 
0423     /* check that we're reading and that there's no (serious) error */
0424     if (state->mode != GZ_READ ||
0425             (state->err != Z_OK && state->err != Z_BUF_ERROR))
0426         return 0;
0427 
0428     /* compute bytes to read -- error on overflow */
0429     len = nitems * size;
0430     if (size && len / size != nitems) {
0431         gz_error(state, Z_STREAM_ERROR, "request does not fit in a size_t");
0432         return 0;
0433     }
0434 
0435     /* read len or fewer bytes to buf, return the number of full items read */
0436     return len ? gz_read(state, buf, len) / size : 0;
0437 }
0438 
0439 /* -- see zlib.h -- */
0440 #ifdef Z_PREFIX_SET
0441 #  undef z_gzgetc
0442 #else
0443 #  undef gzgetc
0444 #endif
0445 int ZEXPORT gzgetc(file)
0446     gzFile file;
0447 {
0448     unsigned char buf[1];
0449     gz_statep state;
0450 
0451     /* get internal structure */
0452     if (file == NULL)
0453         return -1;
0454     state = (gz_statep)file;
0455 
0456     /* check that we're reading and that there's no (serious) error */
0457     if (state->mode != GZ_READ ||
0458         (state->err != Z_OK && state->err != Z_BUF_ERROR))
0459         return -1;
0460 
0461     /* try output buffer (no need to check for skip request) */
0462     if (state->x.have) {
0463         state->x.have--;
0464         state->x.pos++;
0465         return *(state->x.next)++;
0466     }
0467 
0468     /* nothing there -- try gz_read() */
0469     return gz_read(state, buf, 1) < 1 ? -1 : buf[0];
0470 }
0471 
0472 int ZEXPORT gzgetc_(file)
0473 gzFile file;
0474 {
0475     return gzgetc(file);
0476 }
0477 
0478 /* -- see zlib.h -- */
0479 int ZEXPORT gzungetc(c, file)
0480     int c;
0481     gzFile file;
0482 {
0483     gz_statep state;
0484 
0485     /* get internal structure */
0486     if (file == NULL)
0487         return -1;
0488     state = (gz_statep)file;
0489 
0490     /* check that we're reading and that there's no (serious) error */
0491     if (state->mode != GZ_READ ||
0492         (state->err != Z_OK && state->err != Z_BUF_ERROR))
0493         return -1;
0494 
0495     /* process a skip request */
0496     if (state->seek) {
0497         state->seek = 0;
0498         if (gz_skip(state, state->skip) == -1)
0499             return -1;
0500     }
0501 
0502     /* can't push EOF */
0503     if (c < 0)
0504         return -1;
0505 
0506     /* if output buffer empty, put byte at end (allows more pushing) */
0507     if (state->x.have == 0) {
0508         state->x.have = 1;
0509         state->x.next = state->out + (state->size << 1) - 1;
0510         state->x.next[0] = (unsigned char)c;
0511         state->x.pos--;
0512         state->past = 0;
0513         return c;
0514     }
0515 
0516     /* if no room, give up (must have already done a gzungetc()) */
0517     if (state->x.have == (state->size << 1)) {
0518         gz_error(state, Z_DATA_ERROR, "out of room to push characters");
0519         return -1;
0520     }
0521 
0522     /* slide output data if needed and insert byte before existing data */
0523     if (state->x.next == state->out) {
0524         unsigned char *src = state->out + state->x.have;
0525         unsigned char *dest = state->out + (state->size << 1);
0526         while (src > state->out)
0527             *--dest = *--src;
0528         state->x.next = dest;
0529     }
0530     state->x.have++;
0531     state->x.next--;
0532     state->x.next[0] = (unsigned char)c;
0533     state->x.pos--;
0534     state->past = 0;
0535     return c;
0536 }
0537 
0538 /* -- see zlib.h -- */
0539 char * ZEXPORT gzgets(file, buf, len)
0540     gzFile file;
0541     char *buf;
0542     int len;
0543 {
0544     unsigned left, n;
0545     char *str;
0546     unsigned char *eol;
0547     gz_statep state;
0548 
0549     /* check parameters and get internal structure */
0550     if (file == NULL || buf == NULL || len < 1)
0551         return NULL;
0552     state = (gz_statep)file;
0553 
0554     /* check that we're reading and that there's no (serious) error */
0555     if (state->mode != GZ_READ ||
0556         (state->err != Z_OK && state->err != Z_BUF_ERROR))
0557         return NULL;
0558 
0559     /* process a skip request */
0560     if (state->seek) {
0561         state->seek = 0;
0562         if (gz_skip(state, state->skip) == -1)
0563             return NULL;
0564     }
0565 
0566     /* copy output bytes up to new line or len - 1, whichever comes first --
0567        append a terminating zero to the string (we don't check for a zero in
0568        the contents, let the user worry about that) */
0569     str = buf;
0570     left = (unsigned)len - 1;
0571     if (left) do {
0572         /* assure that something is in the output buffer */
0573         if (state->x.have == 0 && gz_fetch(state) == -1)
0574             return NULL;                /* error */
0575         if (state->x.have == 0) {       /* end of file */
0576             state->past = 1;            /* read past end */
0577             break;                      /* return what we have */
0578         }
0579 
0580         /* look for end-of-line in current output buffer */
0581         n = state->x.have > left ? left : state->x.have;
0582         eol = (unsigned char *)memchr(state->x.next, '\n', n);
0583         if (eol != NULL)
0584             n = (unsigned)(eol - state->x.next) + 1;
0585 
0586         /* copy through end-of-line, or remainder if not found */
0587         memcpy(buf, state->x.next, n);
0588         state->x.have -= n;
0589         state->x.next += n;
0590         state->x.pos += n;
0591         left -= n;
0592         buf += n;
0593     } while (left && eol == NULL);
0594 
0595     /* return terminated string, or if nothing, end of file */
0596     if (buf == str)
0597         return NULL;
0598     buf[0] = 0;
0599     return str;
0600 }
0601 
0602 /* -- see zlib.h -- */
0603 int ZEXPORT gzdirect(file)
0604     gzFile file;
0605 {
0606     gz_statep state;
0607 
0608     /* get internal structure */
0609     if (file == NULL)
0610         return 0;
0611     state = (gz_statep)file;
0612 
0613     /* if the state is not known, but we can find out, then do so (this is
0614        mainly for right after a gzopen() or gzdopen()) */
0615     if (state->mode == GZ_READ && state->how == LOOK && state->x.have == 0)
0616         (void)gz_look(state);
0617 
0618     /* return 1 if transparent, 0 if processing a gzip stream */
0619     return state->direct;
0620 }
0621 
0622 /* -- see zlib.h -- */
0623 int ZEXPORT gzclose_r(file)
0624     gzFile file;
0625 {
0626     int ret, err;
0627     gz_statep state;
0628 
0629     /* get internal structure */
0630     if (file == NULL)
0631         return Z_STREAM_ERROR;
0632     state = (gz_statep)file;
0633 
0634     /* check that we're reading */
0635     if (state->mode != GZ_READ)
0636         return Z_STREAM_ERROR;
0637 
0638     /* free memory and close file */
0639     if (state->size) {
0640         inflateEnd(&(state->strm));
0641         free(state->out);
0642         free(state->in);
0643     }
0644     err = state->err == Z_BUF_ERROR ? Z_BUF_ERROR : Z_OK;
0645     gz_error(state, Z_OK, NULL);
0646     free(state->path);
0647     ret = close(state->fd);
0648     free(state);
0649     return ret ? Z_ERRNO : err;
0650 }