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