1 /* 2 * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 /** 27 * Note: Lifted from uncrunch.c from jdk sources 28 */ 29 #include <stdio.h> 30 #include <string.h> 31 #include <errno.h> 32 #include <time.h> 33 34 #include <stdlib.h> 35 36 #ifndef _MSC_VER 37 #include <strings.h> 38 #endif 39 40 #include "defines.h" 41 #include "bytes.h" 42 #include "utils.h" 43 44 #include "constants.h" 45 #include "unpack.h" 46 47 #include "zip.h" 48 49 #ifdef NO_ZLIB 50 51 inline bool jar::deflate_bytes(bytes& head, bytes& tail) { 52 return false; 53 } 54 inline uint jar::get_crc32(uint c, uchar *ptr, uint len) { return 0; } 55 #define Z_NULL NULL 56 57 #else // Have ZLIB 58 59 #include <zlib.h> 60 61 inline uint jar::get_crc32(uint c, uchar *ptr, uint len) { return crc32(c, ptr, len); } 62 63 #endif // End of ZLIB 64 65 #ifdef _BIG_ENDIAN 66 #define SWAP_BYTES(a) \ 67 ((((a) << 8) & 0xff00) | 0x00ff) & (((a) >> 8) | 0xff00) 68 #else 69 #define SWAP_BYTES(a) (a) 70 #endif 71 72 #define GET_INT_LO(a) \ 73 SWAP_BYTES(a & 0xFFFF) 74 75 #define GET_INT_HI(a) \ 76 SWAP_BYTES((a >> 16) & 0xFFFF); 77 78 79 void jar::init(unpacker* u_) { 80 BYTES_OF(*this).clear(); 81 u = u_; 82 u->jarout = this; 83 } 84 85 // Write data to the ZIP output stream. 86 void jar::write_data(void* buff, int len) { 87 while (len > 0) { 88 int rc = (int)fwrite(buff, 1, len, jarfp); 89 if (rc <= 0) { 90 fprintf(u->errstrm, "Error: write on output file failed err=%d\n",errno); 91 exit(1); // Called only from the native standalone unpacker 92 } 93 output_file_offset += rc; 94 buff = ((char *)buff) + rc; 95 len -= rc; 96 } 97 } 98 99 void jar::add_to_jar_directory(const char* fname, bool store, int modtime, 100 int len, int clen, uLong crc) { 101 uint fname_length = (uint)strlen(fname); 102 ushort header[23]; 103 if (modtime == 0) modtime = default_modtime; 104 uLong dostime = get_dostime(modtime); 105 106 header[0] = (ushort)SWAP_BYTES(0x4B50); 107 header[1] = (ushort)SWAP_BYTES(0x0201); 108 header[2] = (ushort)SWAP_BYTES(0xA); 109 110 // required version 111 header[3] = (ushort)SWAP_BYTES(0xA); 112 113 // flags 02 = maximum sub-compression flag 114 header[4] = ( store ) ? 0x0 : SWAP_BYTES(0x2); 115 116 // Compression method 8=deflate. 117 header[5] = ( store ) ? 0x0 : SWAP_BYTES(0x08); 118 119 // Last modified date and time. 120 header[6] = (ushort)GET_INT_LO(dostime); 121 header[7] = (ushort)GET_INT_HI(dostime); 122 123 // CRC 124 header[8] = (ushort)GET_INT_LO(crc); 125 header[9] = (ushort)GET_INT_HI(crc); 126 127 // Compressed length: 128 header[10] = (ushort)GET_INT_LO(clen); 129 header[11] = (ushort)GET_INT_HI(clen); 130 131 // Uncompressed length. 132 header[12] = (ushort)GET_INT_LO(len); 133 header[13] = (ushort)GET_INT_HI(len); 134 135 // Filename length 136 header[14] = (ushort)SWAP_BYTES(fname_length); 137 // So called "extra field" length. 138 header[15] = 0; 139 // So called "comment" length. 140 header[16] = 0; 141 // Disk number start 142 header[17] = 0; 143 // File flags => binary 144 header[18] = 0; 145 // More file flags 146 header[19] = 0; 147 header[20] = 0; 148 // Offset within ZIP file. 149 header[21] = (ushort)GET_INT_LO(output_file_offset); 150 header[22] = (ushort)GET_INT_HI(output_file_offset); 151 152 // Copy the whole thing into the central directory. 153 central_directory.append(header, sizeof(header)); 154 155 // Copy the fname to the header. 156 central_directory.append(fname, fname_length); 157 158 central_directory_count++; 159 } 160 161 void jar::write_jar_header(const char* fname, bool store, int modtime, 162 int len, int clen, uint crc) { 163 uint fname_length = (uint)strlen(fname); 164 ushort header[15]; 165 if (modtime == 0) modtime = default_modtime; 166 uLong dostime = get_dostime(modtime); 167 168 // ZIP LOC magic. 169 header[0] = (ushort)SWAP_BYTES(0x4B50); 170 header[1] = (ushort)SWAP_BYTES(0x0403); 171 172 // Version 173 header[2] = (ushort)SWAP_BYTES(0xA); 174 175 // flags 02 = maximum sub-compression flag 176 header[3] = ( store ) ? 0x0 : SWAP_BYTES(0x2); 177 178 // Compression method = deflate 179 header[4] = ( store ) ? 0x0 : SWAP_BYTES(0x08); 180 181 // Last modified date and time. 182 header[5] = (ushort)GET_INT_LO(dostime); 183 header[6] = (ushort)GET_INT_HI(dostime); 184 185 // CRC 186 header[7] = (ushort)GET_INT_LO(crc); 187 header[8] = (ushort)GET_INT_HI(crc); 188 189 // Compressed length: 190 header[9] = (ushort)GET_INT_LO(clen); 191 header[10] = (ushort)GET_INT_HI(clen); 192 193 // Uncompressed length. 194 header[11] = (ushort)GET_INT_LO(len); 195 header[12] = (ushort)GET_INT_HI(len); 196 197 // Filename length 198 header[13] = (ushort)SWAP_BYTES(fname_length); 199 // So called "extra field" length. 200 header[14] = 0; 201 202 // Write the LOC header to the output file. 203 write_data(header, (int)sizeof(header)); 204 205 // Copy the fname to the header. 206 write_data((char*)fname, (int)fname_length); 207 } 208 209 static const char marker_comment[] = ZIP_ARCHIVE_MARKER_COMMENT; 210 211 void jar::write_central_directory() { 212 bytes mc; mc.set(marker_comment); 213 214 ushort header[11]; 215 216 // Create the End of Central Directory structure. 217 header[0] = (ushort)SWAP_BYTES(0x4B50); 218 header[1] = (ushort)SWAP_BYTES(0x0605); 219 // disk numbers 220 header[2] = 0; 221 header[3] = 0; 222 // Number of entries in central directory. 223 header[4] = (ushort)SWAP_BYTES(central_directory_count); 224 header[5] = (ushort)SWAP_BYTES(central_directory_count); 225 // Size of the central directory} 226 header[6] = (ushort)GET_INT_LO((int)central_directory.size()); 227 header[7] = (ushort)GET_INT_HI((int)central_directory.size()); 228 // Offset of central directory within disk. 229 header[8] = (ushort)GET_INT_LO(output_file_offset); 230 header[9] = (ushort)GET_INT_HI(output_file_offset); 231 // zipfile comment length; 232 header [10] = (ushort)SWAP_BYTES((int)mc.len); 233 234 // Write the central directory. 235 PRINTCR((2, "Central directory at %d\n", output_file_offset)); 236 write_data(central_directory.b); 237 238 // Write the End of Central Directory structure. 239 PRINTCR((2, "end-of-directory at %d\n", output_file_offset)); 240 write_data(header, (int)sizeof(header)); 241 242 PRINTCR((2, "writing zip comment\n")); 243 // Write the comment. 244 write_data(mc); 245 } 246 247 // Public API 248 249 // Open a Jar file and initialize. 250 void jar::openJarFile(const char* fname) { 251 if (!jarfp) { 252 PRINTCR((1, "jar::openJarFile: opening %s\n",fname)); 253 jarfp = fopen(fname, "wb"); 254 if (!jarfp) { 255 fprintf(u->errstrm, "Error: Could not open jar file: %s\n",fname); 256 exit(3); // Called only from the native standalone unpacker 257 } 258 } 259 } 260 261 // Add a ZIP entry and copy the file data 262 void jar::addJarEntry(const char* fname, 263 bool deflate_hint, int modtime, 264 bytes& head, bytes& tail) { 265 int len = (int)(head.len + tail.len); 266 int clen = 0; 267 268 uint crc = get_crc32(0,Z_NULL,0); 269 if (head.len != 0) 270 crc = get_crc32(crc, (uchar *)head.ptr, (uint)head.len); 271 if (tail.len != 0) 272 crc = get_crc32(crc, (uchar *)tail.ptr, (uint)tail.len); 273 274 bool deflate = (deflate_hint && len > 0); 275 276 if (deflate) { 277 if (deflate_bytes(head, tail) == false) { 278 PRINTCR((2, "Reverting to store fn=%s\t%d -> %d\n", 279 fname, len, deflated.size())); 280 deflate = false; 281 } 282 } 283 clen = (int)((deflate) ? deflated.size() : len); 284 add_to_jar_directory(fname, !deflate, modtime, len, clen, crc); 285 write_jar_header( fname, !deflate, modtime, len, clen, crc); 286 287 if (deflate) { 288 write_data(deflated.b); 289 } else { 290 write_data(head); 291 write_data(tail); 292 } 293 } 294 295 // Add a ZIP entry for a directory name no data 296 void jar::addDirectoryToJarFile(const char* dir_name) { 297 bool store = true; 298 add_to_jar_directory((const char*)dir_name, store, default_modtime, 0, 0, 0); 299 write_jar_header( (const char*)dir_name, store, default_modtime, 0, 0, 0); 300 } 301 302 // Write out the central directory and close the jar file. 303 void jar::closeJarFile(bool central) { 304 if (jarfp) { 305 fflush(jarfp); 306 if (central) write_central_directory(); 307 fflush(jarfp); 308 fclose(jarfp); 309 PRINTCR((2, "jar::closeJarFile:closed jar-file\n")); 310 } 311 reset(); 312 } 313 314 /* Convert the date y/n/d and time h:m:s to a four byte DOS date and 315 * time (date in high two bytes, time in low two bytes allowing magnitude 316 * comparison). 317 */ 318 inline 319 uLong jar::dostime(int y, int n, int d, int h, int m, int s) { 320 return y < 1980 ? dostime(1980, 1, 1, 0, 0, 0) : 321 (((uLong)y - 1980) << 25) | ((uLong)n << 21) | ((uLong)d << 16) | 322 ((uLong)h << 11) | ((uLong)m << 5) | ((uLong)s >> 1); 323 } 324 325 #ifdef _REENTRANT // solaris 326 extern "C" struct tm *gmtime_r(const time_t *, struct tm *); 327 #else 328 #define gmtime_r(t, s) gmtime(t) 329 #endif 330 /* 331 * Return the Unix time in DOS format 332 */ 333 uLong jar::get_dostime(int modtime) { 334 // see defines.h 335 if (modtime != 0 && modtime == modtime_cache) 336 return dostime_cache; 337 if (modtime != 0 && default_modtime == 0) 338 default_modtime = modtime; // catch a reasonable default 339 time_t t = modtime; 340 struct tm sbuf; 341 (void)memset((void*)&sbuf,0, sizeof(sbuf)); 342 struct tm* s = gmtime_r(&t, &sbuf); 343 if (s == NULL) { 344 fprintf(u->errstrm, "Error: gmtime failure, invalid input archive\n"); 345 exit(2); 346 } 347 modtime_cache = modtime; 348 dostime_cache = dostime(s->tm_year + 1900, s->tm_mon + 1, s->tm_mday, 349 s->tm_hour, s->tm_min, s->tm_sec); 350 //printf("modtime %d => %d\n", modtime_cache, dostime_cache); 351 return dostime_cache; 352 } 353 354 355 356 #ifndef NO_ZLIB 357 358 /* Returns true on success, and will set the clen to the compressed 359 length, the caller should verify if true and clen less than the 360 input data 361 */ 362 bool jar::deflate_bytes(bytes& head, bytes& tail) { 363 int len = (int)(head.len + tail.len); 364 365 z_stream zs; 366 BYTES_OF(zs).clear(); 367 368 // NOTE: the window size should always be -MAX_WBITS normally -15. 369 // unzip/zipup.c and java/Deflater.c 370 371 int error = deflateInit2(&zs, Z_BEST_COMPRESSION, Z_DEFLATED, 372 -MAX_WBITS, 8, Z_DEFAULT_STRATEGY); 373 if (error != Z_OK) { 374 switch (error) { 375 case Z_MEM_ERROR: 376 PRINTCR((2, "Error: deflate error : Out of memory \n")); 377 break; 378 case Z_STREAM_ERROR: 379 PRINTCR((2,"Error: deflate error : Invalid compression level \n")); 380 break; 381 case Z_VERSION_ERROR: 382 PRINTCR((2,"Error: deflate error : Invalid version\n")); 383 break; 384 default: 385 PRINTCR((2,"Error: Internal deflate error error = %d\n", error)); 386 } 387 return false; 388 } 389 390 deflated.empty(); 391 zs.next_out = (uchar*) deflated.grow(add_size(len, (len/2))); 392 zs.avail_out = (int)deflated.size(); 393 394 zs.next_in = (uchar*)head.ptr; 395 zs.avail_in = (int)head.len; 396 397 bytes* first = &head; 398 bytes* last = &tail; 399 if (last->len == 0) { 400 first = null; 401 last = &head; 402 } else if (first->len == 0) { 403 first = null; 404 } 405 406 if (first != null && error == Z_OK) { 407 zs.next_in = (uchar*) first->ptr; 408 zs.avail_in = (int)first->len; 409 error = deflate(&zs, Z_NO_FLUSH); 410 } 411 if (error == Z_OK) { 412 zs.next_in = (uchar*) last->ptr; 413 zs.avail_in = (int)last->len; 414 error = deflate(&zs, Z_FINISH); 415 } 416 if (error == Z_STREAM_END) { 417 if (len > (int)zs.total_out ) { 418 PRINTCR((2, "deflate compressed data %d -> %d\n", len, zs.total_out)); 419 deflated.b.len = zs.total_out; 420 deflateEnd(&zs); 421 return true; 422 } 423 PRINTCR((2, "deflate expanded data %d -> %d\n", len, zs.total_out)); 424 deflateEnd(&zs); 425 return false; 426 } 427 428 deflateEnd(&zs); 429 PRINTCR((2, "Error: deflate error deflate did not finish error=%d\n",error)); 430 return false; 431 } 432 433 // Callback for fetching data from a GZIP input stream 434 static jlong read_input_via_gzip(unpacker* u, 435 void* buf, jlong minlen, jlong maxlen) { 436 assert(minlen <= maxlen); // don't talk nonsense 437 jlong numread = 0; 438 char* bufptr = (char*) buf; 439 char* inbuf = u->gzin->inbuf; 440 size_t inbuflen = sizeof(u->gzin->inbuf); 441 unpacker::read_input_fn_t read_gzin_fn = 442 (unpacker::read_input_fn_t) u->gzin->read_input_fn; 443 z_stream& zs = *(z_stream*) u->gzin->zstream; 444 while (numread < minlen) { 445 int readlen = (1 << 16); // pretty arbitrary 446 if (readlen > (maxlen - numread)) 447 readlen = (int)(maxlen - numread); 448 zs.next_out = (uchar*) bufptr; 449 zs.avail_out = readlen; 450 if (zs.avail_in == 0) { 451 zs.avail_in = (int) read_gzin_fn(u, inbuf, 1, inbuflen); 452 zs.next_in = (uchar*) inbuf; 453 } 454 int error = inflate(&zs, Z_NO_FLUSH); 455 if (error != Z_OK && error != Z_STREAM_END) { 456 u->abort("error inflating input"); 457 break; 458 } 459 int nr = readlen - zs.avail_out; 460 numread += nr; 461 bufptr += nr; 462 assert(numread <= maxlen); 463 if (error == Z_STREAM_END) { 464 enum { TRAILER_LEN = 8 }; 465 // skip 8-byte trailer 466 if (zs.avail_in >= TRAILER_LEN) { 467 zs.avail_in -= TRAILER_LEN; 468 } else { 469 // Bug: 5023768,we read past the TRAILER_LEN to see if there is 470 // any extraneous data, as we dont support concatenated .gz 471 // files just yet. 472 int extra = (int) read_gzin_fn(u, inbuf, 1, inbuflen); 473 zs.avail_in += extra - TRAILER_LEN; 474 } 475 // %%% should check final CRC and length here 476 // %%% should check for concatenated *.gz files here 477 if (zs.avail_in > 0) 478 u->abort("garbage after end of deflated input stream"); 479 // pop this filter off: 480 u->gzin->free(); 481 break; 482 } 483 } 484 485 //fprintf(u->errstrm, "readInputFn(%d,%d) => %d (gunzip)\n", 486 // (int)minlen, (int)maxlen, (int)numread); 487 return numread; 488 } 489 490 void gunzip::init(unpacker* u_) { 491 BYTES_OF(*this).clear(); 492 u = u_; 493 assert(u->gzin == null); // once only, please 494 read_input_fn = (void*)u->read_input_fn; 495 zstream = NEW(z_stream, 1); 496 u->gzin = this; 497 u->read_input_fn = read_input_via_gzip; 498 } 499 500 void gunzip::start(int magic) { 501 assert((magic & GZIP_MAGIC_MASK) == GZIP_MAGIC); 502 int gz_flg = (magic & 0xFF); // keep "flg", discard other 3 bytes 503 enum { 504 FHCRC = (1<<1), 505 FEXTRA = (1<<2), 506 FNAME = (1<<3), 507 FCOMMENT = (1<<4) 508 }; 509 char gz_mtime[4]; 510 char gz_xfl[1]; 511 char gz_os[1]; 512 char gz_extra_len[2]; 513 char gz_hcrc[2]; 514 char gz_ignore; 515 // do not save extra, name, comment 516 read_fixed_field(gz_mtime, sizeof(gz_mtime)); 517 read_fixed_field(gz_xfl, sizeof(gz_xfl)); 518 read_fixed_field(gz_os, sizeof(gz_os)); 519 if (gz_flg & FEXTRA) { 520 read_fixed_field(gz_extra_len, sizeof(gz_extra_len)); 521 int extra_len = gz_extra_len[0] & 0xFF; 522 extra_len += (gz_extra_len[1] & 0xFF) << 8; 523 for (; extra_len > 0; extra_len--) { 524 read_fixed_field(&gz_ignore, 1); 525 } 526 } 527 int null_terms = 0; 528 if (gz_flg & FNAME) null_terms++; 529 if (gz_flg & FCOMMENT) null_terms++; 530 for (; null_terms; null_terms--) { 531 for (;;) { 532 gz_ignore = 0; 533 read_fixed_field(&gz_ignore, 1); 534 if (gz_ignore == 0) break; 535 } 536 } 537 if (gz_flg & FHCRC) 538 read_fixed_field(gz_hcrc, sizeof(gz_hcrc)); 539 540 if (aborting()) return; 541 542 // now the input stream is ready to read into the inflater 543 int error = inflateInit2((z_stream*) zstream, -MAX_WBITS); 544 if (error != Z_OK) { abort("cannot create input"); return; } 545 } 546 547 void gunzip::free() { 548 assert(u->gzin == this); 549 u->gzin = null; 550 u->read_input_fn = (unpacker::read_input_fn_t) this->read_input_fn; 551 inflateEnd((z_stream*) zstream); 552 mtrace('f', zstream, 0); 553 ::free(zstream); 554 zstream = null; 555 mtrace('f', this, 0); 556 ::free(this); 557 } 558 559 void gunzip::read_fixed_field(char* buf, size_t buflen) { 560 if (aborting()) return; 561 jlong nr = ((unpacker::read_input_fn_t)read_input_fn) 562 (u, buf, buflen, buflen); 563 if ((size_t)nr != buflen) 564 u->abort("short stream header"); 565 } 566 567 #else // NO_ZLIB 568 569 void gunzip::free() { 570 } 571 572 #endif // NO_ZLIB