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