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, 2010, 2011, 2012, 2013 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__) 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 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 _WIN32 216 if (fd == -2) { 217 len = wcstombs(NULL, path, 0); 218 if (len == (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 _WIN32 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 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 _WIN32 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 state->mode = GZ_WRITE; /* simplify later checks */ 277 278 /* save the current position for rewinding (only if reading) */ 279 if (state->mode == GZ_READ) { 280 state->start = LSEEK(state->fd, 0, SEEK_CUR); 281 if (state->start == -1) state->start = 0; 282 } 283 284 /* initialize stream */ 285 gz_reset(state); 286 287 /* return stream */ 288 return (gzFile)state; 289 } 290 291 /* -- see zlib.h -- */ 292 gzFile ZEXPORT gzopen(path, mode) 293 const char *path; 294 const char *mode; 295 { 296 return gz_open(path, -1, mode); 297 } 298 299 /* -- see zlib.h -- */ 300 gzFile ZEXPORT gzopen64(path, mode) 301 const char *path; 302 const char *mode; 303 { 304 return gz_open(path, -1, mode); 305 } 306 307 /* -- see zlib.h -- */ 308 gzFile ZEXPORT gzdopen(fd, mode) 309 int fd; 310 const char *mode; 311 { 312 char *path; /* identifier for error messages */ 313 gzFile gz; 314 315 if (fd == -1 || (path = (char *)malloc(7 + 3 * sizeof(int))) == NULL) 316 return NULL; 317 #if !defined(NO_snprintf) && !defined(NO_vsnprintf) 318 snprintf(path, 7 + 3 * sizeof(int), "<fd:%d>", fd); /* for debugging */ 319 #else 320 sprintf(path, "<fd:%d>", fd); /* for debugging */ 321 #endif 322 gz = gz_open(path, fd, mode); 323 free(path); 324 return gz; 325 } 326 327 /* -- see zlib.h -- */ 328 #ifdef _WIN32 329 gzFile ZEXPORT gzopen_w(path, mode) 330 const wchar_t *path; 331 const char *mode; 332 { 333 return gz_open(path, -2, mode); 334 } 335 #endif 336 337 /* -- see zlib.h -- */ 338 int ZEXPORT gzbuffer(file, size) 339 gzFile file; 340 unsigned size; 341 { 342 gz_statep state; 343 344 /* get internal structure and check integrity */ 345 if (file == NULL) 346 return -1; 347 state = (gz_statep)file; 348 if (state->mode != GZ_READ && state->mode != GZ_WRITE) 349 return -1; 350 351 /* make sure we haven't already allocated memory */ 352 if (state->size != 0) 353 return -1; 354 355 /* check and set requested size */ 356 if (size < 2) 357 size = 2; /* need two bytes to check magic header */ 358 state->want = size; 359 return 0; 360 } 361 362 /* -- see zlib.h -- */ 363 int ZEXPORT gzrewind(file) 364 gzFile file; 365 { 366 gz_statep state; 367 368 /* get internal structure */ 369 if (file == NULL) 370 return -1; 371 state = (gz_statep)file; 372 373 /* check that we're reading and that there's no error */ 374 if (state->mode != GZ_READ || 375 (state->err != Z_OK && state->err != Z_BUF_ERROR)) 376 return -1; 377 378 /* back up and start over */ 379 if (LSEEK(state->fd, state->start, SEEK_SET) == -1) 380 return -1; 381 gz_reset(state); 382 return 0; 383 } 384 385 /* -- see zlib.h -- */ 386 z_off64_t ZEXPORT gzseek64(file, offset, whence) 387 gzFile file; 388 z_off64_t offset; 389 int whence; 390 { 391 unsigned n; 392 z_off64_t ret; 393 gz_statep state; 394 395 /* get internal structure and check integrity */ 396 if (file == NULL) 397 return -1; 398 state = (gz_statep)file; 399 if (state->mode != GZ_READ && state->mode != GZ_WRITE) 400 return -1; 401 402 /* check that there's no error */ 403 if (state->err != Z_OK && state->err != Z_BUF_ERROR) 404 return -1; 405 406 /* can only seek from start or relative to current position */ 407 if (whence != SEEK_SET && whence != SEEK_CUR) 408 return -1; 409 410 /* normalize offset to a SEEK_CUR specification */ 411 if (whence == SEEK_SET) 412 offset -= state->x.pos; 413 else if (state->seek) 414 offset += state->skip; 415 state->seek = 0; 416 417 /* if within raw area while reading, just go there */ 418 if (state->mode == GZ_READ && state->how == COPY && 419 state->x.pos + offset >= 0) { 420 ret = LSEEK(state->fd, offset - state->x.have, SEEK_CUR); 421 if (ret == -1) 422 return -1; 423 state->x.have = 0; 424 state->eof = 0; 425 state->past = 0; 426 state->seek = 0; 427 gz_error(state, Z_OK, NULL); 428 state->strm.avail_in = 0; 429 state->x.pos += offset; 430 return state->x.pos; 431 } 432 433 /* calculate skip amount, rewinding if needed for back seek when reading */ 434 if (offset < 0) { 435 if (state->mode != GZ_READ) /* writing -- can't go backwards */ 436 return -1; 437 offset += state->x.pos; 438 if (offset < 0) /* before start of file! */ 439 return -1; 440 if (gzrewind(file) == -1) /* rewind, then skip to offset */ 441 return -1; 442 } 443 444 /* if reading, skip what's in output buffer (one less gzgetc() check) */ 445 if (state->mode == GZ_READ) { 446 n = GT_OFF(state->x.have) || (z_off64_t)state->x.have > offset ? 447 (unsigned)offset : state->x.have; 448 state->x.have -= n; 449 state->x.next += n; 450 state->x.pos += n; 451 offset -= n; 452 } 453 454 /* request skip (if not zero) */ 455 if (offset) { 456 state->seek = 1; 457 state->skip = offset; 458 } 459 return state->x.pos + offset; 460 } 461 462 /* -- see zlib.h -- */ 463 z_off_t ZEXPORT gzseek(file, offset, whence) 464 gzFile file; 465 z_off_t offset; 466 int whence; 467 { 468 z_off64_t ret; 469 470 ret = gzseek64(file, (z_off64_t)offset, whence); 471 return ret == (z_off_t)ret ? (z_off_t)ret : -1; 472 } 473 474 /* -- see zlib.h -- */ 475 z_off64_t ZEXPORT gztell64(file) 476 gzFile file; 477 { 478 gz_statep state; 479 480 /* get internal structure and check integrity */ 481 if (file == NULL) 482 return -1; 483 state = (gz_statep)file; 484 if (state->mode != GZ_READ && state->mode != GZ_WRITE) 485 return -1; 486 487 /* return position */ 488 return state->x.pos + (state->seek ? state->skip : 0); 489 } 490 491 /* -- see zlib.h -- */ 492 z_off_t ZEXPORT gztell(file) 493 gzFile file; 494 { 495 z_off64_t ret; 496 497 ret = gztell64(file); 498 return ret == (z_off_t)ret ? (z_off_t)ret : -1; 499 } 500 501 /* -- see zlib.h -- */ 502 z_off64_t ZEXPORT gzoffset64(file) 503 gzFile file; 504 { 505 z_off64_t offset; 506 gz_statep state; 507 508 /* get internal structure and check integrity */ 509 if (file == NULL) 510 return -1; 511 state = (gz_statep)file; 512 if (state->mode != GZ_READ && state->mode != GZ_WRITE) 513 return -1; 514 515 /* compute and return effective offset in file */ 516 offset = LSEEK(state->fd, 0, SEEK_CUR); 517 if (offset == -1) 518 return -1; 519 if (state->mode == GZ_READ) /* reading */ 520 offset -= state->strm.avail_in; /* don't count buffered input */ 521 return offset; 522 } 523 524 /* -- see zlib.h -- */ 525 z_off_t ZEXPORT gzoffset(file) 526 gzFile file; 527 { 528 z_off64_t ret; 529 530 ret = gzoffset64(file); 531 return ret == (z_off_t)ret ? (z_off_t)ret : -1; 532 } 533 534 /* -- see zlib.h -- */ 535 int ZEXPORT gzeof(file) 536 gzFile file; 537 { 538 gz_statep state; 539 540 /* get internal structure and check integrity */ 541 if (file == NULL) 542 return 0; 543 state = (gz_statep)file; 544 if (state->mode != GZ_READ && state->mode != GZ_WRITE) 545 return 0; 546 547 /* return end-of-file state */ 548 return state->mode == GZ_READ ? state->past : 0; 549 } 550 551 /* -- see zlib.h -- */ 552 const char * ZEXPORT gzerror(file, errnum) 553 gzFile file; 554 int *errnum; 555 { 556 gz_statep state; 557 558 /* get internal structure and check integrity */ 559 if (file == NULL) 560 return NULL; 561 state = (gz_statep)file; 562 if (state->mode != GZ_READ && state->mode != GZ_WRITE) 563 return NULL; 564 565 /* return error information */ 566 if (errnum != NULL) 567 *errnum = state->err; 568 return state->err == Z_MEM_ERROR ? "out of memory" : 569 (state->msg == NULL ? "" : state->msg); 570 } 571 572 /* -- see zlib.h -- */ 573 void ZEXPORT gzclearerr(file) 574 gzFile file; 575 { 576 gz_statep state; 577 578 /* get internal structure and check integrity */ 579 if (file == NULL) 580 return; 581 state = (gz_statep)file; 582 if (state->mode != GZ_READ && state->mode != GZ_WRITE) 583 return; 584 585 /* clear error and end-of-file */ 586 if (state->mode == GZ_READ) { 587 state->eof = 0; 588 state->past = 0; 589 } 590 gz_error(state, Z_OK, NULL); 591 } 592 593 /* Create an error message in allocated memory and set state->err and 594 state->msg accordingly. Free any previous error message already there. Do 595 not try to free or allocate space if the error is Z_MEM_ERROR (out of 596 memory). Simply save the error message as a static string. If there is an 597 allocation failure constructing the error message, then convert the error to 598 out of memory. */ 599 void ZLIB_INTERNAL gz_error(state, err, msg) 600 gz_statep state; 601 int err; 602 const char *msg; 603 { 604 /* free previously allocated message and clear */ 605 if (state->msg != NULL) { 606 if (state->err != Z_MEM_ERROR) 607 free(state->msg); 608 state->msg = NULL; 609 } 610 611 /* if fatal, set state->x.have to 0 so that the gzgetc() macro fails */ 612 if (err != Z_OK && err != Z_BUF_ERROR) 613 state->x.have = 0; 614 615 /* set error code, and if no message, then done */ 616 state->err = err; 617 if (msg == NULL) 618 return; 619 620 /* for an out of memory error, return literal string when requested */ 621 if (err == Z_MEM_ERROR) 622 return; 623 624 /* construct error message with path */ 625 if ((state->msg = (char *)malloc(strlen(state->path) + strlen(msg) + 3)) == 626 NULL) { 627 state->err = Z_MEM_ERROR; 628 return; 629 } 630 #if !defined(NO_snprintf) && !defined(NO_vsnprintf) 631 snprintf(state->msg, strlen(state->path) + strlen(msg) + 3, 632 "%s%s%s", state->path, ": ", msg); 633 #else 634 strcpy(state->msg, state->path); 635 strcat(state->msg, ": "); 636 strcat(state->msg, msg); 637 #endif 638 return; 639 } 640 641 #ifndef INT_MAX 642 /* portably return maximum value for an int (when limits.h presumed not 643 available) -- we need to do this to cover cases where 2's complement not 644 used, since C standard permits 1's complement and sign-bit representations, 645 otherwise we could just use ((unsigned)-1) >> 1 */ 646 unsigned ZLIB_INTERNAL gz_intmax() 647 { 648 unsigned p, q; 649 650 p = 1; 651 do { 652 q = p; 653 p <<= 1; 654 p++; 655 } while (p > q); 656 return q >> 1; 657 } 658 #endif