Coverage Report

Created: 2026-09-28 06:47

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
23.8k
                  unsigned *have) {
20
23.8k
    int ret;
21
23.8k
    unsigned get, max = ((unsigned)-1 >> 2) + 1;
22
23
23.8k
    state->again = 0;
24
23.8k
    errno = 0;
25
23.8k
    *have = 0;
26
47.4k
    do {
27
47.4k
        get = len - *have;
28
47.4k
        if (get > max)
29
0
            get = max;
30
47.4k
        ret = (int)read(state->fd, buf + *have, get);
31
47.4k
        if (ret <= 0)
32
23.6k
            break;
33
23.7k
        *have += (unsigned)ret;
34
23.7k
    } while (*have < len);
35
23.8k
    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
23.8k
    if (ret == 0)
45
23.6k
        state->eof = 1;
46
23.8k
    return 0;
47
23.8k
}
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
38.1k
local int gz_avail(gz_statep state) {
57
38.1k
    unsigned got;
58
38.1k
    z_streamp strm = &(state->strm);
59
60
38.1k
    if (state->err != Z_OK && state->err != Z_BUF_ERROR)
61
0
        return -1;
62
38.1k
    if (state->eof == 0) {
63
23.8k
        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
23.8k
        if (gz_load(state, state->in + strm->avail_in,
76
23.8k
                    state->size - strm->avail_in, &got) == -1)
77
0
            return -1;
78
23.8k
        strm->avail_in += got;
79
23.8k
        strm->next_in = state->in;
80
23.8k
    }
81
38.1k
    return 0;
82
38.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
36.1k
local int gz_look(gz_statep state) {
94
36.1k
    z_streamp strm = &(state->strm);
95
96
    /* allocate read buffers and inflate memory */
97
36.1k
    if (state->size == 0) {
98
        /* allocate buffers */
99
23.3k
        state->in = (unsigned char *)malloc(state->want);
100
23.3k
        state->out = (unsigned char *)malloc(state->want << 1);
101
23.3k
        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
23.3k
        state->size = state->want;
108
109
        /* allocate inflate memory */
110
23.3k
        state->strm.zalloc = Z_NULL;
111
23.3k
        state->strm.zfree = Z_NULL;
112
23.3k
        state->strm.opaque = Z_NULL;
113
23.3k
        state->strm.avail_in = 0;
114
23.3k
        state->strm.next_in = Z_NULL;
115
23.3k
        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
23.3k
    }
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
36.1k
    if (state->direct == -1 || state->junk == 0) {
128
        /* wait for input before committing to another gzip member */
129
12.3k
        if (state->junk == 0 && strm->avail_in == 0) {
130
0
            if (gz_avail(state) == -1)
131
0
                return -1;
132
0
            if (strm->avail_in == 0)
133
0
                return 0;
134
0
        }
135
12.3k
        inflateReset(strm);
136
12.3k
        state->how = GZIP;
137
12.3k
        state->junk = state->junk != -1;
138
12.3k
        state->direct = 0;
139
12.3k
        return 0;
140
12.3k
    }
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
23.7k
    if (gz_avail(state) == -1)
149
0
        return -1;
150
23.7k
    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
23.7k
    if (strm->avail_in > 3 &&
159
23.7k
            strm->next_in[0] == 31 && strm->next_in[1] == 139 &&
160
23.7k
            strm->next_in[2] == 8 && strm->next_in[3] < 32) {
161
23.4k
        inflateReset(strm);
162
23.4k
        state->how = GZIP;
163
23.4k
        state->junk = 1;
164
23.4k
        state->direct = 0;
165
23.4k
        return 0;
166
23.4k
    }
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
299
    state->x.next = state->out;
172
299
    memcpy(state->x.next, strm->next_in, strm->avail_in);
173
299
    state->x.have = strm->avail_in;
174
299
    strm->avail_in = 0;
175
299
    state->how = COPY;
176
299
    return 0;
177
23.7k
}
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
167k
local int gz_decomp(gz_statep state) {
188
167k
    int ret = Z_OK;
189
167k
    unsigned had;
190
167k
    z_streamp strm = &(state->strm);
191
192
    /* fill output buffer up to end of deflate stream */
193
167k
    had = strm->avail_out;
194
181k
    do {
195
        /* get more input for inflate() */
196
181k
        if (strm->avail_in == 0 && gz_avail(state) == -1) {
197
0
            ret = state->err;
198
0
            break;
199
0
        }
200
181k
        if (strm->avail_in == 0) {
201
14.4k
            if (!state->again)
202
14.4k
                gz_error(state, Z_BUF_ERROR, "unexpected end of file");
203
14.4k
            break;
204
14.4k
        }
205
206
        /* decompress and handle errors */
207
167k
        ret = inflate(strm, Z_NO_FLUSH);
208
167k
        if (strm->avail_out < had)
209
            /* any decompressed data marks this as a real gzip stream */
210
148k
            state->junk = 0;
211
167k
        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
167k
        if (ret == Z_MEM_ERROR) {
217
0
            gz_error(state, Z_MEM_ERROR, "out of memory");
218
0
            break;
219
0
        }
220
167k
        if (ret == Z_DATA_ERROR) {              /* deflate stream invalid */
221
8.49k
            if (state->junk == 1) {             /* trailing garbage is ok */
222
3.98k
                strm->avail_in = 0;
223
3.98k
                state->eof = 1;
224
3.98k
                state->how = LOOK;
225
3.98k
                ret = Z_OK;
226
3.98k
                break;
227
3.98k
            }
228
4.50k
            gz_error(state, Z_DATA_ERROR,
229
4.50k
                     strm->msg == NULL ? "compressed data error" : strm->msg);
230
4.50k
            break;
231
8.49k
        }
232
167k
    } while (strm->avail_out && ret != Z_STREAM_END);
233
234
    /* update available output */
235
167k
    state->x.have = had - strm->avail_out;
236
167k
    state->x.next = strm->next_out - state->x.have;
237
238
    /* if the gzip stream completed successfully, look for another */
239
167k
    if (ret == Z_STREAM_END) {
240
12.3k
        state->junk = 0;
241
12.3k
        state->how = LOOK;
242
12.3k
        return 0;
243
12.3k
    }
244
245
    /* return decompression status */
246
154k
    return ret != Z_OK ? -1 : 0;
247
167k
}
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
156k
local int gz_fetch(gz_statep state) {
256
156k
    z_streamp strm = &(state->strm);
257
258
203k
    do {
259
203k
        switch(state->how) {
260
36.1k
        case LOOK:      /* -> LOOK, COPY (only if never GZIP), or GZIP */
261
36.1k
            if (gz_look(state) == -1)
262
0
                return -1;
263
36.1k
            if (state->how == LOOK)
264
0
                return 0;
265
36.1k
            break;
266
36.1k
        case COPY:      /* -> COPY */
267
20
            if (gz_load(state, state->out, state->size << 1, &(state->x.have))
268
20
                    == -1)
269
0
                return -1;
270
20
            state->x.next = state->out;
271
20
            return 0;
272
167k
        case GZIP:      /* -> GZIP or LOOK (if end of gzip stream) */
273
167k
            strm->avail_out = state->size << 1;
274
167k
            strm->next_out = state->out;
275
167k
            if (gz_decomp(state) == -1)
276
4.50k
                return -1;
277
162k
            break;
278
162k
        default:
279
0
            gz_error(state, Z_STREAM_ERROR, "state corrupt");
280
0
            return -1;
281
203k
        }
282
203k
    } while (state->x.have == 0 && (!state->eof || strm->avail_in));
283
151k
    return 0;
284
156k
}
285
286
/* Skip state->skip (> 0) uncompressed bytes of output.  Return -1 on error, 0
287
   on success. */
288
493
local int gz_skip(gz_statep state) {
289
493
    unsigned n;
290
291
    /* skip over len bytes or reach end-of-file, whichever comes first */
292
11.3k
    do {
293
        /* skip over whatever is in output buffer */
294
11.3k
        if (state->x.have) {
295
5.52k
            n = GT_OFF(state->x.have) ||
296
5.52k
                (z_off64_t)state->x.have > state->skip ?
297
5.27k
                (unsigned)state->skip : state->x.have;
298
5.52k
            state->x.have -= n;
299
5.52k
            state->x.next += n;
300
5.52k
            state->x.pos += n;
301
5.52k
            state->skip -= n;
302
5.52k
        }
303
304
        /* output buffer empty -- return if we're at the end of the input */
305
5.77k
        else if (state->eof && state->strm.avail_in == 0) {
306
212
            if (state->how == GZIP && state->err == Z_OK)
307
4
                gz_error(state, Z_BUF_ERROR, "unexpected end of file");
308
212
            break;
309
212
        }
310
311
        /* need more data to skip -- load up output buffer */
312
5.56k
        else {
313
            /* get more output, looking for header if required */
314
5.56k
            if (gz_fetch(state) == -1)
315
31
                return -1;
316
5.56k
        }
317
11.3k
    } while (state->skip);
318
462
    return 0;
319
493
}
320
321
/* Read len bytes into buf from file, or less than len up to the end of the
322
   input. Return the number of bytes read. If zero is returned, either the end
323
   of file was reached, or there was an error. state->err must be consulted in
324
   that case to determine which. If there was an error, but some uncompressed
325
   bytes were read before the error, then that count is returned. The error is
326
   still recorded, and so is deferred until the next call. */
327
309k
local z_size_t gz_read(gz_statep state, voidp buf, z_size_t len) {
328
309k
    z_size_t got;
329
309k
    unsigned n;
330
309k
    int err;
331
332
    /* if len is zero, avoid unnecessary operations */
333
309k
    if (len == 0)
334
0
        return 0;
335
336
    /* process a skip request */
337
309k
    if (state->skip && gz_skip(state) == -1)
338
31
        return 0;
339
340
    /* get len bytes to buf, or less than len if at the end */
341
309k
    got = 0;
342
309k
    err = 0;
343
581k
    do {
344
        /* set n to the maximum amount of len that fits in an unsigned int */
345
581k
        n = (unsigned)-1;
346
581k
        if (n > len)
347
581k
            n = (unsigned)len;
348
349
        /* first just try copying data from the output buffer */
350
581k
        if (state->x.have) {
351
340k
            if (state->x.have < n)
352
135k
                n = state->x.have;
353
340k
            memcpy(buf, state->x.next, n);
354
340k
            state->x.next += n;
355
340k
            state->x.have -= n;
356
340k
            if (state->err != Z_OK)
357
                /* caught deferred error from gz_fetch() */
358
37.5k
                err = -1;
359
340k
        }
360
361
        /* output buffer empty -- return if we're at the end of the input */
362
241k
        else if (state->eof && state->strm.avail_in == 0) {
363
90.7k
            if (state->how == GZIP && state->err == Z_OK)
364
442
                gz_error(state, Z_BUF_ERROR, "unexpected end of file");
365
90.7k
            break;
366
90.7k
        }
367
368
        /* need output data -- for small len or new stream load up our output
369
           buffer, so that gzgetc() can be fast */
370
150k
        else if (state->how == LOOK || n < (state->size << 1)) {
371
            /* get more output, looking for header if required */
372
150k
            if (gz_fetch(state) == -1 && state->x.have == 0)
373
                /* if state->x.have != 0, error will be caught after copy */
374
13
                err = -1;
375
150k
            continue;       /* no progress yet -- go back to copy above */
376
            /* the copy above assures that we will leave with space in the
377
               output buffer, allowing at least one gzungetc() to succeed */
378
150k
        }
379
380
        /* large len -- read directly into user buffer */
381
0
        else if (state->how == COPY)        /* read directly */
382
0
            err = gz_load(state, (unsigned char *)buf, n, &n);
383
384
        /* large len -- decompress directly into user buffer */
385
0
        else {  /* state->how == GZIP */
386
0
            state->strm.avail_out = n;
387
0
            state->strm.next_out = (unsigned char *)buf;
388
0
            err = gz_decomp(state);
389
0
            n = state->x.have;
390
0
            state->x.have = 0;
391
0
        }
392
393
        /* update progress */
394
340k
        len -= n;
395
340k
        buf = (char *)buf + n;
396
340k
        got += n;
397
340k
        state->x.pos += n;
398
491k
    } while (len && !err);
399
400
    /* note read past eof */
401
309k
    if (len && state->eof)
402
104k
        state->past = 1;
403
404
    /* return number of bytes read into user buffer */
405
309k
    return got;
406
309k
}
407
408
/* -- see zlib.h -- */
409
327k
int ZEXPORT gzread(gzFile file, voidp buf, unsigned len) {
410
327k
    gz_statep state;
411
412
    /* get internal structure and check that it's for reading */
413
327k
    if (file == NULL)
414
0
        return -1;
415
327k
    state = (gz_statep)file;
416
327k
    if (state->mode != GZ_READ)
417
0
        return -1;
418
419
    /* check that there was no (serious) error */
420
327k
    if (state->err != Z_OK && state->err != Z_BUF_ERROR && !state->again)
421
26.8k
        return -1;
422
300k
    if (state->again)
423
0
        gz_error(state, Z_OK, NULL);
424
425
    /* since an int is returned, make sure len fits in one, otherwise return
426
       with an error (this avoids a flaw in the interface) */
427
300k
    if ((int)len < 0) {
428
0
        gz_error(state, Z_STREAM_ERROR, "request does not fit in an int");
429
0
        return -1;
430
0
    }
431
432
    /* read len or fewer bytes to buf */
433
300k
    len = (unsigned)gz_read(state, buf, len);
434
435
    /* check for an error */
436
300k
    if (len == 0) {
437
87.5k
        if (state->err != Z_OK && state->err != Z_BUF_ERROR)
438
30
            return -1;
439
87.4k
        if (state->again) {
440
            /* non-blocking input stalled after some input was read, but no
441
               uncompressed bytes were produced -- let the application know
442
               this isn't EOF */
443
0
            gz_error(state, Z_ERRNO, zstrerror());
444
0
            return -1;
445
0
        }
446
87.4k
    }
447
448
    /* return the number of bytes read */
449
300k
    return (int)len;
450
300k
}
451
452
/* -- see zlib.h -- */
453
z_size_t ZEXPORT gzfread(voidp buf, z_size_t size, z_size_t nitems,
454
0
                         gzFile file) {
455
0
    z_size_t len;
456
0
    gz_statep state;
457
458
    /* get internal structure and check that it's for reading */
459
0
    if (file == NULL)
460
0
        return 0;
461
0
    state = (gz_statep)file;
462
0
    if (state->mode != GZ_READ)
463
0
        return 0;
464
465
    /* check that there was no (serious) error */
466
0
    if (state->err != Z_OK && state->err != Z_BUF_ERROR && !state->again)
467
0
        return 0;
468
0
    if (state->again)
469
0
        gz_error(state, Z_OK, NULL);
470
471
    /* compute bytes to read -- error on overflow */
472
0
    len = nitems * size;
473
0
    if (size && len / size != nitems) {
474
0
        gz_error(state, Z_STREAM_ERROR, "request does not fit in a size_t");
475
0
        return 0;
476
0
    }
477
478
    /* read len or fewer bytes to buf, return the number of full items read */
479
0
    return len ? gz_read(state, buf, len) / size : 0;
480
0
}
481
482
/* -- see zlib.h -- */
483
#ifdef Z_PREFIX_SET
484
#  undef z_gzgetc
485
#else
486
#  undef gzgetc
487
#endif
488
10.0k
int ZEXPORT gzgetc(gzFile file) {
489
10.0k
    unsigned char buf[1];
490
10.0k
    gz_statep state;
491
492
    /* get internal structure and check that it's for reading */
493
10.0k
    if (file == NULL)
494
0
        return -1;
495
10.0k
    state = (gz_statep)file;
496
10.0k
    if (state->mode != GZ_READ)
497
0
        return -1;
498
499
    /* check that there was no (serious) error */
500
10.0k
    if (state->err != Z_OK && state->err != Z_BUF_ERROR && !state->again)
501
377
        return -1;
502
9.64k
    if (state->again)
503
0
        gz_error(state, Z_OK, NULL);
504
505
    /* try output buffer (no need to check for skip request) */
506
9.64k
    if (state->x.have) {
507
0
        state->x.have--;
508
0
        state->x.pos++;
509
0
        return *(state->x.next)++;
510
0
    }
511
512
    /* nothing there -- try gz_read() */
513
9.64k
    return gz_read(state, buf, 1) < 1 ? -1 : buf[0];
514
9.64k
}
515
516
0
int ZEXPORT gzgetc_(gzFile file) {
517
0
    return gzgetc(file);
518
0
}
519
520
/* -- see zlib.h -- */
521
0
int ZEXPORT gzungetc(int c, gzFile file) {
522
0
    gz_statep state;
523
524
    /* get internal structure and check that it's for reading */
525
0
    if (file == NULL)
526
0
        return -1;
527
0
    state = (gz_statep)file;
528
0
    if (state->mode != GZ_READ)
529
0
        return -1;
530
531
    /* in case this was just opened, set up the input buffer */
532
0
    if (state->how == LOOK && state->x.have == 0)
533
0
        (void)gz_look(state);
534
535
    /* check that there was no (serious) error */
536
0
    if (state->err != Z_OK && state->err != Z_BUF_ERROR && !state->again)
537
0
        return -1;
538
0
    if (state->again)
539
0
        gz_error(state, Z_OK, NULL);
540
541
    /* process a skip request */
542
0
    if (state->skip && gz_skip(state) == -1)
543
0
        return -1;
544
545
    /* can't push EOF */
546
0
    if (c < 0)
547
0
        return -1;
548
549
    /* if output buffer empty, put byte at end (allows more pushing) */
550
0
    if (state->x.have == 0) {
551
0
        state->x.have = 1;
552
0
        state->x.next = state->out + (state->size << 1) - 1;
553
0
        state->x.next[0] = (unsigned char)c;
554
0
        state->x.pos--;
555
0
        state->past = 0;
556
0
        return c;
557
0
    }
558
559
    /* if no room, give up (must have already done a gzungetc()) */
560
0
    if (state->x.have == (state->size << 1)) {
561
0
        gz_error(state, Z_DATA_ERROR, "out of room to push characters");
562
0
        return -1;
563
0
    }
564
565
    /* slide output data if needed and insert byte before existing data */
566
0
    if (state->x.next == state->out) {
567
0
        unsigned char *src = state->out + state->x.have;
568
0
        unsigned char *dest = state->out + (state->size << 1);
569
570
0
        while (src > state->out)
571
0
            *--dest = *--src;
572
0
        state->x.next = dest;
573
0
    }
574
0
    state->x.have++;
575
0
    state->x.next--;
576
0
    state->x.next[0] = (unsigned char)c;
577
0
    state->x.pos--;
578
0
    state->past = 0;
579
0
    return c;
580
0
}
581
582
/* -- see zlib.h -- */
583
0
char * ZEXPORT gzgets(gzFile file, char *buf, int len) {
584
0
    unsigned left, n;
585
0
    char *str;
586
0
    unsigned char *eol;
587
0
    gz_statep state;
588
589
    /* check parameters, get internal structure, and check that it's for
590
       reading */
591
0
    if (file == NULL || buf == NULL || len < 1)
592
0
        return NULL;
593
0
    state = (gz_statep)file;
594
0
    if (state->mode != GZ_READ)
595
0
        return NULL;
596
597
    /* check that there was no (serious) error */
598
0
    if (state->err != Z_OK && state->err != Z_BUF_ERROR && !state->again)
599
0
        return NULL;
600
0
    if (state->again)
601
0
        gz_error(state, Z_OK, NULL);
602
603
    /* process a skip request */
604
0
    if (state->skip && gz_skip(state) == -1)
605
0
        return NULL;
606
607
    /* copy output up to a new line, len-1 bytes, or there is no more output,
608
       whichever comes first */
609
0
    str = buf;
610
0
    left = (unsigned)len - 1;
611
0
    if (left) do {
612
        /* assure that something is in the output buffer */
613
0
        if (state->x.have == 0 && gz_fetch(state) == -1)
614
0
            break;                      /* error */
615
0
        if (state->x.have == 0) {       /* end of file */
616
0
            state->past = 1;            /* read past end */
617
0
            break;                      /* return what we have */
618
0
        }
619
620
        /* look for end-of-line in current output buffer */
621
0
        n = state->x.have > left ? left : state->x.have;
622
0
        eol = (unsigned char *)memchr(state->x.next, '\n', n);
623
0
        if (eol != NULL)
624
0
            n = (unsigned)(eol - state->x.next) + 1;
625
626
        /* copy through end-of-line, or remainder if not found */
627
0
        memcpy(buf, state->x.next, n);
628
0
        state->x.have -= n;
629
0
        state->x.next += n;
630
0
        state->x.pos += n;
631
0
        left -= n;
632
0
        buf += n;
633
0
    } while (left && eol == NULL);
634
635
    /* append a terminating zero to the string (we don't check for a zero in
636
       the contents, let the user worry about that) -- return the terminated
637
       string, or if nothing was read, NULL */
638
0
    if (buf == str)
639
0
        return NULL;
640
0
    buf[0] = 0;
641
0
    return str;
642
0
}
643
644
/* -- see zlib.h -- */
645
0
int ZEXPORT gzdirect(gzFile file) {
646
0
    gz_statep state;
647
648
    /* get internal structure */
649
0
    if (file == NULL)
650
0
        return 0;
651
0
    state = (gz_statep)file;
652
653
    /* if the state is not known, but we can find out, then do so (this is
654
       mainly for right after a gzopen() or gzdopen()) */
655
0
    if (state->mode == GZ_READ && state->how == LOOK && state->x.have == 0)
656
0
        (void)gz_look(state);
657
658
    /* return 1 if transparent, 0 if processing a gzip stream */
659
0
    return state->direct == 1;
660
0
}
661
662
/* -- see zlib.h -- */
663
45.1k
int ZEXPORT gzclose_r(gzFile file) {
664
45.1k
    int ret, err;
665
45.1k
    gz_statep state;
666
667
    /* get internal structure and check that it's for reading */
668
45.1k
    if (file == NULL)
669
0
        return Z_STREAM_ERROR;
670
45.1k
    state = (gz_statep)file;
671
45.1k
    if (state->mode != GZ_READ)
672
0
        return Z_STREAM_ERROR;
673
674
    /* free memory and close file */
675
45.1k
    if (state->size) {
676
23.3k
        inflateEnd(&(state->strm));
677
23.3k
        free(state->out);
678
23.3k
        free(state->in);
679
23.3k
    }
680
45.1k
    err = state->err == Z_BUF_ERROR ? Z_BUF_ERROR : Z_OK;
681
45.1k
    gz_error(state, Z_OK, NULL);
682
45.1k
    free(state->path);
683
45.1k
    ret = close(state->fd);
684
45.1k
    free(state);
685
45.1k
    return ret ? Z_ERRNO : err;
686
45.1k
}