1228753Smm/*- 2228753Smm * Copyright (c) 2004 Tim Kientzle 3228753Smm * All rights reserved. 4228753Smm * 5228753Smm * Redistribution and use in source and binary forms, with or without 6228753Smm * modification, are permitted provided that the following conditions 7228753Smm * are met: 8228753Smm * 1. Redistributions of source code must retain the above copyright 9228753Smm * notice, this list of conditions and the following disclaimer. 10228753Smm * 2. Redistributions in binary form must reproduce the above copyright 11228753Smm * notice, this list of conditions and the following disclaimer in the 12228753Smm * documentation and/or other materials provided with the distribution. 13228753Smm * 14228753Smm * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR 15228753Smm * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 16228753Smm * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 17228753Smm * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, 18228753Smm * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 19228753Smm * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 20228753Smm * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 21228753Smm * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22228753Smm * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 23228753Smm * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24228753Smm */ 25228753Smm 26228753Smm#include "archive_platform.h" 27229592Smm__FBSDID("$FreeBSD$"); 28228753Smm 29228753Smm#ifdef HAVE_ERRNO_H 30228753Smm#include <errno.h> 31228753Smm#endif 32228753Smm#include <stdio.h> 33228753Smm#ifdef HAVE_STDLIB_H 34228753Smm#include <stdlib.h> 35228753Smm#endif 36228753Smm#include <time.h> 37228753Smm#ifdef HAVE_ZLIB_H 38228753Smm#include <zlib.h> 39228753Smm#endif 40228753Smm 41228753Smm#include "archive.h" 42228753Smm#include "archive_entry.h" 43228753Smm#include "archive_private.h" 44228753Smm#include "archive_read_private.h" 45228753Smm#include "archive_endian.h" 46228753Smm 47228753Smm#ifndef HAVE_ZLIB_H 48228753Smm#include "archive_crc32.h" 49228753Smm#endif 50228753Smm 51228753Smmstruct zip { 52228753Smm /* entry_bytes_remaining is the number of bytes we expect. */ 53228753Smm int64_t entry_bytes_remaining; 54228753Smm int64_t entry_offset; 55228753Smm 56228753Smm /* These count the number of bytes actually read for the entry. */ 57228753Smm int64_t entry_compressed_bytes_read; 58228753Smm int64_t entry_uncompressed_bytes_read; 59228753Smm 60228753Smm /* Running CRC32 of the decompressed data */ 61228753Smm unsigned long entry_crc32; 62228753Smm 63228753Smm unsigned version; 64228753Smm unsigned system; 65228753Smm unsigned flags; 66228753Smm unsigned compression; 67228753Smm const char * compression_name; 68228753Smm time_t mtime; 69228753Smm time_t ctime; 70228753Smm time_t atime; 71228753Smm mode_t mode; 72228753Smm uid_t uid; 73228753Smm gid_t gid; 74228753Smm 75228753Smm /* Flags to mark progress of decompression. */ 76228753Smm char decompress_init; 77228753Smm char end_of_entry; 78228753Smm 79228753Smm unsigned long crc32; 80228753Smm ssize_t filename_length; 81228753Smm ssize_t extra_length; 82228753Smm int64_t uncompressed_size; 83228753Smm int64_t compressed_size; 84228753Smm 85228753Smm unsigned char *uncompressed_buffer; 86228753Smm size_t uncompressed_buffer_size; 87228753Smm#ifdef HAVE_ZLIB_H 88228753Smm z_stream stream; 89228753Smm char stream_valid; 90228753Smm#endif 91228753Smm 92228753Smm struct archive_string pathname; 93228753Smm struct archive_string extra; 94228753Smm char format_name[64]; 95228753Smm}; 96228753Smm 97228753Smm#define ZIP_LENGTH_AT_END 8 98228753Smm 99228753Smmstruct zip_file_header { 100228753Smm char signature[4]; 101228753Smm char version[2]; 102228753Smm char flags[2]; 103228753Smm char compression[2]; 104228753Smm char timedate[4]; 105228753Smm char crc32[4]; 106228753Smm char compressed_size[4]; 107228753Smm char uncompressed_size[4]; 108228753Smm char filename_length[2]; 109228753Smm char extra_length[2]; 110228753Smm}; 111228753Smm 112228753Smmstatic const char *compression_names[] = { 113228753Smm "uncompressed", 114228753Smm "shrinking", 115228753Smm "reduced-1", 116228753Smm "reduced-2", 117228753Smm "reduced-3", 118228753Smm "reduced-4", 119228753Smm "imploded", 120228753Smm "reserved", 121228753Smm "deflation" 122228753Smm}; 123228753Smm 124228753Smmstatic int archive_read_format_zip_bid(struct archive_read *); 125228753Smmstatic int archive_read_format_zip_cleanup(struct archive_read *); 126228753Smmstatic int archive_read_format_zip_read_data(struct archive_read *, 127228753Smm const void **, size_t *, off_t *); 128228753Smmstatic int archive_read_format_zip_read_data_skip(struct archive_read *a); 129228753Smmstatic int archive_read_format_zip_read_header(struct archive_read *, 130228753Smm struct archive_entry *); 131229592Smmstatic int search_next_signature(struct archive_read *); 132228753Smmstatic int zip_read_data_deflate(struct archive_read *a, const void **buff, 133228753Smm size_t *size, off_t *offset); 134228753Smmstatic int zip_read_data_none(struct archive_read *a, const void **buff, 135228753Smm size_t *size, off_t *offset); 136228753Smmstatic int zip_read_file_header(struct archive_read *a, 137228753Smm struct archive_entry *entry, struct zip *zip); 138228753Smmstatic time_t zip_time(const char *); 139228753Smmstatic void process_extra(const void* extra, struct zip* zip); 140228753Smm 141228753Smmint 142228753Smmarchive_read_support_format_zip(struct archive *_a) 143228753Smm{ 144228753Smm struct archive_read *a = (struct archive_read *)_a; 145228753Smm struct zip *zip; 146228753Smm int r; 147228753Smm 148228753Smm zip = (struct zip *)malloc(sizeof(*zip)); 149228753Smm if (zip == NULL) { 150228753Smm archive_set_error(&a->archive, ENOMEM, "Can't allocate zip data"); 151228753Smm return (ARCHIVE_FATAL); 152228753Smm } 153228753Smm memset(zip, 0, sizeof(*zip)); 154228753Smm 155228753Smm r = __archive_read_register_format(a, 156228753Smm zip, 157228753Smm "zip", 158228753Smm archive_read_format_zip_bid, 159228753Smm NULL, 160228753Smm archive_read_format_zip_read_header, 161228753Smm archive_read_format_zip_read_data, 162228753Smm archive_read_format_zip_read_data_skip, 163228753Smm archive_read_format_zip_cleanup); 164228753Smm 165228753Smm if (r != ARCHIVE_OK) 166228753Smm free(zip); 167228753Smm return (ARCHIVE_OK); 168228753Smm} 169228753Smm 170228753Smm 171228753Smmstatic int 172228753Smmarchive_read_format_zip_bid(struct archive_read *a) 173228753Smm{ 174228753Smm const char *p; 175228753Smm const void *buff; 176228753Smm ssize_t bytes_avail, offset; 177228753Smm 178228753Smm if ((p = __archive_read_ahead(a, 4, NULL)) == NULL) 179228753Smm return (-1); 180228753Smm 181228753Smm /* 182228753Smm * Bid of 30 here is: 16 bits for "PK", 183228753Smm * next 16-bit field has four options (-2 bits). 184228753Smm * 16 + 16-2 = 30. 185228753Smm */ 186228753Smm if (p[0] == 'P' && p[1] == 'K') { 187228753Smm if ((p[2] == '\001' && p[3] == '\002') 188228753Smm || (p[2] == '\003' && p[3] == '\004') 189228753Smm || (p[2] == '\005' && p[3] == '\006') 190228753Smm || (p[2] == '\007' && p[3] == '\010') 191228753Smm || (p[2] == '0' && p[3] == '0')) 192228753Smm return (30); 193228753Smm } 194228753Smm 195228753Smm /* 196228753Smm * Attempt to handle self-extracting archives 197228753Smm * by noting a PE header and searching forward 198228753Smm * up to 128k for a 'PK\003\004' marker. 199228753Smm */ 200228753Smm if (p[0] == 'M' && p[1] == 'Z') { 201228753Smm /* 202228753Smm * TODO: Optimize by initializing 'offset' to an 203228753Smm * estimate of the likely start of the archive data 204228753Smm * based on values in the PE header. Note that we 205228753Smm * don't need to be exact, but we mustn't skip too 206228753Smm * far. The search below will compensate if we 207228753Smm * undershoot. 208228753Smm */ 209228753Smm offset = 0; 210228753Smm while (offset < 124000) { 211228753Smm /* Get 4k of data beyond where we stopped. */ 212228753Smm buff = __archive_read_ahead(a, offset + 4096, 213228753Smm &bytes_avail); 214228753Smm if (buff == NULL) 215228753Smm break; 216228753Smm p = (const char *)buff + offset; 217228753Smm while (p + 9 < (const char *)buff + bytes_avail) { 218228753Smm if (p[0] == 'P' && p[1] == 'K' /* signature */ 219228753Smm && p[2] == 3 && p[3] == 4 /* File entry */ 220228753Smm && p[8] == 8 /* compression == deflate */ 221228753Smm && p[9] == 0 /* High byte of compression */ 222228753Smm ) 223228753Smm { 224228753Smm return (30); 225228753Smm } 226228753Smm ++p; 227228753Smm } 228228753Smm offset = p - (const char *)buff; 229228753Smm } 230228753Smm } 231228753Smm 232228753Smm return (0); 233228753Smm} 234228753Smm 235228753Smm/* 236228753Smm * Search forward for a "PK\003\004" file header. This handles the 237228753Smm * case of self-extracting archives, where there is an executable 238228753Smm * prepended to the ZIP archive. 239228753Smm */ 240228753Smmstatic int 241228753Smmskip_sfx(struct archive_read *a) 242228753Smm{ 243228753Smm const void *h; 244228753Smm const char *p, *q; 245228753Smm size_t skip; 246228753Smm ssize_t bytes; 247228753Smm 248228753Smm /* 249228753Smm * TODO: We should be able to skip forward by a bunch 250228753Smm * by lifting some values from the PE header. We don't 251228753Smm * need to be exact (we're still going to search forward 252228753Smm * to find the header), but it will speed things up and 253228753Smm * reduce the chance of a false positive. 254228753Smm */ 255228753Smm for (;;) { 256228753Smm h = __archive_read_ahead(a, 4, &bytes); 257228753Smm if (bytes < 4) 258228753Smm return (ARCHIVE_FATAL); 259228753Smm p = h; 260228753Smm q = p + bytes; 261228753Smm 262228753Smm /* 263228753Smm * Scan ahead until we find something that looks 264228753Smm * like the zip header. 265228753Smm */ 266228753Smm while (p + 4 < q) { 267228753Smm switch (p[3]) { 268228753Smm case '\004': 269228753Smm /* TODO: Additional verification here. */ 270228753Smm if (memcmp("PK\003\004", p, 4) == 0) { 271228753Smm skip = p - (const char *)h; 272228753Smm __archive_read_consume(a, skip); 273228753Smm return (ARCHIVE_OK); 274228753Smm } 275228753Smm p += 4; 276228753Smm break; 277228753Smm case '\003': p += 1; break; 278228753Smm case 'K': p += 2; break; 279228753Smm case 'P': p += 3; break; 280228753Smm default: p += 4; break; 281228753Smm } 282228753Smm } 283228753Smm skip = p - (const char *)h; 284228753Smm __archive_read_consume(a, skip); 285228753Smm } 286228753Smm} 287228753Smm 288228753Smmstatic int 289228753Smmarchive_read_format_zip_read_header(struct archive_read *a, 290228753Smm struct archive_entry *entry) 291228753Smm{ 292228753Smm const void *h; 293228753Smm const char *signature; 294228753Smm struct zip *zip; 295228753Smm int r = ARCHIVE_OK, r1; 296228753Smm 297228753Smm a->archive.archive_format = ARCHIVE_FORMAT_ZIP; 298228753Smm if (a->archive.archive_format_name == NULL) 299228753Smm a->archive.archive_format_name = "ZIP"; 300228753Smm 301228753Smm zip = (struct zip *)(a->format->data); 302228753Smm zip->decompress_init = 0; 303228753Smm zip->end_of_entry = 0; 304228753Smm zip->entry_uncompressed_bytes_read = 0; 305228753Smm zip->entry_compressed_bytes_read = 0; 306228753Smm zip->entry_crc32 = crc32(0, NULL, 0); 307228753Smm if ((h = __archive_read_ahead(a, 4, NULL)) == NULL) 308228753Smm return (ARCHIVE_FATAL); 309228753Smm 310228753Smm signature = (const char *)h; 311228753Smm if (signature[0] == 'M' && signature[1] == 'Z') { 312228753Smm /* This is an executable? Must be self-extracting... */ 313228753Smm r = skip_sfx(a); 314228753Smm if (r < ARCHIVE_WARN) 315228753Smm return (r); 316228753Smm if ((h = __archive_read_ahead(a, 4, NULL)) == NULL) 317228753Smm return (ARCHIVE_FATAL); 318228753Smm signature = (const char *)h; 319228753Smm } 320228753Smm 321229592Smm /* If we don't see a PK signature here, scan forward. */ 322228753Smm if (signature[0] != 'P' || signature[1] != 'K') { 323229592Smm r = search_next_signature(a); 324229592Smm if (r != ARCHIVE_OK) { 325229592Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 326229592Smm "Bad ZIP file"); 327229592Smm return (ARCHIVE_FATAL); 328229592Smm } 329229592Smm if ((h = __archive_read_ahead(a, 4, NULL)) == NULL) 330229592Smm return (ARCHIVE_FATAL); 331229592Smm signature = (const char *)h; 332228753Smm } 333228753Smm 334228753Smm /* 335228753Smm * "PK00" signature is used for "split" archives that 336228753Smm * only have a single segment. This means we can just 337228753Smm * skip the PK00; the first real file header should follow. 338228753Smm */ 339228753Smm if (signature[2] == '0' && signature[3] == '0') { 340228753Smm __archive_read_consume(a, 4); 341228753Smm if ((h = __archive_read_ahead(a, 4, NULL)) == NULL) 342228753Smm return (ARCHIVE_FATAL); 343228753Smm signature = (const char *)h; 344228753Smm if (signature[0] != 'P' || signature[1] != 'K') { 345228753Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 346228753Smm "Bad ZIP file"); 347228753Smm return (ARCHIVE_FATAL); 348228753Smm } 349228753Smm } 350228753Smm 351228753Smm if (signature[2] == '\001' && signature[3] == '\002') { 352228753Smm /* Beginning of central directory. */ 353228753Smm return (ARCHIVE_EOF); 354228753Smm } 355228753Smm 356228753Smm if (signature[2] == '\003' && signature[3] == '\004') { 357228753Smm /* Regular file entry. */ 358228753Smm r1 = zip_read_file_header(a, entry, zip); 359228753Smm if (r1 != ARCHIVE_OK) 360228753Smm return (r1); 361228753Smm return (r); 362228753Smm } 363228753Smm 364228753Smm if (signature[2] == '\005' && signature[3] == '\006') { 365228753Smm /* End-of-archive record. */ 366228753Smm return (ARCHIVE_EOF); 367228753Smm } 368228753Smm 369228753Smm if (signature[2] == '\007' && signature[3] == '\010') { 370228753Smm /* 371228753Smm * We should never encounter this record here; 372228753Smm * see ZIP_LENGTH_AT_END handling below for details. 373228753Smm */ 374228753Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, 375228753Smm "Bad ZIP file: Unexpected end-of-entry record"); 376228753Smm return (ARCHIVE_FATAL); 377228753Smm } 378228753Smm 379228753Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 380228753Smm "Damaged ZIP file or unsupported format variant (%d,%d)", 381228753Smm signature[2], signature[3]); 382228753Smm return (ARCHIVE_FATAL); 383228753Smm} 384228753Smm 385228753Smmstatic int 386229592Smmsearch_next_signature(struct archive_read *a) 387229592Smm{ 388229592Smm const void *h; 389229592Smm const char *p, *q; 390229592Smm size_t skip; 391229592Smm ssize_t bytes; 392229592Smm int64_t skipped = 0; 393229592Smm 394229592Smm for (;;) { 395229592Smm h = __archive_read_ahead(a, 4, &bytes); 396229592Smm if (h == NULL) 397229592Smm return (ARCHIVE_FATAL); 398229592Smm p = h; 399229592Smm q = p + bytes; 400229592Smm 401229592Smm while (p + 4 <= q) { 402229592Smm if (p[0] == 'P' && p[1] == 'K') { 403229592Smm if ((p[2] == '\001' && p[3] == '\002') 404229592Smm || (p[2] == '\003' && p[3] == '\004') 405229592Smm || (p[2] == '\005' && p[3] == '\006') 406229592Smm || (p[2] == '\007' && p[3] == '\010') 407229592Smm || (p[2] == '0' && p[3] == '0')) { 408229592Smm skip = p - (const char *)h; 409229592Smm __archive_read_consume(a, skip); 410229592Smm return (ARCHIVE_OK); 411229592Smm } 412229592Smm } 413229592Smm ++p; 414229592Smm } 415229592Smm skip = p - (const char *)h; 416229592Smm __archive_read_consume(a, skip); 417229592Smm skipped += skip; 418229592Smm } 419229592Smm} 420229592Smm 421229592Smmstatic int 422228753Smmzip_read_file_header(struct archive_read *a, struct archive_entry *entry, 423228753Smm struct zip *zip) 424228753Smm{ 425228753Smm const struct zip_file_header *p; 426228753Smm const void *h; 427228753Smm 428228753Smm if ((p = __archive_read_ahead(a, sizeof *p, NULL)) == NULL) { 429228753Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 430228753Smm "Truncated ZIP file header"); 431228753Smm return (ARCHIVE_FATAL); 432228753Smm } 433228753Smm 434228753Smm zip->version = p->version[0]; 435228753Smm zip->system = p->version[1]; 436228753Smm zip->flags = archive_le16dec(p->flags); 437228753Smm zip->compression = archive_le16dec(p->compression); 438228753Smm if (zip->compression < 439228753Smm sizeof(compression_names)/sizeof(compression_names[0])) 440228753Smm zip->compression_name = compression_names[zip->compression]; 441228753Smm else 442228753Smm zip->compression_name = "??"; 443228753Smm zip->mtime = zip_time(p->timedate); 444228753Smm zip->ctime = 0; 445228753Smm zip->atime = 0; 446228753Smm zip->mode = 0; 447228753Smm zip->uid = 0; 448228753Smm zip->gid = 0; 449228753Smm zip->crc32 = archive_le32dec(p->crc32); 450228753Smm zip->filename_length = archive_le16dec(p->filename_length); 451228753Smm zip->extra_length = archive_le16dec(p->extra_length); 452228753Smm zip->uncompressed_size = archive_le32dec(p->uncompressed_size); 453228753Smm zip->compressed_size = archive_le32dec(p->compressed_size); 454228753Smm 455228753Smm __archive_read_consume(a, sizeof(struct zip_file_header)); 456228753Smm 457228753Smm 458228753Smm /* Read the filename. */ 459228753Smm if ((h = __archive_read_ahead(a, zip->filename_length, NULL)) == NULL) { 460228753Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 461228753Smm "Truncated ZIP file header"); 462228753Smm return (ARCHIVE_FATAL); 463228753Smm } 464228753Smm if (archive_string_ensure(&zip->pathname, zip->filename_length) == NULL) 465228753Smm __archive_errx(1, "Out of memory"); 466228753Smm archive_strncpy(&zip->pathname, h, zip->filename_length); 467228753Smm __archive_read_consume(a, zip->filename_length); 468228753Smm archive_entry_set_pathname(entry, zip->pathname.s); 469228753Smm 470228753Smm if (zip->pathname.s[archive_strlen(&zip->pathname) - 1] == '/') 471228753Smm zip->mode = AE_IFDIR | 0777; 472228753Smm else 473228753Smm zip->mode = AE_IFREG | 0777; 474228753Smm 475228753Smm /* Read the extra data. */ 476228753Smm if ((h = __archive_read_ahead(a, zip->extra_length, NULL)) == NULL) { 477228753Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 478228753Smm "Truncated ZIP file header"); 479228753Smm return (ARCHIVE_FATAL); 480228753Smm } 481228753Smm process_extra(h, zip); 482228753Smm __archive_read_consume(a, zip->extra_length); 483228753Smm 484228753Smm /* Populate some additional entry fields: */ 485228753Smm archive_entry_set_mode(entry, zip->mode); 486228753Smm archive_entry_set_uid(entry, zip->uid); 487228753Smm archive_entry_set_gid(entry, zip->gid); 488228753Smm archive_entry_set_mtime(entry, zip->mtime, 0); 489228753Smm archive_entry_set_ctime(entry, zip->ctime, 0); 490228753Smm archive_entry_set_atime(entry, zip->atime, 0); 491228753Smm /* Set the size only if it's meaningful. */ 492228753Smm if (0 == (zip->flags & ZIP_LENGTH_AT_END)) 493228753Smm archive_entry_set_size(entry, zip->uncompressed_size); 494228753Smm 495228753Smm zip->entry_bytes_remaining = zip->compressed_size; 496228753Smm zip->entry_offset = 0; 497228753Smm 498228753Smm /* If there's no body, force read_data() to return EOF immediately. */ 499228753Smm if (0 == (zip->flags & ZIP_LENGTH_AT_END) 500228753Smm && zip->entry_bytes_remaining < 1) 501228753Smm zip->end_of_entry = 1; 502228753Smm 503228753Smm /* Set up a more descriptive format name. */ 504228753Smm sprintf(zip->format_name, "ZIP %d.%d (%s)", 505228753Smm zip->version / 10, zip->version % 10, 506228753Smm zip->compression_name); 507228753Smm a->archive.archive_format_name = zip->format_name; 508228753Smm 509228753Smm return (ARCHIVE_OK); 510228753Smm} 511228753Smm 512228753Smm/* Convert an MSDOS-style date/time into Unix-style time. */ 513228753Smmstatic time_t 514228753Smmzip_time(const char *p) 515228753Smm{ 516228753Smm int msTime, msDate; 517228753Smm struct tm ts; 518228753Smm 519228753Smm msTime = (0xff & (unsigned)p[0]) + 256 * (0xff & (unsigned)p[1]); 520228753Smm msDate = (0xff & (unsigned)p[2]) + 256 * (0xff & (unsigned)p[3]); 521228753Smm 522228753Smm memset(&ts, 0, sizeof(ts)); 523228753Smm ts.tm_year = ((msDate >> 9) & 0x7f) + 80; /* Years since 1900. */ 524228753Smm ts.tm_mon = ((msDate >> 5) & 0x0f) - 1; /* Month number. */ 525228753Smm ts.tm_mday = msDate & 0x1f; /* Day of month. */ 526228753Smm ts.tm_hour = (msTime >> 11) & 0x1f; 527228753Smm ts.tm_min = (msTime >> 5) & 0x3f; 528228753Smm ts.tm_sec = (msTime << 1) & 0x3e; 529228753Smm ts.tm_isdst = -1; 530228753Smm return mktime(&ts); 531228753Smm} 532228753Smm 533228753Smmstatic int 534228753Smmarchive_read_format_zip_read_data(struct archive_read *a, 535228753Smm const void **buff, size_t *size, off_t *offset) 536228753Smm{ 537228753Smm int r; 538228753Smm struct zip *zip; 539228753Smm 540228753Smm zip = (struct zip *)(a->format->data); 541228753Smm 542228753Smm /* 543228753Smm * If we hit end-of-entry last time, clean up and return 544228753Smm * ARCHIVE_EOF this time. 545228753Smm */ 546228753Smm if (zip->end_of_entry) { 547228753Smm *offset = zip->entry_uncompressed_bytes_read; 548228753Smm *size = 0; 549228753Smm *buff = NULL; 550228753Smm return (ARCHIVE_EOF); 551228753Smm } 552228753Smm 553228753Smm switch(zip->compression) { 554228753Smm case 0: /* No compression. */ 555228753Smm r = zip_read_data_none(a, buff, size, offset); 556228753Smm break; 557228753Smm case 8: /* Deflate compression. */ 558228753Smm r = zip_read_data_deflate(a, buff, size, offset); 559228753Smm break; 560228753Smm default: /* Unsupported compression. */ 561228753Smm *buff = NULL; 562228753Smm *size = 0; 563228753Smm *offset = 0; 564228753Smm /* Return a warning. */ 565228753Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 566228753Smm "Unsupported ZIP compression method (%s)", 567228753Smm zip->compression_name); 568228753Smm if (zip->flags & ZIP_LENGTH_AT_END) { 569228753Smm /* 570228753Smm * ZIP_LENGTH_AT_END requires us to 571228753Smm * decompress the entry in order to 572228753Smm * skip it, but we don't know this 573228753Smm * compression method, so we give up. 574228753Smm */ 575228753Smm r = ARCHIVE_FATAL; 576228753Smm } else { 577228753Smm /* We can't decompress this entry, but we will 578228753Smm * be able to skip() it and try the next entry. */ 579228753Smm r = ARCHIVE_WARN; 580228753Smm } 581228753Smm break; 582228753Smm } 583228753Smm if (r != ARCHIVE_OK) 584228753Smm return (r); 585228753Smm /* Update checksum */ 586228753Smm if (*size) 587228753Smm zip->entry_crc32 = crc32(zip->entry_crc32, *buff, *size); 588228753Smm /* If we hit the end, swallow any end-of-data marker. */ 589228753Smm if (zip->end_of_entry) { 590228753Smm if (zip->flags & ZIP_LENGTH_AT_END) { 591228753Smm const char *p; 592228753Smm 593228753Smm if ((p = __archive_read_ahead(a, 16, NULL)) == NULL) { 594228753Smm archive_set_error(&a->archive, 595228753Smm ARCHIVE_ERRNO_FILE_FORMAT, 596228753Smm "Truncated ZIP end-of-file record"); 597228753Smm return (ARCHIVE_FATAL); 598228753Smm } 599228753Smm zip->crc32 = archive_le32dec(p + 4); 600228753Smm zip->compressed_size = archive_le32dec(p + 8); 601228753Smm zip->uncompressed_size = archive_le32dec(p + 12); 602228753Smm __archive_read_consume(a, 16); 603228753Smm } 604228753Smm /* Check file size, CRC against these values. */ 605228753Smm if (zip->compressed_size != zip->entry_compressed_bytes_read) { 606228753Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, 607228753Smm "ZIP compressed data is wrong size"); 608228753Smm return (ARCHIVE_WARN); 609228753Smm } 610228753Smm /* Size field only stores the lower 32 bits of the actual size. */ 611228753Smm if ((zip->uncompressed_size & UINT32_MAX) 612228753Smm != (zip->entry_uncompressed_bytes_read & UINT32_MAX)) { 613228753Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, 614228753Smm "ZIP uncompressed data is wrong size"); 615228753Smm return (ARCHIVE_WARN); 616228753Smm } 617228753Smm /* Check computed CRC against header */ 618228753Smm if (zip->crc32 != zip->entry_crc32) { 619228753Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, 620228753Smm "ZIP bad CRC: 0x%lx should be 0x%lx", 621228753Smm zip->entry_crc32, zip->crc32); 622228753Smm return (ARCHIVE_WARN); 623228753Smm } 624228753Smm } 625228753Smm 626228753Smm /* Return EOF immediately if this is a non-regular file. */ 627228753Smm if (AE_IFREG != (zip->mode & AE_IFMT)) 628228753Smm return (ARCHIVE_EOF); 629228753Smm return (ARCHIVE_OK); 630228753Smm} 631228753Smm 632228753Smm/* 633228753Smm * Read "uncompressed" data. According to the current specification, 634228753Smm * if ZIP_LENGTH_AT_END is specified, then the size fields in the 635228753Smm * initial file header are supposed to be set to zero. This would, of 636228753Smm * course, make it impossible for us to read the archive, since we 637228753Smm * couldn't determine the end of the file data. Info-ZIP seems to 638228753Smm * include the real size fields both before and after the data in this 639228753Smm * case (the CRC only appears afterwards), so this works as you would 640228753Smm * expect. 641228753Smm * 642228753Smm * Returns ARCHIVE_OK if successful, ARCHIVE_FATAL otherwise, sets 643228753Smm * zip->end_of_entry if it consumes all of the data. 644228753Smm */ 645228753Smmstatic int 646228753Smmzip_read_data_none(struct archive_read *a, const void **buff, 647228753Smm size_t *size, off_t *offset) 648228753Smm{ 649228753Smm struct zip *zip; 650228753Smm ssize_t bytes_avail; 651228753Smm 652228753Smm zip = (struct zip *)(a->format->data); 653228753Smm 654228753Smm if (zip->entry_bytes_remaining == 0) { 655228753Smm *buff = NULL; 656228753Smm *size = 0; 657228753Smm *offset = zip->entry_offset; 658228753Smm zip->end_of_entry = 1; 659228753Smm return (ARCHIVE_OK); 660228753Smm } 661228753Smm /* 662228753Smm * Note: '1' here is a performance optimization. 663228753Smm * Recall that the decompression layer returns a count of 664228753Smm * available bytes; asking for more than that forces the 665228753Smm * decompressor to combine reads by copying data. 666228753Smm */ 667228753Smm *buff = __archive_read_ahead(a, 1, &bytes_avail); 668228753Smm if (bytes_avail <= 0) { 669228753Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 670228753Smm "Truncated ZIP file data"); 671228753Smm return (ARCHIVE_FATAL); 672228753Smm } 673228753Smm if (bytes_avail > zip->entry_bytes_remaining) 674228753Smm bytes_avail = zip->entry_bytes_remaining; 675228753Smm __archive_read_consume(a, bytes_avail); 676228753Smm *size = bytes_avail; 677228753Smm *offset = zip->entry_offset; 678228753Smm zip->entry_offset += *size; 679228753Smm zip->entry_bytes_remaining -= *size; 680228753Smm zip->entry_uncompressed_bytes_read += *size; 681228753Smm zip->entry_compressed_bytes_read += *size; 682228753Smm return (ARCHIVE_OK); 683228753Smm} 684228753Smm 685228753Smm#ifdef HAVE_ZLIB_H 686228753Smmstatic int 687228753Smmzip_read_data_deflate(struct archive_read *a, const void **buff, 688228753Smm size_t *size, off_t *offset) 689228753Smm{ 690228753Smm struct zip *zip; 691228753Smm ssize_t bytes_avail; 692228753Smm const void *compressed_buff; 693228753Smm int r; 694228753Smm 695228753Smm zip = (struct zip *)(a->format->data); 696228753Smm 697228753Smm /* If the buffer hasn't been allocated, allocate it now. */ 698228753Smm if (zip->uncompressed_buffer == NULL) { 699228753Smm zip->uncompressed_buffer_size = 32 * 1024; 700228753Smm zip->uncompressed_buffer 701228753Smm = (unsigned char *)malloc(zip->uncompressed_buffer_size); 702228753Smm if (zip->uncompressed_buffer == NULL) { 703228753Smm archive_set_error(&a->archive, ENOMEM, 704228753Smm "No memory for ZIP decompression"); 705228753Smm return (ARCHIVE_FATAL); 706228753Smm } 707228753Smm } 708228753Smm 709228753Smm /* If we haven't yet read any data, initialize the decompressor. */ 710228753Smm if (!zip->decompress_init) { 711228753Smm if (zip->stream_valid) 712228753Smm r = inflateReset(&zip->stream); 713228753Smm else 714228753Smm r = inflateInit2(&zip->stream, 715228753Smm -15 /* Don't check for zlib header */); 716228753Smm if (r != Z_OK) { 717228753Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, 718228753Smm "Can't initialize ZIP decompression."); 719228753Smm return (ARCHIVE_FATAL); 720228753Smm } 721228753Smm /* Stream structure has been set up. */ 722228753Smm zip->stream_valid = 1; 723228753Smm /* We've initialized decompression for this stream. */ 724228753Smm zip->decompress_init = 1; 725228753Smm } 726228753Smm 727228753Smm /* 728228753Smm * Note: '1' here is a performance optimization. 729228753Smm * Recall that the decompression layer returns a count of 730228753Smm * available bytes; asking for more than that forces the 731228753Smm * decompressor to combine reads by copying data. 732228753Smm */ 733228753Smm compressed_buff = __archive_read_ahead(a, 1, &bytes_avail); 734228753Smm if (bytes_avail <= 0) { 735228753Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, 736228753Smm "Truncated ZIP file body"); 737228753Smm return (ARCHIVE_FATAL); 738228753Smm } 739228753Smm 740228753Smm /* 741228753Smm * A bug in zlib.h: stream.next_in should be marked 'const' 742228753Smm * but isn't (the library never alters data through the 743228753Smm * next_in pointer, only reads it). The result: this ugly 744228753Smm * cast to remove 'const'. 745228753Smm */ 746228753Smm zip->stream.next_in = (Bytef *)(uintptr_t)(const void *)compressed_buff; 747228753Smm zip->stream.avail_in = bytes_avail; 748228753Smm zip->stream.total_in = 0; 749228753Smm zip->stream.next_out = zip->uncompressed_buffer; 750228753Smm zip->stream.avail_out = zip->uncompressed_buffer_size; 751228753Smm zip->stream.total_out = 0; 752228753Smm 753228753Smm r = inflate(&zip->stream, 0); 754228753Smm switch (r) { 755228753Smm case Z_OK: 756228753Smm break; 757228753Smm case Z_STREAM_END: 758228753Smm zip->end_of_entry = 1; 759228753Smm break; 760228753Smm case Z_MEM_ERROR: 761228753Smm archive_set_error(&a->archive, ENOMEM, 762228753Smm "Out of memory for ZIP decompression"); 763228753Smm return (ARCHIVE_FATAL); 764228753Smm default: 765228753Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, 766228753Smm "ZIP decompression failed (%d)", r); 767228753Smm return (ARCHIVE_FATAL); 768228753Smm } 769228753Smm 770228753Smm /* Consume as much as the compressor actually used. */ 771228753Smm bytes_avail = zip->stream.total_in; 772228753Smm __archive_read_consume(a, bytes_avail); 773228753Smm zip->entry_bytes_remaining -= bytes_avail; 774228753Smm zip->entry_compressed_bytes_read += bytes_avail; 775228753Smm 776228753Smm *offset = zip->entry_offset; 777228753Smm *size = zip->stream.total_out; 778228753Smm zip->entry_uncompressed_bytes_read += *size; 779228753Smm *buff = zip->uncompressed_buffer; 780228753Smm zip->entry_offset += *size; 781228753Smm return (ARCHIVE_OK); 782228753Smm} 783228753Smm#else 784228753Smmstatic int 785228753Smmzip_read_data_deflate(struct archive_read *a, const void **buff, 786228753Smm size_t *size, off_t *offset) 787228753Smm{ 788228753Smm *buff = NULL; 789228753Smm *size = 0; 790228753Smm *offset = 0; 791228753Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, 792228753Smm "libarchive compiled without deflate support (no libz)"); 793228753Smm return (ARCHIVE_FATAL); 794228753Smm} 795228753Smm#endif 796228753Smm 797228753Smmstatic int 798228753Smmarchive_read_format_zip_read_data_skip(struct archive_read *a) 799228753Smm{ 800228753Smm struct zip *zip; 801228753Smm const void *buff = NULL; 802228753Smm off_t bytes_skipped; 803228753Smm 804228753Smm zip = (struct zip *)(a->format->data); 805228753Smm 806228753Smm /* If we've already read to end of data, we're done. */ 807228753Smm if (zip->end_of_entry) 808228753Smm return (ARCHIVE_OK); 809228753Smm 810228753Smm /* 811228753Smm * If the length is at the end, we have no choice but 812228753Smm * to decompress all the data to find the end marker. 813228753Smm */ 814228753Smm if (zip->flags & ZIP_LENGTH_AT_END) { 815228753Smm size_t size; 816228753Smm off_t offset; 817228753Smm int r; 818228753Smm do { 819228753Smm r = archive_read_format_zip_read_data(a, &buff, 820228753Smm &size, &offset); 821228753Smm } while (r == ARCHIVE_OK); 822228753Smm return (r); 823228753Smm } 824228753Smm 825228753Smm /* 826228753Smm * If the length is at the beginning, we can skip the 827228753Smm * compressed data much more quickly. 828228753Smm */ 829228753Smm bytes_skipped = __archive_read_skip(a, zip->entry_bytes_remaining); 830228753Smm if (bytes_skipped < 0) 831228753Smm return (ARCHIVE_FATAL); 832228753Smm 833228753Smm /* This entry is finished and done. */ 834228753Smm zip->end_of_entry = 1; 835228753Smm return (ARCHIVE_OK); 836228753Smm} 837228753Smm 838228753Smmstatic int 839228753Smmarchive_read_format_zip_cleanup(struct archive_read *a) 840228753Smm{ 841228753Smm struct zip *zip; 842228753Smm 843228753Smm zip = (struct zip *)(a->format->data); 844228753Smm#ifdef HAVE_ZLIB_H 845228753Smm if (zip->stream_valid) 846228753Smm inflateEnd(&zip->stream); 847228753Smm#endif 848228753Smm free(zip->uncompressed_buffer); 849228753Smm archive_string_free(&(zip->pathname)); 850228753Smm archive_string_free(&(zip->extra)); 851228753Smm free(zip); 852228753Smm (a->format->data) = NULL; 853228753Smm return (ARCHIVE_OK); 854228753Smm} 855228753Smm 856228753Smm/* 857228753Smm * The extra data is stored as a list of 858228753Smm * id1+size1+data1 + id2+size2+data2 ... 859228753Smm * triplets. id and size are 2 bytes each. 860228753Smm */ 861228753Smmstatic void 862228753Smmprocess_extra(const void* extra, struct zip* zip) 863228753Smm{ 864228753Smm int offset = 0; 865228753Smm const char *p = (const char *)extra; 866228753Smm while (offset < zip->extra_length - 4) 867228753Smm { 868228753Smm unsigned short headerid = archive_le16dec(p + offset); 869228753Smm unsigned short datasize = archive_le16dec(p + offset + 2); 870228753Smm offset += 4; 871228753Smm if (offset + datasize > zip->extra_length) 872228753Smm break; 873228753Smm#ifdef DEBUG 874228753Smm fprintf(stderr, "Header id 0x%04x, length %d\n", 875228753Smm headerid, datasize); 876228753Smm#endif 877228753Smm switch (headerid) { 878228753Smm case 0x0001: 879228753Smm /* Zip64 extended information extra field. */ 880228753Smm if (datasize >= 8) 881228753Smm zip->uncompressed_size = archive_le64dec(p + offset); 882228753Smm if (datasize >= 16) 883228753Smm zip->compressed_size = archive_le64dec(p + offset + 8); 884228753Smm break; 885228753Smm case 0x5455: 886228753Smm { 887228753Smm /* Extended time field "UT". */ 888228753Smm int flags = p[offset]; 889228753Smm offset++; 890228753Smm datasize--; 891228753Smm /* Flag bits indicate which dates are present. */ 892228753Smm if (flags & 0x01) 893228753Smm { 894228753Smm#ifdef DEBUG 895228753Smm fprintf(stderr, "mtime: %lld -> %d\n", 896228753Smm (long long)zip->mtime, 897228753Smm archive_le32dec(p + offset)); 898228753Smm#endif 899228753Smm if (datasize < 4) 900228753Smm break; 901228753Smm zip->mtime = archive_le32dec(p + offset); 902228753Smm offset += 4; 903228753Smm datasize -= 4; 904228753Smm } 905228753Smm if (flags & 0x02) 906228753Smm { 907228753Smm if (datasize < 4) 908228753Smm break; 909228753Smm zip->atime = archive_le32dec(p + offset); 910228753Smm offset += 4; 911228753Smm datasize -= 4; 912228753Smm } 913228753Smm if (flags & 0x04) 914228753Smm { 915228753Smm if (datasize < 4) 916228753Smm break; 917228753Smm zip->ctime = archive_le32dec(p + offset); 918228753Smm offset += 4; 919228753Smm datasize -= 4; 920228753Smm } 921228753Smm break; 922228753Smm } 923228753Smm case 0x7855: 924228753Smm /* Info-ZIP Unix Extra Field (type 2) "Ux". */ 925228753Smm#ifdef DEBUG 926228753Smm fprintf(stderr, "uid %d gid %d\n", 927228753Smm archive_le16dec(p + offset), 928228753Smm archive_le16dec(p + offset + 2)); 929228753Smm#endif 930228753Smm if (datasize >= 2) 931228753Smm zip->uid = archive_le16dec(p + offset); 932228753Smm if (datasize >= 4) 933228753Smm zip->gid = archive_le16dec(p + offset + 2); 934228753Smm break; 935229592Smm case 0x7875: 936229592Smm /* Info-Zip Unix Extra Field (type 3) "ux". */ 937229592Smm break; 938228753Smm default: 939228753Smm break; 940228753Smm } 941228753Smm offset += datasize; 942228753Smm } 943228753Smm#ifdef DEBUG 944228753Smm if (offset != zip->extra_length) 945228753Smm { 946228753Smm fprintf(stderr, 947228753Smm "Extra data field contents do not match reported size!"); 948228753Smm } 949228753Smm#endif 950228753Smm} 951