Coverage Report

Created: 2026-11-12 07:35

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/zlib/gzread.c
Line
Count
Source
1
/* gzread.c -- zlib functions for reading gzip files
2
 * Copyright (C) 2004-2026 Mark Adler
3
 * For conditions of distribution and use, see copyright notice in zlib.h
4
 */
5
6
#include "gzguts.h"
7
8
/* Use read() to load a buffer -- return -1 on error, otherwise 0.  Read from
9
   state->fd, and update state->eof, state->err, and state->msg as appropriate.
10
   This function needs to loop on read(), since read() is not guaranteed to
11
   read the number of bytes requested, depending on the type of descriptor. It
12
   also needs to loop to manage the fact that read() returns an int. If the
13
   descriptor is non-blocking and read() returns with no data in order to avoid
14
   blocking, then gz_load() will return 0 if some data has been read, or -1 if
15
   no data has been read. Either way, state->again is set true to indicate a
16
   non-blocking event. If errno is non-zero on return, then there was an error
17
   signaled from read().  *have is set to the number of bytes read. */
18
local int gz_load(gz_statep state, unsigned char *buf, unsigned len,
19
39.2k
                  unsigned *have) {
20
39.2k
    int ret;
21
39.2k
    unsigned get, max = ((unsigned)-1 >> 2) + 1;
22
23
39.2k
    state->again = 0;
24
39.2k
    errno = 0;
25
39.2k
    *have = 0;
26
78.1k
    do {
27
78.1k
        get = len - *have;
28
78.1k
        if (get > max)
29
0
            get = max;
30
78.1k
        ret = (int)read(state->fd, buf + *have, get);
31
78.1k
        if (ret <= 0)
32
39.0k
            break;
33
39.1k
        *have += (unsigned)ret;
34
39.1k
    } while (*have < len);
35
39.2k
    if (ret < 0) {
36
0
        if (BLOCKED(errno)) {
37
0
            state->again = 1;
38
0
            if (*have != 0)
39
0
                return 0;
40
0
        }
41
0
        gz_error(state, Z_ERRNO, zstrerror());
42
0
        return -1;
43
0
    }
44
39.2k
    if (ret == 0)
45
39.0k
        state->eof = 1;
46
39.2k
    return 0;
47
39.2k
}
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. */
56
65.1k
local int gz_avail(gz_statep state) {
57
65.1k
    unsigned got;
58
65.1k
    z_streamp strm = &(state->strm);
59
60
65.1k
    if (state->err != Z_OK && state->err != Z_BUF_ERROR)
61
0
        return -1;
62
65.1k
    if (state->eof == 0) {
63
39.2k
        if (strm->avail_in) {       /* copy what's there to the start */
64
0
            unsigned char *p = state->in;
65
0
            unsigned const char *q = strm->next_in;
66
67
0
            if (q != p) {
68
0
                unsigned n = strm->avail_in;
69
70
0
                do {
71
0
                    *p++ = *q++;
72
0
                } while (--n);
73
0
            }
74
0
        }
75
39.2k
        if (gz_load(state, state->in + strm->avail_in,
76
39.2k
                    state->size - strm->avail_in, &got) == -1)
77
0
            return -1;
78
39.2k
        strm->avail_in += got;
79
39.2k
        strm->next_in = state->in;
80
39.2k
    }
81
65.1k
    return 0;
82
65.1k
}
83
84
/* Look for gzip header, set up for inflate or copy.  state->x.have must be 0.
85
   If this is the first time in, allocate required memory.  state->how will be
86
   left unchanged if there is no more input data available, will be set to COPY
87
   if there is no gzip header and direct copying will be performed, or it will
88
   be set to GZIP for decompression.  If direct copying, then leftover input
89
   data from the input buffer will be copied to the output buffer.  In that
90
   case, all further file reads will be directly to either the output buffer or
91
   a user buffer.  If decompressing, the inflate state will be initialized.
92
   gz_look() will return 0 on success or -1 on failure. */
93
63.8k
local int gz_look(gz_statep state) {
94
63.8k
    z_streamp strm = &(state->strm);
95
96
    /* allocate read buffers and inflate memory */
97
63.8k
    if (state->size == 0) {
98
        /* allocate buffers */
99
36.9k
        state->in = (unsigned char *)malloc(state->want);
100
36.9k
        state->out = (unsigned char *)malloc(state->want << 1);
101
36.9k
        if (state->in == NULL || state->out == NULL) {
102
0
            free(state->out);
103
0
            free(state->in);
104
0
            gz_error(state, Z_MEM_ERROR, "out of memory");
105
0
            return -1;
106
0
        }
107
36.9k
        state->size = state->want;
108
109
        /* allocate inflate memory */
110
36.9k
        state->strm.zalloc = Z_NULL;
111
36.9k
        state->strm.zfree = Z_NULL;
112
36.9k
        state->strm.opaque = Z_NULL;
113
36.9k
        state->strm.avail_in = 0;
114
36.9k
        state->strm.next_in = Z_NULL;
115
36.9k
        if (inflateInit2(&(state->strm), 15 + 16) != Z_OK) {    /* gunzip */
116
0
            free(state->out);
117
0
            free(state->in);
118
0
            state->size = 0;
119
0
            gz_error(state, Z_MEM_ERROR, "out of memory");
120
0
            return -1;
121
0
        }
122
36.9k
    }
123
124
    /* if transparent reading is disabled, which would only be at the start, or
125
       if we're looking for a gzip member after the first one, which is not at
126
       the start, then proceed directly to look for a gzip member next */
127
63.8k
    if (state->direct == -1 || state->junk == 0) {
128
        /* wait for input before committing to another gzip member */
129
24.7k
        if (state->junk == 0 && strm->avail_in == 0) {
130
1
            if (gz_avail(state) == -1)
131
0
                return -1;
132
1
            if (strm->avail_in == 0)
133
1
                return 0;
134
1
        }
135
24.7k
        inflateReset(strm);
136
24.7k
        state->how = GZIP;
137
24.7k
        state->junk = state->junk != -1;
138
24.7k
        state->direct = 0;
139
24.7k
        return 0;
140
24.7k
    }
141
142
    /* otherwise we're at the start with auto-detect -- we check to see if the
143
       first four bytes could be gzip header in order to decide whether or not
144
       this will be a transparent read */
145
146
    /* load any header bytes into the input buffer -- if the input is empty,
147
       then it's not an error as this is a transparent read of zero bytes */
148
39.1k
    if (gz_avail(state) == -1)
149
0
        return -1;
150
39.1k
    if (strm->avail_in == 0 || (state->again && strm->avail_in < 4))
151
        /* if non-blocking input stalled before getting four bytes, then
152
           return and wait until a later call has accumulated enough */
153
0
        return 0;
154
155
    /* see if this is (likely) gzip input -- if the first four bytes are
156
       consistent with a gzip header, then go look for the first gzip member,
157
       otherwise proceed to copy the input transparently */
158
39.1k
    if (strm->avail_in > 3 &&
159
39.0k
            strm->next_in[0] == 31 && strm->next_in[1] == 139 &&
160
39.0k
            strm->next_in[2] == 8 && strm->next_in[3] < 32) {
161
38.6k
        inflateReset(strm);
162
38.6k
        state->how = GZIP;
163
38.6k
        state->junk = 0;
164
38.6k
        state->direct = 0;
165
38.6k
        return 0;
166
38.6k
    }
167
168
    /* doing raw i/o: copy any leftover input to output -- this assumes that
169
       the output buffer is larger than the input buffer, which also assures
170
       space for gzungetc() */
171
426
    state->x.next = state->out;
172
426
    memcpy(state->x.next, strm->next_in, strm->avail_in);
173
426
    state->x.have = strm->avail_in;
174
426
    strm->avail_in = 0;
175
426
    state->how = COPY;
176
426
    return 0;
177
39.1k
}
178
179
/* Decompress from input to the provided next_out and avail_out in the state.
180
   On return, state->x.have and state->x.next point to the just decompressed
181
   data. If the gzip stream completes, state->how is reset to LOOK to look for
182
   the next gzip stream or raw data, once state->x.have is depleted. Returns 0
183
   on success, -1 on failure. If EOF is reached when looking for more input to
184
   complete the gzip member, then an unexpected end of file error is raised.
185
   If there is no more input, but state->again is true, then EOF has not been
186
   reached, and no error is raised. */
187
220k
local int gz_decomp(gz_statep state) {
188
220k
    int ret = Z_OK;
189
220k
    unsigned had;
190
220k
    z_streamp strm = &(state->strm);
191
192
    /* fill output buffer up to end of deflate stream */
193
220k
    had = strm->avail_out;
194
245k
    do {
195
        /* get more input for inflate() */
196
245k
        if (strm->avail_in == 0 && gz_avail(state) == -1) {
197
0
            ret = state->err;
198
0
            break;
199
0
        }
200
245k
        if (strm->avail_in == 0) {
201
26.0k
            if (!state->again)
202
26.0k
                gz_error(state, Z_BUF_ERROR, "unexpected end of file");
203
26.0k
            break;
204
26.0k
        }
205
206
        /* decompress and handle errors */
207
219k
        ret = inflate(strm, Z_NO_FLUSH);
208
219k
        if (strm->avail_out < had)
209
            /* any decompressed data marks this as a real gzip stream */
210
186k
            state->junk = 0;
211
219k
        if (ret == Z_STREAM_ERROR || ret == Z_NEED_DICT) {
212
0
            gz_error(state, Z_STREAM_ERROR,
213
0
                     "internal error: inflate stream corrupt");
214
0
            break;
215
0
        }
216
219k
        if (ret == Z_MEM_ERROR) {
217
0
            gz_error(state, Z_MEM_ERROR, "out of memory");
218
0
            break;
219
0
        }
220
219k
        if (ret == Z_DATA_ERROR) {              /* deflate stream invalid */
221
11.4k
            if (state->junk == 1) {             /* trailing garbage is ok */
222
1.11k
                strm->avail_in = 0;
223
1.11k
                state->eof = 1;
224
1.11k
                state->how = LOOK;
225
1.11k
                ret = Z_OK;
226
1.11k
                break;
227
1.11k
            }
228
10.3k
            gz_error(state, Z_DATA_ERROR,
229
10.3k
                     strm->msg == NULL ? "compressed data error" : strm->msg);
230
10.3k
            break;
231
11.4k
        }
232
219k
    } while (strm->avail_out && ret != Z_STREAM_END);
233
234
    /* update available output */
235
220k
    state->x.have = had - strm->avail_out;
236
220k
    state->x.next = strm->next_out - state->x.have;
237
238
    /* if the gzip stream completed successfully, look for another */
239
220k
    if (ret == Z_STREAM_END) {
240
24.7k
        state->junk = 0;
241
24.7k
        state->how = LOOK;
242
24.7k
        return 0;
243
24.7k
    }
244
245
    /* return decompression status */
246
195k
    return ret != Z_OK ? -1 : 0;
247
220k
}
248
249
/* Fetch data and put it in the output buffer.  Assumes state->x.have is 0.
250
   Data is either copied from the input file or decompressed from the input
251
   file depending on state->how.  If state->how is LOOK, then a gzip header is
252
   looked for to determine whether to copy or decompress.  Returns -1 on error,
253
   otherwise 0.  gz_fetch() will leave state->how as COPY or GZIP unless the
254
   end of the input file has been reached and all data has been processed.  */
255
198k
local int gz_fetch(gz_statep state) {
256
198k
    z_streamp strm = &(state->strm);
257
258
    /* after a serious error, only what is already in the output buffer is
259
       delivered -- don't try to decompress any more */
260
198k
    if (state->err != Z_OK && state->err != Z_BUF_ERROR && !state->again)
261
49
        return -1;
262
263
283k
    do {
264
283k
        switch(state->how) {
265
63.8k
        case LOOK:      /* -> LOOK, COPY (only if never GZIP), or GZIP */
266
63.8k
            if (gz_look(state) == -1)
267
0
                return -1;
268
63.8k
            if (state->how == LOOK)
269
1
                return 0;
270
63.8k
            break;
271
63.8k
        case COPY:      /* -> COPY */
272
62
            if (gz_load(state, state->out, state->size << 1, &(state->x.have))
273
62
                    == -1)
274
0
                return -1;
275
62
            state->x.next = state->out;
276
62
            return 0;
277
220k
        case GZIP:      /* -> GZIP or LOOK (if end of gzip stream) */
278
220k
            strm->avail_out = state->size << 1;
279
220k
            strm->next_out = state->out;
280
220k
            if (gz_decomp(state) == -1)
281
10.3k
                return -1;
282
209k
            break;
283
209k
        default:
284
0
            gz_error(state, Z_STREAM_ERROR, "state corrupt");
285
0
            return -1;
286
283k
        }
287
283k
    } while (state->x.have == 0 && (!state->eof || strm->avail_in));
288
187k
    return 0;
289
198k
}
290
291
/* Apply as much of a pending skip request as the output already available in
292
   state->x allows. */
293
18.4k
local void gz_skip_have(gz_statep state) {
294
18.4k
    unsigned n;
295
296
18.4k
    n = GT_OFF(state->x.have) ||
297
18.4k
        (z_off64_t)state->x.have > state->skip ?
298
16.8k
        (unsigned)state->skip : state->x.have;
299
18.4k
    state->x.have -= n;
300
18.4k
    state->x.next += n;
301
18.4k
    state->x.pos += n;
302
18.4k
    state->skip -= n;
303
18.4k
}
304
305
/* Skip state->skip (> 0) uncompressed bytes of output.  Return -1 on error, 0
306
   on success. */
307
2.57k
local int gz_skip(gz_statep state) {
308
    /* skip over len bytes or reach end-of-file, whichever comes first */
309
37.8k
    do {
310
        /* skip over whatever is in output buffer */
311
37.8k
        if (state->x.have)
312
18.4k
            gz_skip_have(state);
313
314
        /* output buffer empty -- return if we're at the end of the input */
315
19.4k
        else if (state->eof && state->strm.avail_in == 0) {
316
916
            if (state->how == GZIP && state->err == Z_OK)
317
8
                gz_error(state, Z_BUF_ERROR, "unexpected end of file");
318
916
            state->skip = 0;
319
916
            state->past = 1;
320
916
            break;
321
916
        }
322
323
        /* need more data to skip -- load up output buffer */
324
18.5k
        else {
325
            /* get more output, looking for header if required. If the fetch
326
               stalled but provided some output, consume it before returning
327
               so that x.have > 0 always implies the data is at the current
328
               logical position (x.pos), as assumed by the gzgetc() fast path
329
               in zlib.h and gzread.c */
330
18.5k
            if (gz_fetch(state) == -1 && state->x.have == 0)
331
34
                return -1;
332
18.5k
        }
333
37.8k
    } while (state->skip);
334
2.53k
    return 0;
335
2.57k
}
336
337
/* Read len bytes into buf from file, or less than len up to the end of the
338
   input. Return the number of bytes read. If zero is returned, either the end
339
   of file was reached, or there was an error. state->err must be consulted in
340
   that case to determine which. If there was an error, but some uncompressed
341
   bytes were read before the error, then that count is returned. The error is
342
   still recorded, and so is deferred until the next call. */
343
454k
local z_size_t gz_read(gz_statep state, voidp buf, z_size_t len) {
344
454k
    z_size_t got;
345
454k
    unsigned n;
346
454k
    int err;
347
348
    /* if len is zero, avoid unnecessary operations */
349
454k
    if (len == 0)
350
0
        return 0;
351
352
    /* process a skip request */
353
454k
    if (state->skip && gz_skip(state) == -1)
354
34
        return 0;
355
356
    /* get len bytes to buf, or less than len if at the end */
357
454k
    got = 0;
358
454k
    err = 0;
359
762k
    do {
360
        /* set n to the maximum amount of len that fits in an unsigned int */
361
762k
        n = (unsigned)-1;
362
762k
        if (n > len)
363
762k
            n = (unsigned)len;
364
365
        /* first just try copying data from the output buffer */
366
762k
        if (state->x.have) {
367
377k
            if (state->x.have < n)
368
150k
                n = state->x.have;
369
377k
            memcpy(buf, state->x.next, n);
370
377k
            state->x.next += n;
371
377k
            state->x.have -= n;
372
377k
            if (state->err != Z_OK)
373
                /* caught deferred error from gz_fetch() */
374
62.3k
                err = -1;
375
377k
        }
376
377
        /* output buffer empty -- return if we're at the end of the input */
378
384k
        else if (state->eof && state->strm.avail_in == 0) {
379
204k
            if (state->how == GZIP && state->err == Z_OK)
380
815
                gz_error(state, Z_BUF_ERROR, "unexpected end of file");
381
204k
            break;
382
204k
        }
383
384
        /* need output data -- for small len or new stream load up our output
385
           buffer, so that gzgetc() can be fast */
386
179k
        else if (state->how == LOOK || n < (state->size << 1)) {
387
            /* get more output, looking for header if required */
388
179k
            if (gz_fetch(state) == -1 && state->x.have == 0)
389
                /* if state->x.have != 0, error will be caught after copy */
390
4.40k
                err = -1;
391
179k
            continue;       /* no progress yet -- go back to copy above */
392
            /* the copy above assures that we will leave with space in the
393
               output buffer, allowing at least one gzungetc() to succeed */
394
179k
        }
395
396
        /* large len -- read directly into user buffer */
397
69
        else if (state->how == COPY)        /* read directly */
398
0
            err = gz_load(state, (unsigned char *)buf, n, &n);
399
400
        /* large len -- decompress directly into user buffer */
401
69
        else {  /* state->how == GZIP */
402
69
            state->strm.avail_out = n;
403
69
            state->strm.next_out = (unsigned char *)buf;
404
69
            err = gz_decomp(state);
405
69
            n = state->x.have;
406
69
            state->x.have = 0;
407
69
        }
408
409
        /* update progress */
410
377k
        len -= n;
411
377k
        buf = (char *)buf + n;
412
377k
        got += n;
413
377k
        state->x.pos += n;
414
557k
    } while (len && !err);
415
416
    /* note read past eof */
417
454k
    if (len && state->eof)
418
227k
        state->past = 1;
419
420
    /* return number of bytes read into user buffer */
421
454k
    return got;
422
454k
}
423
424
/* -- see zlib.h -- */
425
478k
int ZEXPORT gzread(gzFile file, voidp buf, unsigned len) {
426
478k
    gz_statep state;
427
428
    /* get internal structure and check that it's for reading */
429
478k
    if (file == NULL)
430
0
        return -1;
431
478k
    state = (gz_statep)file;
432
478k
    if (state->mode != GZ_READ)
433
0
        return -1;
434
435
    /* check that there was no (serious) error -- if there was, deliver any
436
       data read before the error until it is exhausted, and only then return
437
       the error */
438
478k
    if (state->err != Z_OK && state->err != Z_BUF_ERROR && !state->again &&
439
132k
            state->x.have == 0)
440
120k
        return -1;
441
358k
    if (state->again)
442
0
        gz_error(state, Z_OK, NULL);
443
444
    /* since an int is returned, make sure len fits in one, otherwise return
445
       with an error (this avoids a flaw in the interface) -- keep a pending
446
       serious error, which is the one the caller needs to see */
447
358k
    if ((int)len < 0) {
448
0
        if (state->err == Z_OK || state->err == Z_BUF_ERROR)
449
0
            gz_error(state, Z_STREAM_ERROR, "request does not fit in an int");
450
0
        return -1;
451
0
    }
452
453
    /* read len or fewer bytes to buf */
454
358k
    len = (unsigned)gz_read(state, buf, len);
455
456
    /* check for an error */
457
358k
    if (len == 0) {
458
129k
        if (state->err != Z_OK && state->err != Z_BUF_ERROR)
459
3.29k
            return -1;
460
125k
        if (state->again) {
461
            /* non-blocking input stalled after some input was read, but no
462
               uncompressed bytes were produced -- let the application know
463
               this isn't EOF */
464
0
            gz_error(state, Z_ERRNO, zstrerror());
465
0
            return -1;
466
0
        }
467
125k
    }
468
469
    /* return the number of bytes read */
470
355k
    return (int)len;
471
358k
}
472
473
/* -- see zlib.h -- */
474
z_size_t ZEXPORT gzfread(voidp buf, z_size_t size, z_size_t nitems,
475
0
                         gzFile file) {
476
0
    z_size_t len;
477
0
    gz_statep state;
478
479
    /* get internal structure and check that it's for reading */
480
0
    if (file == NULL)
481
0
        return 0;
482
0
    state = (gz_statep)file;
483
0
    if (state->mode != GZ_READ)
484
0
        return 0;
485
486
    /* check that there was no (serious) error -- if there was, deliver any
487
       data read before the error until it is exhausted, and only then return
488
       the error */
489
0
    if (state->err != Z_OK && state->err != Z_BUF_ERROR && !state->again &&
490
0
            state->x.have == 0)
491
0
        return 0;
492
0
    if (state->again)
493
0
        gz_error(state, Z_OK, NULL);
494
495
    /* compute bytes to read -- error on overflow, keeping a pending serious
496
       error, which is the one the caller needs to see */
497
0
    len = nitems * size;
498
0
    if (size && len / size != nitems) {
499
0
        if (state->err == Z_OK || state->err == Z_BUF_ERROR)
500
0
            gz_error(state, Z_STREAM_ERROR,
501
0
                     "request does not fit in a size_t");
502
0
        return 0;
503
0
    }
504
505
    /* read len or fewer bytes to buf, return the number of full items read */
506
0
    return len ? gz_read(state, buf, len) / size : 0;
507
0
}
508
509
/* -- see zlib.h -- */
510
#ifdef Z_PREFIX_SET
511
#  undef z_gzgetc
512
#else
513
#  undef gzgetc
514
#endif
515
16.8M
int ZEXPORT gzgetc(gzFile file) {
516
16.8M
    unsigned char buf[1];
517
16.8M
    gz_statep state;
518
519
    /* get internal structure and check that it's for reading */
520
16.8M
    if (file == NULL)
521
0
        return -1;
522
16.8M
    state = (gz_statep)file;
523
16.8M
    if (state->mode != GZ_READ)
524
0
        return -1;
525
526
    /* check that there was no (serious) error -- if there was, deliver any
527
       data read before the error until it is exhausted, and only then return
528
       the error, as the gzgetc() macro does */
529
16.8M
    if (state->err != Z_OK && state->err != Z_BUF_ERROR && !state->again &&
530
16.7M
            state->x.have == 0)
531
16.7M
        return -1;
532
96.1k
    if (state->again)
533
0
        gz_error(state, Z_OK, NULL);
534
535
    /* try output buffer (no need to check for skip request) */
536
96.1k
    if (state->x.have) {
537
0
        state->x.have--;
538
0
        state->x.pos++;
539
0
        return *(state->x.next)++;
540
0
    }
541
542
    /* nothing there -- try gz_read() */
543
96.1k
    return gz_read(state, buf, 1) < 1 ? -1 : buf[0];
544
96.1k
}
545
546
0
int ZEXPORT gzgetc_(gzFile file) {
547
0
    return gzgetc(file);
548
0
}
549
550
/* -- see zlib.h -- */
551
0
int ZEXPORT gzungetc(int c, gzFile file) {
552
0
    gz_statep state;
553
554
    /* get internal structure and check that it's for reading */
555
0
    if (file == NULL)
556
0
        return -1;
557
0
    state = (gz_statep)file;
558
0
    if (state->mode != GZ_READ)
559
0
        return -1;
560
561
    /* in case this was just opened, set up the input buffer */
562
0
    if (state->how == LOOK && state->x.have == 0)
563
0
        (void)gz_look(state);
564
565
    /* check that there was no (serious) error -- a character can still be
566
       pushed back after one, since it is data that was read before the
567
       error, and it will be returned before the error is signaled -- but only
568
       if there is an output buffer to put it in */
569
0
    if (state->err != Z_OK && state->err != Z_BUF_ERROR && !state->again &&
570
0
            state->size == 0)
571
0
        return -1;
572
0
    if (state->again)
573
0
        gz_error(state, Z_OK, NULL);
574
575
    /* process a skip request */
576
0
    if (state->skip && gz_skip(state) == -1)
577
0
        return -1;
578
579
    /* can't push EOF */
580
0
    if (c < 0)
581
0
        return -1;
582
583
    /* if output buffer empty, put byte at end (allows more pushing) */
584
0
    if (state->x.have == 0) {
585
0
        state->x.have = 1;
586
0
        state->x.next = state->out + (state->size << 1) - 1;
587
0
        state->x.next[0] = (unsigned char)c;
588
0
        state->x.pos--;
589
0
        state->past = 0;
590
0
        return c;
591
0
    }
592
593
    /* if no room, give up (must have already done a gzungetc()) */
594
0
    if (state->x.have == (state->size << 1)) {
595
0
        if (state->err == Z_OK || state->err == Z_BUF_ERROR)
596
0
            gz_error(state, Z_DATA_ERROR, "out of room to push characters");
597
0
        return -1;
598
0
    }
599
600
    /* slide output data if needed and insert byte before existing data */
601
0
    if (state->x.next == state->out) {
602
0
        unsigned char *src = state->out + state->x.have;
603
0
        unsigned char *dest = state->out + (state->size << 1);
604
605
0
        while (src > state->out)
606
0
            *--dest = *--src;
607
0
        state->x.next = dest;
608
0
    }
609
0
    state->x.have++;
610
0
    state->x.next--;
611
0
    state->x.next[0] = (unsigned char)c;
612
0
    state->x.pos--;
613
0
    state->past = 0;
614
0
    return c;
615
0
}
616
617
/* -- see zlib.h -- */
618
4.44k
char * ZEXPORT gzgets(gzFile file, char *buf, int len) {
619
4.44k
    unsigned left, n;
620
4.44k
    char *str;
621
4.44k
    unsigned char *eol;
622
4.44k
    gz_statep state;
623
624
    /* check parameters, get internal structure, and check that it's for
625
       reading */
626
4.44k
    if (file == NULL || buf == NULL || len < 1)
627
0
        return NULL;
628
4.44k
    state = (gz_statep)file;
629
4.44k
    if (state->mode != GZ_READ)
630
0
        return NULL;
631
632
    /* check that there was no (serious) error -- if there was, deliver any
633
       data read before the error until it is exhausted, and only then return
634
       the error */
635
4.44k
    if (state->err != Z_OK && state->err != Z_BUF_ERROR && !state->again &&
636
157
            state->x.have == 0)
637
15
        return NULL;
638
4.42k
    if (state->again)
639
0
        gz_error(state, Z_OK, NULL);
640
641
    /* process a skip request */
642
4.42k
    if (state->skip && gz_skip(state) == -1)
643
0
        return NULL;
644
645
    /* copy output up to a new line, len-1 bytes, or there is no more output,
646
       whichever comes first */
647
4.42k
    str = buf;
648
4.42k
    left = (unsigned)len - 1;
649
4.49k
    if (left) do {
650
        /* assure that something is in the output buffer */
651
4.49k
        if (state->x.have == 0 && gz_fetch(state) == -1 &&
652
32
                state->x.have == 0)
653
15
            break;                      /* error, and nothing left to return */
654
4.48k
        if (state->x.have == 0) {       /* end of file */
655
129
            state->past = 1;            /* read past end */
656
129
            break;                      /* return what we have */
657
129
        }
658
659
        /* look for end-of-line in current output buffer */
660
4.35k
        n = state->x.have > left ? left : state->x.have;
661
4.35k
        eol = (unsigned char *)memchr(state->x.next, '\n', n);
662
4.35k
        if (eol != NULL)
663
4.28k
            n = (unsigned)(eol - state->x.next) + 1;
664
665
        /* copy through end-of-line, or remainder if not found */
666
4.35k
        memcpy(buf, state->x.next, n);
667
4.35k
        state->x.have -= n;
668
4.35k
        state->x.next += n;
669
4.35k
        state->x.pos += n;
670
4.35k
        left -= n;
671
4.35k
        buf += n;
672
4.35k
    } while (left && eol == NULL);
673
674
    /* append a terminating zero to the string (we don't check for a zero in
675
       the contents, let the user worry about that) -- return the terminated
676
       string, or if nothing was read, NULL */
677
4.42k
    if (buf == str && len > 1)
678
72
        return NULL;
679
4.35k
    buf[0] = 0;
680
4.35k
    return str;
681
4.42k
}
682
683
/* -- see zlib.h -- */
684
0
int ZEXPORT gzdirect(gzFile file) {
685
0
    gz_statep state;
686
687
    /* get internal structure */
688
0
    if (file == NULL)
689
0
        return 0;
690
0
    state = (gz_statep)file;
691
692
    /* if the state is not known, but we can find out, then do so (this is
693
       mainly for right after a gzopen() or gzdopen()) */
694
0
    if (state->mode == GZ_READ && state->how == LOOK && state->x.have == 0) {
695
0
        (void)gz_look(state);
696
0
        gz_skip_have(state);        /* apply skip to current buffer */
697
0
    }
698
699
    /* return 1 if transparent, 0 if processing a gzip stream */
700
0
    return state->direct == 1;
701
0
}
702
703
/* -- see zlib.h -- */
704
70.7k
int ZEXPORT gzclose_r(gzFile file) {
705
70.7k
    int ret, err;
706
70.7k
    gz_statep state;
707
708
    /* get internal structure and check that it's for reading */
709
70.7k
    if (file == NULL)
710
0
        return Z_STREAM_ERROR;
711
70.7k
    state = (gz_statep)file;
712
70.7k
    if (state->mode != GZ_READ)
713
0
        return Z_STREAM_ERROR;
714
715
    /* free memory and close file */
716
70.7k
    if (state->size) {
717
36.9k
        inflateEnd(&(state->strm));
718
36.9k
        free(state->out);
719
36.9k
        free(state->in);
720
36.9k
    }
721
70.7k
    err = state->err == Z_BUF_ERROR ? Z_BUF_ERROR : Z_OK;
722
70.7k
    gz_error(state, Z_OK, NULL);
723
70.7k
    free(state->path);
724
70.7k
    ret = close(state->fd);
725
70.7k
    free(state);
726
70.7k
    return ret ? Z_ERRNO : err;
727
70.7k
}