static int tk_archive_read_format_zip_read_data(struct archive_read *a, const void **buff, size_t *size, off_t *offset) { int r; struct zip *zip; zip = (struct zip *)(a->format->data); /* * If we hit end-of-entry last time, clean up and return * ARCHIVE_EOF this time. */ if (zip->end_of_entry) { *offset = zip->entry_uncompressed_bytes_read; *size = 0; *buff = NULL; return (ARCHIVE_EOF); } switch(zip->compression) { case 0: /* No compression. */ r = zip_read_data_none(a, buff, size, offset); break; case 8: /* Deflate compression. */ r = zip_read_data_deflate(a, buff, size, offset); break; default: /* Unsupported compression. */ *buff = NULL; *size = 0; *offset = 0; /* Return a warning. */ tk_archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, "Unsupported ZIP compression method (%s)", zip->compression_name); if (zip->flags & ZIP_LENGTH_AT_END) { /* * ZIP_LENGTH_AT_END requires us to * decompress the entry in order to * skip it, but we don't know this * compression method, so we give up. */ r = ARCHIVE_FATAL; } else { /* We can't decompress this entry, but we will * be able to skip() it and try the next entry. */ r = ARCHIVE_WARN; } break; } if (r != ARCHIVE_OK) return (r); /* Update checksum */ if (*size) zip->entry_crc32 = crc32(zip->entry_crc32, *buff, *size); /* If we hit the end, swallow any end-of-data marker. */ if (zip->end_of_entry) { if (zip->flags & ZIP_LENGTH_AT_END) { const char *p; if ((p = __archive_read_ahead(a, 16, NULL)) == NULL) { tk_archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, "Truncated ZIP end-of-file record"); return (ARCHIVE_FATAL); } zip->crc32 = tk_archive_le32dec(p + 4); zip->compressed_size = tk_archive_le32dec(p + 8); zip->uncompressed_size = tk_archive_le32dec(p + 12); __archive_read_consume(a, 16); } /* Check file size, CRC against these values. */ if (zip->compressed_size != zip->entry_compressed_bytes_read) { tk_archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, "ZIP compressed data is wrong size"); return (ARCHIVE_WARN); } /* Size field only stores the lower 32 bits of the actual size. */ if ((zip->uncompressed_size & UINT32_MAX) != (zip->entry_uncompressed_bytes_read & UINT32_MAX)) { tk_archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, "ZIP uncompressed data is wrong size"); return (ARCHIVE_WARN); } /* Check computed CRC against header */ if (zip->crc32 != zip->entry_crc32) { tk_archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, "ZIP bad CRC: 0x%lx should be 0x%lx", zip->entry_crc32, zip->crc32); return (ARCHIVE_WARN); } } /* Return EOF immediately if this is a non-regular file. */ if (AE_IFREG != (zip->mode & AE_IFMT)) return (ARCHIVE_EOF); return (ARCHIVE_OK); }
static int archive_read_format_zip_read_data(struct archive_read *a, const void **buff, size_t *size, off_t *offset) { int r; struct zip *zip; zip = (struct zip *)(a->format->data); /* * If we hit end-of-entry last time, clean up and return * ARCHIVE_EOF this time. */ if (zip->end_of_entry) { if (!zip->end_of_entry_cleanup) { if (zip->flags & ZIP_LENGTH_AT_END) { const char *p; if ((p = __archive_read_ahead(a, 16)) == NULL) { archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, "Truncated ZIP end-of-file record"); return (ARCHIVE_FATAL); } zip->crc32 = archive_le32dec(p + 4); zip->compressed_size = archive_le32dec(p + 8); zip->uncompressed_size = archive_le32dec(p + 12); (a->decompressor->consume)(a, 16); } /* Check file size, CRC against these values. */ if (zip->compressed_size != zip->entry_compressed_bytes_read) { archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, "ZIP compressed data is wrong size"); return (ARCHIVE_WARN); } /* Size field only stores the lower 32 bits of the actual size. */ if ((zip->uncompressed_size & UINT32_MAX) != (zip->entry_uncompressed_bytes_read & UINT32_MAX)) { archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, "ZIP uncompressed data is wrong size"); return (ARCHIVE_WARN); } /* TODO: Compute CRC. */ /* if (zip->crc32 != zip->entry_crc32_calculated) { archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, "ZIP data CRC error"); return (ARCHIVE_WARN); } */ /* End-of-entry cleanup done. */ zip->end_of_entry_cleanup = 1; } *offset = zip->entry_uncompressed_bytes_read; *size = 0; *buff = NULL; return (ARCHIVE_EOF); } switch(zip->compression) { case 0: /* No compression. */ r = zip_read_data_none(a, buff, size, offset); break; case 8: /* Deflate compression. */ r = zip_read_data_deflate(a, buff, size, offset); break; default: /* Unsupported compression. */ *buff = NULL; *size = 0; *offset = 0; /* Return a warning. */ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, "Unsupported ZIP compression method (%s)", zip->compression_name); if (zip->flags & ZIP_LENGTH_AT_END) { /* * ZIP_LENGTH_AT_END requires us to * decompress the entry in order to * skip it, but we don't know this * compression method, so we give up. */ r = ARCHIVE_FATAL; } else { /* We can't decompress this entry, but we will * be able to skip() it and try the next entry. */ r = ARCHIVE_WARN; } break; } return (r); }