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