1 /* 2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3 * 4 * This code is free software; you can redistribute it and/or modify it 5 * under the terms of the GNU General Public License version 2 only, as 6 * published by the Free Software Foundation. Oracle designates this 7 * particular file as subject to the "Classpath" exception as provided 8 * by Oracle in the LICENSE file that accompanied this code. 9 * 10 * This code is distributed in the hope that it will be useful, but WITHOUT 11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 * version 2 for more details (a copy is included in the LICENSE file that 14 * accompanied this code). 15 * 16 * You should have received a copy of the GNU General Public License version 17 * 2 along with this work; if not, write to the Free Software Foundation, 18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 19 * 20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 21 * or visit www.oracle.com if you need additional information or have any 22 * questions. 23 */ 24 25 /* gzlib.c -- zlib functions common to reading and writing gzip files 26 * Copyright (C) 2004-2017 Mark Adler 27 * For conditions of distribution and use, see copyright notice in zlib.h 28 */ 29 30 #include "gzguts.h" 31 32 #if defined(_WIN32) && !defined(__BORLANDC__) && !defined(__MINGW32__) 33 # define LSEEK _lseeki64 34 #else 35 #if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0 36 # define LSEEK lseek64 37 #else 38 # define LSEEK lseek 39 #endif 40 #endif 41 42 /* Local functions */ 43 local void gz_reset OF((gz_statep)); 44 local gzFile gz_open OF((const void *, int, const char *)); 45 46 #if defined UNDER_CE 47 48 /* Map the Windows error number in ERROR to a locale-dependent error message 49 string and return a pointer to it. Typically, the values for ERROR come 50 from GetLastError. 51 52 The string pointed to shall not be modified by the application, but may be 53 overwritten by a subsequent call to gz_strwinerror 54 55 The gz_strwinerror function does not change the current setting of 56 GetLastError. */ 57 char ZLIB_INTERNAL *gz_strwinerror (error) 58 DWORD error; 59 { 60 static char buf[1024]; 61 62 wchar_t *msgbuf; 63 DWORD lasterr = GetLastError(); 64 DWORD chars = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM 65 | FORMAT_MESSAGE_ALLOCATE_BUFFER, 66 NULL, 67 error, 68 0, /* Default language */ 69 (LPVOID)&msgbuf, 70 0, 71 NULL); 72 if (chars != 0) { 73 /* If there is an \r\n appended, zap it. */ 74 if (chars >= 2 75 && msgbuf[chars - 2] == '\r' && msgbuf[chars - 1] == '\n') { 76 chars -= 2; 77 msgbuf[chars] = 0; 78 } 79 80 if (chars > sizeof (buf) - 1) { 81 chars = sizeof (buf) - 1; 82 msgbuf[chars] = 0; 83 } 84 85 wcstombs(buf, msgbuf, chars + 1); 86 LocalFree(msgbuf); 87 } 88 else { 89 sprintf(buf, "unknown win32 error (%ld)", error); 90 } 91 92 SetLastError(lasterr); 93 return buf; 94 } 95 96 #endif /* UNDER_CE */ 97 98 /* Reset gzip file state */ 99 local void gz_reset(state) 100 gz_statep state; 101 { 102 state->x.have = 0; /* no output data available */ 103 if (state->mode == GZ_READ) { /* for reading ... */ 104 state->eof = 0; /* not at end of file */ 105 state->past = 0; /* have not read past end yet */ 106 state->how = LOOK; /* look for gzip header */ 107 } 108 state->seek = 0; /* no seek request pending */ 109 gz_error(state, Z_OK, NULL); /* clear error */ 110 state->x.pos = 0; /* no uncompressed data yet */ 111 state->strm.avail_in = 0; /* no input data yet */ 112 } 113 114 /* Open a gzip file either by name or file descriptor. */ 115 local gzFile gz_open(path, fd, mode) 116 const void *path; 117 int fd; 118 const char *mode; 119 { 120 gz_statep state; 121 z_size_t len; 122 int oflag; 123 #ifdef O_CLOEXEC 124 int cloexec = 0; 125 #endif 126 #ifdef O_EXCL 127 int exclusive = 0; 128 #endif 129 130 /* check input */ 131 if (path == NULL) 132 return NULL; 133 134 /* allocate gzFile structure to return */ 135 state = (gz_statep)malloc(sizeof(gz_state)); 136 if (state == NULL) 137 return NULL; 138 state->size = 0; /* no buffers allocated yet */ 139 state->want = GZBUFSIZE; /* requested buffer size */ 140 state->msg = NULL; /* no error message yet */ 141 142 /* interpret mode */ 143 state->mode = GZ_NONE; 144 state->level = Z_DEFAULT_COMPRESSION; 145 state->strategy = Z_DEFAULT_STRATEGY; 146 state->direct = 0; 147 while (*mode) { 148 if (*mode >= '0' && *mode <= '9') 149 state->level = *mode - '0'; 150 else 151 switch (*mode) { 152 case 'r': 153 state->mode = GZ_READ; 154 break; 155 #ifndef NO_GZCOMPRESS 156 case 'w': 157 state->mode = GZ_WRITE; 158 break; 159 case 'a': 160 state->mode = GZ_APPEND; 161 break; 162 #endif 163 case '+': /* can't read and write at the same time */ 164 free(state); 165 return NULL; 166 case 'b': /* ignore -- will request binary anyway */ 167 break; 168 #ifdef O_CLOEXEC 169 case 'e': 170 cloexec = 1; 171 break; 172 #endif 173 #ifdef O_EXCL 174 case 'x': 175 exclusive = 1; 176 break; 177 #endif 178 case 'f': 179 state->strategy = Z_FILTERED; 180 break; 181 case 'h': 182 state->strategy = Z_HUFFMAN_ONLY; 183 break; 184 case 'R': 185 state->strategy = Z_RLE; 186 break; 187 case 'F': 188 state->strategy = Z_FIXED; 189 break; 190 case 'T': 191 state->direct = 1; 192 break; 193 default: /* could consider as an error, but just ignore */ 194 ; 195 } 196 mode++; 197 } 198 199 /* must provide an "r", "w", or "a" */ 200 if (state->mode == GZ_NONE) { 201 free(state); 202 return NULL; 203 } 204 205 /* can't force transparent read */ 206 if (state->mode == GZ_READ) { 207 if (state->direct) { 208 free(state); 209 return NULL; 210 } 211 state->direct = 1; /* for empty file */ 212 } 213 214 /* save the path name for error messages */ 215 #ifdef WIDECHAR 216 if (fd == -2) { 217 len = wcstombs(NULL, path, 0); 218 if (len == (z_size_t)-1) 219 len = 0; 220 } 221 else 222 #endif 223 len = strlen((const char *)path); 224 state->path = (char *)malloc(len + 1); 225 if (state->path == NULL) { 226 free(state); 227 return NULL; 228 } 229 #ifdef WIDECHAR 230 if (fd == -2) 231 if (len) 232 wcstombs(state->path, path, len + 1); 233 else 234 *(state->path) = 0; 235 else 236 #endif 237 #if !defined(NO_snprintf) && !defined(NO_vsnprintf) 238 (void)snprintf(state->path, len + 1, "%s", (const char *)path); 239 #else 240 strcpy(state->path, path); 241 #endif 242 243 /* compute the flags for open() */ 244 oflag = 245 #ifdef O_LARGEFILE 246 O_LARGEFILE | 247 #endif 248 #ifdef O_BINARY 249 O_BINARY | 250 #endif 251 #ifdef O_CLOEXEC 252 (cloexec ? O_CLOEXEC : 0) | 253 #endif 254 (state->mode == GZ_READ ? 255 O_RDONLY : 256 (O_WRONLY | O_CREAT | 257 #ifdef O_EXCL 258 (exclusive ? O_EXCL : 0) | 259 #endif 260 (state->mode == GZ_WRITE ? 261 O_TRUNC : 262 O_APPEND))); 263 264 /* open the file with the appropriate flags (or just use fd) */ 265 state->fd = fd > -1 ? fd : ( 266 #ifdef WIDECHAR 267 fd == -2 ? _wopen(path, oflag, 0666) : 268 #endif 269 open((const char *)path, oflag, 0666)); 270 if (state->fd == -1) { 271 free(state->path); 272 free(state); 273 return NULL; 274 } 275 if (state->mode == GZ_APPEND) { 276 LSEEK(state->fd, 0, SEEK_END); /* so gzoffset() is correct */ 277 state->mode = GZ_WRITE; /* simplify later checks */ 278 } 279 280 /* save the current position for rewinding (only if reading) */ 281 if (state->mode == GZ_READ) { 282 state->start = LSEEK(state->fd, 0, SEEK_CUR); 283 if (state->start == -1) state->start = 0; 284 } 285 286 /* initialize stream */ 287 gz_reset(state); 288 289 /* return stream */ 290 return (gzFile)state; 291 } 292 293 /* -- see zlib.h -- */ 294 gzFile ZEXPORT gzopen(path, mode) 295 const char *path; 296 const char *mode; 297 { 298 return gz_open(path, -1, mode); 299 } 300 301 /* -- see zlib.h -- */ 302 gzFile ZEXPORT gzopen64(path, mode) 303 const char *path; 304 const char *mode; 305 { 306 return gz_open(path, -1, mode); 307 } 308 309 /* -- see zlib.h -- */ 310 gzFile ZEXPORT gzdopen(fd, mode) 311 int fd; 312 const char *mode; 313 { 314 char *path; /* identifier for error messages */ 315 gzFile gz; 316 317 if (fd == -1 || (path = (char *)malloc(7 + 3 * sizeof(int))) == NULL) 318 return NULL; 319 #if !defined(NO_snprintf) && !defined(NO_vsnprintf) 320 (void)snprintf(path, 7 + 3 * sizeof(int), "<fd:%d>", fd); 321 #else 322 sprintf(path, "<fd:%d>", fd); /* for debugging */ 323 #endif 324 gz = gz_open(path, fd, mode); 325 free(path); 326 return gz; 327 } 328 329 /* -- see zlib.h -- */ 330 #ifdef WIDECHAR 331 gzFile ZEXPORT gzopen_w(path, mode) 332 const wchar_t *path; 333 const char *mode; 334 { 335 return gz_open(path, -2, mode); 336 } 337 #endif 338 339 /* -- see zlib.h -- */ 340 int ZEXPORT gzbuffer(file, size) 341 gzFile file; 342 unsigned size; 343 { 344 gz_statep state; 345 346 /* get internal structure and check integrity */ 347 if (file == NULL) 348 return -1; 349 state = (gz_statep)file; 350 if (state->mode != GZ_READ && state->mode != GZ_WRITE) 351 return -1; 352 353 /* make sure we haven't already allocated memory */ 354 if (state->size != 0) 355 return -1; 356 357 /* check and set requested size */ 358 if ((size << 1) < size) 359 return -1; /* need to be able to double it */ 360 if (size < 2) 361 size = 2; /* need two bytes to check magic header */ 362 state->want = size; 363 return 0; 364 } 365 366 /* -- see zlib.h -- */ 367 int ZEXPORT gzrewind(file) 368 gzFile file; 369 { 370 gz_statep state; 371 372 /* get internal structure */ 373 if (file == NULL) 374 return -1; 375 state = (gz_statep)file; 376 377 /* check that we're reading and that there's no error */ 378 if (state->mode != GZ_READ || 379 (state->err != Z_OK && state->err != Z_BUF_ERROR)) 380 return -1; 381 382 /* back up and start over */ 383 if (LSEEK(state->fd, state->start, SEEK_SET) == -1) 384 return -1; 385 gz_reset(state); 386 return 0; 387 } 388 389 /* -- see zlib.h -- */ 390 z_off64_t ZEXPORT gzseek64(file, offset, whence) 391 gzFile file; 392 z_off64_t offset; 393 int whence; 394 { 395 unsigned n; 396 z_off64_t ret; 397 gz_statep state; 398 399 /* get internal structure and check integrity */ 400 if (file == NULL) 401 return -1; 402 state = (gz_statep)file; 403 if (state->mode != GZ_READ && state->mode != GZ_WRITE) 404 return -1; 405 406 /* check that there's no error */ 407 if (state->err != Z_OK && state->err != Z_BUF_ERROR) 408 return -1; 409 410 /* can only seek from start or relative to current position */ 411 if (whence != SEEK_SET && whence != SEEK_CUR) 412 return -1; 413 414 /* normalize offset to a SEEK_CUR specification */ 415 if (whence == SEEK_SET) 416 offset -= state->x.pos; 417 else if (state->seek) 418 offset += state->skip; 419 state->seek = 0; 420 421 /* if within raw area while reading, just go there */ 422 if (state->mode == GZ_READ && state->how == COPY && 423 state->x.pos + offset >= 0) { 424 ret = LSEEK(state->fd, offset - state->x.have, SEEK_CUR); 425 if (ret == -1) 426 return -1; 427 state->x.have = 0; 428 state->eof = 0; 429 state->past = 0; 430 state->seek = 0; 431 gz_error(state, Z_OK, NULL); 432 state->strm.avail_in = 0; 433 state->x.pos += offset; 434 return state->x.pos; 435 } 436 437 /* calculate skip amount, rewinding if needed for back seek when reading */ 438 if (offset < 0) { 439 if (state->mode != GZ_READ) /* writing -- can't go backwards */ 440 return -1; 441 offset += state->x.pos; 442 if (offset < 0) /* before start of file! */ 443 return -1; 444 if (gzrewind(file) == -1) /* rewind, then skip to offset */ 445 return -1; 446 } 447 448 /* if reading, skip what's in output buffer (one less gzgetc() check) */ 449 if (state->mode == GZ_READ) { 450 n = GT_OFF(state->x.have) || (z_off64_t)state->x.have > offset ? 451 (unsigned)offset : state->x.have; 452 state->x.have -= n; 453 state->x.next += n; 454 state->x.pos += n; 455 offset -= n; 456 } 457 458 /* request skip (if not zero) */ 459 if (offset) { 460 state->seek = 1; 461 state->skip = offset; 462 } 463 return state->x.pos + offset; 464 } 465 466 /* -- see zlib.h -- */ 467 z_off_t ZEXPORT gzseek(file, offset, whence) 468 gzFile file; 469 z_off_t offset; 470 int whence; 471 { 472 z_off64_t ret; 473 474 ret = gzseek64(file, (z_off64_t)offset, whence); 475 return ret == (z_off_t)ret ? (z_off_t)ret : -1; 476 } 477 478 /* -- see zlib.h -- */ 479 z_off64_t ZEXPORT gztell64(file) 480 gzFile file; 481 { 482 gz_statep state; 483 484 /* get internal structure and check integrity */ 485 if (file == NULL) 486 return -1; 487 state = (gz_statep)file; 488 if (state->mode != GZ_READ && state->mode != GZ_WRITE) 489 return -1; 490 491 /* return position */ 492 return state->x.pos + (state->seek ? state->skip : 0); 493 } 494 495 /* -- see zlib.h -- */ 496 z_off_t ZEXPORT gztell(file) 497 gzFile file; 498 { 499 z_off64_t ret; 500 501 ret = gztell64(file); 502 return ret == (z_off_t)ret ? (z_off_t)ret : -1; 503 } 504 505 /* -- see zlib.h -- */ 506 z_off64_t ZEXPORT gzoffset64(file) 507 gzFile file; 508 { 509 z_off64_t offset; 510 gz_statep state; 511 512 /* get internal structure and check integrity */ 513 if (file == NULL) 514 return -1; 515 state = (gz_statep)file; 516 if (state->mode != GZ_READ && state->mode != GZ_WRITE) 517 return -1; 518 519 /* compute and return effective offset in file */ 520 offset = LSEEK(state->fd, 0, SEEK_CUR); 521 if (offset == -1) 522 return -1; 523 if (state->mode == GZ_READ) /* reading */ 524 offset -= state->strm.avail_in; /* don't count buffered input */ 525 return offset; 526 } 527 528 /* -- see zlib.h -- */ 529 z_off_t ZEXPORT gzoffset(file) 530 gzFile file; 531 { 532 z_off64_t ret; 533 534 ret = gzoffset64(file); 535 return ret == (z_off_t)ret ? (z_off_t)ret : -1; 536 } 537 538 /* -- see zlib.h -- */ 539 int ZEXPORT gzeof(file) 540 gzFile file; 541 { 542 gz_statep state; 543 544 /* get internal structure and check integrity */ 545 if (file == NULL) 546 return 0; 547 state = (gz_statep)file; 548 if (state->mode != GZ_READ && state->mode != GZ_WRITE) 549 return 0; 550 551 /* return end-of-file state */ 552 return state->mode == GZ_READ ? state->past : 0; 553 } 554 555 /* -- see zlib.h -- */ 556 const char * ZEXPORT gzerror(file, errnum) 557 gzFile file; 558 int *errnum; 559 { 560 gz_statep state; 561 562 /* get internal structure and check integrity */ 563 if (file == NULL) 564 return NULL; 565 state = (gz_statep)file; 566 if (state->mode != GZ_READ && state->mode != GZ_WRITE) 567 return NULL; 568 569 /* return error information */ 570 if (errnum != NULL) 571 *errnum = state->err; 572 return state->err == Z_MEM_ERROR ? "out of memory" : 573 (state->msg == NULL ? "" : state->msg); 574 } 575 576 /* -- see zlib.h -- */ 577 void ZEXPORT gzclearerr(file) 578 gzFile file; 579 { 580 gz_statep state; 581 582 /* get internal structure and check integrity */ 583 if (file == NULL) 584 return; 585 state = (gz_statep)file; 586 if (state->mode != GZ_READ && state->mode != GZ_WRITE) 587 return; 588 589 /* clear error and end-of-file */ 590 if (state->mode == GZ_READ) { 591 state->eof = 0; 592 state->past = 0; 593 } 594 gz_error(state, Z_OK, NULL); 595 } 596 597 /* Create an error message in allocated memory and set state->err and 598 state->msg accordingly. Free any previous error message already there. Do 599 not try to free or allocate space if the error is Z_MEM_ERROR (out of 600 memory). Simply save the error message as a static string. If there is an 601 allocation failure constructing the error message, then convert the error to 602 out of memory. */ 603 void ZLIB_INTERNAL gz_error(state, err, msg) 604 gz_statep state; 605 int err; 606 const char *msg; 607 { 608 /* free previously allocated message and clear */ 609 if (state->msg != NULL) { 610 if (state->err != Z_MEM_ERROR) 611 free(state->msg); 612 state->msg = NULL; 613 } 614 615 /* if fatal, set state->x.have to 0 so that the gzgetc() macro fails */ 616 if (err != Z_OK && err != Z_BUF_ERROR) 617 state->x.have = 0; 618 619 /* set error code, and if no message, then done */ 620 state->err = err; 621 if (msg == NULL) 622 return; 623 624 /* for an out of memory error, return literal string when requested */ 625 if (err == Z_MEM_ERROR) 626 return; 627 628 /* construct error message with path */ 629 if ((state->msg = (char *)malloc(strlen(state->path) + strlen(msg) + 3)) == 630 NULL) { 631 state->err = Z_MEM_ERROR; 632 return; 633 } 634 #if !defined(NO_snprintf) && !defined(NO_vsnprintf) 635 (void)snprintf(state->msg, strlen(state->path) + strlen(msg) + 3, 636 "%s%s%s", state->path, ": ", msg); 637 #else 638 strcpy(state->msg, state->path); 639 strcat(state->msg, ": "); 640 strcat(state->msg, msg); 641 #endif 642 } 643 644 #ifndef INT_MAX 645 /* portably return maximum value for an int (when limits.h presumed not 646 available) -- we need to do this to cover cases where 2's complement not 647 used, since C standard permits 1's complement and sign-bit representations, 648 otherwise we could just use ((unsigned)-1) >> 1 */ 649 unsigned ZLIB_INTERNAL gz_intmax() 650 { 651 unsigned p, q; 652 653 p = 1; 654 do { 655 q = p; 656 p <<= 1; 657 p++; 658 } while (p > q); 659 return q >> 1; 660 } 661 #endif