| OLD | NEW | 
|---|
| 1 /* gzread.c -- zlib functions for reading gzip files | 1 /* gzread.c -- zlib functions for reading gzip files | 
| 2  * Copyright (C) 2004, 2005, 2010, 2011, 2012, 2013 Mark Adler | 2  * Copyright (C) 2004, 2005, 2010, 2011, 2012, 2013, 2016 Mark Adler | 
| 3  * For conditions of distribution and use, see copyright notice in zlib.h | 3  * For conditions of distribution and use, see copyright notice in zlib.h | 
| 4  */ | 4  */ | 
| 5 | 5 | 
| 6 #include "gzguts.h" | 6 #include "gzguts.h" | 
| 7 | 7 | 
| 8 /* Local functions */ | 8 /* Local functions */ | 
| 9 local int gz_load OF((gz_statep, unsigned char *, unsigned, unsigned *)); | 9 local int gz_load OF((gz_statep, unsigned char *, unsigned, unsigned *)); | 
| 10 local int gz_avail OF((gz_statep)); | 10 local int gz_avail OF((gz_statep)); | 
| 11 local int gz_look OF((gz_statep)); | 11 local int gz_look OF((gz_statep)); | 
| 12 local int gz_decomp OF((gz_statep)); | 12 local int gz_decomp OF((gz_statep)); | 
| 13 local int gz_fetch OF((gz_statep)); | 13 local int gz_fetch OF((gz_statep)); | 
| 14 local int gz_skip OF((gz_statep, z_off64_t)); | 14 local int gz_skip OF((gz_statep, z_off64_t)); | 
|  | 15 local z_size_t gz_read OF((gz_statep, voidp, z_size_t)); | 
| 15 | 16 | 
| 16 /* Use read() to load a buffer -- return -1 on error, otherwise 0.  Read from | 17 /* Use read() to load a buffer -- return -1 on error, otherwise 0.  Read from | 
| 17    state->fd, and update state->eof, state->err, and state->msg as appropriate. | 18    state->fd, and update state->eof, state->err, and state->msg as appropriate. | 
| 18    This function needs to loop on read(), since read() is not guaranteed to | 19    This function needs to loop on read(), since read() is not guaranteed to | 
| 19    read the number of bytes requested, depending on the type of descriptor. */ | 20    read the number of bytes requested, depending on the type of descriptor. */ | 
| 20 local int gz_load(state, buf, len, have) | 21 local int gz_load(state, buf, len, have) | 
| 21     gz_statep state; | 22     gz_statep state; | 
| 22     unsigned char *buf; | 23     unsigned char *buf; | 
| 23     unsigned len; | 24     unsigned len; | 
| 24     unsigned *have; | 25     unsigned *have; | 
| 25 { | 26 { | 
| 26     int ret; | 27     int ret; | 
|  | 28     unsigned get, max = ((unsigned)-1 >> 2) + 1; | 
| 27 | 29 | 
| 28     *have = 0; | 30     *have = 0; | 
| 29     do { | 31     do { | 
| 30         ret = read(state->fd, buf + *have, len - *have); | 32         get = len - *have; | 
|  | 33         if (get > max) | 
|  | 34             get = max; | 
|  | 35         ret = read(state->fd, buf + *have, get); | 
| 31         if (ret <= 0) | 36         if (ret <= 0) | 
| 32             break; | 37             break; | 
| 33         *have += ret; | 38         *have += (unsigned)ret; | 
| 34     } while (*have < len); | 39     } while (*have < len); | 
| 35     if (ret < 0) { | 40     if (ret < 0) { | 
| 36         gz_error(state, Z_ERRNO, zstrerror()); | 41         gz_error(state, Z_ERRNO, zstrerror()); | 
| 37         return -1; | 42         return -1; | 
| 38     } | 43     } | 
| 39     if (ret == 0) | 44     if (ret == 0) | 
| 40         state->eof = 1; | 45         state->eof = 1; | 
| 41     return 0; | 46     return 0; | 
| 42 } | 47 } | 
| 43 | 48 | 
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 87     gz_statep state; | 92     gz_statep state; | 
| 88 { | 93 { | 
| 89     z_streamp strm = &(state->strm); | 94     z_streamp strm = &(state->strm); | 
| 90 | 95 | 
| 91     /* allocate read buffers and inflate memory */ | 96     /* allocate read buffers and inflate memory */ | 
| 92     if (state->size == 0) { | 97     if (state->size == 0) { | 
| 93         /* allocate buffers */ | 98         /* allocate buffers */ | 
| 94         state->in = (unsigned char *)malloc(state->want); | 99         state->in = (unsigned char *)malloc(state->want); | 
| 95         state->out = (unsigned char *)malloc(state->want << 1); | 100         state->out = (unsigned char *)malloc(state->want << 1); | 
| 96         if (state->in == NULL || state->out == NULL) { | 101         if (state->in == NULL || state->out == NULL) { | 
| 97             if (state->out != NULL) | 102             free(state->out); | 
| 98                 free(state->out); | 103             free(state->in); | 
| 99             if (state->in != NULL) |  | 
| 100                 free(state->in); |  | 
| 101             gz_error(state, Z_MEM_ERROR, "out of memory"); | 104             gz_error(state, Z_MEM_ERROR, "out of memory"); | 
| 102             return -1; | 105             return -1; | 
| 103         } | 106         } | 
| 104         state->size = state->want; | 107         state->size = state->want; | 
| 105 | 108 | 
| 106         /* allocate inflate memory */ | 109         /* allocate inflate memory */ | 
| 107         state->strm.zalloc = Z_NULL; | 110         state->strm.zalloc = Z_NULL; | 
| 108         state->strm.zfree = Z_NULL; | 111         state->strm.zfree = Z_NULL; | 
| 109         state->strm.opaque = Z_NULL; | 112         state->strm.opaque = Z_NULL; | 
| 110         state->strm.avail_in = 0; | 113         state->strm.avail_in = 0; | 
| (...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 277 | 280 | 
| 278         /* need more data to skip -- load up output buffer */ | 281         /* need more data to skip -- load up output buffer */ | 
| 279         else { | 282         else { | 
| 280             /* get more output, looking for header if required */ | 283             /* get more output, looking for header if required */ | 
| 281             if (gz_fetch(state) == -1) | 284             if (gz_fetch(state) == -1) | 
| 282                 return -1; | 285                 return -1; | 
| 283         } | 286         } | 
| 284     return 0; | 287     return 0; | 
| 285 } | 288 } | 
| 286 | 289 | 
| 287 /* -- see zlib.h -- */ | 290 /* Read len bytes into buf from file, or less than len up to the end of the | 
| 288 int ZEXPORT gzread(file, buf, len) | 291    input.  Return the number of bytes read.  If zero is returned, either the | 
| 289     gzFile file; | 292    end of file was reached, or there was an error.  state->err must be | 
|  | 293    consulted in that case to determine which. */ | 
|  | 294 local z_size_t gz_read(state, buf, len) | 
|  | 295     gz_statep state; | 
| 290     voidp buf; | 296     voidp buf; | 
| 291     unsigned len; | 297     z_size_t len; | 
| 292 { | 298 { | 
| 293     unsigned got, n; | 299     z_size_t got; | 
| 294     gz_statep state; | 300     unsigned n; | 
| 295     z_streamp strm; |  | 
| 296 |  | 
| 297     /* get internal structure */ |  | 
| 298     if (file == NULL) |  | 
| 299         return -1; |  | 
| 300     state = (gz_statep)file; |  | 
| 301     strm = &(state->strm); |  | 
| 302 |  | 
| 303     /* check that we're reading and that there's no (serious) error */ |  | 
| 304     if (state->mode != GZ_READ || |  | 
| 305             (state->err != Z_OK && state->err != Z_BUF_ERROR)) |  | 
| 306         return -1; |  | 
| 307 |  | 
| 308     /* since an int is returned, make sure len fits in one, otherwise return |  | 
| 309        with an error (this avoids the flaw in the interface) */ |  | 
| 310     if ((int)len < 0) { |  | 
| 311         gz_error(state, Z_DATA_ERROR, "requested length does not fit in int"); |  | 
| 312         return -1; |  | 
| 313     } |  | 
| 314 | 301 | 
| 315     /* if len is zero, avoid unnecessary operations */ | 302     /* if len is zero, avoid unnecessary operations */ | 
| 316     if (len == 0) | 303     if (len == 0) | 
| 317         return 0; | 304         return 0; | 
| 318 | 305 | 
| 319     /* process a skip request */ | 306     /* process a skip request */ | 
| 320     if (state->seek) { | 307     if (state->seek) { | 
| 321         state->seek = 0; | 308         state->seek = 0; | 
| 322         if (gz_skip(state, state->skip) == -1) | 309         if (gz_skip(state, state->skip) == -1) | 
| 323             return -1; | 310             return 0; | 
| 324     } | 311     } | 
| 325 | 312 | 
| 326     /* get len bytes to buf, or less than len if at the end */ | 313     /* get len bytes to buf, or less than len if at the end */ | 
| 327     got = 0; | 314     got = 0; | 
| 328     do { | 315     do { | 
|  | 316         /* set n to the maximum amount of len that fits in an unsigned int */ | 
|  | 317         n = -1; | 
|  | 318         if (n > len) | 
|  | 319             n = len; | 
|  | 320 | 
| 329         /* first just try copying data from the output buffer */ | 321         /* first just try copying data from the output buffer */ | 
| 330         if (state->x.have) { | 322         if (state->x.have) { | 
| 331             n = state->x.have > len ? len : state->x.have; | 323             if (state->x.have < n) | 
|  | 324                 n = state->x.have; | 
| 332             memcpy(buf, state->x.next, n); | 325             memcpy(buf, state->x.next, n); | 
| 333             state->x.next += n; | 326             state->x.next += n; | 
| 334             state->x.have -= n; | 327             state->x.have -= n; | 
| 335         } | 328         } | 
| 336 | 329 | 
| 337         /* output buffer empty -- return if we're at the end of the input */ | 330         /* output buffer empty -- return if we're at the end of the input */ | 
| 338         else if (state->eof && strm->avail_in == 0) { | 331         else if (state->eof && state->strm.avail_in == 0) { | 
| 339             state->past = 1;        /* tried to read past end */ | 332             state->past = 1;        /* tried to read past end */ | 
| 340             break; | 333             break; | 
| 341         } | 334         } | 
| 342 | 335 | 
| 343         /* need output data -- for small len or new stream load up our output | 336         /* need output data -- for small len or new stream load up our output | 
| 344            buffer */ | 337            buffer */ | 
| 345         else if (state->how == LOOK || len < (state->size << 1)) { | 338         else if (state->how == LOOK || n < (state->size << 1)) { | 
| 346             /* get more output, looking for header if required */ | 339             /* get more output, looking for header if required */ | 
| 347             if (gz_fetch(state) == -1) | 340             if (gz_fetch(state) == -1) | 
| 348                 return -1; | 341                 return 0; | 
| 349             continue;       /* no progress yet -- go back to copy above */ | 342             continue;       /* no progress yet -- go back to copy above */ | 
| 350             /* the copy above assures that we will leave with space in the | 343             /* the copy above assures that we will leave with space in the | 
| 351                output buffer, allowing at least one gzungetc() to succeed */ | 344                output buffer, allowing at least one gzungetc() to succeed */ | 
| 352         } | 345         } | 
| 353 | 346 | 
| 354         /* large len -- read directly into user buffer */ | 347         /* large len -- read directly into user buffer */ | 
| 355         else if (state->how == COPY) {      /* read directly */ | 348         else if (state->how == COPY) {      /* read directly */ | 
| 356             if (gz_load(state, (unsigned char *)buf, len, &n) == -1) | 349             if (gz_load(state, (unsigned char *)buf, n, &n) == -1) | 
| 357                 return -1; | 350                 return 0; | 
| 358         } | 351         } | 
| 359 | 352 | 
| 360         /* large len -- decompress directly into user buffer */ | 353         /* large len -- decompress directly into user buffer */ | 
| 361         else {  /* state->how == GZIP */ | 354         else {  /* state->how == GZIP */ | 
| 362             strm->avail_out = len; | 355             state->strm.avail_out = n; | 
| 363             strm->next_out = (unsigned char *)buf; | 356             state->strm.next_out = (unsigned char *)buf; | 
| 364             if (gz_decomp(state) == -1) | 357             if (gz_decomp(state) == -1) | 
| 365                 return -1; | 358                 return 0; | 
| 366             n = state->x.have; | 359             n = state->x.have; | 
| 367             state->x.have = 0; | 360             state->x.have = 0; | 
| 368         } | 361         } | 
| 369 | 362 | 
| 370         /* update progress */ | 363         /* update progress */ | 
| 371         len -= n; | 364         len -= n; | 
| 372         buf = (char *)buf + n; | 365         buf = (char *)buf + n; | 
| 373         got += n; | 366         got += n; | 
| 374         state->x.pos += n; | 367         state->x.pos += n; | 
| 375     } while (len); | 368     } while (len); | 
| 376 | 369 | 
| 377     /* return number of bytes read into user buffer (will fit in int) */ | 370     /* return number of bytes read into user buffer */ | 
| 378     return (int)got; | 371     return got; | 
| 379 } | 372 } | 
| 380 | 373 | 
| 381 /* -- see zlib.h -- */ | 374 /* -- see zlib.h -- */ | 
|  | 375 int ZEXPORT gzread(file, buf, len) | 
|  | 376     gzFile file; | 
|  | 377     voidp buf; | 
|  | 378     unsigned len; | 
|  | 379 { | 
|  | 380     gz_statep state; | 
|  | 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 */ | 
|  | 400     len = gz_read(state, buf, len); | 
|  | 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 -- */ | 
|  | 411 z_size_t ZEXPORT gzfread(buf, size, nitems, file) | 
|  | 412     voidp buf; | 
|  | 413     z_size_t size; | 
|  | 414     z_size_t nitems; | 
|  | 415     gzFile file; | 
|  | 416 { | 
|  | 417     z_size_t len; | 
|  | 418     gz_statep state; | 
|  | 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 -- */ | 
| 382 #ifdef Z_PREFIX_SET | 442 #ifdef Z_PREFIX_SET | 
| 383 #  undef z_gzgetc | 443 #  undef z_gzgetc | 
| 384 #else | 444 #else | 
| 385 #  undef gzgetc | 445 #  undef gzgetc | 
| 386 #  ifdef MOZZCONF_H | 446 #  ifdef Z_CR_PREFIX_SET | 
| 387 #    define gzgetc MOZ_Z_gzgetc | 447 #    define gzgetc Cr_z_gzgetc | 
| 388 #  endif | 448 #  endif | 
| 389 #endif | 449 #endif | 
| 390 | 450 | 
| 391 int ZEXPORT gzgetc(file) | 451 int ZEXPORT gzgetc(file) | 
| 392     gzFile file; | 452     gzFile file; | 
| 393 { | 453 { | 
| 394     int ret; | 454     int ret; | 
| 395     unsigned char buf[1]; | 455     unsigned char buf[1]; | 
| 396     gz_statep state; | 456     gz_statep state; | 
| 397 | 457 | 
| 398     /* get internal structure */ | 458     /* get internal structure */ | 
| 399     if (file == NULL) | 459     if (file == NULL) | 
| 400         return -1; | 460         return -1; | 
| 401     state = (gz_statep)file; | 461     state = (gz_statep)file; | 
| 402 | 462 | 
| 403     /* check that we're reading and that there's no (serious) error */ | 463     /* check that we're reading and that there's no (serious) error */ | 
| 404     if (state->mode != GZ_READ || | 464     if (state->mode != GZ_READ || | 
| 405         (state->err != Z_OK && state->err != Z_BUF_ERROR)) | 465         (state->err != Z_OK && state->err != Z_BUF_ERROR)) | 
| 406         return -1; | 466         return -1; | 
| 407 | 467 | 
| 408     /* try output buffer (no need to check for skip request) */ | 468     /* try output buffer (no need to check for skip request) */ | 
| 409     if (state->x.have) { | 469     if (state->x.have) { | 
| 410         state->x.have--; | 470         state->x.have--; | 
| 411         state->x.pos++; | 471         state->x.pos++; | 
| 412         return *(state->x.next)++; | 472         return *(state->x.next)++; | 
| 413     } | 473     } | 
| 414 | 474 | 
| 415     /* nothing there -- try gzread() */ | 475     /* nothing there -- try gz_read() */ | 
| 416     ret = gzread(file, buf, 1); | 476     ret = gz_read(state, buf, 1); | 
| 417     return ret < 1 ? -1 : buf[0]; | 477     return ret < 1 ? -1 : buf[0]; | 
| 418 } | 478 } | 
| 419 | 479 | 
| 420 int ZEXPORT gzgetc_(file) | 480 int ZEXPORT gzgetc_(file) | 
| 421 gzFile file; | 481 gzFile file; | 
| 422 { | 482 { | 
| 423     return gzgetc(file); | 483     return gzgetc(file); | 
| 424 } | 484 } | 
| 425 | 485 | 
| 426 /* -- see zlib.h -- */ | 486 /* -- see zlib.h -- */ | 
| (...skipping 21 matching lines...) Expand all  Loading... | 
| 448     } | 508     } | 
| 449 | 509 | 
| 450     /* can't push EOF */ | 510     /* can't push EOF */ | 
| 451     if (c < 0) | 511     if (c < 0) | 
| 452         return -1; | 512         return -1; | 
| 453 | 513 | 
| 454     /* if output buffer empty, put byte at end (allows more pushing) */ | 514     /* if output buffer empty, put byte at end (allows more pushing) */ | 
| 455     if (state->x.have == 0) { | 515     if (state->x.have == 0) { | 
| 456         state->x.have = 1; | 516         state->x.have = 1; | 
| 457         state->x.next = state->out + (state->size << 1) - 1; | 517         state->x.next = state->out + (state->size << 1) - 1; | 
| 458         state->x.next[0] = c; | 518         state->x.next[0] = (unsigned char)c; | 
| 459         state->x.pos--; | 519         state->x.pos--; | 
| 460         state->past = 0; | 520         state->past = 0; | 
| 461         return c; | 521         return c; | 
| 462     } | 522     } | 
| 463 | 523 | 
| 464     /* if no room, give up (must have already done a gzungetc()) */ | 524     /* if no room, give up (must have already done a gzungetc()) */ | 
| 465     if (state->x.have == (state->size << 1)) { | 525     if (state->x.have == (state->size << 1)) { | 
| 466         gz_error(state, Z_DATA_ERROR, "out of room to push characters"); | 526         gz_error(state, Z_DATA_ERROR, "out of room to push characters"); | 
| 467         return -1; | 527         return -1; | 
| 468     } | 528     } | 
| 469 | 529 | 
| 470     /* slide output data if needed and insert byte before existing data */ | 530     /* slide output data if needed and insert byte before existing data */ | 
| 471     if (state->x.next == state->out) { | 531     if (state->x.next == state->out) { | 
| 472         unsigned char *src = state->out + state->x.have; | 532         unsigned char *src = state->out + state->x.have; | 
| 473         unsigned char *dest = state->out + (state->size << 1); | 533         unsigned char *dest = state->out + (state->size << 1); | 
| 474         while (src > state->out) | 534         while (src > state->out) | 
| 475             *--dest = *--src; | 535             *--dest = *--src; | 
| 476         state->x.next = dest; | 536         state->x.next = dest; | 
| 477     } | 537     } | 
| 478     state->x.have++; | 538     state->x.have++; | 
| 479     state->x.next--; | 539     state->x.next--; | 
| 480     state->x.next[0] = c; | 540     state->x.next[0] = (unsigned char)c; | 
| 481     state->x.pos--; | 541     state->x.pos--; | 
| 482     state->past = 0; | 542     state->past = 0; | 
| 483     return c; | 543     return c; | 
| 484 } | 544 } | 
| 485 | 545 | 
| 486 /* -- see zlib.h -- */ | 546 /* -- see zlib.h -- */ | 
| 487 char * ZEXPORT gzgets(file, buf, len) | 547 char * ZEXPORT gzgets(file, buf, len) | 
| 488     gzFile file; | 548     gzFile file; | 
| 489     char *buf; | 549     char *buf; | 
| 490     int len; | 550     int len; | 
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 589         free(state->out); | 649         free(state->out); | 
| 590         free(state->in); | 650         free(state->in); | 
| 591     } | 651     } | 
| 592     err = state->err == Z_BUF_ERROR ? Z_BUF_ERROR : Z_OK; | 652     err = state->err == Z_BUF_ERROR ? Z_BUF_ERROR : Z_OK; | 
| 593     gz_error(state, Z_OK, NULL); | 653     gz_error(state, Z_OK, NULL); | 
| 594     free(state->path); | 654     free(state->path); | 
| 595     ret = close(state->fd); | 655     ret = close(state->fd); | 
| 596     free(state); | 656     free(state); | 
| 597     return ret ? Z_ERRNO : err; | 657     return ret ? Z_ERRNO : err; | 
| 598 } | 658 } | 
| OLD | NEW | 
|---|