Coverage Report

Created: 2025-12-13 07:57

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