libarchive-static 1.0.6 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/ext/extconf.rb +2 -9
- data/ext/libarchive-0.1.1/ext/archive_read_support_compression.c +6 -6
- data/ext/libarchive-0.1.1/ext/archive_read_support_compression.o +0 -0
- data/ext/libarchive-0.1.1/ext/archive_read_support_format.o +0 -0
- data/ext/libarchive-0.1.1/ext/archive_write_open_rb_str.c +1 -1
- data/ext/libarchive-0.1.1/ext/archive_write_open_rb_str.o +0 -0
- data/ext/libarchive-0.1.1/ext/archive_write_set_compression.c +5 -5
- data/ext/libarchive-0.1.1/ext/archive_write_set_compression.o +0 -0
- data/ext/libarchive-0.1.1/ext/config.h +23 -0
- data/ext/libarchive-0.1.1/ext/config.log +230 -0
- data/ext/libarchive-0.1.1/ext/config.status +671 -0
- data/ext/libarchive-0.1.1/ext/libarchive.c +1 -1
- data/ext/libarchive-0.1.1/ext/libarchive.o +0 -0
- data/ext/libarchive-0.1.1/ext/libarchive_archive.c +7 -7
- data/ext/libarchive-0.1.1/ext/libarchive_archive.o +0 -0
- data/ext/libarchive-0.1.1/ext/libarchive_entry.c +6 -0
- data/ext/libarchive-0.1.1/ext/libarchive_entry.o +0 -0
- data/ext/libarchive-0.1.1/ext/libarchive_reader.c +6 -4
- data/ext/libarchive-0.1.1/ext/libarchive_reader.o +0 -0
- data/ext/libarchive-0.1.1/ext/libarchive_ruby.so +0 -0
- data/ext/libarchive-0.1.1/ext/libarchive_win32.h +1 -1
- data/ext/libarchive-0.1.1/ext/libarchive_writer.c +2 -2
- data/ext/libarchive-0.1.1/ext/libarchive_writer.o +0 -0
- data/ext/libarchive-3.6.2/Makefile.in +16892 -0
- data/ext/libarchive-3.6.2/build/autoconf/ax_append_compile_flags.m4 +67 -0
- data/ext/libarchive-3.6.2/build/autoconf/ax_append_flag.m4 +71 -0
- data/ext/libarchive-3.6.2/build/autoconf/ax_check_compile_flag.m4 +74 -0
- data/ext/libarchive-3.6.2/build/autoconf/ax_require_defined.m4 +37 -0
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/build/autoconf/check_stdcall_func.m4 +0 -0
- data/ext/libarchive-3.6.2/build/autoconf/compile +348 -0
- data/ext/libarchive-3.6.2/build/autoconf/config.guess +1754 -0
- data/ext/libarchive-3.6.2/build/autoconf/config.rpath +696 -0
- data/ext/libarchive-3.6.2/build/autoconf/config.sub +1890 -0
- data/ext/libarchive-3.6.2/build/autoconf/depcomp +791 -0
- data/ext/libarchive-3.6.2/build/autoconf/iconv.m4 +271 -0
- data/ext/libarchive-3.6.2/build/autoconf/install-sh +541 -0
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/build/autoconf/la_uid_t.m4 +0 -0
- data/ext/libarchive-3.6.2/build/autoconf/lib-ld.m4 +109 -0
- data/ext/libarchive-3.6.2/build/autoconf/lib-link.m4 +777 -0
- data/ext/libarchive-3.6.2/build/autoconf/lib-prefix.m4 +224 -0
- data/ext/libarchive-3.6.2/build/autoconf/ltmain.sh +11251 -0
- data/ext/libarchive-3.6.2/build/autoconf/m4_ax_compile_check_sizeof.m4 +115 -0
- data/ext/libarchive-3.6.2/build/autoconf/missing +215 -0
- data/ext/libarchive-3.6.2/build/autoconf/test-driver +153 -0
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/build/pkgconfig/libarchive.pc.in +4 -1
- data/ext/libarchive-3.6.2/config.h.in +1504 -0
- data/ext/libarchive-3.6.2/configure +25558 -0
- data/ext/libarchive-3.6.2/libarchive/archive.h +1212 -0
- data/ext/libarchive-3.6.2/libarchive/archive_acl.c +2097 -0
- data/ext/libarchive-3.6.2/libarchive/archive_acl_private.h +83 -0
- data/ext/libarchive-3.6.2/libarchive/archive_blake2.h +197 -0
- data/ext/libarchive-3.6.2/libarchive/archive_blake2_impl.h +161 -0
- data/ext/libarchive-3.6.2/libarchive/archive_blake2s_ref.c +369 -0
- data/ext/libarchive-3.6.2/libarchive/archive_blake2sp_ref.c +361 -0
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_check_magic.c +63 -22
- data/ext/libarchive-3.6.2/libarchive/archive_cmdline.c +227 -0
- data/ext/libarchive-3.6.2/libarchive/archive_cmdline_private.h +47 -0
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_crc32.h +17 -0
- data/ext/libarchive-3.6.2/libarchive/archive_cryptor.c +534 -0
- data/ext/libarchive-3.6.2/libarchive/archive_cryptor_private.h +188 -0
- data/ext/libarchive-3.6.2/libarchive/archive_digest.c +1505 -0
- data/ext/libarchive-3.6.2/libarchive/archive_digest_private.h +416 -0
- data/ext/libarchive-3.6.2/libarchive/archive_disk_acl_darwin.c +559 -0
- data/ext/libarchive-3.6.2/libarchive/archive_disk_acl_freebsd.c +712 -0
- data/ext/libarchive-3.6.2/libarchive/archive_disk_acl_linux.c +760 -0
- data/ext/libarchive-3.6.2/libarchive/archive_disk_acl_sunos.c +824 -0
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_endian.h +48 -15
- data/ext/libarchive-3.6.2/libarchive/archive_entry.c +2149 -0
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_entry.h +305 -106
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_entry_copy_bhfi.c +5 -4
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_entry_copy_stat.c +9 -3
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_entry_link_resolver.c +104 -62
- data/ext/libarchive-3.6.2/libarchive/archive_entry_locale.h +92 -0
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_entry_private.h +65 -49
- data/ext/libarchive-3.6.2/libarchive/archive_entry_sparse.c +156 -0
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_entry_stat.c +6 -6
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_entry_strmode.c +1 -1
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_entry_xattr.c +4 -6
- data/ext/libarchive-3.6.2/libarchive/archive_getdate.c +1165 -0
- data/ext/libarchive-3.6.2/libarchive/archive_getdate.h +39 -0
- data/ext/libarchive-3.6.2/libarchive/archive_hmac.c +334 -0
- data/ext/libarchive-3.6.2/libarchive/archive_hmac_private.h +117 -0
- data/ext/libarchive-3.6.2/libarchive/archive_match.c +1875 -0
- data/ext/libarchive-3.6.2/libarchive/archive_openssl_evp_private.h +53 -0
- data/ext/libarchive-3.6.2/libarchive/archive_openssl_hmac_private.h +54 -0
- data/ext/libarchive-3.6.2/libarchive/archive_options.c +218 -0
- data/ext/libarchive-3.6.2/libarchive/archive_options_private.h +51 -0
- data/ext/libarchive-3.6.2/libarchive/archive_pack_dev.c +337 -0
- data/ext/libarchive-3.6.2/libarchive/archive_pack_dev.h +49 -0
- data/ext/libarchive-3.6.2/libarchive/archive_pathmatch.c +463 -0
- data/ext/libarchive-3.6.2/libarchive/archive_pathmatch.h +52 -0
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_platform.h +77 -9
- data/ext/libarchive-3.6.2/libarchive/archive_platform_acl.h +55 -0
- data/ext/libarchive-3.6.2/libarchive/archive_platform_xattr.h +47 -0
- data/ext/libarchive-3.6.2/libarchive/archive_ppmd7.c +1168 -0
- data/ext/libarchive-3.6.2/libarchive/archive_ppmd7_private.h +119 -0
- data/ext/libarchive-3.6.2/libarchive/archive_ppmd8.c +1287 -0
- data/ext/libarchive-3.6.2/libarchive/archive_ppmd8_private.h +148 -0
- data/ext/libarchive-3.6.2/libarchive/archive_ppmd_private.h +151 -0
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_private.h +74 -18
- data/ext/libarchive-3.6.2/libarchive/archive_random.c +272 -0
- data/ext/libarchive-3.6.2/libarchive/archive_random_private.h +36 -0
- data/ext/libarchive-3.6.2/libarchive/archive_rb.c +709 -0
- data/ext/libarchive-3.6.2/libarchive/archive_rb.h +113 -0
- data/ext/libarchive-3.6.2/libarchive/archive_read.c +1756 -0
- data/ext/libarchive-3.6.2/libarchive/archive_read_add_passphrase.c +190 -0
- data/ext/libarchive-3.6.2/libarchive/archive_read_append_filter.c +204 -0
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_read_data_into_fd.c +64 -18
- data/ext/libarchive-3.6.2/libarchive/archive_read_disk_entry_from_file.c +1086 -0
- data/ext/libarchive-3.6.2/libarchive/archive_read_disk_posix.c +2732 -0
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_read_disk_private.h +40 -4
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_read_disk_set_standard_lookup.c +21 -11
- data/ext/libarchive-3.6.2/libarchive/archive_read_disk_windows.c +2479 -0
- data/ext/libarchive-3.6.2/libarchive/archive_read_extract.c +60 -0
- data/ext/{libarchive-2.8.4/libarchive/archive_read_extract.c → libarchive-3.6.2/libarchive/archive_read_extract2.c} +34 -61
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_read_open_fd.c +70 -49
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_read_open_file.c +38 -23
- data/ext/libarchive-3.6.2/libarchive/archive_read_open_filename.c +586 -0
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_read_open_memory.c +58 -28
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_read_private.h +127 -59
- data/ext/libarchive-3.6.2/libarchive/archive_read_set_format.c +117 -0
- data/ext/libarchive-3.6.2/libarchive/archive_read_set_options.c +133 -0
- data/ext/{libarchive-2.8.4/libarchive/archive_read_support_compression_all.c → libarchive-3.6.2/libarchive/archive_read_support_filter_all.c} +35 -10
- data/ext/libarchive-3.6.2/libarchive/archive_read_support_filter_by_code.c +83 -0
- data/ext/{libarchive-2.8.4/libarchive/archive_read_support_compression_bzip2.c → libarchive-3.6.2/libarchive/archive_read_support_filter_bzip2.c} +38 -26
- data/ext/{libarchive-2.8.4/libarchive/archive_read_support_compression_compress.c → libarchive-3.6.2/libarchive/archive_read_support_filter_compress.c} +52 -44
- data/ext/libarchive-3.6.2/libarchive/archive_read_support_filter_grzip.c +112 -0
- data/ext/{libarchive-2.8.4/libarchive/archive_read_support_compression_gzip.c → libarchive-3.6.2/libarchive/archive_read_support_filter_gzip.c} +108 -37
- data/ext/libarchive-3.6.2/libarchive/archive_read_support_filter_lrzip.c +122 -0
- data/ext/libarchive-3.6.2/libarchive/archive_read_support_filter_lz4.c +742 -0
- data/ext/libarchive-3.6.2/libarchive/archive_read_support_filter_lzop.c +499 -0
- data/ext/{libarchive-2.8.4/libarchive/archive_read_support_compression_none.c → libarchive-3.6.2/libarchive/archive_read_support_filter_none.c} +15 -3
- data/ext/{libarchive-2.8.4/libarchive/archive_read_support_compression_program.c → libarchive-3.6.2/libarchive/archive_read_support_filter_program.c} +114 -77
- data/ext/{libarchive-2.8.4/libarchive/archive_read_support_compression_rpm.c → libarchive-3.6.2/libarchive/archive_read_support_filter_rpm.c} +31 -31
- data/ext/{libarchive-2.8.4/libarchive/archive_read_support_compression_uu.c → libarchive-3.6.2/libarchive/archive_read_support_filter_uu.c} +141 -85
- data/ext/{libarchive-2.8.4/libarchive/archive_read_support_compression_xz.c → libarchive-3.6.2/libarchive/archive_read_support_filter_xz.c} +369 -284
- data/ext/libarchive-3.6.2/libarchive/archive_read_support_filter_zstd.c +297 -0
- data/ext/libarchive-3.6.2/libarchive/archive_read_support_format_7zip.c +3900 -0
- data/ext/libarchive-3.6.2/libarchive/archive_read_support_format_all.c +89 -0
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_read_support_format_ar.c +126 -72
- data/ext/libarchive-3.6.2/libarchive/archive_read_support_format_by_code.c +92 -0
- data/ext/libarchive-3.6.2/libarchive/archive_read_support_format_cab.c +3228 -0
- data/ext/libarchive-3.6.2/libarchive/archive_read_support_format_cpio.c +1104 -0
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_read_support_format_empty.c +14 -11
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_read_support_format_iso9660.c +990 -541
- data/ext/libarchive-3.6.2/libarchive/archive_read_support_format_lha.c +2916 -0
- data/ext/libarchive-3.6.2/libarchive/archive_read_support_format_mtree.c +2150 -0
- data/ext/libarchive-3.6.2/libarchive/archive_read_support_format_rar.c +3797 -0
- data/ext/libarchive-3.6.2/libarchive/archive_read_support_format_rar5.c +4251 -0
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_read_support_format_raw.c +38 -31
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_read_support_format_tar.c +1157 -629
- data/ext/libarchive-3.6.2/libarchive/archive_read_support_format_warc.c +848 -0
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_read_support_format_xar.c +439 -258
- data/ext/libarchive-3.6.2/libarchive/archive_read_support_format_zip.c +4270 -0
- data/ext/libarchive-3.6.2/libarchive/archive_string.c +4240 -0
- data/ext/libarchive-3.6.2/libarchive/archive_string.h +243 -0
- data/ext/libarchive-3.6.2/libarchive/archive_string_composition.h +2292 -0
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_string_sprintf.c +44 -16
- data/ext/libarchive-3.6.2/libarchive/archive_util.c +655 -0
- data/ext/libarchive-3.6.2/libarchive/archive_version_details.c +151 -0
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_virtual.c +85 -16
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_windows.c +214 -541
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_windows.h +74 -106
- data/ext/libarchive-3.6.2/libarchive/archive_write.c +828 -0
- data/ext/libarchive-3.6.2/libarchive/archive_write_add_filter.c +72 -0
- data/ext/libarchive-3.6.2/libarchive/archive_write_add_filter_b64encode.c +304 -0
- data/ext/libarchive-3.6.2/libarchive/archive_write_add_filter_by_name.c +77 -0
- data/ext/libarchive-3.6.2/libarchive/archive_write_add_filter_bzip2.c +401 -0
- data/ext/{libarchive-2.8.4/libarchive/archive_write_set_compression_compress.c → libarchive-3.6.2/libarchive/archive_write_add_filter_compress.c} +86 -131
- data/ext/libarchive-3.6.2/libarchive/archive_write_add_filter_grzip.c +135 -0
- data/ext/libarchive-3.6.2/libarchive/archive_write_add_filter_gzip.c +442 -0
- data/ext/libarchive-3.6.2/libarchive/archive_write_add_filter_lrzip.c +197 -0
- data/ext/libarchive-3.6.2/libarchive/archive_write_add_filter_lz4.c +700 -0
- data/ext/libarchive-3.6.2/libarchive/archive_write_add_filter_lzop.c +478 -0
- data/ext/{libarchive-2.8.4/libarchive/archive_read_support_format_all.c → libarchive-3.6.2/libarchive/archive_write_add_filter_none.c} +11 -11
- data/ext/libarchive-3.6.2/libarchive/archive_write_add_filter_program.c +391 -0
- data/ext/libarchive-3.6.2/libarchive/archive_write_add_filter_uuencode.c +295 -0
- data/ext/libarchive-3.6.2/libarchive/archive_write_add_filter_xz.c +545 -0
- data/ext/libarchive-3.6.2/libarchive/archive_write_add_filter_zstd.c +418 -0
- data/ext/libarchive-3.6.2/libarchive/archive_write_disk_posix.c +4711 -0
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_write_disk_private.h +9 -2
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_write_disk_set_standard_lookup.c +30 -29
- data/ext/libarchive-3.6.2/libarchive/archive_write_disk_windows.c +2842 -0
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_write_open_fd.c +15 -10
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_write_open_file.c +15 -9
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_write_open_filename.c +128 -20
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_write_open_memory.c +7 -18
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_write_private.h +72 -29
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_write_set_format.c +56 -3
- data/ext/libarchive-3.6.2/libarchive/archive_write_set_format_7zip.c +2322 -0
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_write_set_format_ar.c +54 -34
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_write_set_format_by_name.c +20 -2
- data/ext/libarchive-3.6.2/libarchive/archive_write_set_format_cpio.c +11 -0
- data/ext/libarchive-3.6.2/libarchive/archive_write_set_format_cpio_binary.c +610 -0
- data/ext/libarchive-3.6.2/libarchive/archive_write_set_format_cpio_newc.c +457 -0
- data/ext/libarchive-3.6.2/libarchive/archive_write_set_format_cpio_odc.c +500 -0
- data/ext/libarchive-3.6.2/libarchive/archive_write_set_format_filter_by_ext.c +142 -0
- data/ext/libarchive-3.6.2/libarchive/archive_write_set_format_gnutar.c +755 -0
- data/ext/libarchive-3.6.2/libarchive/archive_write_set_format_iso9660.c +8165 -0
- data/ext/libarchive-3.6.2/libarchive/archive_write_set_format_mtree.c +2217 -0
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_write_set_format_pax.c +1049 -387
- data/ext/libarchive-3.6.2/libarchive/archive_write_set_format_private.h +42 -0
- data/ext/libarchive-3.6.2/libarchive/archive_write_set_format_raw.c +125 -0
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_write_set_format_shar.c +62 -47
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_write_set_format_ustar.c +279 -108
- data/ext/libarchive-3.6.2/libarchive/archive_write_set_format_v7tar.c +638 -0
- data/ext/libarchive-3.6.2/libarchive/archive_write_set_format_warc.c +453 -0
- data/ext/libarchive-3.6.2/libarchive/archive_write_set_format_xar.c +3259 -0
- data/ext/libarchive-3.6.2/libarchive/archive_write_set_format_zip.c +1704 -0
- data/ext/libarchive-3.6.2/libarchive/archive_write_set_options.c +130 -0
- data/ext/libarchive-3.6.2/libarchive/archive_write_set_passphrase.c +95 -0
- data/ext/libarchive-3.6.2/libarchive/archive_xxhash.h +48 -0
- data/ext/libarchive-3.6.2/libarchive/config_freebsd.h +271 -0
- data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/filter_fork.h +10 -5
- data/ext/{libarchive-2.8.4/libarchive/filter_fork.c → libarchive-3.6.2/libarchive/filter_fork_posix.c} +98 -19
- data/ext/libarchive-3.6.2/libarchive/filter_fork_windows.c +236 -0
- data/ext/libarchive-3.6.2/libarchive/xxhash.c +525 -0
- data/ext/libarchive-static-makefile +144 -80
- data/ext/libarchive-static-wrapper-makefile +1 -1
- data/ext/zlib-1.2.13/Makefile.in +404 -0
- data/ext/{zlib-1.2.5 → zlib-1.2.13}/adler32.c +51 -34
- data/ext/{zlib-1.2.5 → zlib-1.2.13}/compress.c +27 -21
- data/ext/zlib-1.2.13/configure +922 -0
- data/ext/zlib-1.2.13/crc32.c +1125 -0
- data/ext/zlib-1.2.13/crc32.h +9446 -0
- data/ext/{zlib-1.2.5 → zlib-1.2.13}/deflate.c +842 -459
- data/ext/{zlib-1.2.5 → zlib-1.2.13}/deflate.h +37 -33
- data/ext/{zlib-1.2.5 → zlib-1.2.13}/gzclose.c +0 -0
- data/ext/{zlib-1.2.5 → zlib-1.2.13}/gzguts.h +103 -16
- data/ext/{zlib-1.2.5 → zlib-1.2.13}/gzlib.c +155 -53
- data/ext/zlib-1.2.13/gzread.c +650 -0
- data/ext/zlib-1.2.13/gzwrite.c +677 -0
- data/ext/{zlib-1.2.5 → zlib-1.2.13}/infback.c +24 -12
- data/ext/{zlib-1.2.5 → zlib-1.2.13}/inffast.c +49 -66
- data/ext/{zlib-1.2.5 → zlib-1.2.13}/inffast.h +0 -0
- data/ext/{zlib-1.2.5 → zlib-1.2.13}/inffixed.h +3 -3
- data/ext/{zlib-1.2.5 → zlib-1.2.13}/inflate.c +209 -94
- data/ext/{zlib-1.2.5 → zlib-1.2.13}/inflate.h +9 -5
- data/ext/{zlib-1.2.5 → zlib-1.2.13}/inftrees.c +24 -50
- data/ext/{zlib-1.2.5 → zlib-1.2.13}/inftrees.h +1 -1
- data/ext/{zlib-1.2.5 → zlib-1.2.13}/trees.c +135 -198
- data/ext/{zlib-1.2.5 → zlib-1.2.13}/trees.h +0 -0
- data/ext/zlib-1.2.13/uncompr.c +93 -0
- data/ext/{zlib-1.2.5 → zlib-1.2.13}/zconf.h +182 -63
- data/ext/{zlib-1.2.5 → zlib-1.2.13}/zlib.h +617 -295
- data/ext/{zlib-1.2.5 → zlib-1.2.13}/zutil.c +50 -41
- data/ext/{zlib-1.2.5 → zlib-1.2.13}/zutil.h +83 -82
- metadata +241 -133
- data/ext/libarchive-0.1.1/libarchive.c +0 -1762
- data/ext/libarchive-2.8.4/Makefile.in +0 -7076
- data/ext/libarchive-2.8.4/build/autoconf/compile +0 -143
- data/ext/libarchive-2.8.4/build/autoconf/config.guess +0 -1502
- data/ext/libarchive-2.8.4/build/autoconf/config.sub +0 -1708
- data/ext/libarchive-2.8.4/build/autoconf/depcomp +0 -630
- data/ext/libarchive-2.8.4/build/autoconf/install-sh +0 -291
- data/ext/libarchive-2.8.4/build/autoconf/ltmain.sh +0 -8406
- data/ext/libarchive-2.8.4/build/autoconf/missing +0 -376
- data/ext/libarchive-2.8.4/config.h.in +0 -772
- data/ext/libarchive-2.8.4/configure +0 -17916
- data/ext/libarchive-2.8.4/libarchive/archive.h +0 -741
- data/ext/libarchive-2.8.4/libarchive/archive_entry.c +0 -2202
- data/ext/libarchive-2.8.4/libarchive/archive_hash.h +0 -281
- data/ext/libarchive-2.8.4/libarchive/archive_read.c +0 -1249
- data/ext/libarchive-2.8.4/libarchive/archive_read_disk.c +0 -198
- data/ext/libarchive-2.8.4/libarchive/archive_read_disk_entry_from_file.c +0 -570
- data/ext/libarchive-2.8.4/libarchive/archive_read_open_filename.c +0 -272
- data/ext/libarchive-2.8.4/libarchive/archive_read_support_format_cpio.c +0 -777
- data/ext/libarchive-2.8.4/libarchive/archive_read_support_format_mtree.c +0 -1304
- data/ext/libarchive-2.8.4/libarchive/archive_read_support_format_zip.c +0 -903
- data/ext/libarchive-2.8.4/libarchive/archive_string.c +0 -453
- data/ext/libarchive-2.8.4/libarchive/archive_string.h +0 -148
- data/ext/libarchive-2.8.4/libarchive/archive_util.c +0 -391
- data/ext/libarchive-2.8.4/libarchive/archive_write.c +0 -466
- data/ext/libarchive-2.8.4/libarchive/archive_write_disk.c +0 -2628
- data/ext/libarchive-2.8.4/libarchive/archive_write_set_compression_bzip2.c +0 -408
- data/ext/libarchive-2.8.4/libarchive/archive_write_set_compression_gzip.c +0 -477
- data/ext/libarchive-2.8.4/libarchive/archive_write_set_compression_none.c +0 -257
- data/ext/libarchive-2.8.4/libarchive/archive_write_set_compression_program.c +0 -347
- data/ext/libarchive-2.8.4/libarchive/archive_write_set_compression_xz.c +0 -438
- data/ext/libarchive-2.8.4/libarchive/archive_write_set_format_cpio.c +0 -344
- data/ext/libarchive-2.8.4/libarchive/archive_write_set_format_cpio_newc.c +0 -295
- data/ext/libarchive-2.8.4/libarchive/archive_write_set_format_mtree.c +0 -1050
- data/ext/libarchive-2.8.4/libarchive/archive_write_set_format_zip.c +0 -667
- data/ext/libarchive-2.8.4/libarchive/config_freebsd.h +0 -154
- data/ext/libarchive-2.8.4/libarchive/filter_fork_windows.c +0 -113
- data/ext/zlib-1.2.5/Makefile.in +0 -257
- data/ext/zlib-1.2.5/configure +0 -596
- data/ext/zlib-1.2.5/crc32.c +0 -442
- data/ext/zlib-1.2.5/crc32.h +0 -441
- data/ext/zlib-1.2.5/example.c +0 -565
- data/ext/zlib-1.2.5/gzread.c +0 -653
- data/ext/zlib-1.2.5/gzwrite.c +0 -531
- data/ext/zlib-1.2.5/minigzip.c +0 -440
- data/ext/zlib-1.2.5/uncompr.c +0 -59
|
@@ -0,0 +1,4270 @@
|
|
|
1
|
+
/*-
|
|
2
|
+
* Copyright (c) 2004-2013 Tim Kientzle
|
|
3
|
+
* Copyright (c) 2011-2012,2014 Michihiro NAKAJIMA
|
|
4
|
+
* Copyright (c) 2013 Konrad Kleine
|
|
5
|
+
* All rights reserved.
|
|
6
|
+
*
|
|
7
|
+
* Redistribution and use in source and binary forms, with or without
|
|
8
|
+
* modification, are permitted provided that the following conditions
|
|
9
|
+
* are met:
|
|
10
|
+
* 1. Redistributions of source code must retain the above copyright
|
|
11
|
+
* notice, this list of conditions and the following disclaimer.
|
|
12
|
+
* 2. Redistributions in binary form must reproduce the above copyright
|
|
13
|
+
* notice, this list of conditions and the following disclaimer in the
|
|
14
|
+
* documentation and/or other materials provided with the distribution.
|
|
15
|
+
*
|
|
16
|
+
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
|
|
17
|
+
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
18
|
+
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
19
|
+
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
20
|
+
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
21
|
+
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
22
|
+
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
23
|
+
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
24
|
+
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
25
|
+
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
26
|
+
*/
|
|
27
|
+
|
|
28
|
+
#include "archive_platform.h"
|
|
29
|
+
__FBSDID("$FreeBSD: head/lib/libarchive/archive_read_support_format_zip.c 201102 2009-12-28 03:11:36Z kientzle $");
|
|
30
|
+
|
|
31
|
+
/*
|
|
32
|
+
* The definitive documentation of the Zip file format is:
|
|
33
|
+
* http://www.pkware.com/documents/casestudies/APPNOTE.TXT
|
|
34
|
+
*
|
|
35
|
+
* The Info-Zip project has pioneered various extensions to better
|
|
36
|
+
* support Zip on Unix, including the 0x5455 "UT", 0x5855 "UX", 0x7855
|
|
37
|
+
* "Ux", and 0x7875 "ux" extensions for time and ownership
|
|
38
|
+
* information.
|
|
39
|
+
*
|
|
40
|
+
* History of this code: The streaming Zip reader was first added to
|
|
41
|
+
* libarchive in January 2005. Support for seekable input sources was
|
|
42
|
+
* added in Nov 2011. Zip64 support (including a significant code
|
|
43
|
+
* refactoring) was added in 2014.
|
|
44
|
+
*/
|
|
45
|
+
|
|
46
|
+
#ifdef HAVE_ERRNO_H
|
|
47
|
+
#include <errno.h>
|
|
48
|
+
#endif
|
|
49
|
+
#ifdef HAVE_STDLIB_H
|
|
50
|
+
#include <stdlib.h>
|
|
51
|
+
#endif
|
|
52
|
+
#ifdef HAVE_ZLIB_H
|
|
53
|
+
#include <zlib.h>
|
|
54
|
+
#endif
|
|
55
|
+
#ifdef HAVE_BZLIB_H
|
|
56
|
+
#include <bzlib.h>
|
|
57
|
+
#endif
|
|
58
|
+
#ifdef HAVE_LZMA_H
|
|
59
|
+
#include <lzma.h>
|
|
60
|
+
#endif
|
|
61
|
+
#ifdef HAVE_ZSTD_H
|
|
62
|
+
#include <zstd.h>
|
|
63
|
+
#endif
|
|
64
|
+
|
|
65
|
+
#include "archive.h"
|
|
66
|
+
#include "archive_digest_private.h"
|
|
67
|
+
#include "archive_cryptor_private.h"
|
|
68
|
+
#include "archive_endian.h"
|
|
69
|
+
#include "archive_entry.h"
|
|
70
|
+
#include "archive_entry_locale.h"
|
|
71
|
+
#include "archive_hmac_private.h"
|
|
72
|
+
#include "archive_private.h"
|
|
73
|
+
#include "archive_rb.h"
|
|
74
|
+
#include "archive_read_private.h"
|
|
75
|
+
#include "archive_ppmd8_private.h"
|
|
76
|
+
|
|
77
|
+
#ifndef HAVE_ZLIB_H
|
|
78
|
+
#include "archive_crc32.h"
|
|
79
|
+
#endif
|
|
80
|
+
|
|
81
|
+
struct zip_entry {
|
|
82
|
+
struct archive_rb_node node;
|
|
83
|
+
struct zip_entry *next;
|
|
84
|
+
int64_t local_header_offset;
|
|
85
|
+
int64_t compressed_size;
|
|
86
|
+
int64_t uncompressed_size;
|
|
87
|
+
int64_t gid;
|
|
88
|
+
int64_t uid;
|
|
89
|
+
struct archive_string rsrcname;
|
|
90
|
+
time_t mtime;
|
|
91
|
+
time_t atime;
|
|
92
|
+
time_t ctime;
|
|
93
|
+
uint32_t crc32;
|
|
94
|
+
uint16_t mode;
|
|
95
|
+
uint16_t zip_flags; /* From GP Flags Field */
|
|
96
|
+
unsigned char compression;
|
|
97
|
+
unsigned char system; /* From "version written by" */
|
|
98
|
+
unsigned char flags; /* Our extra markers. */
|
|
99
|
+
unsigned char decdat;/* Used for Decryption check */
|
|
100
|
+
|
|
101
|
+
/* WinZip AES encryption extra field should be available
|
|
102
|
+
* when compression is 99. */
|
|
103
|
+
struct {
|
|
104
|
+
/* Vendor version: AE-1 - 0x0001, AE-2 - 0x0002 */
|
|
105
|
+
unsigned vendor;
|
|
106
|
+
#define AES_VENDOR_AE_1 0x0001
|
|
107
|
+
#define AES_VENDOR_AE_2 0x0002
|
|
108
|
+
/* AES encryption strength:
|
|
109
|
+
* 1 - 128 bits, 2 - 192 bits, 2 - 256 bits. */
|
|
110
|
+
unsigned strength;
|
|
111
|
+
/* Actual compression method. */
|
|
112
|
+
unsigned char compression;
|
|
113
|
+
} aes_extra;
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
struct trad_enc_ctx {
|
|
117
|
+
uint32_t keys[3];
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
/* Bits used in zip_flags. */
|
|
121
|
+
#define ZIP_ENCRYPTED (1 << 0)
|
|
122
|
+
#define ZIP_LENGTH_AT_END (1 << 3)
|
|
123
|
+
#define ZIP_STRONG_ENCRYPTED (1 << 6)
|
|
124
|
+
#define ZIP_UTF8_NAME (1 << 11)
|
|
125
|
+
/* See "7.2 Single Password Symmetric Encryption Method"
|
|
126
|
+
in http://www.pkware.com/documents/casestudies/APPNOTE.TXT */
|
|
127
|
+
#define ZIP_CENTRAL_DIRECTORY_ENCRYPTED (1 << 13)
|
|
128
|
+
|
|
129
|
+
/* Bits used in flags. */
|
|
130
|
+
#define LA_USED_ZIP64 (1 << 0)
|
|
131
|
+
#define LA_FROM_CENTRAL_DIRECTORY (1 << 1)
|
|
132
|
+
|
|
133
|
+
/*
|
|
134
|
+
* See "WinZip - AES Encryption Information"
|
|
135
|
+
* http://www.winzip.com/aes_info.htm
|
|
136
|
+
*/
|
|
137
|
+
/* Value used in compression method. */
|
|
138
|
+
#define WINZIP_AES_ENCRYPTION 99
|
|
139
|
+
/* Authentication code size. */
|
|
140
|
+
#define AUTH_CODE_SIZE 10
|
|
141
|
+
/**/
|
|
142
|
+
#define MAX_DERIVED_KEY_BUF_SIZE (AES_MAX_KEY_SIZE * 2 + 2)
|
|
143
|
+
|
|
144
|
+
struct zip {
|
|
145
|
+
/* Structural information about the archive. */
|
|
146
|
+
struct archive_string format_name;
|
|
147
|
+
int64_t central_directory_offset;
|
|
148
|
+
int64_t central_directory_offset_adjusted;
|
|
149
|
+
size_t central_directory_entries_total;
|
|
150
|
+
size_t central_directory_entries_on_this_disk;
|
|
151
|
+
int has_encrypted_entries;
|
|
152
|
+
|
|
153
|
+
/* List of entries (seekable Zip only) */
|
|
154
|
+
struct zip_entry *zip_entries;
|
|
155
|
+
struct archive_rb_tree tree;
|
|
156
|
+
struct archive_rb_tree tree_rsrc;
|
|
157
|
+
|
|
158
|
+
/* Bytes read but not yet consumed via __archive_read_consume() */
|
|
159
|
+
size_t unconsumed;
|
|
160
|
+
|
|
161
|
+
/* Information about entry we're currently reading. */
|
|
162
|
+
struct zip_entry *entry;
|
|
163
|
+
int64_t entry_bytes_remaining;
|
|
164
|
+
|
|
165
|
+
/* These count the number of bytes actually read for the entry. */
|
|
166
|
+
int64_t entry_compressed_bytes_read;
|
|
167
|
+
int64_t entry_uncompressed_bytes_read;
|
|
168
|
+
|
|
169
|
+
/* Running CRC32 of the decompressed data */
|
|
170
|
+
unsigned long entry_crc32;
|
|
171
|
+
unsigned long (*crc32func)(unsigned long, const void *,
|
|
172
|
+
size_t);
|
|
173
|
+
char ignore_crc32;
|
|
174
|
+
|
|
175
|
+
/* Flags to mark progress of decompression. */
|
|
176
|
+
char decompress_init;
|
|
177
|
+
char end_of_entry;
|
|
178
|
+
|
|
179
|
+
unsigned char *uncompressed_buffer;
|
|
180
|
+
size_t uncompressed_buffer_size;
|
|
181
|
+
|
|
182
|
+
#ifdef HAVE_ZLIB_H
|
|
183
|
+
z_stream stream;
|
|
184
|
+
char stream_valid;
|
|
185
|
+
#endif
|
|
186
|
+
|
|
187
|
+
#if HAVE_LZMA_H && HAVE_LIBLZMA
|
|
188
|
+
lzma_stream zipx_lzma_stream;
|
|
189
|
+
char zipx_lzma_valid;
|
|
190
|
+
#endif
|
|
191
|
+
|
|
192
|
+
#ifdef HAVE_BZLIB_H
|
|
193
|
+
bz_stream bzstream;
|
|
194
|
+
char bzstream_valid;
|
|
195
|
+
#endif
|
|
196
|
+
|
|
197
|
+
#if HAVE_ZSTD_H && HAVE_LIBZSTD
|
|
198
|
+
ZSTD_DStream *zstdstream;
|
|
199
|
+
char zstdstream_valid;
|
|
200
|
+
#endif
|
|
201
|
+
|
|
202
|
+
IByteIn zipx_ppmd_stream;
|
|
203
|
+
ssize_t zipx_ppmd_read_compressed;
|
|
204
|
+
CPpmd8 ppmd8;
|
|
205
|
+
char ppmd8_valid;
|
|
206
|
+
char ppmd8_stream_failed;
|
|
207
|
+
|
|
208
|
+
struct archive_string_conv *sconv;
|
|
209
|
+
struct archive_string_conv *sconv_default;
|
|
210
|
+
struct archive_string_conv *sconv_utf8;
|
|
211
|
+
int init_default_conversion;
|
|
212
|
+
int process_mac_extensions;
|
|
213
|
+
|
|
214
|
+
char init_decryption;
|
|
215
|
+
|
|
216
|
+
/* Decryption buffer. */
|
|
217
|
+
/*
|
|
218
|
+
* The decrypted data starts at decrypted_ptr and
|
|
219
|
+
* extends for decrypted_bytes_remaining. Decryption
|
|
220
|
+
* adds new data to the end of this block, data is returned
|
|
221
|
+
* to clients from the beginning. When the block hits the
|
|
222
|
+
* end of decrypted_buffer, it has to be shuffled back to
|
|
223
|
+
* the beginning of the buffer.
|
|
224
|
+
*/
|
|
225
|
+
unsigned char *decrypted_buffer;
|
|
226
|
+
unsigned char *decrypted_ptr;
|
|
227
|
+
size_t decrypted_buffer_size;
|
|
228
|
+
size_t decrypted_bytes_remaining;
|
|
229
|
+
size_t decrypted_unconsumed_bytes;
|
|
230
|
+
|
|
231
|
+
/* Traditional PKWARE decryption. */
|
|
232
|
+
struct trad_enc_ctx tctx;
|
|
233
|
+
char tctx_valid;
|
|
234
|
+
|
|
235
|
+
/* WinZip AES decryption. */
|
|
236
|
+
/* Contexts used for AES decryption. */
|
|
237
|
+
archive_crypto_ctx cctx;
|
|
238
|
+
char cctx_valid;
|
|
239
|
+
archive_hmac_sha1_ctx hctx;
|
|
240
|
+
char hctx_valid;
|
|
241
|
+
|
|
242
|
+
/* Strong encryption's decryption header information. */
|
|
243
|
+
unsigned iv_size;
|
|
244
|
+
unsigned alg_id;
|
|
245
|
+
unsigned bit_len;
|
|
246
|
+
unsigned flags;
|
|
247
|
+
unsigned erd_size;
|
|
248
|
+
unsigned v_size;
|
|
249
|
+
unsigned v_crc32;
|
|
250
|
+
uint8_t *iv;
|
|
251
|
+
uint8_t *erd;
|
|
252
|
+
uint8_t *v_data;
|
|
253
|
+
};
|
|
254
|
+
|
|
255
|
+
/* Many systems define min or MIN, but not all. */
|
|
256
|
+
#define zipmin(a,b) ((a) < (b) ? (a) : (b))
|
|
257
|
+
|
|
258
|
+
#ifdef HAVE_ZLIB_H
|
|
259
|
+
static int
|
|
260
|
+
zip_read_data_deflate(struct archive_read *a, const void **buff,
|
|
261
|
+
size_t *size, int64_t *offset);
|
|
262
|
+
#endif
|
|
263
|
+
#if HAVE_LZMA_H && HAVE_LIBLZMA
|
|
264
|
+
static int
|
|
265
|
+
zip_read_data_zipx_lzma_alone(struct archive_read *a, const void **buff,
|
|
266
|
+
size_t *size, int64_t *offset);
|
|
267
|
+
#endif
|
|
268
|
+
|
|
269
|
+
/* This function is used by Ppmd8_DecodeSymbol during decompression of Ppmd8
|
|
270
|
+
* streams inside ZIP files. It has 2 purposes: one is to fetch the next
|
|
271
|
+
* compressed byte from the stream, second one is to increase the counter how
|
|
272
|
+
* many compressed bytes were read. */
|
|
273
|
+
static Byte
|
|
274
|
+
ppmd_read(void* p) {
|
|
275
|
+
/* Get the handle to current decompression context. */
|
|
276
|
+
struct archive_read *a = ((IByteIn*)p)->a;
|
|
277
|
+
struct zip *zip = (struct zip*) a->format->data;
|
|
278
|
+
ssize_t bytes_avail = 0;
|
|
279
|
+
|
|
280
|
+
/* Fetch next byte. */
|
|
281
|
+
const uint8_t* data = __archive_read_ahead(a, 1, &bytes_avail);
|
|
282
|
+
if(bytes_avail < 1) {
|
|
283
|
+
zip->ppmd8_stream_failed = 1;
|
|
284
|
+
return 0;
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
__archive_read_consume(a, 1);
|
|
288
|
+
|
|
289
|
+
/* Increment the counter. */
|
|
290
|
+
++zip->zipx_ppmd_read_compressed;
|
|
291
|
+
|
|
292
|
+
/* Return the next compressed byte. */
|
|
293
|
+
return data[0];
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
/* ------------------------------------------------------------------------ */
|
|
297
|
+
|
|
298
|
+
/*
|
|
299
|
+
Traditional PKWARE Decryption functions.
|
|
300
|
+
*/
|
|
301
|
+
|
|
302
|
+
static void
|
|
303
|
+
trad_enc_update_keys(struct trad_enc_ctx *ctx, uint8_t c)
|
|
304
|
+
{
|
|
305
|
+
uint8_t t;
|
|
306
|
+
#define CRC32(c, b) (crc32(c ^ 0xffffffffUL, &b, 1) ^ 0xffffffffUL)
|
|
307
|
+
|
|
308
|
+
ctx->keys[0] = CRC32(ctx->keys[0], c);
|
|
309
|
+
ctx->keys[1] = (ctx->keys[1] + (ctx->keys[0] & 0xff)) * 134775813L + 1;
|
|
310
|
+
t = (ctx->keys[1] >> 24) & 0xff;
|
|
311
|
+
ctx->keys[2] = CRC32(ctx->keys[2], t);
|
|
312
|
+
#undef CRC32
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
static uint8_t
|
|
316
|
+
trad_enc_decrypt_byte(struct trad_enc_ctx *ctx)
|
|
317
|
+
{
|
|
318
|
+
unsigned temp = ctx->keys[2] | 2;
|
|
319
|
+
return (uint8_t)((temp * (temp ^ 1)) >> 8) & 0xff;
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
static void
|
|
323
|
+
trad_enc_decrypt_update(struct trad_enc_ctx *ctx, const uint8_t *in,
|
|
324
|
+
size_t in_len, uint8_t *out, size_t out_len)
|
|
325
|
+
{
|
|
326
|
+
unsigned i, max;
|
|
327
|
+
|
|
328
|
+
max = (unsigned)((in_len < out_len)? in_len: out_len);
|
|
329
|
+
|
|
330
|
+
for (i = 0; i < max; i++) {
|
|
331
|
+
uint8_t t = in[i] ^ trad_enc_decrypt_byte(ctx);
|
|
332
|
+
out[i] = t;
|
|
333
|
+
trad_enc_update_keys(ctx, t);
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
static int
|
|
338
|
+
trad_enc_init(struct trad_enc_ctx *ctx, const char *pw, size_t pw_len,
|
|
339
|
+
const uint8_t *key, size_t key_len, uint8_t *crcchk)
|
|
340
|
+
{
|
|
341
|
+
uint8_t header[12];
|
|
342
|
+
|
|
343
|
+
if (key_len < 12) {
|
|
344
|
+
*crcchk = 0xff;
|
|
345
|
+
return -1;
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
ctx->keys[0] = 305419896L;
|
|
349
|
+
ctx->keys[1] = 591751049L;
|
|
350
|
+
ctx->keys[2] = 878082192L;
|
|
351
|
+
|
|
352
|
+
for (;pw_len; --pw_len)
|
|
353
|
+
trad_enc_update_keys(ctx, *pw++);
|
|
354
|
+
|
|
355
|
+
trad_enc_decrypt_update(ctx, key, 12, header, 12);
|
|
356
|
+
/* Return the last byte for CRC check. */
|
|
357
|
+
*crcchk = header[11];
|
|
358
|
+
return 0;
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
#if 0
|
|
362
|
+
static void
|
|
363
|
+
crypt_derive_key_sha1(const void *p, int size, unsigned char *key,
|
|
364
|
+
int key_size)
|
|
365
|
+
{
|
|
366
|
+
#define MD_SIZE 20
|
|
367
|
+
archive_sha1_ctx ctx;
|
|
368
|
+
unsigned char md1[MD_SIZE];
|
|
369
|
+
unsigned char md2[MD_SIZE * 2];
|
|
370
|
+
unsigned char mkb[64];
|
|
371
|
+
int i;
|
|
372
|
+
|
|
373
|
+
archive_sha1_init(&ctx);
|
|
374
|
+
archive_sha1_update(&ctx, p, size);
|
|
375
|
+
archive_sha1_final(&ctx, md1);
|
|
376
|
+
|
|
377
|
+
memset(mkb, 0x36, sizeof(mkb));
|
|
378
|
+
for (i = 0; i < MD_SIZE; i++)
|
|
379
|
+
mkb[i] ^= md1[i];
|
|
380
|
+
archive_sha1_init(&ctx);
|
|
381
|
+
archive_sha1_update(&ctx, mkb, sizeof(mkb));
|
|
382
|
+
archive_sha1_final(&ctx, md2);
|
|
383
|
+
|
|
384
|
+
memset(mkb, 0x5C, sizeof(mkb));
|
|
385
|
+
for (i = 0; i < MD_SIZE; i++)
|
|
386
|
+
mkb[i] ^= md1[i];
|
|
387
|
+
archive_sha1_init(&ctx);
|
|
388
|
+
archive_sha1_update(&ctx, mkb, sizeof(mkb));
|
|
389
|
+
archive_sha1_final(&ctx, md2 + MD_SIZE);
|
|
390
|
+
|
|
391
|
+
if (key_size > 32)
|
|
392
|
+
key_size = 32;
|
|
393
|
+
memcpy(key, md2, key_size);
|
|
394
|
+
#undef MD_SIZE
|
|
395
|
+
}
|
|
396
|
+
#endif
|
|
397
|
+
|
|
398
|
+
/*
|
|
399
|
+
* Common code for streaming or seeking modes.
|
|
400
|
+
*
|
|
401
|
+
* Includes code to read local file headers, decompress data
|
|
402
|
+
* from entry bodies, and common API.
|
|
403
|
+
*/
|
|
404
|
+
|
|
405
|
+
static unsigned long
|
|
406
|
+
real_crc32(unsigned long crc, const void *buff, size_t len)
|
|
407
|
+
{
|
|
408
|
+
return crc32(crc, buff, (unsigned int)len);
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
/* Used by "ignorecrc32" option to speed up tests. */
|
|
412
|
+
static unsigned long
|
|
413
|
+
fake_crc32(unsigned long crc, const void *buff, size_t len)
|
|
414
|
+
{
|
|
415
|
+
(void)crc; /* UNUSED */
|
|
416
|
+
(void)buff; /* UNUSED */
|
|
417
|
+
(void)len; /* UNUSED */
|
|
418
|
+
return 0;
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
static const struct {
|
|
422
|
+
int id;
|
|
423
|
+
const char * name;
|
|
424
|
+
} compression_methods[] = {
|
|
425
|
+
{0, "uncompressed"}, /* The file is stored (no compression) */
|
|
426
|
+
{1, "shrinking"}, /* The file is Shrunk */
|
|
427
|
+
{2, "reduced-1"}, /* The file is Reduced with compression factor 1 */
|
|
428
|
+
{3, "reduced-2"}, /* The file is Reduced with compression factor 2 */
|
|
429
|
+
{4, "reduced-3"}, /* The file is Reduced with compression factor 3 */
|
|
430
|
+
{5, "reduced-4"}, /* The file is Reduced with compression factor 4 */
|
|
431
|
+
{6, "imploded"}, /* The file is Imploded */
|
|
432
|
+
{7, "reserved"}, /* Reserved for Tokenizing compression algorithm */
|
|
433
|
+
{8, "deflation"}, /* The file is Deflated */
|
|
434
|
+
{9, "deflation-64-bit"}, /* Enhanced Deflating using Deflate64(tm) */
|
|
435
|
+
{10, "ibm-terse"},/* PKWARE Data Compression Library Imploding
|
|
436
|
+
* (old IBM TERSE) */
|
|
437
|
+
{11, "reserved"}, /* Reserved by PKWARE */
|
|
438
|
+
{12, "bzip"}, /* File is compressed using BZIP2 algorithm */
|
|
439
|
+
{13, "reserved"}, /* Reserved by PKWARE */
|
|
440
|
+
{14, "lzma"}, /* LZMA (EFS) */
|
|
441
|
+
{15, "reserved"}, /* Reserved by PKWARE */
|
|
442
|
+
{16, "reserved"}, /* Reserved by PKWARE */
|
|
443
|
+
{17, "reserved"}, /* Reserved by PKWARE */
|
|
444
|
+
{18, "ibm-terse-new"}, /* File is compressed using IBM TERSE (new) */
|
|
445
|
+
{19, "ibm-lz777"},/* IBM LZ77 z Architecture (PFS) */
|
|
446
|
+
{93, "zstd"}, /* Zstandard (zstd) Compression */
|
|
447
|
+
{95, "xz"}, /* XZ compressed data */
|
|
448
|
+
{96, "jpeg"}, /* JPEG compressed data */
|
|
449
|
+
{97, "wav-pack"}, /* WavPack compressed data */
|
|
450
|
+
{98, "ppmd-1"}, /* PPMd version I, Rev 1 */
|
|
451
|
+
{99, "aes"} /* WinZip AES encryption */
|
|
452
|
+
};
|
|
453
|
+
|
|
454
|
+
static const char *
|
|
455
|
+
compression_name(const int compression)
|
|
456
|
+
{
|
|
457
|
+
static const int num_compression_methods =
|
|
458
|
+
sizeof(compression_methods)/sizeof(compression_methods[0]);
|
|
459
|
+
int i=0;
|
|
460
|
+
|
|
461
|
+
while(compression >= 0 && i < num_compression_methods) {
|
|
462
|
+
if (compression_methods[i].id == compression)
|
|
463
|
+
return compression_methods[i].name;
|
|
464
|
+
i++;
|
|
465
|
+
}
|
|
466
|
+
return "??";
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
/* Convert an MSDOS-style date/time into Unix-style time. */
|
|
470
|
+
static time_t
|
|
471
|
+
zip_time(const char *p)
|
|
472
|
+
{
|
|
473
|
+
int msTime, msDate;
|
|
474
|
+
struct tm ts;
|
|
475
|
+
|
|
476
|
+
msTime = (0xff & (unsigned)p[0]) + 256 * (0xff & (unsigned)p[1]);
|
|
477
|
+
msDate = (0xff & (unsigned)p[2]) + 256 * (0xff & (unsigned)p[3]);
|
|
478
|
+
|
|
479
|
+
memset(&ts, 0, sizeof(ts));
|
|
480
|
+
ts.tm_year = ((msDate >> 9) & 0x7f) + 80; /* Years since 1900. */
|
|
481
|
+
ts.tm_mon = ((msDate >> 5) & 0x0f) - 1; /* Month number. */
|
|
482
|
+
ts.tm_mday = msDate & 0x1f; /* Day of month. */
|
|
483
|
+
ts.tm_hour = (msTime >> 11) & 0x1f;
|
|
484
|
+
ts.tm_min = (msTime >> 5) & 0x3f;
|
|
485
|
+
ts.tm_sec = (msTime << 1) & 0x3e;
|
|
486
|
+
ts.tm_isdst = -1;
|
|
487
|
+
return mktime(&ts);
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
/*
|
|
491
|
+
* The extra data is stored as a list of
|
|
492
|
+
* id1+size1+data1 + id2+size2+data2 ...
|
|
493
|
+
* triplets. id and size are 2 bytes each.
|
|
494
|
+
*/
|
|
495
|
+
static int
|
|
496
|
+
process_extra(struct archive_read *a, struct archive_entry *entry,
|
|
497
|
+
const char *p, size_t extra_length, struct zip_entry* zip_entry)
|
|
498
|
+
{
|
|
499
|
+
unsigned offset = 0;
|
|
500
|
+
struct zip *zip = (struct zip *)(a->format->data);
|
|
501
|
+
|
|
502
|
+
if (extra_length == 0) {
|
|
503
|
+
return ARCHIVE_OK;
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
if (extra_length < 4) {
|
|
507
|
+
size_t i = 0;
|
|
508
|
+
/* Some ZIP files may have trailing 0 bytes. Let's check they
|
|
509
|
+
* are all 0 and ignore them instead of returning an error.
|
|
510
|
+
*
|
|
511
|
+
* This is not technically correct, but some ZIP files look
|
|
512
|
+
* like this and other tools support those files - so let's
|
|
513
|
+
* also support them.
|
|
514
|
+
*/
|
|
515
|
+
for (; i < extra_length; i++) {
|
|
516
|
+
if (p[i] != 0) {
|
|
517
|
+
archive_set_error(&a->archive,
|
|
518
|
+
ARCHIVE_ERRNO_FILE_FORMAT,
|
|
519
|
+
"Too-small extra data: "
|
|
520
|
+
"Need at least 4 bytes, "
|
|
521
|
+
"but only found %d bytes",
|
|
522
|
+
(int)extra_length);
|
|
523
|
+
return ARCHIVE_FAILED;
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
return ARCHIVE_OK;
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
while (offset <= extra_length - 4) {
|
|
531
|
+
unsigned short headerid = archive_le16dec(p + offset);
|
|
532
|
+
unsigned short datasize = archive_le16dec(p + offset + 2);
|
|
533
|
+
|
|
534
|
+
offset += 4;
|
|
535
|
+
if (offset + datasize > extra_length) {
|
|
536
|
+
archive_set_error(&a->archive,
|
|
537
|
+
ARCHIVE_ERRNO_FILE_FORMAT, "Extra data overflow: "
|
|
538
|
+
"Need %d bytes but only found %d bytes",
|
|
539
|
+
(int)datasize, (int)(extra_length - offset));
|
|
540
|
+
return ARCHIVE_FAILED;
|
|
541
|
+
}
|
|
542
|
+
#ifdef DEBUG
|
|
543
|
+
fprintf(stderr, "Header id 0x%04x, length %d\n",
|
|
544
|
+
headerid, datasize);
|
|
545
|
+
#endif
|
|
546
|
+
switch (headerid) {
|
|
547
|
+
case 0x0001:
|
|
548
|
+
/* Zip64 extended information extra field. */
|
|
549
|
+
zip_entry->flags |= LA_USED_ZIP64;
|
|
550
|
+
if (zip_entry->uncompressed_size == 0xffffffff) {
|
|
551
|
+
uint64_t t = 0;
|
|
552
|
+
if (datasize < 8
|
|
553
|
+
|| (t = archive_le64dec(p + offset)) >
|
|
554
|
+
INT64_MAX) {
|
|
555
|
+
archive_set_error(&a->archive,
|
|
556
|
+
ARCHIVE_ERRNO_FILE_FORMAT,
|
|
557
|
+
"Malformed 64-bit "
|
|
558
|
+
"uncompressed size");
|
|
559
|
+
return ARCHIVE_FAILED;
|
|
560
|
+
}
|
|
561
|
+
zip_entry->uncompressed_size = t;
|
|
562
|
+
offset += 8;
|
|
563
|
+
datasize -= 8;
|
|
564
|
+
}
|
|
565
|
+
if (zip_entry->compressed_size == 0xffffffff) {
|
|
566
|
+
uint64_t t = 0;
|
|
567
|
+
if (datasize < 8
|
|
568
|
+
|| (t = archive_le64dec(p + offset)) >
|
|
569
|
+
INT64_MAX) {
|
|
570
|
+
archive_set_error(&a->archive,
|
|
571
|
+
ARCHIVE_ERRNO_FILE_FORMAT,
|
|
572
|
+
"Malformed 64-bit "
|
|
573
|
+
"compressed size");
|
|
574
|
+
return ARCHIVE_FAILED;
|
|
575
|
+
}
|
|
576
|
+
zip_entry->compressed_size = t;
|
|
577
|
+
offset += 8;
|
|
578
|
+
datasize -= 8;
|
|
579
|
+
}
|
|
580
|
+
if (zip_entry->local_header_offset == 0xffffffff) {
|
|
581
|
+
uint64_t t = 0;
|
|
582
|
+
if (datasize < 8
|
|
583
|
+
|| (t = archive_le64dec(p + offset)) >
|
|
584
|
+
INT64_MAX) {
|
|
585
|
+
archive_set_error(&a->archive,
|
|
586
|
+
ARCHIVE_ERRNO_FILE_FORMAT,
|
|
587
|
+
"Malformed 64-bit "
|
|
588
|
+
"local header offset");
|
|
589
|
+
return ARCHIVE_FAILED;
|
|
590
|
+
}
|
|
591
|
+
zip_entry->local_header_offset = t;
|
|
592
|
+
offset += 8;
|
|
593
|
+
datasize -= 8;
|
|
594
|
+
}
|
|
595
|
+
/* archive_le32dec(p + offset) gives disk
|
|
596
|
+
* on which file starts, but we don't handle
|
|
597
|
+
* multi-volume Zip files. */
|
|
598
|
+
break;
|
|
599
|
+
#ifdef DEBUG
|
|
600
|
+
case 0x0017:
|
|
601
|
+
{
|
|
602
|
+
/* Strong encryption field. */
|
|
603
|
+
if (archive_le16dec(p + offset) == 2) {
|
|
604
|
+
unsigned algId =
|
|
605
|
+
archive_le16dec(p + offset + 2);
|
|
606
|
+
unsigned bitLen =
|
|
607
|
+
archive_le16dec(p + offset + 4);
|
|
608
|
+
int flags =
|
|
609
|
+
archive_le16dec(p + offset + 6);
|
|
610
|
+
fprintf(stderr, "algId=0x%04x, bitLen=%u, "
|
|
611
|
+
"flgas=%d\n", algId, bitLen,flags);
|
|
612
|
+
}
|
|
613
|
+
break;
|
|
614
|
+
}
|
|
615
|
+
#endif
|
|
616
|
+
case 0x5455:
|
|
617
|
+
{
|
|
618
|
+
/* Extended time field "UT". */
|
|
619
|
+
int flags;
|
|
620
|
+
if (datasize == 0) {
|
|
621
|
+
archive_set_error(&a->archive,
|
|
622
|
+
ARCHIVE_ERRNO_FILE_FORMAT,
|
|
623
|
+
"Incomplete extended time field");
|
|
624
|
+
return ARCHIVE_FAILED;
|
|
625
|
+
}
|
|
626
|
+
flags = p[offset];
|
|
627
|
+
offset++;
|
|
628
|
+
datasize--;
|
|
629
|
+
/* Flag bits indicate which dates are present. */
|
|
630
|
+
if (flags & 0x01)
|
|
631
|
+
{
|
|
632
|
+
#ifdef DEBUG
|
|
633
|
+
fprintf(stderr, "mtime: %lld -> %d\n",
|
|
634
|
+
(long long)zip_entry->mtime,
|
|
635
|
+
archive_le32dec(p + offset));
|
|
636
|
+
#endif
|
|
637
|
+
if (datasize < 4)
|
|
638
|
+
break;
|
|
639
|
+
zip_entry->mtime = archive_le32dec(p + offset);
|
|
640
|
+
offset += 4;
|
|
641
|
+
datasize -= 4;
|
|
642
|
+
}
|
|
643
|
+
if (flags & 0x02)
|
|
644
|
+
{
|
|
645
|
+
if (datasize < 4)
|
|
646
|
+
break;
|
|
647
|
+
zip_entry->atime = archive_le32dec(p + offset);
|
|
648
|
+
offset += 4;
|
|
649
|
+
datasize -= 4;
|
|
650
|
+
}
|
|
651
|
+
if (flags & 0x04)
|
|
652
|
+
{
|
|
653
|
+
if (datasize < 4)
|
|
654
|
+
break;
|
|
655
|
+
zip_entry->ctime = archive_le32dec(p + offset);
|
|
656
|
+
offset += 4;
|
|
657
|
+
datasize -= 4;
|
|
658
|
+
}
|
|
659
|
+
break;
|
|
660
|
+
}
|
|
661
|
+
case 0x5855:
|
|
662
|
+
{
|
|
663
|
+
/* Info-ZIP Unix Extra Field (old version) "UX". */
|
|
664
|
+
if (datasize >= 8) {
|
|
665
|
+
zip_entry->atime = archive_le32dec(p + offset);
|
|
666
|
+
zip_entry->mtime =
|
|
667
|
+
archive_le32dec(p + offset + 4);
|
|
668
|
+
}
|
|
669
|
+
if (datasize >= 12) {
|
|
670
|
+
zip_entry->uid =
|
|
671
|
+
archive_le16dec(p + offset + 8);
|
|
672
|
+
zip_entry->gid =
|
|
673
|
+
archive_le16dec(p + offset + 10);
|
|
674
|
+
}
|
|
675
|
+
break;
|
|
676
|
+
}
|
|
677
|
+
case 0x6c78:
|
|
678
|
+
{
|
|
679
|
+
/* Experimental 'xl' field */
|
|
680
|
+
/*
|
|
681
|
+
* Introduced Dec 2013 to provide a way to
|
|
682
|
+
* include external file attributes (and other
|
|
683
|
+
* fields that ordinarily appear only in
|
|
684
|
+
* central directory) in local file header.
|
|
685
|
+
* This provides file type and permission
|
|
686
|
+
* information necessary to support full
|
|
687
|
+
* streaming extraction. Currently being
|
|
688
|
+
* discussed with other Zip developers
|
|
689
|
+
* ... subject to change.
|
|
690
|
+
*
|
|
691
|
+
* Format:
|
|
692
|
+
* The field starts with a bitmap that specifies
|
|
693
|
+
* which additional fields are included. The
|
|
694
|
+
* bitmap is variable length and can be extended in
|
|
695
|
+
* the future.
|
|
696
|
+
*
|
|
697
|
+
* n bytes - feature bitmap: first byte has low-order
|
|
698
|
+
* 7 bits. If high-order bit is set, a subsequent
|
|
699
|
+
* byte holds the next 7 bits, etc.
|
|
700
|
+
*
|
|
701
|
+
* if bitmap & 1, 2 byte "version made by"
|
|
702
|
+
* if bitmap & 2, 2 byte "internal file attributes"
|
|
703
|
+
* if bitmap & 4, 4 byte "external file attributes"
|
|
704
|
+
* if bitmap & 8, 2 byte comment length + n byte
|
|
705
|
+
* comment
|
|
706
|
+
*/
|
|
707
|
+
int bitmap, bitmap_last;
|
|
708
|
+
|
|
709
|
+
if (datasize < 1)
|
|
710
|
+
break;
|
|
711
|
+
bitmap_last = bitmap = 0xff & p[offset];
|
|
712
|
+
offset += 1;
|
|
713
|
+
datasize -= 1;
|
|
714
|
+
|
|
715
|
+
/* We only support first 7 bits of bitmap; skip rest. */
|
|
716
|
+
while ((bitmap_last & 0x80) != 0
|
|
717
|
+
&& datasize >= 1) {
|
|
718
|
+
bitmap_last = p[offset];
|
|
719
|
+
offset += 1;
|
|
720
|
+
datasize -= 1;
|
|
721
|
+
}
|
|
722
|
+
|
|
723
|
+
if (bitmap & 1) {
|
|
724
|
+
/* 2 byte "version made by" */
|
|
725
|
+
if (datasize < 2)
|
|
726
|
+
break;
|
|
727
|
+
zip_entry->system
|
|
728
|
+
= archive_le16dec(p + offset) >> 8;
|
|
729
|
+
offset += 2;
|
|
730
|
+
datasize -= 2;
|
|
731
|
+
}
|
|
732
|
+
if (bitmap & 2) {
|
|
733
|
+
/* 2 byte "internal file attributes" */
|
|
734
|
+
uint32_t internal_attributes;
|
|
735
|
+
if (datasize < 2)
|
|
736
|
+
break;
|
|
737
|
+
internal_attributes
|
|
738
|
+
= archive_le16dec(p + offset);
|
|
739
|
+
/* Not used by libarchive at present. */
|
|
740
|
+
(void)internal_attributes; /* UNUSED */
|
|
741
|
+
offset += 2;
|
|
742
|
+
datasize -= 2;
|
|
743
|
+
}
|
|
744
|
+
if (bitmap & 4) {
|
|
745
|
+
/* 4 byte "external file attributes" */
|
|
746
|
+
uint32_t external_attributes;
|
|
747
|
+
if (datasize < 4)
|
|
748
|
+
break;
|
|
749
|
+
external_attributes
|
|
750
|
+
= archive_le32dec(p + offset);
|
|
751
|
+
if (zip_entry->system == 3) {
|
|
752
|
+
zip_entry->mode
|
|
753
|
+
= external_attributes >> 16;
|
|
754
|
+
} else if (zip_entry->system == 0) {
|
|
755
|
+
// Interpret MSDOS directory bit
|
|
756
|
+
if (0x10 == (external_attributes &
|
|
757
|
+
0x10)) {
|
|
758
|
+
zip_entry->mode =
|
|
759
|
+
AE_IFDIR | 0775;
|
|
760
|
+
} else {
|
|
761
|
+
zip_entry->mode =
|
|
762
|
+
AE_IFREG | 0664;
|
|
763
|
+
}
|
|
764
|
+
if (0x01 == (external_attributes &
|
|
765
|
+
0x01)) {
|
|
766
|
+
/* Read-only bit;
|
|
767
|
+
* strip write permissions */
|
|
768
|
+
zip_entry->mode &= 0555;
|
|
769
|
+
}
|
|
770
|
+
} else {
|
|
771
|
+
zip_entry->mode = 0;
|
|
772
|
+
}
|
|
773
|
+
offset += 4;
|
|
774
|
+
datasize -= 4;
|
|
775
|
+
}
|
|
776
|
+
if (bitmap & 8) {
|
|
777
|
+
/* 2 byte comment length + comment */
|
|
778
|
+
uint32_t comment_length;
|
|
779
|
+
if (datasize < 2)
|
|
780
|
+
break;
|
|
781
|
+
comment_length
|
|
782
|
+
= archive_le16dec(p + offset);
|
|
783
|
+
offset += 2;
|
|
784
|
+
datasize -= 2;
|
|
785
|
+
|
|
786
|
+
if (datasize < comment_length)
|
|
787
|
+
break;
|
|
788
|
+
/* Comment is not supported by libarchive */
|
|
789
|
+
offset += comment_length;
|
|
790
|
+
datasize -= comment_length;
|
|
791
|
+
}
|
|
792
|
+
break;
|
|
793
|
+
}
|
|
794
|
+
case 0x7075:
|
|
795
|
+
{
|
|
796
|
+
/* Info-ZIP Unicode Path Extra Field. */
|
|
797
|
+
if (datasize < 5 || entry == NULL)
|
|
798
|
+
break;
|
|
799
|
+
offset += 5;
|
|
800
|
+
datasize -= 5;
|
|
801
|
+
|
|
802
|
+
/* The path name in this field is always encoded
|
|
803
|
+
* in UTF-8. */
|
|
804
|
+
if (zip->sconv_utf8 == NULL) {
|
|
805
|
+
zip->sconv_utf8 =
|
|
806
|
+
archive_string_conversion_from_charset(
|
|
807
|
+
&a->archive, "UTF-8", 1);
|
|
808
|
+
/* If the converter from UTF-8 is not
|
|
809
|
+
* available, then the path name from the main
|
|
810
|
+
* field will more likely be correct. */
|
|
811
|
+
if (zip->sconv_utf8 == NULL)
|
|
812
|
+
break;
|
|
813
|
+
}
|
|
814
|
+
|
|
815
|
+
/* Make sure the CRC32 of the filename matches. */
|
|
816
|
+
if (!zip->ignore_crc32) {
|
|
817
|
+
const char *cp = archive_entry_pathname(entry);
|
|
818
|
+
if (cp) {
|
|
819
|
+
unsigned long file_crc =
|
|
820
|
+
zip->crc32func(0, cp, strlen(cp));
|
|
821
|
+
unsigned long utf_crc =
|
|
822
|
+
archive_le32dec(p + offset - 4);
|
|
823
|
+
if (file_crc != utf_crc) {
|
|
824
|
+
#ifdef DEBUG
|
|
825
|
+
fprintf(stderr,
|
|
826
|
+
"CRC filename mismatch; "
|
|
827
|
+
"CDE is %lx, but UTF8 "
|
|
828
|
+
"is outdated with %lx\n",
|
|
829
|
+
file_crc, utf_crc);
|
|
830
|
+
#endif
|
|
831
|
+
break;
|
|
832
|
+
}
|
|
833
|
+
}
|
|
834
|
+
}
|
|
835
|
+
|
|
836
|
+
if (archive_entry_copy_pathname_l(entry,
|
|
837
|
+
p + offset, datasize, zip->sconv_utf8) != 0) {
|
|
838
|
+
/* Ignore the error, and fallback to the path
|
|
839
|
+
* name from the main field. */
|
|
840
|
+
#ifdef DEBUG
|
|
841
|
+
fprintf(stderr, "Failed to read the ZIP "
|
|
842
|
+
"0x7075 extra field path.\n");
|
|
843
|
+
#endif
|
|
844
|
+
}
|
|
845
|
+
break;
|
|
846
|
+
}
|
|
847
|
+
case 0x7855:
|
|
848
|
+
/* Info-ZIP Unix Extra Field (type 2) "Ux". */
|
|
849
|
+
#ifdef DEBUG
|
|
850
|
+
fprintf(stderr, "uid %d gid %d\n",
|
|
851
|
+
archive_le16dec(p + offset),
|
|
852
|
+
archive_le16dec(p + offset + 2));
|
|
853
|
+
#endif
|
|
854
|
+
if (datasize >= 2)
|
|
855
|
+
zip_entry->uid = archive_le16dec(p + offset);
|
|
856
|
+
if (datasize >= 4)
|
|
857
|
+
zip_entry->gid =
|
|
858
|
+
archive_le16dec(p + offset + 2);
|
|
859
|
+
break;
|
|
860
|
+
case 0x7875:
|
|
861
|
+
{
|
|
862
|
+
/* Info-Zip Unix Extra Field (type 3) "ux". */
|
|
863
|
+
int uidsize = 0, gidsize = 0;
|
|
864
|
+
|
|
865
|
+
/* TODO: support arbitrary uidsize/gidsize. */
|
|
866
|
+
if (datasize >= 1 && p[offset] == 1) {/* version=1 */
|
|
867
|
+
if (datasize >= 4) {
|
|
868
|
+
/* get a uid size. */
|
|
869
|
+
uidsize = 0xff & (int)p[offset+1];
|
|
870
|
+
if (uidsize == 2)
|
|
871
|
+
zip_entry->uid =
|
|
872
|
+
archive_le16dec(
|
|
873
|
+
p + offset + 2);
|
|
874
|
+
else if (uidsize == 4 && datasize >= 6)
|
|
875
|
+
zip_entry->uid =
|
|
876
|
+
archive_le32dec(
|
|
877
|
+
p + offset + 2);
|
|
878
|
+
}
|
|
879
|
+
if (datasize >= (2 + uidsize + 3)) {
|
|
880
|
+
/* get a gid size. */
|
|
881
|
+
gidsize = 0xff &
|
|
882
|
+
(int)p[offset+2+uidsize];
|
|
883
|
+
if (gidsize == 2)
|
|
884
|
+
zip_entry->gid =
|
|
885
|
+
archive_le16dec(
|
|
886
|
+
p+offset+2+uidsize+1);
|
|
887
|
+
else if (gidsize == 4 &&
|
|
888
|
+
datasize >= (2 + uidsize + 5))
|
|
889
|
+
zip_entry->gid =
|
|
890
|
+
archive_le32dec(
|
|
891
|
+
p+offset+2+uidsize+1);
|
|
892
|
+
}
|
|
893
|
+
}
|
|
894
|
+
break;
|
|
895
|
+
}
|
|
896
|
+
case 0x9901:
|
|
897
|
+
/* WinZip AES extra data field. */
|
|
898
|
+
if (datasize < 6) {
|
|
899
|
+
archive_set_error(&a->archive,
|
|
900
|
+
ARCHIVE_ERRNO_FILE_FORMAT,
|
|
901
|
+
"Incomplete AES field");
|
|
902
|
+
return ARCHIVE_FAILED;
|
|
903
|
+
}
|
|
904
|
+
if (p[offset + 2] == 'A' && p[offset + 3] == 'E') {
|
|
905
|
+
/* Vendor version. */
|
|
906
|
+
zip_entry->aes_extra.vendor =
|
|
907
|
+
archive_le16dec(p + offset);
|
|
908
|
+
/* AES encryption strength. */
|
|
909
|
+
zip_entry->aes_extra.strength = p[offset + 4];
|
|
910
|
+
/* Actual compression method. */
|
|
911
|
+
zip_entry->aes_extra.compression =
|
|
912
|
+
p[offset + 5];
|
|
913
|
+
}
|
|
914
|
+
break;
|
|
915
|
+
default:
|
|
916
|
+
break;
|
|
917
|
+
}
|
|
918
|
+
offset += datasize;
|
|
919
|
+
}
|
|
920
|
+
return ARCHIVE_OK;
|
|
921
|
+
}
|
|
922
|
+
|
|
923
|
+
/*
|
|
924
|
+
* Assumes file pointer is at beginning of local file header.
|
|
925
|
+
*/
|
|
926
|
+
static int
|
|
927
|
+
zip_read_local_file_header(struct archive_read *a, struct archive_entry *entry,
|
|
928
|
+
struct zip *zip)
|
|
929
|
+
{
|
|
930
|
+
const char *p;
|
|
931
|
+
const void *h;
|
|
932
|
+
const wchar_t *wp;
|
|
933
|
+
const char *cp;
|
|
934
|
+
size_t len, filename_length, extra_length;
|
|
935
|
+
struct archive_string_conv *sconv;
|
|
936
|
+
struct zip_entry *zip_entry = zip->entry;
|
|
937
|
+
struct zip_entry zip_entry_central_dir;
|
|
938
|
+
int ret = ARCHIVE_OK;
|
|
939
|
+
char version;
|
|
940
|
+
|
|
941
|
+
/* Save a copy of the original for consistency checks. */
|
|
942
|
+
zip_entry_central_dir = *zip_entry;
|
|
943
|
+
|
|
944
|
+
zip->decompress_init = 0;
|
|
945
|
+
zip->end_of_entry = 0;
|
|
946
|
+
zip->entry_uncompressed_bytes_read = 0;
|
|
947
|
+
zip->entry_compressed_bytes_read = 0;
|
|
948
|
+
zip->entry_crc32 = zip->crc32func(0, NULL, 0);
|
|
949
|
+
|
|
950
|
+
/* Setup default conversion. */
|
|
951
|
+
if (zip->sconv == NULL && !zip->init_default_conversion) {
|
|
952
|
+
zip->sconv_default =
|
|
953
|
+
archive_string_default_conversion_for_read(&(a->archive));
|
|
954
|
+
zip->init_default_conversion = 1;
|
|
955
|
+
}
|
|
956
|
+
|
|
957
|
+
if ((p = __archive_read_ahead(a, 30, NULL)) == NULL) {
|
|
958
|
+
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
|
959
|
+
"Truncated ZIP file header");
|
|
960
|
+
return (ARCHIVE_FATAL);
|
|
961
|
+
}
|
|
962
|
+
|
|
963
|
+
if (memcmp(p, "PK\003\004", 4) != 0) {
|
|
964
|
+
archive_set_error(&a->archive, -1, "Damaged Zip archive");
|
|
965
|
+
return ARCHIVE_FATAL;
|
|
966
|
+
}
|
|
967
|
+
version = p[4];
|
|
968
|
+
zip_entry->system = p[5];
|
|
969
|
+
zip_entry->zip_flags = archive_le16dec(p + 6);
|
|
970
|
+
if (zip_entry->zip_flags & (ZIP_ENCRYPTED | ZIP_STRONG_ENCRYPTED)) {
|
|
971
|
+
zip->has_encrypted_entries = 1;
|
|
972
|
+
archive_entry_set_is_data_encrypted(entry, 1);
|
|
973
|
+
if (zip_entry->zip_flags & ZIP_CENTRAL_DIRECTORY_ENCRYPTED &&
|
|
974
|
+
zip_entry->zip_flags & ZIP_ENCRYPTED &&
|
|
975
|
+
zip_entry->zip_flags & ZIP_STRONG_ENCRYPTED) {
|
|
976
|
+
archive_entry_set_is_metadata_encrypted(entry, 1);
|
|
977
|
+
return ARCHIVE_FATAL;
|
|
978
|
+
}
|
|
979
|
+
}
|
|
980
|
+
zip->init_decryption = (zip_entry->zip_flags & ZIP_ENCRYPTED);
|
|
981
|
+
zip_entry->compression = (char)archive_le16dec(p + 8);
|
|
982
|
+
zip_entry->mtime = zip_time(p + 10);
|
|
983
|
+
zip_entry->crc32 = archive_le32dec(p + 14);
|
|
984
|
+
if (zip_entry->zip_flags & ZIP_LENGTH_AT_END)
|
|
985
|
+
zip_entry->decdat = p[11];
|
|
986
|
+
else
|
|
987
|
+
zip_entry->decdat = p[17];
|
|
988
|
+
zip_entry->compressed_size = archive_le32dec(p + 18);
|
|
989
|
+
zip_entry->uncompressed_size = archive_le32dec(p + 22);
|
|
990
|
+
filename_length = archive_le16dec(p + 26);
|
|
991
|
+
extra_length = archive_le16dec(p + 28);
|
|
992
|
+
|
|
993
|
+
__archive_read_consume(a, 30);
|
|
994
|
+
|
|
995
|
+
/* Read the filename. */
|
|
996
|
+
if ((h = __archive_read_ahead(a, filename_length, NULL)) == NULL) {
|
|
997
|
+
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
|
998
|
+
"Truncated ZIP file header");
|
|
999
|
+
return (ARCHIVE_FATAL);
|
|
1000
|
+
}
|
|
1001
|
+
if (zip_entry->zip_flags & ZIP_UTF8_NAME) {
|
|
1002
|
+
/* The filename is stored to be UTF-8. */
|
|
1003
|
+
if (zip->sconv_utf8 == NULL) {
|
|
1004
|
+
zip->sconv_utf8 =
|
|
1005
|
+
archive_string_conversion_from_charset(
|
|
1006
|
+
&a->archive, "UTF-8", 1);
|
|
1007
|
+
if (zip->sconv_utf8 == NULL)
|
|
1008
|
+
return (ARCHIVE_FATAL);
|
|
1009
|
+
}
|
|
1010
|
+
sconv = zip->sconv_utf8;
|
|
1011
|
+
} else if (zip->sconv != NULL)
|
|
1012
|
+
sconv = zip->sconv;
|
|
1013
|
+
else
|
|
1014
|
+
sconv = zip->sconv_default;
|
|
1015
|
+
|
|
1016
|
+
if (archive_entry_copy_pathname_l(entry,
|
|
1017
|
+
h, filename_length, sconv) != 0) {
|
|
1018
|
+
if (errno == ENOMEM) {
|
|
1019
|
+
archive_set_error(&a->archive, ENOMEM,
|
|
1020
|
+
"Can't allocate memory for Pathname");
|
|
1021
|
+
return (ARCHIVE_FATAL);
|
|
1022
|
+
}
|
|
1023
|
+
archive_set_error(&a->archive,
|
|
1024
|
+
ARCHIVE_ERRNO_FILE_FORMAT,
|
|
1025
|
+
"Pathname cannot be converted "
|
|
1026
|
+
"from %s to current locale.",
|
|
1027
|
+
archive_string_conversion_charset_name(sconv));
|
|
1028
|
+
ret = ARCHIVE_WARN;
|
|
1029
|
+
}
|
|
1030
|
+
__archive_read_consume(a, filename_length);
|
|
1031
|
+
|
|
1032
|
+
/* Read the extra data. */
|
|
1033
|
+
if ((h = __archive_read_ahead(a, extra_length, NULL)) == NULL) {
|
|
1034
|
+
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
|
1035
|
+
"Truncated ZIP file header");
|
|
1036
|
+
return (ARCHIVE_FATAL);
|
|
1037
|
+
}
|
|
1038
|
+
|
|
1039
|
+
if (ARCHIVE_OK != process_extra(a, entry, h, extra_length,
|
|
1040
|
+
zip_entry)) {
|
|
1041
|
+
return ARCHIVE_FATAL;
|
|
1042
|
+
}
|
|
1043
|
+
__archive_read_consume(a, extra_length);
|
|
1044
|
+
|
|
1045
|
+
/* Work around a bug in Info-Zip: When reading from a pipe, it
|
|
1046
|
+
* stats the pipe instead of synthesizing a file entry. */
|
|
1047
|
+
if ((zip_entry->mode & AE_IFMT) == AE_IFIFO) {
|
|
1048
|
+
zip_entry->mode &= ~ AE_IFMT;
|
|
1049
|
+
zip_entry->mode |= AE_IFREG;
|
|
1050
|
+
}
|
|
1051
|
+
|
|
1052
|
+
/* If the mode is totally empty, set some sane default. */
|
|
1053
|
+
if (zip_entry->mode == 0) {
|
|
1054
|
+
zip_entry->mode |= 0664;
|
|
1055
|
+
}
|
|
1056
|
+
|
|
1057
|
+
/* Windows archivers sometimes use backslash as the directory
|
|
1058
|
+
* separator. Normalize to slash. */
|
|
1059
|
+
if (zip_entry->system == 0 &&
|
|
1060
|
+
(wp = archive_entry_pathname_w(entry)) != NULL) {
|
|
1061
|
+
if (wcschr(wp, L'/') == NULL && wcschr(wp, L'\\') != NULL) {
|
|
1062
|
+
size_t i;
|
|
1063
|
+
struct archive_wstring s;
|
|
1064
|
+
archive_string_init(&s);
|
|
1065
|
+
archive_wstrcpy(&s, wp);
|
|
1066
|
+
for (i = 0; i < archive_strlen(&s); i++) {
|
|
1067
|
+
if (s.s[i] == '\\')
|
|
1068
|
+
s.s[i] = '/';
|
|
1069
|
+
}
|
|
1070
|
+
archive_entry_copy_pathname_w(entry, s.s);
|
|
1071
|
+
archive_wstring_free(&s);
|
|
1072
|
+
}
|
|
1073
|
+
}
|
|
1074
|
+
|
|
1075
|
+
/* Make sure that entries with a trailing '/' are marked as directories
|
|
1076
|
+
* even if the External File Attributes contains bogus values. If this
|
|
1077
|
+
* is not a directory and there is no type, assume a regular file. */
|
|
1078
|
+
if ((zip_entry->mode & AE_IFMT) != AE_IFDIR) {
|
|
1079
|
+
int has_slash;
|
|
1080
|
+
|
|
1081
|
+
wp = archive_entry_pathname_w(entry);
|
|
1082
|
+
if (wp != NULL) {
|
|
1083
|
+
len = wcslen(wp);
|
|
1084
|
+
has_slash = len > 0 && wp[len - 1] == L'/';
|
|
1085
|
+
} else {
|
|
1086
|
+
cp = archive_entry_pathname(entry);
|
|
1087
|
+
len = (cp != NULL)?strlen(cp):0;
|
|
1088
|
+
has_slash = len > 0 && cp[len - 1] == '/';
|
|
1089
|
+
}
|
|
1090
|
+
/* Correct file type as needed. */
|
|
1091
|
+
if (has_slash) {
|
|
1092
|
+
zip_entry->mode &= ~AE_IFMT;
|
|
1093
|
+
zip_entry->mode |= AE_IFDIR;
|
|
1094
|
+
zip_entry->mode |= 0111;
|
|
1095
|
+
} else if ((zip_entry->mode & AE_IFMT) == 0) {
|
|
1096
|
+
zip_entry->mode |= AE_IFREG;
|
|
1097
|
+
}
|
|
1098
|
+
}
|
|
1099
|
+
|
|
1100
|
+
/* Make sure directories end in '/' */
|
|
1101
|
+
if ((zip_entry->mode & AE_IFMT) == AE_IFDIR) {
|
|
1102
|
+
wp = archive_entry_pathname_w(entry);
|
|
1103
|
+
if (wp != NULL) {
|
|
1104
|
+
len = wcslen(wp);
|
|
1105
|
+
if (len > 0 && wp[len - 1] != L'/') {
|
|
1106
|
+
struct archive_wstring s;
|
|
1107
|
+
archive_string_init(&s);
|
|
1108
|
+
archive_wstrcat(&s, wp);
|
|
1109
|
+
archive_wstrappend_wchar(&s, L'/');
|
|
1110
|
+
archive_entry_copy_pathname_w(entry, s.s);
|
|
1111
|
+
archive_wstring_free(&s);
|
|
1112
|
+
}
|
|
1113
|
+
} else {
|
|
1114
|
+
cp = archive_entry_pathname(entry);
|
|
1115
|
+
len = (cp != NULL)?strlen(cp):0;
|
|
1116
|
+
if (len > 0 && cp[len - 1] != '/') {
|
|
1117
|
+
struct archive_string s;
|
|
1118
|
+
archive_string_init(&s);
|
|
1119
|
+
archive_strcat(&s, cp);
|
|
1120
|
+
archive_strappend_char(&s, '/');
|
|
1121
|
+
archive_entry_set_pathname(entry, s.s);
|
|
1122
|
+
archive_string_free(&s);
|
|
1123
|
+
}
|
|
1124
|
+
}
|
|
1125
|
+
}
|
|
1126
|
+
|
|
1127
|
+
if (zip_entry->flags & LA_FROM_CENTRAL_DIRECTORY) {
|
|
1128
|
+
/* If this came from the central dir, its size info
|
|
1129
|
+
* is definitive, so ignore the length-at-end flag. */
|
|
1130
|
+
zip_entry->zip_flags &= ~ZIP_LENGTH_AT_END;
|
|
1131
|
+
/* If local header is missing a value, use the one from
|
|
1132
|
+
the central directory. If both have it, warn about
|
|
1133
|
+
mismatches. */
|
|
1134
|
+
if (zip_entry->crc32 == 0) {
|
|
1135
|
+
zip_entry->crc32 = zip_entry_central_dir.crc32;
|
|
1136
|
+
} else if (!zip->ignore_crc32
|
|
1137
|
+
&& zip_entry->crc32 != zip_entry_central_dir.crc32) {
|
|
1138
|
+
archive_set_error(&a->archive,
|
|
1139
|
+
ARCHIVE_ERRNO_FILE_FORMAT,
|
|
1140
|
+
"Inconsistent CRC32 values");
|
|
1141
|
+
ret = ARCHIVE_WARN;
|
|
1142
|
+
}
|
|
1143
|
+
if (zip_entry->compressed_size == 0) {
|
|
1144
|
+
zip_entry->compressed_size
|
|
1145
|
+
= zip_entry_central_dir.compressed_size;
|
|
1146
|
+
} else if (zip_entry->compressed_size
|
|
1147
|
+
!= zip_entry_central_dir.compressed_size) {
|
|
1148
|
+
archive_set_error(&a->archive,
|
|
1149
|
+
ARCHIVE_ERRNO_FILE_FORMAT,
|
|
1150
|
+
"Inconsistent compressed size: "
|
|
1151
|
+
"%jd in central directory, %jd in local header",
|
|
1152
|
+
(intmax_t)zip_entry_central_dir.compressed_size,
|
|
1153
|
+
(intmax_t)zip_entry->compressed_size);
|
|
1154
|
+
ret = ARCHIVE_WARN;
|
|
1155
|
+
}
|
|
1156
|
+
if (zip_entry->uncompressed_size == 0 ||
|
|
1157
|
+
zip_entry->uncompressed_size == 0xffffffff) {
|
|
1158
|
+
zip_entry->uncompressed_size
|
|
1159
|
+
= zip_entry_central_dir.uncompressed_size;
|
|
1160
|
+
} else if (zip_entry->uncompressed_size
|
|
1161
|
+
!= zip_entry_central_dir.uncompressed_size) {
|
|
1162
|
+
archive_set_error(&a->archive,
|
|
1163
|
+
ARCHIVE_ERRNO_FILE_FORMAT,
|
|
1164
|
+
"Inconsistent uncompressed size: "
|
|
1165
|
+
"%jd in central directory, %jd in local header",
|
|
1166
|
+
(intmax_t)zip_entry_central_dir.uncompressed_size,
|
|
1167
|
+
(intmax_t)zip_entry->uncompressed_size);
|
|
1168
|
+
ret = ARCHIVE_WARN;
|
|
1169
|
+
}
|
|
1170
|
+
}
|
|
1171
|
+
|
|
1172
|
+
/* Populate some additional entry fields: */
|
|
1173
|
+
archive_entry_set_mode(entry, zip_entry->mode);
|
|
1174
|
+
archive_entry_set_uid(entry, zip_entry->uid);
|
|
1175
|
+
archive_entry_set_gid(entry, zip_entry->gid);
|
|
1176
|
+
archive_entry_set_mtime(entry, zip_entry->mtime, 0);
|
|
1177
|
+
archive_entry_set_ctime(entry, zip_entry->ctime, 0);
|
|
1178
|
+
archive_entry_set_atime(entry, zip_entry->atime, 0);
|
|
1179
|
+
|
|
1180
|
+
if ((zip->entry->mode & AE_IFMT) == AE_IFLNK) {
|
|
1181
|
+
size_t linkname_length;
|
|
1182
|
+
|
|
1183
|
+
if (zip_entry->compressed_size > 64 * 1024) {
|
|
1184
|
+
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
|
1185
|
+
"Zip file with oversized link entry");
|
|
1186
|
+
return ARCHIVE_FATAL;
|
|
1187
|
+
}
|
|
1188
|
+
|
|
1189
|
+
linkname_length = (size_t)zip_entry->compressed_size;
|
|
1190
|
+
|
|
1191
|
+
archive_entry_set_size(entry, 0);
|
|
1192
|
+
|
|
1193
|
+
// take into account link compression if any
|
|
1194
|
+
size_t linkname_full_length = linkname_length;
|
|
1195
|
+
if (zip->entry->compression != 0)
|
|
1196
|
+
{
|
|
1197
|
+
// symlink target string appeared to be compressed
|
|
1198
|
+
int status = ARCHIVE_FATAL;
|
|
1199
|
+
const void *uncompressed_buffer = NULL;
|
|
1200
|
+
|
|
1201
|
+
switch (zip->entry->compression)
|
|
1202
|
+
{
|
|
1203
|
+
#if HAVE_ZLIB_H
|
|
1204
|
+
case 8: /* Deflate compression. */
|
|
1205
|
+
zip->entry_bytes_remaining = zip_entry->compressed_size;
|
|
1206
|
+
status = zip_read_data_deflate(a, &uncompressed_buffer,
|
|
1207
|
+
&linkname_full_length, NULL);
|
|
1208
|
+
break;
|
|
1209
|
+
#endif
|
|
1210
|
+
#if HAVE_LZMA_H && HAVE_LIBLZMA
|
|
1211
|
+
case 14: /* ZIPx LZMA compression. */
|
|
1212
|
+
/*(see zip file format specification, section 4.4.5)*/
|
|
1213
|
+
zip->entry_bytes_remaining = zip_entry->compressed_size;
|
|
1214
|
+
status = zip_read_data_zipx_lzma_alone(a, &uncompressed_buffer,
|
|
1215
|
+
&linkname_full_length, NULL);
|
|
1216
|
+
break;
|
|
1217
|
+
#endif
|
|
1218
|
+
default: /* Unsupported compression. */
|
|
1219
|
+
break;
|
|
1220
|
+
}
|
|
1221
|
+
if (status == ARCHIVE_OK)
|
|
1222
|
+
{
|
|
1223
|
+
p = uncompressed_buffer;
|
|
1224
|
+
}
|
|
1225
|
+
else
|
|
1226
|
+
{
|
|
1227
|
+
archive_set_error(&a->archive,
|
|
1228
|
+
ARCHIVE_ERRNO_FILE_FORMAT,
|
|
1229
|
+
"Unsupported ZIP compression method "
|
|
1230
|
+
"during decompression of link entry (%d: %s)",
|
|
1231
|
+
zip->entry->compression,
|
|
1232
|
+
compression_name(zip->entry->compression));
|
|
1233
|
+
return ARCHIVE_FAILED;
|
|
1234
|
+
}
|
|
1235
|
+
}
|
|
1236
|
+
else
|
|
1237
|
+
{
|
|
1238
|
+
p = __archive_read_ahead(a, linkname_length, NULL);
|
|
1239
|
+
}
|
|
1240
|
+
|
|
1241
|
+
if (p == NULL) {
|
|
1242
|
+
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
|
1243
|
+
"Truncated Zip file");
|
|
1244
|
+
return ARCHIVE_FATAL;
|
|
1245
|
+
}
|
|
1246
|
+
|
|
1247
|
+
sconv = zip->sconv;
|
|
1248
|
+
if (sconv == NULL && (zip->entry->zip_flags & ZIP_UTF8_NAME))
|
|
1249
|
+
sconv = zip->sconv_utf8;
|
|
1250
|
+
if (sconv == NULL)
|
|
1251
|
+
sconv = zip->sconv_default;
|
|
1252
|
+
if (archive_entry_copy_symlink_l(entry, p, linkname_full_length,
|
|
1253
|
+
sconv) != 0) {
|
|
1254
|
+
if (errno != ENOMEM && sconv == zip->sconv_utf8 &&
|
|
1255
|
+
(zip->entry->zip_flags & ZIP_UTF8_NAME))
|
|
1256
|
+
archive_entry_copy_symlink_l(entry, p,
|
|
1257
|
+
linkname_full_length, NULL);
|
|
1258
|
+
if (errno == ENOMEM) {
|
|
1259
|
+
archive_set_error(&a->archive, ENOMEM,
|
|
1260
|
+
"Can't allocate memory for Symlink");
|
|
1261
|
+
return (ARCHIVE_FATAL);
|
|
1262
|
+
}
|
|
1263
|
+
/*
|
|
1264
|
+
* Since there is no character-set regulation for
|
|
1265
|
+
* symlink name, do not report the conversion error
|
|
1266
|
+
* in an automatic conversion.
|
|
1267
|
+
*/
|
|
1268
|
+
if (sconv != zip->sconv_utf8 ||
|
|
1269
|
+
(zip->entry->zip_flags & ZIP_UTF8_NAME) == 0) {
|
|
1270
|
+
archive_set_error(&a->archive,
|
|
1271
|
+
ARCHIVE_ERRNO_FILE_FORMAT,
|
|
1272
|
+
"Symlink cannot be converted "
|
|
1273
|
+
"from %s to current locale.",
|
|
1274
|
+
archive_string_conversion_charset_name(
|
|
1275
|
+
sconv));
|
|
1276
|
+
ret = ARCHIVE_WARN;
|
|
1277
|
+
}
|
|
1278
|
+
}
|
|
1279
|
+
zip_entry->uncompressed_size = zip_entry->compressed_size = 0;
|
|
1280
|
+
|
|
1281
|
+
if (__archive_read_consume(a, linkname_length) < 0) {
|
|
1282
|
+
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
|
1283
|
+
"Read error skipping symlink target name");
|
|
1284
|
+
return ARCHIVE_FATAL;
|
|
1285
|
+
}
|
|
1286
|
+
} else if (0 == (zip_entry->zip_flags & ZIP_LENGTH_AT_END)
|
|
1287
|
+
|| zip_entry->uncompressed_size > 0) {
|
|
1288
|
+
/* Set the size only if it's meaningful. */
|
|
1289
|
+
archive_entry_set_size(entry, zip_entry->uncompressed_size);
|
|
1290
|
+
}
|
|
1291
|
+
zip->entry_bytes_remaining = zip_entry->compressed_size;
|
|
1292
|
+
|
|
1293
|
+
/* If there's no body, force read_data() to return EOF immediately. */
|
|
1294
|
+
if (0 == (zip_entry->zip_flags & ZIP_LENGTH_AT_END)
|
|
1295
|
+
&& zip->entry_bytes_remaining < 1)
|
|
1296
|
+
zip->end_of_entry = 1;
|
|
1297
|
+
|
|
1298
|
+
/* Set up a more descriptive format name. */
|
|
1299
|
+
archive_string_empty(&zip->format_name);
|
|
1300
|
+
archive_string_sprintf(&zip->format_name, "ZIP %d.%d (%s)",
|
|
1301
|
+
version / 10, version % 10,
|
|
1302
|
+
compression_name(zip->entry->compression));
|
|
1303
|
+
a->archive.archive_format_name = zip->format_name.s;
|
|
1304
|
+
|
|
1305
|
+
return (ret);
|
|
1306
|
+
}
|
|
1307
|
+
|
|
1308
|
+
static int
|
|
1309
|
+
check_authentication_code(struct archive_read *a, const void *_p)
|
|
1310
|
+
{
|
|
1311
|
+
struct zip *zip = (struct zip *)(a->format->data);
|
|
1312
|
+
|
|
1313
|
+
/* Check authentication code. */
|
|
1314
|
+
if (zip->hctx_valid) {
|
|
1315
|
+
const void *p;
|
|
1316
|
+
uint8_t hmac[20];
|
|
1317
|
+
size_t hmac_len = 20;
|
|
1318
|
+
int cmp;
|
|
1319
|
+
|
|
1320
|
+
archive_hmac_sha1_final(&zip->hctx, hmac, &hmac_len);
|
|
1321
|
+
if (_p == NULL) {
|
|
1322
|
+
/* Read authentication code. */
|
|
1323
|
+
p = __archive_read_ahead(a, AUTH_CODE_SIZE, NULL);
|
|
1324
|
+
if (p == NULL) {
|
|
1325
|
+
archive_set_error(&a->archive,
|
|
1326
|
+
ARCHIVE_ERRNO_FILE_FORMAT,
|
|
1327
|
+
"Truncated ZIP file data");
|
|
1328
|
+
return (ARCHIVE_FATAL);
|
|
1329
|
+
}
|
|
1330
|
+
} else {
|
|
1331
|
+
p = _p;
|
|
1332
|
+
}
|
|
1333
|
+
cmp = memcmp(hmac, p, AUTH_CODE_SIZE);
|
|
1334
|
+
__archive_read_consume(a, AUTH_CODE_SIZE);
|
|
1335
|
+
if (cmp != 0) {
|
|
1336
|
+
archive_set_error(&a->archive,
|
|
1337
|
+
ARCHIVE_ERRNO_MISC,
|
|
1338
|
+
"ZIP bad Authentication code");
|
|
1339
|
+
return (ARCHIVE_WARN);
|
|
1340
|
+
}
|
|
1341
|
+
}
|
|
1342
|
+
return (ARCHIVE_OK);
|
|
1343
|
+
}
|
|
1344
|
+
|
|
1345
|
+
/*
|
|
1346
|
+
* Read "uncompressed" data. There are three cases:
|
|
1347
|
+
* 1) We know the size of the data. This is always true for the
|
|
1348
|
+
* seeking reader (we've examined the Central Directory already).
|
|
1349
|
+
* 2) ZIP_LENGTH_AT_END was set, but only the CRC was deferred.
|
|
1350
|
+
* Info-ZIP seems to do this; we know the size but have to grab
|
|
1351
|
+
* the CRC from the data descriptor afterwards.
|
|
1352
|
+
* 3) We're streaming and ZIP_LENGTH_AT_END was specified and
|
|
1353
|
+
* we have no size information. In this case, we can do pretty
|
|
1354
|
+
* well by watching for the data descriptor record. The data
|
|
1355
|
+
* descriptor is 16 bytes and includes a computed CRC that should
|
|
1356
|
+
* provide a strong check.
|
|
1357
|
+
*
|
|
1358
|
+
* TODO: Technically, the PK\007\010 signature is optional.
|
|
1359
|
+
* In the original spec, the data descriptor contained CRC
|
|
1360
|
+
* and size fields but had no leading signature. In practice,
|
|
1361
|
+
* newer writers seem to provide the signature pretty consistently.
|
|
1362
|
+
*
|
|
1363
|
+
* For uncompressed data, the PK\007\010 marker seems essential
|
|
1364
|
+
* to be sure we've actually seen the end of the entry.
|
|
1365
|
+
*
|
|
1366
|
+
* Returns ARCHIVE_OK if successful, ARCHIVE_FATAL otherwise, sets
|
|
1367
|
+
* zip->end_of_entry if it consumes all of the data.
|
|
1368
|
+
*/
|
|
1369
|
+
static int
|
|
1370
|
+
zip_read_data_none(struct archive_read *a, const void **_buff,
|
|
1371
|
+
size_t *size, int64_t *offset)
|
|
1372
|
+
{
|
|
1373
|
+
struct zip *zip;
|
|
1374
|
+
const char *buff;
|
|
1375
|
+
ssize_t bytes_avail;
|
|
1376
|
+
int r;
|
|
1377
|
+
|
|
1378
|
+
(void)offset; /* UNUSED */
|
|
1379
|
+
|
|
1380
|
+
zip = (struct zip *)(a->format->data);
|
|
1381
|
+
|
|
1382
|
+
if (zip->entry->zip_flags & ZIP_LENGTH_AT_END) {
|
|
1383
|
+
const char *p;
|
|
1384
|
+
ssize_t grabbing_bytes = 24;
|
|
1385
|
+
|
|
1386
|
+
if (zip->hctx_valid)
|
|
1387
|
+
grabbing_bytes += AUTH_CODE_SIZE;
|
|
1388
|
+
/* Grab at least 24 bytes. */
|
|
1389
|
+
buff = __archive_read_ahead(a, grabbing_bytes, &bytes_avail);
|
|
1390
|
+
if (bytes_avail < grabbing_bytes) {
|
|
1391
|
+
/* Zip archives have end-of-archive markers
|
|
1392
|
+
that are longer than this, so a failure to get at
|
|
1393
|
+
least 24 bytes really does indicate a truncated
|
|
1394
|
+
file. */
|
|
1395
|
+
archive_set_error(&a->archive,
|
|
1396
|
+
ARCHIVE_ERRNO_FILE_FORMAT,
|
|
1397
|
+
"Truncated ZIP file data");
|
|
1398
|
+
return (ARCHIVE_FATAL);
|
|
1399
|
+
}
|
|
1400
|
+
/* Check for a complete PK\007\010 signature, followed
|
|
1401
|
+
* by the correct 4-byte CRC. */
|
|
1402
|
+
p = buff;
|
|
1403
|
+
if (zip->hctx_valid)
|
|
1404
|
+
p += AUTH_CODE_SIZE;
|
|
1405
|
+
if (p[0] == 'P' && p[1] == 'K'
|
|
1406
|
+
&& p[2] == '\007' && p[3] == '\010'
|
|
1407
|
+
&& (archive_le32dec(p + 4) == zip->entry_crc32
|
|
1408
|
+
|| zip->ignore_crc32
|
|
1409
|
+
|| (zip->hctx_valid
|
|
1410
|
+
&& zip->entry->aes_extra.vendor == AES_VENDOR_AE_2))) {
|
|
1411
|
+
if (zip->entry->flags & LA_USED_ZIP64) {
|
|
1412
|
+
uint64_t compressed, uncompressed;
|
|
1413
|
+
zip->entry->crc32 = archive_le32dec(p + 4);
|
|
1414
|
+
compressed = archive_le64dec(p + 8);
|
|
1415
|
+
uncompressed = archive_le64dec(p + 16);
|
|
1416
|
+
if (compressed > INT64_MAX || uncompressed >
|
|
1417
|
+
INT64_MAX) {
|
|
1418
|
+
archive_set_error(&a->archive,
|
|
1419
|
+
ARCHIVE_ERRNO_FILE_FORMAT,
|
|
1420
|
+
"Overflow of 64-bit file sizes");
|
|
1421
|
+
return ARCHIVE_FAILED;
|
|
1422
|
+
}
|
|
1423
|
+
zip->entry->compressed_size = compressed;
|
|
1424
|
+
zip->entry->uncompressed_size = uncompressed;
|
|
1425
|
+
zip->unconsumed = 24;
|
|
1426
|
+
} else {
|
|
1427
|
+
zip->entry->crc32 = archive_le32dec(p + 4);
|
|
1428
|
+
zip->entry->compressed_size =
|
|
1429
|
+
archive_le32dec(p + 8);
|
|
1430
|
+
zip->entry->uncompressed_size =
|
|
1431
|
+
archive_le32dec(p + 12);
|
|
1432
|
+
zip->unconsumed = 16;
|
|
1433
|
+
}
|
|
1434
|
+
if (zip->hctx_valid) {
|
|
1435
|
+
r = check_authentication_code(a, buff);
|
|
1436
|
+
if (r != ARCHIVE_OK)
|
|
1437
|
+
return (r);
|
|
1438
|
+
}
|
|
1439
|
+
zip->end_of_entry = 1;
|
|
1440
|
+
return (ARCHIVE_OK);
|
|
1441
|
+
}
|
|
1442
|
+
/* If not at EOF, ensure we consume at least one byte. */
|
|
1443
|
+
++p;
|
|
1444
|
+
|
|
1445
|
+
/* Scan forward until we see where a PK\007\010 signature
|
|
1446
|
+
* might be. */
|
|
1447
|
+
/* Return bytes up until that point. On the next call,
|
|
1448
|
+
* the code above will verify the data descriptor. */
|
|
1449
|
+
while (p < buff + bytes_avail - 4) {
|
|
1450
|
+
if (p[3] == 'P') { p += 3; }
|
|
1451
|
+
else if (p[3] == 'K') { p += 2; }
|
|
1452
|
+
else if (p[3] == '\007') { p += 1; }
|
|
1453
|
+
else if (p[3] == '\010' && p[2] == '\007'
|
|
1454
|
+
&& p[1] == 'K' && p[0] == 'P') {
|
|
1455
|
+
if (zip->hctx_valid)
|
|
1456
|
+
p -= AUTH_CODE_SIZE;
|
|
1457
|
+
break;
|
|
1458
|
+
} else { p += 4; }
|
|
1459
|
+
}
|
|
1460
|
+
bytes_avail = p - buff;
|
|
1461
|
+
} else {
|
|
1462
|
+
if (zip->entry_bytes_remaining == 0) {
|
|
1463
|
+
zip->end_of_entry = 1;
|
|
1464
|
+
if (zip->hctx_valid) {
|
|
1465
|
+
r = check_authentication_code(a, NULL);
|
|
1466
|
+
if (r != ARCHIVE_OK)
|
|
1467
|
+
return (r);
|
|
1468
|
+
}
|
|
1469
|
+
return (ARCHIVE_OK);
|
|
1470
|
+
}
|
|
1471
|
+
/* Grab a bunch of bytes. */
|
|
1472
|
+
buff = __archive_read_ahead(a, 1, &bytes_avail);
|
|
1473
|
+
if (bytes_avail <= 0) {
|
|
1474
|
+
archive_set_error(&a->archive,
|
|
1475
|
+
ARCHIVE_ERRNO_FILE_FORMAT,
|
|
1476
|
+
"Truncated ZIP file data");
|
|
1477
|
+
return (ARCHIVE_FATAL);
|
|
1478
|
+
}
|
|
1479
|
+
if (bytes_avail > zip->entry_bytes_remaining)
|
|
1480
|
+
bytes_avail = (ssize_t)zip->entry_bytes_remaining;
|
|
1481
|
+
}
|
|
1482
|
+
if (zip->tctx_valid || zip->cctx_valid) {
|
|
1483
|
+
size_t dec_size = bytes_avail;
|
|
1484
|
+
|
|
1485
|
+
if (dec_size > zip->decrypted_buffer_size)
|
|
1486
|
+
dec_size = zip->decrypted_buffer_size;
|
|
1487
|
+
if (zip->tctx_valid) {
|
|
1488
|
+
trad_enc_decrypt_update(&zip->tctx,
|
|
1489
|
+
(const uint8_t *)buff, dec_size,
|
|
1490
|
+
zip->decrypted_buffer, dec_size);
|
|
1491
|
+
} else {
|
|
1492
|
+
size_t dsize = dec_size;
|
|
1493
|
+
archive_hmac_sha1_update(&zip->hctx,
|
|
1494
|
+
(const uint8_t *)buff, dec_size);
|
|
1495
|
+
archive_decrypto_aes_ctr_update(&zip->cctx,
|
|
1496
|
+
(const uint8_t *)buff, dec_size,
|
|
1497
|
+
zip->decrypted_buffer, &dsize);
|
|
1498
|
+
}
|
|
1499
|
+
bytes_avail = dec_size;
|
|
1500
|
+
buff = (const char *)zip->decrypted_buffer;
|
|
1501
|
+
}
|
|
1502
|
+
*size = bytes_avail;
|
|
1503
|
+
zip->entry_bytes_remaining -= bytes_avail;
|
|
1504
|
+
zip->entry_uncompressed_bytes_read += bytes_avail;
|
|
1505
|
+
zip->entry_compressed_bytes_read += bytes_avail;
|
|
1506
|
+
zip->unconsumed += bytes_avail;
|
|
1507
|
+
*_buff = buff;
|
|
1508
|
+
return (ARCHIVE_OK);
|
|
1509
|
+
}
|
|
1510
|
+
|
|
1511
|
+
static int
|
|
1512
|
+
consume_optional_marker(struct archive_read *a, struct zip *zip)
|
|
1513
|
+
{
|
|
1514
|
+
if (zip->end_of_entry && (zip->entry->zip_flags & ZIP_LENGTH_AT_END)) {
|
|
1515
|
+
const char *p;
|
|
1516
|
+
|
|
1517
|
+
if (NULL == (p = __archive_read_ahead(a, 24, NULL))) {
|
|
1518
|
+
archive_set_error(&a->archive,
|
|
1519
|
+
ARCHIVE_ERRNO_FILE_FORMAT,
|
|
1520
|
+
"Truncated ZIP end-of-file record");
|
|
1521
|
+
return (ARCHIVE_FATAL);
|
|
1522
|
+
}
|
|
1523
|
+
/* Consume the optional PK\007\010 marker. */
|
|
1524
|
+
if (p[0] == 'P' && p[1] == 'K' &&
|
|
1525
|
+
p[2] == '\007' && p[3] == '\010') {
|
|
1526
|
+
p += 4;
|
|
1527
|
+
zip->unconsumed = 4;
|
|
1528
|
+
}
|
|
1529
|
+
if (zip->entry->flags & LA_USED_ZIP64) {
|
|
1530
|
+
uint64_t compressed, uncompressed;
|
|
1531
|
+
zip->entry->crc32 = archive_le32dec(p);
|
|
1532
|
+
compressed = archive_le64dec(p + 4);
|
|
1533
|
+
uncompressed = archive_le64dec(p + 12);
|
|
1534
|
+
if (compressed > INT64_MAX ||
|
|
1535
|
+
uncompressed > INT64_MAX) {
|
|
1536
|
+
archive_set_error(&a->archive,
|
|
1537
|
+
ARCHIVE_ERRNO_FILE_FORMAT,
|
|
1538
|
+
"Overflow of 64-bit file sizes");
|
|
1539
|
+
return ARCHIVE_FAILED;
|
|
1540
|
+
}
|
|
1541
|
+
zip->entry->compressed_size = compressed;
|
|
1542
|
+
zip->entry->uncompressed_size = uncompressed;
|
|
1543
|
+
zip->unconsumed += 20;
|
|
1544
|
+
} else {
|
|
1545
|
+
zip->entry->crc32 = archive_le32dec(p);
|
|
1546
|
+
zip->entry->compressed_size = archive_le32dec(p + 4);
|
|
1547
|
+
zip->entry->uncompressed_size = archive_le32dec(p + 8);
|
|
1548
|
+
zip->unconsumed += 12;
|
|
1549
|
+
}
|
|
1550
|
+
}
|
|
1551
|
+
|
|
1552
|
+
return (ARCHIVE_OK);
|
|
1553
|
+
}
|
|
1554
|
+
|
|
1555
|
+
#if HAVE_LZMA_H && HAVE_LIBLZMA
|
|
1556
|
+
static int
|
|
1557
|
+
zipx_xz_init(struct archive_read *a, struct zip *zip)
|
|
1558
|
+
{
|
|
1559
|
+
lzma_ret r;
|
|
1560
|
+
|
|
1561
|
+
if(zip->zipx_lzma_valid) {
|
|
1562
|
+
lzma_end(&zip->zipx_lzma_stream);
|
|
1563
|
+
zip->zipx_lzma_valid = 0;
|
|
1564
|
+
}
|
|
1565
|
+
|
|
1566
|
+
memset(&zip->zipx_lzma_stream, 0, sizeof(zip->zipx_lzma_stream));
|
|
1567
|
+
r = lzma_stream_decoder(&zip->zipx_lzma_stream, UINT64_MAX, 0);
|
|
1568
|
+
if (r != LZMA_OK) {
|
|
1569
|
+
archive_set_error(&(a->archive), ARCHIVE_ERRNO_MISC,
|
|
1570
|
+
"xz initialization failed(%d)",
|
|
1571
|
+
r);
|
|
1572
|
+
|
|
1573
|
+
return (ARCHIVE_FAILED);
|
|
1574
|
+
}
|
|
1575
|
+
|
|
1576
|
+
zip->zipx_lzma_valid = 1;
|
|
1577
|
+
|
|
1578
|
+
free(zip->uncompressed_buffer);
|
|
1579
|
+
|
|
1580
|
+
zip->uncompressed_buffer_size = 256 * 1024;
|
|
1581
|
+
zip->uncompressed_buffer =
|
|
1582
|
+
(uint8_t*) malloc(zip->uncompressed_buffer_size);
|
|
1583
|
+
if (zip->uncompressed_buffer == NULL) {
|
|
1584
|
+
archive_set_error(&a->archive, ENOMEM,
|
|
1585
|
+
"No memory for xz decompression");
|
|
1586
|
+
return (ARCHIVE_FATAL);
|
|
1587
|
+
}
|
|
1588
|
+
|
|
1589
|
+
zip->decompress_init = 1;
|
|
1590
|
+
return (ARCHIVE_OK);
|
|
1591
|
+
}
|
|
1592
|
+
|
|
1593
|
+
static int
|
|
1594
|
+
zipx_lzma_alone_init(struct archive_read *a, struct zip *zip)
|
|
1595
|
+
{
|
|
1596
|
+
lzma_ret r;
|
|
1597
|
+
const uint8_t* p;
|
|
1598
|
+
|
|
1599
|
+
#pragma pack(push)
|
|
1600
|
+
#pragma pack(1)
|
|
1601
|
+
struct _alone_header {
|
|
1602
|
+
uint8_t bytes[5];
|
|
1603
|
+
uint64_t uncompressed_size;
|
|
1604
|
+
} alone_header;
|
|
1605
|
+
#pragma pack(pop)
|
|
1606
|
+
|
|
1607
|
+
if(zip->zipx_lzma_valid) {
|
|
1608
|
+
lzma_end(&zip->zipx_lzma_stream);
|
|
1609
|
+
zip->zipx_lzma_valid = 0;
|
|
1610
|
+
}
|
|
1611
|
+
|
|
1612
|
+
/* To unpack ZIPX's "LZMA" (id 14) stream we can use standard liblzma
|
|
1613
|
+
* that is a part of XZ Utils. The stream format stored inside ZIPX
|
|
1614
|
+
* file is a modified "lzma alone" file format, that was used by the
|
|
1615
|
+
* `lzma` utility which was later deprecated in favour of `xz` utility.
|
|
1616
|
+
* Since those formats are nearly the same, we can use a standard
|
|
1617
|
+
* "lzma alone" decoder from XZ Utils. */
|
|
1618
|
+
|
|
1619
|
+
memset(&zip->zipx_lzma_stream, 0, sizeof(zip->zipx_lzma_stream));
|
|
1620
|
+
r = lzma_alone_decoder(&zip->zipx_lzma_stream, UINT64_MAX);
|
|
1621
|
+
if (r != LZMA_OK) {
|
|
1622
|
+
archive_set_error(&(a->archive), ARCHIVE_ERRNO_MISC,
|
|
1623
|
+
"lzma initialization failed(%d)", r);
|
|
1624
|
+
|
|
1625
|
+
return (ARCHIVE_FAILED);
|
|
1626
|
+
}
|
|
1627
|
+
|
|
1628
|
+
/* Flag the cleanup function that we want our lzma-related structures
|
|
1629
|
+
* to be freed later. */
|
|
1630
|
+
zip->zipx_lzma_valid = 1;
|
|
1631
|
+
|
|
1632
|
+
/* The "lzma alone" file format and the stream format inside ZIPx are
|
|
1633
|
+
* almost the same. Here's an example of a structure of "lzma alone"
|
|
1634
|
+
* format:
|
|
1635
|
+
*
|
|
1636
|
+
* $ cat /bin/ls | lzma | xxd | head -n 1
|
|
1637
|
+
* 00000000: 5d00 0080 00ff ffff ffff ffff ff00 2814
|
|
1638
|
+
*
|
|
1639
|
+
* 5 bytes 8 bytes n bytes
|
|
1640
|
+
* <lzma_params><uncompressed_size><data...>
|
|
1641
|
+
*
|
|
1642
|
+
* lzma_params is a 5-byte blob that has to be decoded to extract
|
|
1643
|
+
* parameters of this LZMA stream. The uncompressed_size field is an
|
|
1644
|
+
* uint64_t value that contains information about the size of the
|
|
1645
|
+
* uncompressed file, or UINT64_MAX if this value is unknown.
|
|
1646
|
+
* The <data...> part is the actual lzma-compressed data stream.
|
|
1647
|
+
*
|
|
1648
|
+
* Now here's the structure of the stream inside the ZIPX file:
|
|
1649
|
+
*
|
|
1650
|
+
* $ cat stream_inside_zipx | xxd | head -n 1
|
|
1651
|
+
* 00000000: 0914 0500 5d00 8000 0000 2814 .... ....
|
|
1652
|
+
*
|
|
1653
|
+
* 2byte 2byte 5 bytes n bytes
|
|
1654
|
+
* <magic1><magic2><lzma_params><data...>
|
|
1655
|
+
*
|
|
1656
|
+
* This means that the ZIPX file contains an additional magic1 and
|
|
1657
|
+
* magic2 headers, the lzma_params field contains the same parameter
|
|
1658
|
+
* set as in the "lzma alone" format, and the <data...> field is the
|
|
1659
|
+
* same as in the "lzma alone" format as well. Note that also the zipx
|
|
1660
|
+
* format is missing the uncompressed_size field.
|
|
1661
|
+
*
|
|
1662
|
+
* So, in order to use the "lzma alone" decoder for the zipx lzma
|
|
1663
|
+
* stream, we simply need to shuffle around some fields, prepare a new
|
|
1664
|
+
* lzma alone header, feed it into lzma alone decoder so it will
|
|
1665
|
+
* initialize itself properly, and then we can start feeding normal
|
|
1666
|
+
* zipx lzma stream into the decoder.
|
|
1667
|
+
*/
|
|
1668
|
+
|
|
1669
|
+
/* Read magic1,magic2,lzma_params from the ZIPX stream. */
|
|
1670
|
+
if(zip->entry_bytes_remaining < 9 || (p = __archive_read_ahead(a, 9, NULL)) == NULL) {
|
|
1671
|
+
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
|
1672
|
+
"Truncated lzma data");
|
|
1673
|
+
return (ARCHIVE_FATAL);
|
|
1674
|
+
}
|
|
1675
|
+
|
|
1676
|
+
if(p[2] != 0x05 || p[3] != 0x00) {
|
|
1677
|
+
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
|
1678
|
+
"Invalid lzma data");
|
|
1679
|
+
return (ARCHIVE_FATAL);
|
|
1680
|
+
}
|
|
1681
|
+
|
|
1682
|
+
/* Prepare an lzma alone header: copy the lzma_params blob into
|
|
1683
|
+
* a proper place into the lzma alone header. */
|
|
1684
|
+
memcpy(&alone_header.bytes[0], p + 4, 5);
|
|
1685
|
+
|
|
1686
|
+
/* Initialize the 'uncompressed size' field to unknown; we'll manually
|
|
1687
|
+
* monitor how many bytes there are still to be uncompressed. */
|
|
1688
|
+
alone_header.uncompressed_size = UINT64_MAX;
|
|
1689
|
+
|
|
1690
|
+
if(!zip->uncompressed_buffer) {
|
|
1691
|
+
zip->uncompressed_buffer_size = 256 * 1024;
|
|
1692
|
+
zip->uncompressed_buffer =
|
|
1693
|
+
(uint8_t*) malloc(zip->uncompressed_buffer_size);
|
|
1694
|
+
|
|
1695
|
+
if (zip->uncompressed_buffer == NULL) {
|
|
1696
|
+
archive_set_error(&a->archive, ENOMEM,
|
|
1697
|
+
"No memory for lzma decompression");
|
|
1698
|
+
return (ARCHIVE_FATAL);
|
|
1699
|
+
}
|
|
1700
|
+
}
|
|
1701
|
+
|
|
1702
|
+
zip->zipx_lzma_stream.next_in = (void*) &alone_header;
|
|
1703
|
+
zip->zipx_lzma_stream.avail_in = sizeof(alone_header);
|
|
1704
|
+
zip->zipx_lzma_stream.total_in = 0;
|
|
1705
|
+
zip->zipx_lzma_stream.next_out = zip->uncompressed_buffer;
|
|
1706
|
+
zip->zipx_lzma_stream.avail_out = zip->uncompressed_buffer_size;
|
|
1707
|
+
zip->zipx_lzma_stream.total_out = 0;
|
|
1708
|
+
|
|
1709
|
+
/* Feed only the header into the lzma alone decoder. This will
|
|
1710
|
+
* effectively initialize the decoder, and will not produce any
|
|
1711
|
+
* output bytes yet. */
|
|
1712
|
+
r = lzma_code(&zip->zipx_lzma_stream, LZMA_RUN);
|
|
1713
|
+
if (r != LZMA_OK) {
|
|
1714
|
+
archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER,
|
|
1715
|
+
"lzma stream initialization error");
|
|
1716
|
+
return ARCHIVE_FATAL;
|
|
1717
|
+
}
|
|
1718
|
+
|
|
1719
|
+
/* We've already consumed some bytes, so take this into account. */
|
|
1720
|
+
__archive_read_consume(a, 9);
|
|
1721
|
+
zip->entry_bytes_remaining -= 9;
|
|
1722
|
+
zip->entry_compressed_bytes_read += 9;
|
|
1723
|
+
|
|
1724
|
+
zip->decompress_init = 1;
|
|
1725
|
+
return (ARCHIVE_OK);
|
|
1726
|
+
}
|
|
1727
|
+
|
|
1728
|
+
static int
|
|
1729
|
+
zip_read_data_zipx_xz(struct archive_read *a, const void **buff,
|
|
1730
|
+
size_t *size, int64_t *offset)
|
|
1731
|
+
{
|
|
1732
|
+
struct zip* zip = (struct zip *)(a->format->data);
|
|
1733
|
+
int ret;
|
|
1734
|
+
lzma_ret lz_ret;
|
|
1735
|
+
const void* compressed_buf;
|
|
1736
|
+
ssize_t bytes_avail, in_bytes, to_consume = 0;
|
|
1737
|
+
|
|
1738
|
+
(void) offset; /* UNUSED */
|
|
1739
|
+
|
|
1740
|
+
/* Initialize decompressor if not yet initialized. */
|
|
1741
|
+
if (!zip->decompress_init) {
|
|
1742
|
+
ret = zipx_xz_init(a, zip);
|
|
1743
|
+
if (ret != ARCHIVE_OK)
|
|
1744
|
+
return (ret);
|
|
1745
|
+
}
|
|
1746
|
+
|
|
1747
|
+
compressed_buf = __archive_read_ahead(a, 1, &bytes_avail);
|
|
1748
|
+
if (bytes_avail < 0) {
|
|
1749
|
+
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
|
1750
|
+
"Truncated xz file body");
|
|
1751
|
+
return (ARCHIVE_FATAL);
|
|
1752
|
+
}
|
|
1753
|
+
|
|
1754
|
+
in_bytes = zipmin(zip->entry_bytes_remaining, bytes_avail);
|
|
1755
|
+
zip->zipx_lzma_stream.next_in = compressed_buf;
|
|
1756
|
+
zip->zipx_lzma_stream.avail_in = in_bytes;
|
|
1757
|
+
zip->zipx_lzma_stream.total_in = 0;
|
|
1758
|
+
zip->zipx_lzma_stream.next_out = zip->uncompressed_buffer;
|
|
1759
|
+
zip->zipx_lzma_stream.avail_out = zip->uncompressed_buffer_size;
|
|
1760
|
+
zip->zipx_lzma_stream.total_out = 0;
|
|
1761
|
+
|
|
1762
|
+
/* Perform the decompression. */
|
|
1763
|
+
lz_ret = lzma_code(&zip->zipx_lzma_stream, LZMA_RUN);
|
|
1764
|
+
switch(lz_ret) {
|
|
1765
|
+
case LZMA_DATA_ERROR:
|
|
1766
|
+
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
|
1767
|
+
"xz data error (error %d)", (int) lz_ret);
|
|
1768
|
+
return (ARCHIVE_FATAL);
|
|
1769
|
+
|
|
1770
|
+
case LZMA_NO_CHECK:
|
|
1771
|
+
case LZMA_OK:
|
|
1772
|
+
break;
|
|
1773
|
+
|
|
1774
|
+
default:
|
|
1775
|
+
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
|
1776
|
+
"xz unknown error %d", (int) lz_ret);
|
|
1777
|
+
return (ARCHIVE_FATAL);
|
|
1778
|
+
|
|
1779
|
+
case LZMA_STREAM_END:
|
|
1780
|
+
lzma_end(&zip->zipx_lzma_stream);
|
|
1781
|
+
zip->zipx_lzma_valid = 0;
|
|
1782
|
+
|
|
1783
|
+
if((int64_t) zip->zipx_lzma_stream.total_in !=
|
|
1784
|
+
zip->entry_bytes_remaining)
|
|
1785
|
+
{
|
|
1786
|
+
archive_set_error(&a->archive,
|
|
1787
|
+
ARCHIVE_ERRNO_MISC,
|
|
1788
|
+
"xz premature end of stream");
|
|
1789
|
+
return (ARCHIVE_FATAL);
|
|
1790
|
+
}
|
|
1791
|
+
|
|
1792
|
+
zip->end_of_entry = 1;
|
|
1793
|
+
break;
|
|
1794
|
+
}
|
|
1795
|
+
|
|
1796
|
+
to_consume = zip->zipx_lzma_stream.total_in;
|
|
1797
|
+
|
|
1798
|
+
__archive_read_consume(a, to_consume);
|
|
1799
|
+
zip->entry_bytes_remaining -= to_consume;
|
|
1800
|
+
zip->entry_compressed_bytes_read += to_consume;
|
|
1801
|
+
zip->entry_uncompressed_bytes_read += zip->zipx_lzma_stream.total_out;
|
|
1802
|
+
|
|
1803
|
+
*size = zip->zipx_lzma_stream.total_out;
|
|
1804
|
+
*buff = zip->uncompressed_buffer;
|
|
1805
|
+
|
|
1806
|
+
ret = consume_optional_marker(a, zip);
|
|
1807
|
+
if (ret != ARCHIVE_OK)
|
|
1808
|
+
return (ret);
|
|
1809
|
+
|
|
1810
|
+
return (ARCHIVE_OK);
|
|
1811
|
+
}
|
|
1812
|
+
|
|
1813
|
+
static int
|
|
1814
|
+
zip_read_data_zipx_lzma_alone(struct archive_read *a, const void **buff,
|
|
1815
|
+
size_t *size, int64_t *offset)
|
|
1816
|
+
{
|
|
1817
|
+
struct zip* zip = (struct zip *)(a->format->data);
|
|
1818
|
+
int ret;
|
|
1819
|
+
lzma_ret lz_ret;
|
|
1820
|
+
const void* compressed_buf;
|
|
1821
|
+
ssize_t bytes_avail, in_bytes, to_consume;
|
|
1822
|
+
|
|
1823
|
+
(void) offset; /* UNUSED */
|
|
1824
|
+
|
|
1825
|
+
/* Initialize decompressor if not yet initialized. */
|
|
1826
|
+
if (!zip->decompress_init) {
|
|
1827
|
+
ret = zipx_lzma_alone_init(a, zip);
|
|
1828
|
+
if (ret != ARCHIVE_OK)
|
|
1829
|
+
return (ret);
|
|
1830
|
+
}
|
|
1831
|
+
|
|
1832
|
+
/* Fetch more compressed data. The same note as in deflate handler
|
|
1833
|
+
* applies here as well:
|
|
1834
|
+
*
|
|
1835
|
+
* Note: '1' here is a performance optimization. Recall that the
|
|
1836
|
+
* decompression layer returns a count of available bytes; asking for
|
|
1837
|
+
* more than that forces the decompressor to combine reads by copying
|
|
1838
|
+
* data.
|
|
1839
|
+
*/
|
|
1840
|
+
compressed_buf = __archive_read_ahead(a, 1, &bytes_avail);
|
|
1841
|
+
if (bytes_avail < 0) {
|
|
1842
|
+
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
|
1843
|
+
"Truncated lzma file body");
|
|
1844
|
+
return (ARCHIVE_FATAL);
|
|
1845
|
+
}
|
|
1846
|
+
|
|
1847
|
+
/* Set decompressor parameters. */
|
|
1848
|
+
in_bytes = zipmin(zip->entry_bytes_remaining, bytes_avail);
|
|
1849
|
+
|
|
1850
|
+
zip->zipx_lzma_stream.next_in = compressed_buf;
|
|
1851
|
+
zip->zipx_lzma_stream.avail_in = in_bytes;
|
|
1852
|
+
zip->zipx_lzma_stream.total_in = 0;
|
|
1853
|
+
zip->zipx_lzma_stream.next_out = zip->uncompressed_buffer;
|
|
1854
|
+
zip->zipx_lzma_stream.avail_out =
|
|
1855
|
+
/* These lzma_alone streams lack end of stream marker, so let's
|
|
1856
|
+
* make sure the unpacker won't try to unpack more than it's
|
|
1857
|
+
* supposed to. */
|
|
1858
|
+
zipmin((int64_t) zip->uncompressed_buffer_size,
|
|
1859
|
+
zip->entry->uncompressed_size -
|
|
1860
|
+
zip->entry_uncompressed_bytes_read);
|
|
1861
|
+
zip->zipx_lzma_stream.total_out = 0;
|
|
1862
|
+
|
|
1863
|
+
/* Perform the decompression. */
|
|
1864
|
+
lz_ret = lzma_code(&zip->zipx_lzma_stream, LZMA_RUN);
|
|
1865
|
+
switch(lz_ret) {
|
|
1866
|
+
case LZMA_DATA_ERROR:
|
|
1867
|
+
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
|
1868
|
+
"lzma data error (error %d)", (int) lz_ret);
|
|
1869
|
+
return (ARCHIVE_FATAL);
|
|
1870
|
+
|
|
1871
|
+
/* This case is optional in lzma alone format. It can happen,
|
|
1872
|
+
* but most of the files don't have it. (GitHub #1257) */
|
|
1873
|
+
case LZMA_STREAM_END:
|
|
1874
|
+
lzma_end(&zip->zipx_lzma_stream);
|
|
1875
|
+
zip->zipx_lzma_valid = 0;
|
|
1876
|
+
if((int64_t) zip->zipx_lzma_stream.total_in !=
|
|
1877
|
+
zip->entry_bytes_remaining)
|
|
1878
|
+
{
|
|
1879
|
+
archive_set_error(&a->archive,
|
|
1880
|
+
ARCHIVE_ERRNO_MISC,
|
|
1881
|
+
"lzma alone premature end of stream");
|
|
1882
|
+
return (ARCHIVE_FATAL);
|
|
1883
|
+
}
|
|
1884
|
+
|
|
1885
|
+
zip->end_of_entry = 1;
|
|
1886
|
+
break;
|
|
1887
|
+
|
|
1888
|
+
case LZMA_OK:
|
|
1889
|
+
break;
|
|
1890
|
+
|
|
1891
|
+
default:
|
|
1892
|
+
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
|
1893
|
+
"lzma unknown error %d", (int) lz_ret);
|
|
1894
|
+
return (ARCHIVE_FATAL);
|
|
1895
|
+
}
|
|
1896
|
+
|
|
1897
|
+
to_consume = zip->zipx_lzma_stream.total_in;
|
|
1898
|
+
|
|
1899
|
+
/* Update pointers. */
|
|
1900
|
+
__archive_read_consume(a, to_consume);
|
|
1901
|
+
zip->entry_bytes_remaining -= to_consume;
|
|
1902
|
+
zip->entry_compressed_bytes_read += to_consume;
|
|
1903
|
+
zip->entry_uncompressed_bytes_read += zip->zipx_lzma_stream.total_out;
|
|
1904
|
+
|
|
1905
|
+
if(zip->entry_bytes_remaining == 0) {
|
|
1906
|
+
zip->end_of_entry = 1;
|
|
1907
|
+
}
|
|
1908
|
+
|
|
1909
|
+
/* Return values. */
|
|
1910
|
+
*size = zip->zipx_lzma_stream.total_out;
|
|
1911
|
+
*buff = zip->uncompressed_buffer;
|
|
1912
|
+
|
|
1913
|
+
/* Behave the same way as during deflate decompression. */
|
|
1914
|
+
ret = consume_optional_marker(a, zip);
|
|
1915
|
+
if (ret != ARCHIVE_OK)
|
|
1916
|
+
return (ret);
|
|
1917
|
+
|
|
1918
|
+
/* Free lzma decoder handle because we'll no longer need it. */
|
|
1919
|
+
if(zip->end_of_entry) {
|
|
1920
|
+
lzma_end(&zip->zipx_lzma_stream);
|
|
1921
|
+
zip->zipx_lzma_valid = 0;
|
|
1922
|
+
}
|
|
1923
|
+
|
|
1924
|
+
/* If we're here, then we're good! */
|
|
1925
|
+
return (ARCHIVE_OK);
|
|
1926
|
+
}
|
|
1927
|
+
#endif /* HAVE_LZMA_H && HAVE_LIBLZMA */
|
|
1928
|
+
|
|
1929
|
+
static int
|
|
1930
|
+
zipx_ppmd8_init(struct archive_read *a, struct zip *zip)
|
|
1931
|
+
{
|
|
1932
|
+
const void* p;
|
|
1933
|
+
uint32_t val;
|
|
1934
|
+
uint32_t order;
|
|
1935
|
+
uint32_t mem;
|
|
1936
|
+
uint32_t restore_method;
|
|
1937
|
+
|
|
1938
|
+
/* Remove previous decompression context if it exists. */
|
|
1939
|
+
if(zip->ppmd8_valid) {
|
|
1940
|
+
__archive_ppmd8_functions.Ppmd8_Free(&zip->ppmd8);
|
|
1941
|
+
zip->ppmd8_valid = 0;
|
|
1942
|
+
}
|
|
1943
|
+
|
|
1944
|
+
/* Create a new decompression context. */
|
|
1945
|
+
__archive_ppmd8_functions.Ppmd8_Construct(&zip->ppmd8);
|
|
1946
|
+
zip->ppmd8_stream_failed = 0;
|
|
1947
|
+
|
|
1948
|
+
/* Setup function pointers required by Ppmd8 decompressor. The
|
|
1949
|
+
* 'ppmd_read' function will feed new bytes to the decompressor,
|
|
1950
|
+
* and will increment the 'zip->zipx_ppmd_read_compressed' counter. */
|
|
1951
|
+
zip->ppmd8.Stream.In = &zip->zipx_ppmd_stream;
|
|
1952
|
+
zip->zipx_ppmd_stream.a = a;
|
|
1953
|
+
zip->zipx_ppmd_stream.Read = &ppmd_read;
|
|
1954
|
+
|
|
1955
|
+
/* Reset number of read bytes to 0. */
|
|
1956
|
+
zip->zipx_ppmd_read_compressed = 0;
|
|
1957
|
+
|
|
1958
|
+
/* Read Ppmd8 header (2 bytes). */
|
|
1959
|
+
p = __archive_read_ahead(a, 2, NULL);
|
|
1960
|
+
if(!p) {
|
|
1961
|
+
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
|
1962
|
+
"Truncated file data in PPMd8 stream");
|
|
1963
|
+
return (ARCHIVE_FATAL);
|
|
1964
|
+
}
|
|
1965
|
+
__archive_read_consume(a, 2);
|
|
1966
|
+
|
|
1967
|
+
/* Decode the stream's compression parameters. */
|
|
1968
|
+
val = archive_le16dec(p);
|
|
1969
|
+
order = (val & 15) + 1;
|
|
1970
|
+
mem = ((val >> 4) & 0xff) + 1;
|
|
1971
|
+
restore_method = (val >> 12);
|
|
1972
|
+
|
|
1973
|
+
if(order < 2 || restore_method > 2) {
|
|
1974
|
+
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
|
1975
|
+
"Invalid parameter set in PPMd8 stream (order=%" PRId32 ", "
|
|
1976
|
+
"restore=%" PRId32 ")", order, restore_method);
|
|
1977
|
+
return (ARCHIVE_FAILED);
|
|
1978
|
+
}
|
|
1979
|
+
|
|
1980
|
+
/* Allocate the memory needed to properly decompress the file. */
|
|
1981
|
+
if(!__archive_ppmd8_functions.Ppmd8_Alloc(&zip->ppmd8, mem << 20)) {
|
|
1982
|
+
archive_set_error(&a->archive, ENOMEM,
|
|
1983
|
+
"Unable to allocate memory for PPMd8 stream: %" PRId32 " bytes",
|
|
1984
|
+
mem << 20);
|
|
1985
|
+
return (ARCHIVE_FATAL);
|
|
1986
|
+
}
|
|
1987
|
+
|
|
1988
|
+
/* Signal the cleanup function to release Ppmd8 context in the
|
|
1989
|
+
* cleanup phase. */
|
|
1990
|
+
zip->ppmd8_valid = 1;
|
|
1991
|
+
|
|
1992
|
+
/* Perform further Ppmd8 initialization. */
|
|
1993
|
+
if(!__archive_ppmd8_functions.Ppmd8_RangeDec_Init(&zip->ppmd8)) {
|
|
1994
|
+
archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER,
|
|
1995
|
+
"PPMd8 stream range decoder initialization error");
|
|
1996
|
+
return (ARCHIVE_FATAL);
|
|
1997
|
+
}
|
|
1998
|
+
|
|
1999
|
+
__archive_ppmd8_functions.Ppmd8_Init(&zip->ppmd8, order,
|
|
2000
|
+
restore_method);
|
|
2001
|
+
|
|
2002
|
+
/* Allocate the buffer that will hold uncompressed data. */
|
|
2003
|
+
free(zip->uncompressed_buffer);
|
|
2004
|
+
|
|
2005
|
+
zip->uncompressed_buffer_size = 256 * 1024;
|
|
2006
|
+
zip->uncompressed_buffer =
|
|
2007
|
+
(uint8_t*) malloc(zip->uncompressed_buffer_size);
|
|
2008
|
+
|
|
2009
|
+
if(zip->uncompressed_buffer == NULL) {
|
|
2010
|
+
archive_set_error(&a->archive, ENOMEM,
|
|
2011
|
+
"No memory for PPMd8 decompression");
|
|
2012
|
+
return ARCHIVE_FATAL;
|
|
2013
|
+
}
|
|
2014
|
+
|
|
2015
|
+
/* Ppmd8 initialization is done. */
|
|
2016
|
+
zip->decompress_init = 1;
|
|
2017
|
+
|
|
2018
|
+
/* We've already read 2 bytes in the output stream. Additionally,
|
|
2019
|
+
* Ppmd8 initialization code could read some data as well. So we
|
|
2020
|
+
* are advancing the stream by 2 bytes plus whatever number of
|
|
2021
|
+
* bytes Ppmd8 init function used. */
|
|
2022
|
+
zip->entry_compressed_bytes_read += 2 + zip->zipx_ppmd_read_compressed;
|
|
2023
|
+
|
|
2024
|
+
return ARCHIVE_OK;
|
|
2025
|
+
}
|
|
2026
|
+
|
|
2027
|
+
static int
|
|
2028
|
+
zip_read_data_zipx_ppmd(struct archive_read *a, const void **buff,
|
|
2029
|
+
size_t *size, int64_t *offset)
|
|
2030
|
+
{
|
|
2031
|
+
struct zip* zip = (struct zip *)(a->format->data);
|
|
2032
|
+
int ret;
|
|
2033
|
+
size_t consumed_bytes = 0;
|
|
2034
|
+
ssize_t bytes_avail = 0;
|
|
2035
|
+
|
|
2036
|
+
(void) offset; /* UNUSED */
|
|
2037
|
+
|
|
2038
|
+
/* If we're here for the first time, initialize Ppmd8 decompression
|
|
2039
|
+
* context first. */
|
|
2040
|
+
if(!zip->decompress_init) {
|
|
2041
|
+
ret = zipx_ppmd8_init(a, zip);
|
|
2042
|
+
if(ret != ARCHIVE_OK)
|
|
2043
|
+
return ret;
|
|
2044
|
+
}
|
|
2045
|
+
|
|
2046
|
+
/* Fetch for more data. We're reading 1 byte here, but libarchive
|
|
2047
|
+
* should prefetch more bytes. */
|
|
2048
|
+
(void) __archive_read_ahead(a, 1, &bytes_avail);
|
|
2049
|
+
if(bytes_avail < 0) {
|
|
2050
|
+
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
|
2051
|
+
"Truncated PPMd8 file body");
|
|
2052
|
+
return (ARCHIVE_FATAL);
|
|
2053
|
+
}
|
|
2054
|
+
|
|
2055
|
+
/* This counter will be updated inside ppmd_read(), which at one
|
|
2056
|
+
* point will be called by Ppmd8_DecodeSymbol. */
|
|
2057
|
+
zip->zipx_ppmd_read_compressed = 0;
|
|
2058
|
+
|
|
2059
|
+
/* Decompression loop. */
|
|
2060
|
+
do {
|
|
2061
|
+
int sym = __archive_ppmd8_functions.Ppmd8_DecodeSymbol(
|
|
2062
|
+
&zip->ppmd8);
|
|
2063
|
+
if(sym < 0) {
|
|
2064
|
+
zip->end_of_entry = 1;
|
|
2065
|
+
break;
|
|
2066
|
+
}
|
|
2067
|
+
|
|
2068
|
+
/* This field is set by ppmd_read() when there was no more data
|
|
2069
|
+
* to be read. */
|
|
2070
|
+
if(zip->ppmd8_stream_failed) {
|
|
2071
|
+
archive_set_error(&a->archive,
|
|
2072
|
+
ARCHIVE_ERRNO_FILE_FORMAT,
|
|
2073
|
+
"Truncated PPMd8 file body");
|
|
2074
|
+
return (ARCHIVE_FATAL);
|
|
2075
|
+
}
|
|
2076
|
+
|
|
2077
|
+
zip->uncompressed_buffer[consumed_bytes] = (uint8_t) sym;
|
|
2078
|
+
++consumed_bytes;
|
|
2079
|
+
} while(consumed_bytes < zip->uncompressed_buffer_size);
|
|
2080
|
+
|
|
2081
|
+
/* Update pointers for libarchive. */
|
|
2082
|
+
*buff = zip->uncompressed_buffer;
|
|
2083
|
+
*size = consumed_bytes;
|
|
2084
|
+
|
|
2085
|
+
/* Update pointers so we can continue decompression in another call. */
|
|
2086
|
+
zip->entry_bytes_remaining -= zip->zipx_ppmd_read_compressed;
|
|
2087
|
+
zip->entry_compressed_bytes_read += zip->zipx_ppmd_read_compressed;
|
|
2088
|
+
zip->entry_uncompressed_bytes_read += consumed_bytes;
|
|
2089
|
+
|
|
2090
|
+
/* If we're at the end of stream, deinitialize Ppmd8 context. */
|
|
2091
|
+
if(zip->end_of_entry) {
|
|
2092
|
+
__archive_ppmd8_functions.Ppmd8_Free(&zip->ppmd8);
|
|
2093
|
+
zip->ppmd8_valid = 0;
|
|
2094
|
+
}
|
|
2095
|
+
|
|
2096
|
+
/* Seek for optional marker, same way as in each zip entry. */
|
|
2097
|
+
ret = consume_optional_marker(a, zip);
|
|
2098
|
+
if (ret != ARCHIVE_OK)
|
|
2099
|
+
return ret;
|
|
2100
|
+
|
|
2101
|
+
return ARCHIVE_OK;
|
|
2102
|
+
}
|
|
2103
|
+
|
|
2104
|
+
#ifdef HAVE_BZLIB_H
|
|
2105
|
+
static int
|
|
2106
|
+
zipx_bzip2_init(struct archive_read *a, struct zip *zip)
|
|
2107
|
+
{
|
|
2108
|
+
int r;
|
|
2109
|
+
|
|
2110
|
+
/* Deallocate already existing BZ2 decompression context if it
|
|
2111
|
+
* exists. */
|
|
2112
|
+
if(zip->bzstream_valid) {
|
|
2113
|
+
BZ2_bzDecompressEnd(&zip->bzstream);
|
|
2114
|
+
zip->bzstream_valid = 0;
|
|
2115
|
+
}
|
|
2116
|
+
|
|
2117
|
+
/* Allocate a new BZ2 decompression context. */
|
|
2118
|
+
memset(&zip->bzstream, 0, sizeof(bz_stream));
|
|
2119
|
+
r = BZ2_bzDecompressInit(&zip->bzstream, 0, 1);
|
|
2120
|
+
if(r != BZ_OK) {
|
|
2121
|
+
archive_set_error(&(a->archive), ARCHIVE_ERRNO_MISC,
|
|
2122
|
+
"bzip2 initialization failed(%d)",
|
|
2123
|
+
r);
|
|
2124
|
+
|
|
2125
|
+
return ARCHIVE_FAILED;
|
|
2126
|
+
}
|
|
2127
|
+
|
|
2128
|
+
/* Mark the bzstream field to be released in cleanup phase. */
|
|
2129
|
+
zip->bzstream_valid = 1;
|
|
2130
|
+
|
|
2131
|
+
/* (Re)allocate the buffer that will contain decompressed bytes. */
|
|
2132
|
+
free(zip->uncompressed_buffer);
|
|
2133
|
+
|
|
2134
|
+
zip->uncompressed_buffer_size = 256 * 1024;
|
|
2135
|
+
zip->uncompressed_buffer =
|
|
2136
|
+
(uint8_t*) malloc(zip->uncompressed_buffer_size);
|
|
2137
|
+
if (zip->uncompressed_buffer == NULL) {
|
|
2138
|
+
archive_set_error(&a->archive, ENOMEM,
|
|
2139
|
+
"No memory for bzip2 decompression");
|
|
2140
|
+
return ARCHIVE_FATAL;
|
|
2141
|
+
}
|
|
2142
|
+
|
|
2143
|
+
/* Initialization done. */
|
|
2144
|
+
zip->decompress_init = 1;
|
|
2145
|
+
return ARCHIVE_OK;
|
|
2146
|
+
}
|
|
2147
|
+
|
|
2148
|
+
static int
|
|
2149
|
+
zip_read_data_zipx_bzip2(struct archive_read *a, const void **buff,
|
|
2150
|
+
size_t *size, int64_t *offset)
|
|
2151
|
+
{
|
|
2152
|
+
struct zip *zip = (struct zip *)(a->format->data);
|
|
2153
|
+
ssize_t bytes_avail = 0, in_bytes, to_consume;
|
|
2154
|
+
const void *compressed_buff;
|
|
2155
|
+
int r;
|
|
2156
|
+
uint64_t total_out;
|
|
2157
|
+
|
|
2158
|
+
(void) offset; /* UNUSED */
|
|
2159
|
+
|
|
2160
|
+
/* Initialize decompression context if we're here for the first time. */
|
|
2161
|
+
if(!zip->decompress_init) {
|
|
2162
|
+
r = zipx_bzip2_init(a, zip);
|
|
2163
|
+
if(r != ARCHIVE_OK)
|
|
2164
|
+
return r;
|
|
2165
|
+
}
|
|
2166
|
+
|
|
2167
|
+
/* Fetch more compressed bytes. */
|
|
2168
|
+
compressed_buff = __archive_read_ahead(a, 1, &bytes_avail);
|
|
2169
|
+
if(bytes_avail < 0) {
|
|
2170
|
+
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
|
2171
|
+
"Truncated bzip2 file body");
|
|
2172
|
+
return (ARCHIVE_FATAL);
|
|
2173
|
+
}
|
|
2174
|
+
|
|
2175
|
+
in_bytes = zipmin(zip->entry_bytes_remaining, bytes_avail);
|
|
2176
|
+
if(in_bytes < 1) {
|
|
2177
|
+
/* libbz2 doesn't complain when caller feeds avail_in == 0.
|
|
2178
|
+
* It will actually return success in this case, which is
|
|
2179
|
+
* undesirable. This is why we need to make this check
|
|
2180
|
+
* manually. */
|
|
2181
|
+
|
|
2182
|
+
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
|
2183
|
+
"Truncated bzip2 file body");
|
|
2184
|
+
return (ARCHIVE_FATAL);
|
|
2185
|
+
}
|
|
2186
|
+
|
|
2187
|
+
/* Setup buffer boundaries. */
|
|
2188
|
+
zip->bzstream.next_in = (char*)(uintptr_t) compressed_buff;
|
|
2189
|
+
zip->bzstream.avail_in = in_bytes;
|
|
2190
|
+
zip->bzstream.total_in_hi32 = 0;
|
|
2191
|
+
zip->bzstream.total_in_lo32 = 0;
|
|
2192
|
+
zip->bzstream.next_out = (char*) zip->uncompressed_buffer;
|
|
2193
|
+
zip->bzstream.avail_out = zip->uncompressed_buffer_size;
|
|
2194
|
+
zip->bzstream.total_out_hi32 = 0;
|
|
2195
|
+
zip->bzstream.total_out_lo32 = 0;
|
|
2196
|
+
|
|
2197
|
+
/* Perform the decompression. */
|
|
2198
|
+
r = BZ2_bzDecompress(&zip->bzstream);
|
|
2199
|
+
switch(r) {
|
|
2200
|
+
case BZ_STREAM_END:
|
|
2201
|
+
/* If we're at the end of the stream, deinitialize the
|
|
2202
|
+
* decompression context now. */
|
|
2203
|
+
switch(BZ2_bzDecompressEnd(&zip->bzstream)) {
|
|
2204
|
+
case BZ_OK:
|
|
2205
|
+
break;
|
|
2206
|
+
default:
|
|
2207
|
+
archive_set_error(&a->archive,
|
|
2208
|
+
ARCHIVE_ERRNO_MISC,
|
|
2209
|
+
"Failed to clean up bzip2 "
|
|
2210
|
+
"decompressor");
|
|
2211
|
+
return ARCHIVE_FATAL;
|
|
2212
|
+
}
|
|
2213
|
+
|
|
2214
|
+
zip->end_of_entry = 1;
|
|
2215
|
+
break;
|
|
2216
|
+
case BZ_OK:
|
|
2217
|
+
/* The decompressor has successfully decoded this
|
|
2218
|
+
* chunk of data, but more data is still in queue. */
|
|
2219
|
+
break;
|
|
2220
|
+
default:
|
|
2221
|
+
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
|
2222
|
+
"bzip2 decompression failed");
|
|
2223
|
+
return ARCHIVE_FATAL;
|
|
2224
|
+
}
|
|
2225
|
+
|
|
2226
|
+
/* Update the pointers so decompressor can continue decoding. */
|
|
2227
|
+
to_consume = zip->bzstream.total_in_lo32;
|
|
2228
|
+
__archive_read_consume(a, to_consume);
|
|
2229
|
+
|
|
2230
|
+
total_out = ((uint64_t) zip->bzstream.total_out_hi32 << 32) +
|
|
2231
|
+
zip->bzstream.total_out_lo32;
|
|
2232
|
+
|
|
2233
|
+
zip->entry_bytes_remaining -= to_consume;
|
|
2234
|
+
zip->entry_compressed_bytes_read += to_consume;
|
|
2235
|
+
zip->entry_uncompressed_bytes_read += total_out;
|
|
2236
|
+
|
|
2237
|
+
/* Give libarchive its due. */
|
|
2238
|
+
*size = total_out;
|
|
2239
|
+
*buff = zip->uncompressed_buffer;
|
|
2240
|
+
|
|
2241
|
+
/* Seek for optional marker, like in other entries. */
|
|
2242
|
+
r = consume_optional_marker(a, zip);
|
|
2243
|
+
if(r != ARCHIVE_OK)
|
|
2244
|
+
return r;
|
|
2245
|
+
|
|
2246
|
+
return ARCHIVE_OK;
|
|
2247
|
+
}
|
|
2248
|
+
|
|
2249
|
+
#endif
|
|
2250
|
+
|
|
2251
|
+
#if HAVE_ZSTD_H && HAVE_LIBZSTD
|
|
2252
|
+
static int
|
|
2253
|
+
zipx_zstd_init(struct archive_read *a, struct zip *zip)
|
|
2254
|
+
{
|
|
2255
|
+
size_t r;
|
|
2256
|
+
|
|
2257
|
+
/* Deallocate already existing Zstd decompression context if it
|
|
2258
|
+
* exists. */
|
|
2259
|
+
if(zip->zstdstream_valid) {
|
|
2260
|
+
ZSTD_freeDStream(zip->zstdstream);
|
|
2261
|
+
zip->zstdstream_valid = 0;
|
|
2262
|
+
}
|
|
2263
|
+
|
|
2264
|
+
/* Allocate a new Zstd decompression context. */
|
|
2265
|
+
zip->zstdstream = ZSTD_createDStream();
|
|
2266
|
+
|
|
2267
|
+
r = ZSTD_initDStream(zip->zstdstream);
|
|
2268
|
+
if (ZSTD_isError(r)) {
|
|
2269
|
+
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
|
2270
|
+
"Error initializing zstd decompressor: %s",
|
|
2271
|
+
ZSTD_getErrorName(r));
|
|
2272
|
+
|
|
2273
|
+
return ARCHIVE_FAILED;
|
|
2274
|
+
}
|
|
2275
|
+
|
|
2276
|
+
/* Mark the zstdstream field to be released in cleanup phase. */
|
|
2277
|
+
zip->zstdstream_valid = 1;
|
|
2278
|
+
|
|
2279
|
+
/* (Re)allocate the buffer that will contain decompressed bytes. */
|
|
2280
|
+
free(zip->uncompressed_buffer);
|
|
2281
|
+
|
|
2282
|
+
zip->uncompressed_buffer_size = ZSTD_DStreamOutSize();
|
|
2283
|
+
zip->uncompressed_buffer =
|
|
2284
|
+
(uint8_t*) malloc(zip->uncompressed_buffer_size);
|
|
2285
|
+
if (zip->uncompressed_buffer == NULL) {
|
|
2286
|
+
archive_set_error(&a->archive, ENOMEM,
|
|
2287
|
+
"No memory for Zstd decompression");
|
|
2288
|
+
|
|
2289
|
+
return ARCHIVE_FATAL;
|
|
2290
|
+
}
|
|
2291
|
+
|
|
2292
|
+
/* Initialization done. */
|
|
2293
|
+
zip->decompress_init = 1;
|
|
2294
|
+
return ARCHIVE_OK;
|
|
2295
|
+
}
|
|
2296
|
+
|
|
2297
|
+
static int
|
|
2298
|
+
zip_read_data_zipx_zstd(struct archive_read *a, const void **buff,
|
|
2299
|
+
size_t *size, int64_t *offset)
|
|
2300
|
+
{
|
|
2301
|
+
struct zip *zip = (struct zip *)(a->format->data);
|
|
2302
|
+
ssize_t bytes_avail = 0, in_bytes, to_consume;
|
|
2303
|
+
const void *compressed_buff;
|
|
2304
|
+
int r;
|
|
2305
|
+
size_t ret;
|
|
2306
|
+
uint64_t total_out;
|
|
2307
|
+
ZSTD_outBuffer out;
|
|
2308
|
+
ZSTD_inBuffer in;
|
|
2309
|
+
|
|
2310
|
+
(void) offset; /* UNUSED */
|
|
2311
|
+
|
|
2312
|
+
/* Initialize decompression context if we're here for the first time. */
|
|
2313
|
+
if(!zip->decompress_init) {
|
|
2314
|
+
r = zipx_zstd_init(a, zip);
|
|
2315
|
+
if(r != ARCHIVE_OK)
|
|
2316
|
+
return r;
|
|
2317
|
+
}
|
|
2318
|
+
|
|
2319
|
+
/* Fetch more compressed bytes */
|
|
2320
|
+
compressed_buff = __archive_read_ahead(a, 1, &bytes_avail);
|
|
2321
|
+
if(bytes_avail < 0) {
|
|
2322
|
+
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
|
2323
|
+
"Truncated zstd file body");
|
|
2324
|
+
return (ARCHIVE_FATAL);
|
|
2325
|
+
}
|
|
2326
|
+
|
|
2327
|
+
in_bytes = zipmin(zip->entry_bytes_remaining, bytes_avail);
|
|
2328
|
+
if(in_bytes < 1) {
|
|
2329
|
+
/* zstd doesn't complain when caller feeds avail_in == 0.
|
|
2330
|
+
* It will actually return success in this case, which is
|
|
2331
|
+
* undesirable. This is why we need to make this check
|
|
2332
|
+
* manually. */
|
|
2333
|
+
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
|
2334
|
+
"Truncated zstd file body");
|
|
2335
|
+
return (ARCHIVE_FATAL);
|
|
2336
|
+
}
|
|
2337
|
+
|
|
2338
|
+
/* Setup buffer boundaries */
|
|
2339
|
+
in.src = compressed_buff;
|
|
2340
|
+
in.size = in_bytes;
|
|
2341
|
+
in.pos = 0;
|
|
2342
|
+
out = (ZSTD_outBuffer) { zip->uncompressed_buffer, zip->uncompressed_buffer_size, 0 };
|
|
2343
|
+
|
|
2344
|
+
/* Perform the decompression. */
|
|
2345
|
+
ret = ZSTD_decompressStream(zip->zstdstream, &out, &in);
|
|
2346
|
+
if (ZSTD_isError(ret)) {
|
|
2347
|
+
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
|
2348
|
+
"Error during zstd decompression: %s",
|
|
2349
|
+
ZSTD_getErrorName(ret));
|
|
2350
|
+
return (ARCHIVE_FATAL);
|
|
2351
|
+
}
|
|
2352
|
+
|
|
2353
|
+
/* Check end of the stream. */
|
|
2354
|
+
if (ret == 0) {
|
|
2355
|
+
if ((in.pos == in.size) && (out.pos < out.size)) {
|
|
2356
|
+
zip->end_of_entry = 1;
|
|
2357
|
+
ZSTD_freeDStream(zip->zstdstream);
|
|
2358
|
+
zip->zstdstream_valid = 0;
|
|
2359
|
+
}
|
|
2360
|
+
}
|
|
2361
|
+
|
|
2362
|
+
/* Update the pointers so decompressor can continue decoding. */
|
|
2363
|
+
to_consume = in.pos;
|
|
2364
|
+
__archive_read_consume(a, to_consume);
|
|
2365
|
+
|
|
2366
|
+
total_out = out.pos;
|
|
2367
|
+
|
|
2368
|
+
zip->entry_bytes_remaining -= to_consume;
|
|
2369
|
+
zip->entry_compressed_bytes_read += to_consume;
|
|
2370
|
+
zip->entry_uncompressed_bytes_read += total_out;
|
|
2371
|
+
|
|
2372
|
+
/* Give libarchive its due. */
|
|
2373
|
+
*size = total_out;
|
|
2374
|
+
*buff = zip->uncompressed_buffer;
|
|
2375
|
+
|
|
2376
|
+
/* Seek for optional marker, like in other entries. */
|
|
2377
|
+
r = consume_optional_marker(a, zip);
|
|
2378
|
+
if(r != ARCHIVE_OK)
|
|
2379
|
+
return r;
|
|
2380
|
+
|
|
2381
|
+
return ARCHIVE_OK;
|
|
2382
|
+
}
|
|
2383
|
+
#endif
|
|
2384
|
+
|
|
2385
|
+
#ifdef HAVE_ZLIB_H
|
|
2386
|
+
static int
|
|
2387
|
+
zip_deflate_init(struct archive_read *a, struct zip *zip)
|
|
2388
|
+
{
|
|
2389
|
+
int r;
|
|
2390
|
+
|
|
2391
|
+
/* If we haven't yet read any data, initialize the decompressor. */
|
|
2392
|
+
if (!zip->decompress_init) {
|
|
2393
|
+
if (zip->stream_valid)
|
|
2394
|
+
r = inflateReset(&zip->stream);
|
|
2395
|
+
else
|
|
2396
|
+
r = inflateInit2(&zip->stream,
|
|
2397
|
+
-15 /* Don't check for zlib header */);
|
|
2398
|
+
if (r != Z_OK) {
|
|
2399
|
+
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
|
2400
|
+
"Can't initialize ZIP decompression.");
|
|
2401
|
+
return (ARCHIVE_FATAL);
|
|
2402
|
+
}
|
|
2403
|
+
/* Stream structure has been set up. */
|
|
2404
|
+
zip->stream_valid = 1;
|
|
2405
|
+
/* We've initialized decompression for this stream. */
|
|
2406
|
+
zip->decompress_init = 1;
|
|
2407
|
+
}
|
|
2408
|
+
return (ARCHIVE_OK);
|
|
2409
|
+
}
|
|
2410
|
+
|
|
2411
|
+
static int
|
|
2412
|
+
zip_read_data_deflate(struct archive_read *a, const void **buff,
|
|
2413
|
+
size_t *size, int64_t *offset)
|
|
2414
|
+
{
|
|
2415
|
+
struct zip *zip;
|
|
2416
|
+
ssize_t bytes_avail;
|
|
2417
|
+
const void *compressed_buff, *sp;
|
|
2418
|
+
int r;
|
|
2419
|
+
|
|
2420
|
+
(void)offset; /* UNUSED */
|
|
2421
|
+
|
|
2422
|
+
zip = (struct zip *)(a->format->data);
|
|
2423
|
+
|
|
2424
|
+
/* If the buffer hasn't been allocated, allocate it now. */
|
|
2425
|
+
if (zip->uncompressed_buffer == NULL) {
|
|
2426
|
+
zip->uncompressed_buffer_size = 256 * 1024;
|
|
2427
|
+
zip->uncompressed_buffer
|
|
2428
|
+
= (unsigned char *)malloc(zip->uncompressed_buffer_size);
|
|
2429
|
+
if (zip->uncompressed_buffer == NULL) {
|
|
2430
|
+
archive_set_error(&a->archive, ENOMEM,
|
|
2431
|
+
"No memory for ZIP decompression");
|
|
2432
|
+
return (ARCHIVE_FATAL);
|
|
2433
|
+
}
|
|
2434
|
+
}
|
|
2435
|
+
|
|
2436
|
+
r = zip_deflate_init(a, zip);
|
|
2437
|
+
if (r != ARCHIVE_OK)
|
|
2438
|
+
return (r);
|
|
2439
|
+
|
|
2440
|
+
/*
|
|
2441
|
+
* Note: '1' here is a performance optimization.
|
|
2442
|
+
* Recall that the decompression layer returns a count of
|
|
2443
|
+
* available bytes; asking for more than that forces the
|
|
2444
|
+
* decompressor to combine reads by copying data.
|
|
2445
|
+
*/
|
|
2446
|
+
compressed_buff = sp = __archive_read_ahead(a, 1, &bytes_avail);
|
|
2447
|
+
if (0 == (zip->entry->zip_flags & ZIP_LENGTH_AT_END)
|
|
2448
|
+
&& bytes_avail > zip->entry_bytes_remaining) {
|
|
2449
|
+
bytes_avail = (ssize_t)zip->entry_bytes_remaining;
|
|
2450
|
+
}
|
|
2451
|
+
if (bytes_avail < 0) {
|
|
2452
|
+
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
|
2453
|
+
"Truncated ZIP file body");
|
|
2454
|
+
return (ARCHIVE_FATAL);
|
|
2455
|
+
}
|
|
2456
|
+
|
|
2457
|
+
if (zip->tctx_valid || zip->cctx_valid) {
|
|
2458
|
+
if (zip->decrypted_bytes_remaining < (size_t)bytes_avail) {
|
|
2459
|
+
size_t buff_remaining =
|
|
2460
|
+
(zip->decrypted_buffer +
|
|
2461
|
+
zip->decrypted_buffer_size)
|
|
2462
|
+
- (zip->decrypted_ptr +
|
|
2463
|
+
zip->decrypted_bytes_remaining);
|
|
2464
|
+
|
|
2465
|
+
if (buff_remaining > (size_t)bytes_avail)
|
|
2466
|
+
buff_remaining = (size_t)bytes_avail;
|
|
2467
|
+
|
|
2468
|
+
if (0 == (zip->entry->zip_flags & ZIP_LENGTH_AT_END) &&
|
|
2469
|
+
zip->entry_bytes_remaining > 0) {
|
|
2470
|
+
if ((int64_t)(zip->decrypted_bytes_remaining
|
|
2471
|
+
+ buff_remaining)
|
|
2472
|
+
> zip->entry_bytes_remaining) {
|
|
2473
|
+
if (zip->entry_bytes_remaining <
|
|
2474
|
+
(int64_t)zip->decrypted_bytes_remaining)
|
|
2475
|
+
buff_remaining = 0;
|
|
2476
|
+
else
|
|
2477
|
+
buff_remaining =
|
|
2478
|
+
(size_t)zip->entry_bytes_remaining
|
|
2479
|
+
- zip->decrypted_bytes_remaining;
|
|
2480
|
+
}
|
|
2481
|
+
}
|
|
2482
|
+
if (buff_remaining > 0) {
|
|
2483
|
+
if (zip->tctx_valid) {
|
|
2484
|
+
trad_enc_decrypt_update(&zip->tctx,
|
|
2485
|
+
compressed_buff, buff_remaining,
|
|
2486
|
+
zip->decrypted_ptr
|
|
2487
|
+
+ zip->decrypted_bytes_remaining,
|
|
2488
|
+
buff_remaining);
|
|
2489
|
+
} else {
|
|
2490
|
+
size_t dsize = buff_remaining;
|
|
2491
|
+
archive_decrypto_aes_ctr_update(
|
|
2492
|
+
&zip->cctx,
|
|
2493
|
+
compressed_buff, buff_remaining,
|
|
2494
|
+
zip->decrypted_ptr
|
|
2495
|
+
+ zip->decrypted_bytes_remaining,
|
|
2496
|
+
&dsize);
|
|
2497
|
+
}
|
|
2498
|
+
zip->decrypted_bytes_remaining +=
|
|
2499
|
+
buff_remaining;
|
|
2500
|
+
}
|
|
2501
|
+
}
|
|
2502
|
+
bytes_avail = zip->decrypted_bytes_remaining;
|
|
2503
|
+
compressed_buff = (const char *)zip->decrypted_ptr;
|
|
2504
|
+
}
|
|
2505
|
+
|
|
2506
|
+
/*
|
|
2507
|
+
* A bug in zlib.h: stream.next_in should be marked 'const'
|
|
2508
|
+
* but isn't (the library never alters data through the
|
|
2509
|
+
* next_in pointer, only reads it). The result: this ugly
|
|
2510
|
+
* cast to remove 'const'.
|
|
2511
|
+
*/
|
|
2512
|
+
zip->stream.next_in = (Bytef *)(uintptr_t)(const void *)compressed_buff;
|
|
2513
|
+
zip->stream.avail_in = (uInt)bytes_avail;
|
|
2514
|
+
zip->stream.total_in = 0;
|
|
2515
|
+
zip->stream.next_out = zip->uncompressed_buffer;
|
|
2516
|
+
zip->stream.avail_out = (uInt)zip->uncompressed_buffer_size;
|
|
2517
|
+
zip->stream.total_out = 0;
|
|
2518
|
+
|
|
2519
|
+
r = inflate(&zip->stream, 0);
|
|
2520
|
+
switch (r) {
|
|
2521
|
+
case Z_OK:
|
|
2522
|
+
break;
|
|
2523
|
+
case Z_STREAM_END:
|
|
2524
|
+
zip->end_of_entry = 1;
|
|
2525
|
+
break;
|
|
2526
|
+
case Z_MEM_ERROR:
|
|
2527
|
+
archive_set_error(&a->archive, ENOMEM,
|
|
2528
|
+
"Out of memory for ZIP decompression");
|
|
2529
|
+
return (ARCHIVE_FATAL);
|
|
2530
|
+
default:
|
|
2531
|
+
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
|
2532
|
+
"ZIP decompression failed (%d)", r);
|
|
2533
|
+
return (ARCHIVE_FATAL);
|
|
2534
|
+
}
|
|
2535
|
+
|
|
2536
|
+
/* Consume as much as the compressor actually used. */
|
|
2537
|
+
bytes_avail = zip->stream.total_in;
|
|
2538
|
+
if (zip->tctx_valid || zip->cctx_valid) {
|
|
2539
|
+
zip->decrypted_bytes_remaining -= bytes_avail;
|
|
2540
|
+
if (zip->decrypted_bytes_remaining == 0)
|
|
2541
|
+
zip->decrypted_ptr = zip->decrypted_buffer;
|
|
2542
|
+
else
|
|
2543
|
+
zip->decrypted_ptr += bytes_avail;
|
|
2544
|
+
}
|
|
2545
|
+
/* Calculate compressed data as much as we used.*/
|
|
2546
|
+
if (zip->hctx_valid)
|
|
2547
|
+
archive_hmac_sha1_update(&zip->hctx, sp, bytes_avail);
|
|
2548
|
+
__archive_read_consume(a, bytes_avail);
|
|
2549
|
+
zip->entry_bytes_remaining -= bytes_avail;
|
|
2550
|
+
zip->entry_compressed_bytes_read += bytes_avail;
|
|
2551
|
+
|
|
2552
|
+
*size = zip->stream.total_out;
|
|
2553
|
+
zip->entry_uncompressed_bytes_read += zip->stream.total_out;
|
|
2554
|
+
*buff = zip->uncompressed_buffer;
|
|
2555
|
+
|
|
2556
|
+
if (zip->end_of_entry && zip->hctx_valid) {
|
|
2557
|
+
r = check_authentication_code(a, NULL);
|
|
2558
|
+
if (r != ARCHIVE_OK)
|
|
2559
|
+
return (r);
|
|
2560
|
+
}
|
|
2561
|
+
|
|
2562
|
+
r = consume_optional_marker(a, zip);
|
|
2563
|
+
if (r != ARCHIVE_OK)
|
|
2564
|
+
return (r);
|
|
2565
|
+
|
|
2566
|
+
return (ARCHIVE_OK);
|
|
2567
|
+
}
|
|
2568
|
+
#endif
|
|
2569
|
+
|
|
2570
|
+
static int
|
|
2571
|
+
read_decryption_header(struct archive_read *a)
|
|
2572
|
+
{
|
|
2573
|
+
struct zip *zip = (struct zip *)(a->format->data);
|
|
2574
|
+
const char *p;
|
|
2575
|
+
unsigned int remaining_size;
|
|
2576
|
+
unsigned int ts;
|
|
2577
|
+
|
|
2578
|
+
/*
|
|
2579
|
+
* Read an initialization vector data field.
|
|
2580
|
+
*/
|
|
2581
|
+
p = __archive_read_ahead(a, 2, NULL);
|
|
2582
|
+
if (p == NULL)
|
|
2583
|
+
goto truncated;
|
|
2584
|
+
ts = zip->iv_size;
|
|
2585
|
+
zip->iv_size = archive_le16dec(p);
|
|
2586
|
+
__archive_read_consume(a, 2);
|
|
2587
|
+
if (ts < zip->iv_size) {
|
|
2588
|
+
free(zip->iv);
|
|
2589
|
+
zip->iv = NULL;
|
|
2590
|
+
}
|
|
2591
|
+
p = __archive_read_ahead(a, zip->iv_size, NULL);
|
|
2592
|
+
if (p == NULL)
|
|
2593
|
+
goto truncated;
|
|
2594
|
+
if (zip->iv == NULL) {
|
|
2595
|
+
zip->iv = malloc(zip->iv_size);
|
|
2596
|
+
if (zip->iv == NULL)
|
|
2597
|
+
goto nomem;
|
|
2598
|
+
}
|
|
2599
|
+
memcpy(zip->iv, p, zip->iv_size);
|
|
2600
|
+
__archive_read_consume(a, zip->iv_size);
|
|
2601
|
+
|
|
2602
|
+
/*
|
|
2603
|
+
* Read a size of remaining decryption header field.
|
|
2604
|
+
*/
|
|
2605
|
+
p = __archive_read_ahead(a, 14, NULL);
|
|
2606
|
+
if (p == NULL)
|
|
2607
|
+
goto truncated;
|
|
2608
|
+
remaining_size = archive_le32dec(p);
|
|
2609
|
+
if (remaining_size < 16 || remaining_size > (1 << 18))
|
|
2610
|
+
goto corrupted;
|
|
2611
|
+
|
|
2612
|
+
/* Check if format version is supported. */
|
|
2613
|
+
if (archive_le16dec(p+4) != 3) {
|
|
2614
|
+
archive_set_error(&a->archive,
|
|
2615
|
+
ARCHIVE_ERRNO_FILE_FORMAT,
|
|
2616
|
+
"Unsupported encryption format version: %u",
|
|
2617
|
+
archive_le16dec(p+4));
|
|
2618
|
+
return (ARCHIVE_FAILED);
|
|
2619
|
+
}
|
|
2620
|
+
|
|
2621
|
+
/*
|
|
2622
|
+
* Read an encryption algorithm field.
|
|
2623
|
+
*/
|
|
2624
|
+
zip->alg_id = archive_le16dec(p+6);
|
|
2625
|
+
switch (zip->alg_id) {
|
|
2626
|
+
case 0x6601:/* DES */
|
|
2627
|
+
case 0x6602:/* RC2 */
|
|
2628
|
+
case 0x6603:/* 3DES 168 */
|
|
2629
|
+
case 0x6609:/* 3DES 112 */
|
|
2630
|
+
case 0x660E:/* AES 128 */
|
|
2631
|
+
case 0x660F:/* AES 192 */
|
|
2632
|
+
case 0x6610:/* AES 256 */
|
|
2633
|
+
case 0x6702:/* RC2 (version >= 5.2) */
|
|
2634
|
+
case 0x6720:/* Blowfish */
|
|
2635
|
+
case 0x6721:/* Twofish */
|
|
2636
|
+
case 0x6801:/* RC4 */
|
|
2637
|
+
/* Supported encryption algorithm. */
|
|
2638
|
+
break;
|
|
2639
|
+
default:
|
|
2640
|
+
archive_set_error(&a->archive,
|
|
2641
|
+
ARCHIVE_ERRNO_FILE_FORMAT,
|
|
2642
|
+
"Unknown encryption algorithm: %u", zip->alg_id);
|
|
2643
|
+
return (ARCHIVE_FAILED);
|
|
2644
|
+
}
|
|
2645
|
+
|
|
2646
|
+
/*
|
|
2647
|
+
* Read a bit length field.
|
|
2648
|
+
*/
|
|
2649
|
+
zip->bit_len = archive_le16dec(p+8);
|
|
2650
|
+
|
|
2651
|
+
/*
|
|
2652
|
+
* Read a flags field.
|
|
2653
|
+
*/
|
|
2654
|
+
zip->flags = archive_le16dec(p+10);
|
|
2655
|
+
switch (zip->flags & 0xf000) {
|
|
2656
|
+
case 0x0001: /* Password is required to decrypt. */
|
|
2657
|
+
case 0x0002: /* Certificates only. */
|
|
2658
|
+
case 0x0003: /* Password or certificate required to decrypt. */
|
|
2659
|
+
break;
|
|
2660
|
+
default:
|
|
2661
|
+
archive_set_error(&a->archive,
|
|
2662
|
+
ARCHIVE_ERRNO_FILE_FORMAT,
|
|
2663
|
+
"Unknown encryption flag: %u", zip->flags);
|
|
2664
|
+
return (ARCHIVE_FAILED);
|
|
2665
|
+
}
|
|
2666
|
+
if ((zip->flags & 0xf000) == 0 ||
|
|
2667
|
+
(zip->flags & 0xf000) == 0x4000) {
|
|
2668
|
+
archive_set_error(&a->archive,
|
|
2669
|
+
ARCHIVE_ERRNO_FILE_FORMAT,
|
|
2670
|
+
"Unknown encryption flag: %u", zip->flags);
|
|
2671
|
+
return (ARCHIVE_FAILED);
|
|
2672
|
+
}
|
|
2673
|
+
|
|
2674
|
+
/*
|
|
2675
|
+
* Read an encrypted random data field.
|
|
2676
|
+
*/
|
|
2677
|
+
ts = zip->erd_size;
|
|
2678
|
+
zip->erd_size = archive_le16dec(p+12);
|
|
2679
|
+
__archive_read_consume(a, 14);
|
|
2680
|
+
if ((zip->erd_size & 0xf) != 0 ||
|
|
2681
|
+
(zip->erd_size + 16) > remaining_size ||
|
|
2682
|
+
(zip->erd_size + 16) < zip->erd_size)
|
|
2683
|
+
goto corrupted;
|
|
2684
|
+
|
|
2685
|
+
if (ts < zip->erd_size) {
|
|
2686
|
+
free(zip->erd);
|
|
2687
|
+
zip->erd = NULL;
|
|
2688
|
+
}
|
|
2689
|
+
p = __archive_read_ahead(a, zip->erd_size, NULL);
|
|
2690
|
+
if (p == NULL)
|
|
2691
|
+
goto truncated;
|
|
2692
|
+
if (zip->erd == NULL) {
|
|
2693
|
+
zip->erd = malloc(zip->erd_size);
|
|
2694
|
+
if (zip->erd == NULL)
|
|
2695
|
+
goto nomem;
|
|
2696
|
+
}
|
|
2697
|
+
memcpy(zip->erd, p, zip->erd_size);
|
|
2698
|
+
__archive_read_consume(a, zip->erd_size);
|
|
2699
|
+
|
|
2700
|
+
/*
|
|
2701
|
+
* Read a reserved data field.
|
|
2702
|
+
*/
|
|
2703
|
+
p = __archive_read_ahead(a, 4, NULL);
|
|
2704
|
+
if (p == NULL)
|
|
2705
|
+
goto truncated;
|
|
2706
|
+
/* Reserved data size should be zero. */
|
|
2707
|
+
if (archive_le32dec(p) != 0)
|
|
2708
|
+
goto corrupted;
|
|
2709
|
+
__archive_read_consume(a, 4);
|
|
2710
|
+
|
|
2711
|
+
/*
|
|
2712
|
+
* Read a password validation data field.
|
|
2713
|
+
*/
|
|
2714
|
+
p = __archive_read_ahead(a, 2, NULL);
|
|
2715
|
+
if (p == NULL)
|
|
2716
|
+
goto truncated;
|
|
2717
|
+
ts = zip->v_size;
|
|
2718
|
+
zip->v_size = archive_le16dec(p);
|
|
2719
|
+
__archive_read_consume(a, 2);
|
|
2720
|
+
if ((zip->v_size & 0x0f) != 0 ||
|
|
2721
|
+
(zip->erd_size + zip->v_size + 16) > remaining_size ||
|
|
2722
|
+
(zip->erd_size + zip->v_size + 16) < (zip->erd_size + zip->v_size))
|
|
2723
|
+
goto corrupted;
|
|
2724
|
+
if (ts < zip->v_size) {
|
|
2725
|
+
free(zip->v_data);
|
|
2726
|
+
zip->v_data = NULL;
|
|
2727
|
+
}
|
|
2728
|
+
p = __archive_read_ahead(a, zip->v_size, NULL);
|
|
2729
|
+
if (p == NULL)
|
|
2730
|
+
goto truncated;
|
|
2731
|
+
if (zip->v_data == NULL) {
|
|
2732
|
+
zip->v_data = malloc(zip->v_size);
|
|
2733
|
+
if (zip->v_data == NULL)
|
|
2734
|
+
goto nomem;
|
|
2735
|
+
}
|
|
2736
|
+
memcpy(zip->v_data, p, zip->v_size);
|
|
2737
|
+
__archive_read_consume(a, zip->v_size);
|
|
2738
|
+
|
|
2739
|
+
p = __archive_read_ahead(a, 4, NULL);
|
|
2740
|
+
if (p == NULL)
|
|
2741
|
+
goto truncated;
|
|
2742
|
+
zip->v_crc32 = archive_le32dec(p);
|
|
2743
|
+
__archive_read_consume(a, 4);
|
|
2744
|
+
|
|
2745
|
+
/*return (ARCHIVE_OK);
|
|
2746
|
+
* This is not fully implemented yet.*/
|
|
2747
|
+
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
|
2748
|
+
"Encrypted file is unsupported");
|
|
2749
|
+
return (ARCHIVE_FAILED);
|
|
2750
|
+
truncated:
|
|
2751
|
+
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
|
2752
|
+
"Truncated ZIP file data");
|
|
2753
|
+
return (ARCHIVE_FATAL);
|
|
2754
|
+
corrupted:
|
|
2755
|
+
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
|
2756
|
+
"Corrupted ZIP file data");
|
|
2757
|
+
return (ARCHIVE_FATAL);
|
|
2758
|
+
nomem:
|
|
2759
|
+
archive_set_error(&a->archive, ENOMEM,
|
|
2760
|
+
"No memory for ZIP decryption");
|
|
2761
|
+
return (ARCHIVE_FATAL);
|
|
2762
|
+
}
|
|
2763
|
+
|
|
2764
|
+
static int
|
|
2765
|
+
zip_alloc_decryption_buffer(struct archive_read *a)
|
|
2766
|
+
{
|
|
2767
|
+
struct zip *zip = (struct zip *)(a->format->data);
|
|
2768
|
+
size_t bs = 256 * 1024;
|
|
2769
|
+
|
|
2770
|
+
if (zip->decrypted_buffer == NULL) {
|
|
2771
|
+
zip->decrypted_buffer_size = bs;
|
|
2772
|
+
zip->decrypted_buffer = malloc(bs);
|
|
2773
|
+
if (zip->decrypted_buffer == NULL) {
|
|
2774
|
+
archive_set_error(&a->archive, ENOMEM,
|
|
2775
|
+
"No memory for ZIP decryption");
|
|
2776
|
+
return (ARCHIVE_FATAL);
|
|
2777
|
+
}
|
|
2778
|
+
}
|
|
2779
|
+
zip->decrypted_ptr = zip->decrypted_buffer;
|
|
2780
|
+
return (ARCHIVE_OK);
|
|
2781
|
+
}
|
|
2782
|
+
|
|
2783
|
+
static int
|
|
2784
|
+
init_traditional_PKWARE_decryption(struct archive_read *a)
|
|
2785
|
+
{
|
|
2786
|
+
struct zip *zip = (struct zip *)(a->format->data);
|
|
2787
|
+
const void *p;
|
|
2788
|
+
int retry;
|
|
2789
|
+
int r;
|
|
2790
|
+
|
|
2791
|
+
if (zip->tctx_valid)
|
|
2792
|
+
return (ARCHIVE_OK);
|
|
2793
|
+
|
|
2794
|
+
/*
|
|
2795
|
+
Read the 12 bytes encryption header stored at
|
|
2796
|
+
the start of the data area.
|
|
2797
|
+
*/
|
|
2798
|
+
#define ENC_HEADER_SIZE 12
|
|
2799
|
+
if (0 == (zip->entry->zip_flags & ZIP_LENGTH_AT_END)
|
|
2800
|
+
&& zip->entry_bytes_remaining < ENC_HEADER_SIZE) {
|
|
2801
|
+
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
|
2802
|
+
"Truncated Zip encrypted body: only %jd bytes available",
|
|
2803
|
+
(intmax_t)zip->entry_bytes_remaining);
|
|
2804
|
+
return (ARCHIVE_FATAL);
|
|
2805
|
+
}
|
|
2806
|
+
|
|
2807
|
+
p = __archive_read_ahead(a, ENC_HEADER_SIZE, NULL);
|
|
2808
|
+
if (p == NULL) {
|
|
2809
|
+
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
|
2810
|
+
"Truncated ZIP file data");
|
|
2811
|
+
return (ARCHIVE_FATAL);
|
|
2812
|
+
}
|
|
2813
|
+
|
|
2814
|
+
for (retry = 0;; retry++) {
|
|
2815
|
+
const char *passphrase;
|
|
2816
|
+
uint8_t crcchk;
|
|
2817
|
+
|
|
2818
|
+
passphrase = __archive_read_next_passphrase(a);
|
|
2819
|
+
if (passphrase == NULL) {
|
|
2820
|
+
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
|
2821
|
+
(retry > 0)?
|
|
2822
|
+
"Incorrect passphrase":
|
|
2823
|
+
"Passphrase required for this entry");
|
|
2824
|
+
return (ARCHIVE_FAILED);
|
|
2825
|
+
}
|
|
2826
|
+
|
|
2827
|
+
/*
|
|
2828
|
+
* Initialize ctx for Traditional PKWARE Decryption.
|
|
2829
|
+
*/
|
|
2830
|
+
r = trad_enc_init(&zip->tctx, passphrase, strlen(passphrase),
|
|
2831
|
+
p, ENC_HEADER_SIZE, &crcchk);
|
|
2832
|
+
if (r == 0 && crcchk == zip->entry->decdat)
|
|
2833
|
+
break;/* The passphrase is OK. */
|
|
2834
|
+
if (retry > 10000) {
|
|
2835
|
+
/* Avoid infinity loop. */
|
|
2836
|
+
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
|
2837
|
+
"Too many incorrect passphrases");
|
|
2838
|
+
return (ARCHIVE_FAILED);
|
|
2839
|
+
}
|
|
2840
|
+
}
|
|
2841
|
+
|
|
2842
|
+
__archive_read_consume(a, ENC_HEADER_SIZE);
|
|
2843
|
+
zip->tctx_valid = 1;
|
|
2844
|
+
if (0 == (zip->entry->zip_flags & ZIP_LENGTH_AT_END)) {
|
|
2845
|
+
zip->entry_bytes_remaining -= ENC_HEADER_SIZE;
|
|
2846
|
+
}
|
|
2847
|
+
/*zip->entry_uncompressed_bytes_read += ENC_HEADER_SIZE;*/
|
|
2848
|
+
zip->entry_compressed_bytes_read += ENC_HEADER_SIZE;
|
|
2849
|
+
zip->decrypted_bytes_remaining = 0;
|
|
2850
|
+
|
|
2851
|
+
return (zip_alloc_decryption_buffer(a));
|
|
2852
|
+
#undef ENC_HEADER_SIZE
|
|
2853
|
+
}
|
|
2854
|
+
|
|
2855
|
+
static int
|
|
2856
|
+
init_WinZip_AES_decryption(struct archive_read *a)
|
|
2857
|
+
{
|
|
2858
|
+
struct zip *zip = (struct zip *)(a->format->data);
|
|
2859
|
+
const void *p;
|
|
2860
|
+
const uint8_t *pv;
|
|
2861
|
+
size_t key_len, salt_len;
|
|
2862
|
+
uint8_t derived_key[MAX_DERIVED_KEY_BUF_SIZE];
|
|
2863
|
+
int retry;
|
|
2864
|
+
int r;
|
|
2865
|
+
|
|
2866
|
+
if (zip->cctx_valid || zip->hctx_valid)
|
|
2867
|
+
return (ARCHIVE_OK);
|
|
2868
|
+
|
|
2869
|
+
switch (zip->entry->aes_extra.strength) {
|
|
2870
|
+
case 1: salt_len = 8; key_len = 16; break;
|
|
2871
|
+
case 2: salt_len = 12; key_len = 24; break;
|
|
2872
|
+
case 3: salt_len = 16; key_len = 32; break;
|
|
2873
|
+
default: goto corrupted;
|
|
2874
|
+
}
|
|
2875
|
+
p = __archive_read_ahead(a, salt_len + 2, NULL);
|
|
2876
|
+
if (p == NULL)
|
|
2877
|
+
goto truncated;
|
|
2878
|
+
|
|
2879
|
+
for (retry = 0;; retry++) {
|
|
2880
|
+
const char *passphrase;
|
|
2881
|
+
|
|
2882
|
+
passphrase = __archive_read_next_passphrase(a);
|
|
2883
|
+
if (passphrase == NULL) {
|
|
2884
|
+
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
|
2885
|
+
(retry > 0)?
|
|
2886
|
+
"Incorrect passphrase":
|
|
2887
|
+
"Passphrase required for this entry");
|
|
2888
|
+
return (ARCHIVE_FAILED);
|
|
2889
|
+
}
|
|
2890
|
+
memset(derived_key, 0, sizeof(derived_key));
|
|
2891
|
+
r = archive_pbkdf2_sha1(passphrase, strlen(passphrase),
|
|
2892
|
+
p, salt_len, 1000, derived_key, key_len * 2 + 2);
|
|
2893
|
+
if (r != 0) {
|
|
2894
|
+
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
|
2895
|
+
"Decryption is unsupported due to lack of "
|
|
2896
|
+
"crypto library");
|
|
2897
|
+
return (ARCHIVE_FAILED);
|
|
2898
|
+
}
|
|
2899
|
+
|
|
2900
|
+
/* Check password verification value. */
|
|
2901
|
+
pv = ((const uint8_t *)p) + salt_len;
|
|
2902
|
+
if (derived_key[key_len * 2] == pv[0] &&
|
|
2903
|
+
derived_key[key_len * 2 + 1] == pv[1])
|
|
2904
|
+
break;/* The passphrase is OK. */
|
|
2905
|
+
if (retry > 10000) {
|
|
2906
|
+
/* Avoid infinity loop. */
|
|
2907
|
+
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
|
2908
|
+
"Too many incorrect passphrases");
|
|
2909
|
+
return (ARCHIVE_FAILED);
|
|
2910
|
+
}
|
|
2911
|
+
}
|
|
2912
|
+
|
|
2913
|
+
r = archive_decrypto_aes_ctr_init(&zip->cctx, derived_key, key_len);
|
|
2914
|
+
if (r != 0) {
|
|
2915
|
+
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
|
2916
|
+
"Decryption is unsupported due to lack of crypto library");
|
|
2917
|
+
return (ARCHIVE_FAILED);
|
|
2918
|
+
}
|
|
2919
|
+
r = archive_hmac_sha1_init(&zip->hctx, derived_key + key_len, key_len);
|
|
2920
|
+
if (r != 0) {
|
|
2921
|
+
archive_decrypto_aes_ctr_release(&zip->cctx);
|
|
2922
|
+
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
|
2923
|
+
"Failed to initialize HMAC-SHA1");
|
|
2924
|
+
return (ARCHIVE_FAILED);
|
|
2925
|
+
}
|
|
2926
|
+
zip->cctx_valid = zip->hctx_valid = 1;
|
|
2927
|
+
__archive_read_consume(a, salt_len + 2);
|
|
2928
|
+
zip->entry_bytes_remaining -= salt_len + 2 + AUTH_CODE_SIZE;
|
|
2929
|
+
if (0 == (zip->entry->zip_flags & ZIP_LENGTH_AT_END)
|
|
2930
|
+
&& zip->entry_bytes_remaining < 0)
|
|
2931
|
+
goto corrupted;
|
|
2932
|
+
zip->entry_compressed_bytes_read += salt_len + 2 + AUTH_CODE_SIZE;
|
|
2933
|
+
zip->decrypted_bytes_remaining = 0;
|
|
2934
|
+
|
|
2935
|
+
zip->entry->compression = zip->entry->aes_extra.compression;
|
|
2936
|
+
return (zip_alloc_decryption_buffer(a));
|
|
2937
|
+
|
|
2938
|
+
truncated:
|
|
2939
|
+
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
|
2940
|
+
"Truncated ZIP file data");
|
|
2941
|
+
return (ARCHIVE_FATAL);
|
|
2942
|
+
corrupted:
|
|
2943
|
+
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
|
2944
|
+
"Corrupted ZIP file data");
|
|
2945
|
+
return (ARCHIVE_FATAL);
|
|
2946
|
+
}
|
|
2947
|
+
|
|
2948
|
+
static int
|
|
2949
|
+
archive_read_format_zip_read_data(struct archive_read *a,
|
|
2950
|
+
const void **buff, size_t *size, int64_t *offset)
|
|
2951
|
+
{
|
|
2952
|
+
int r;
|
|
2953
|
+
struct zip *zip = (struct zip *)(a->format->data);
|
|
2954
|
+
|
|
2955
|
+
if (zip->has_encrypted_entries ==
|
|
2956
|
+
ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW) {
|
|
2957
|
+
zip->has_encrypted_entries = 0;
|
|
2958
|
+
}
|
|
2959
|
+
|
|
2960
|
+
*offset = zip->entry_uncompressed_bytes_read;
|
|
2961
|
+
*size = 0;
|
|
2962
|
+
*buff = NULL;
|
|
2963
|
+
|
|
2964
|
+
/* If we hit end-of-entry last time, return ARCHIVE_EOF. */
|
|
2965
|
+
if (zip->end_of_entry)
|
|
2966
|
+
return (ARCHIVE_EOF);
|
|
2967
|
+
|
|
2968
|
+
/* Return EOF immediately if this is a non-regular file. */
|
|
2969
|
+
if (AE_IFREG != (zip->entry->mode & AE_IFMT))
|
|
2970
|
+
return (ARCHIVE_EOF);
|
|
2971
|
+
|
|
2972
|
+
__archive_read_consume(a, zip->unconsumed);
|
|
2973
|
+
zip->unconsumed = 0;
|
|
2974
|
+
|
|
2975
|
+
if (zip->init_decryption) {
|
|
2976
|
+
zip->has_encrypted_entries = 1;
|
|
2977
|
+
if (zip->entry->zip_flags & ZIP_STRONG_ENCRYPTED)
|
|
2978
|
+
r = read_decryption_header(a);
|
|
2979
|
+
else if (zip->entry->compression == WINZIP_AES_ENCRYPTION)
|
|
2980
|
+
r = init_WinZip_AES_decryption(a);
|
|
2981
|
+
else
|
|
2982
|
+
r = init_traditional_PKWARE_decryption(a);
|
|
2983
|
+
if (r != ARCHIVE_OK)
|
|
2984
|
+
return (r);
|
|
2985
|
+
zip->init_decryption = 0;
|
|
2986
|
+
}
|
|
2987
|
+
|
|
2988
|
+
switch(zip->entry->compression) {
|
|
2989
|
+
case 0: /* No compression. */
|
|
2990
|
+
r = zip_read_data_none(a, buff, size, offset);
|
|
2991
|
+
break;
|
|
2992
|
+
#ifdef HAVE_BZLIB_H
|
|
2993
|
+
case 12: /* ZIPx bzip2 compression. */
|
|
2994
|
+
r = zip_read_data_zipx_bzip2(a, buff, size, offset);
|
|
2995
|
+
break;
|
|
2996
|
+
#endif
|
|
2997
|
+
#if HAVE_LZMA_H && HAVE_LIBLZMA
|
|
2998
|
+
case 14: /* ZIPx LZMA compression. */
|
|
2999
|
+
r = zip_read_data_zipx_lzma_alone(a, buff, size, offset);
|
|
3000
|
+
break;
|
|
3001
|
+
case 95: /* ZIPx XZ compression. */
|
|
3002
|
+
r = zip_read_data_zipx_xz(a, buff, size, offset);
|
|
3003
|
+
break;
|
|
3004
|
+
#endif
|
|
3005
|
+
#if HAVE_ZSTD_H && HAVE_LIBZSTD
|
|
3006
|
+
case 93: /* ZIPx Zstd compression. */
|
|
3007
|
+
r = zip_read_data_zipx_zstd(a, buff, size, offset);
|
|
3008
|
+
break;
|
|
3009
|
+
#endif
|
|
3010
|
+
/* PPMd support is built-in, so we don't need any #if guards. */
|
|
3011
|
+
case 98: /* ZIPx PPMd compression. */
|
|
3012
|
+
r = zip_read_data_zipx_ppmd(a, buff, size, offset);
|
|
3013
|
+
break;
|
|
3014
|
+
|
|
3015
|
+
#ifdef HAVE_ZLIB_H
|
|
3016
|
+
case 8: /* Deflate compression. */
|
|
3017
|
+
r = zip_read_data_deflate(a, buff, size, offset);
|
|
3018
|
+
break;
|
|
3019
|
+
#endif
|
|
3020
|
+
default: /* Unsupported compression. */
|
|
3021
|
+
/* Return a warning. */
|
|
3022
|
+
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
|
3023
|
+
"Unsupported ZIP compression method (%d: %s)",
|
|
3024
|
+
zip->entry->compression, compression_name(zip->entry->compression));
|
|
3025
|
+
/* We can't decompress this entry, but we will
|
|
3026
|
+
* be able to skip() it and try the next entry. */
|
|
3027
|
+
return (ARCHIVE_FAILED);
|
|
3028
|
+
break;
|
|
3029
|
+
}
|
|
3030
|
+
if (r != ARCHIVE_OK)
|
|
3031
|
+
return (r);
|
|
3032
|
+
/* Update checksum */
|
|
3033
|
+
if (*size)
|
|
3034
|
+
zip->entry_crc32 = zip->crc32func(zip->entry_crc32, *buff,
|
|
3035
|
+
(unsigned)*size);
|
|
3036
|
+
/* If we hit the end, swallow any end-of-data marker. */
|
|
3037
|
+
if (zip->end_of_entry) {
|
|
3038
|
+
/* Check file size, CRC against these values. */
|
|
3039
|
+
if (zip->entry->compressed_size !=
|
|
3040
|
+
zip->entry_compressed_bytes_read) {
|
|
3041
|
+
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
|
3042
|
+
"ZIP compressed data is wrong size "
|
|
3043
|
+
"(read %jd, expected %jd)",
|
|
3044
|
+
(intmax_t)zip->entry_compressed_bytes_read,
|
|
3045
|
+
(intmax_t)zip->entry->compressed_size);
|
|
3046
|
+
return (ARCHIVE_WARN);
|
|
3047
|
+
}
|
|
3048
|
+
/* Size field only stores the lower 32 bits of the actual
|
|
3049
|
+
* size. */
|
|
3050
|
+
if ((zip->entry->uncompressed_size & UINT32_MAX)
|
|
3051
|
+
!= (zip->entry_uncompressed_bytes_read & UINT32_MAX)) {
|
|
3052
|
+
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
|
3053
|
+
"ZIP uncompressed data is wrong size "
|
|
3054
|
+
"(read %jd, expected %jd)\n",
|
|
3055
|
+
(intmax_t)zip->entry_uncompressed_bytes_read,
|
|
3056
|
+
(intmax_t)zip->entry->uncompressed_size);
|
|
3057
|
+
return (ARCHIVE_WARN);
|
|
3058
|
+
}
|
|
3059
|
+
/* Check computed CRC against header */
|
|
3060
|
+
if ((!zip->hctx_valid ||
|
|
3061
|
+
zip->entry->aes_extra.vendor != AES_VENDOR_AE_2) &&
|
|
3062
|
+
zip->entry->crc32 != zip->entry_crc32
|
|
3063
|
+
&& !zip->ignore_crc32) {
|
|
3064
|
+
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
|
3065
|
+
"ZIP bad CRC: 0x%lx should be 0x%lx",
|
|
3066
|
+
(unsigned long)zip->entry_crc32,
|
|
3067
|
+
(unsigned long)zip->entry->crc32);
|
|
3068
|
+
return (ARCHIVE_WARN);
|
|
3069
|
+
}
|
|
3070
|
+
}
|
|
3071
|
+
|
|
3072
|
+
return (ARCHIVE_OK);
|
|
3073
|
+
}
|
|
3074
|
+
|
|
3075
|
+
static int
|
|
3076
|
+
archive_read_format_zip_cleanup(struct archive_read *a)
|
|
3077
|
+
{
|
|
3078
|
+
struct zip *zip;
|
|
3079
|
+
struct zip_entry *zip_entry, *next_zip_entry;
|
|
3080
|
+
|
|
3081
|
+
zip = (struct zip *)(a->format->data);
|
|
3082
|
+
|
|
3083
|
+
#ifdef HAVE_ZLIB_H
|
|
3084
|
+
if (zip->stream_valid)
|
|
3085
|
+
inflateEnd(&zip->stream);
|
|
3086
|
+
#endif
|
|
3087
|
+
|
|
3088
|
+
#if HAVE_LZMA_H && HAVE_LIBLZMA
|
|
3089
|
+
if (zip->zipx_lzma_valid) {
|
|
3090
|
+
lzma_end(&zip->zipx_lzma_stream);
|
|
3091
|
+
}
|
|
3092
|
+
#endif
|
|
3093
|
+
|
|
3094
|
+
#ifdef HAVE_BZLIB_H
|
|
3095
|
+
if (zip->bzstream_valid) {
|
|
3096
|
+
BZ2_bzDecompressEnd(&zip->bzstream);
|
|
3097
|
+
}
|
|
3098
|
+
#endif
|
|
3099
|
+
|
|
3100
|
+
#if HAVE_ZSTD_H && HAVE_LIBZSTD
|
|
3101
|
+
if (zip->zstdstream_valid) {
|
|
3102
|
+
ZSTD_freeDStream(zip->zstdstream);
|
|
3103
|
+
}
|
|
3104
|
+
#endif
|
|
3105
|
+
|
|
3106
|
+
free(zip->uncompressed_buffer);
|
|
3107
|
+
|
|
3108
|
+
if (zip->ppmd8_valid)
|
|
3109
|
+
__archive_ppmd8_functions.Ppmd8_Free(&zip->ppmd8);
|
|
3110
|
+
|
|
3111
|
+
if (zip->zip_entries) {
|
|
3112
|
+
zip_entry = zip->zip_entries;
|
|
3113
|
+
while (zip_entry != NULL) {
|
|
3114
|
+
next_zip_entry = zip_entry->next;
|
|
3115
|
+
archive_string_free(&zip_entry->rsrcname);
|
|
3116
|
+
free(zip_entry);
|
|
3117
|
+
zip_entry = next_zip_entry;
|
|
3118
|
+
}
|
|
3119
|
+
}
|
|
3120
|
+
free(zip->decrypted_buffer);
|
|
3121
|
+
if (zip->cctx_valid)
|
|
3122
|
+
archive_decrypto_aes_ctr_release(&zip->cctx);
|
|
3123
|
+
if (zip->hctx_valid)
|
|
3124
|
+
archive_hmac_sha1_cleanup(&zip->hctx);
|
|
3125
|
+
free(zip->iv);
|
|
3126
|
+
free(zip->erd);
|
|
3127
|
+
free(zip->v_data);
|
|
3128
|
+
archive_string_free(&zip->format_name);
|
|
3129
|
+
free(zip);
|
|
3130
|
+
(a->format->data) = NULL;
|
|
3131
|
+
return (ARCHIVE_OK);
|
|
3132
|
+
}
|
|
3133
|
+
|
|
3134
|
+
static int
|
|
3135
|
+
archive_read_format_zip_has_encrypted_entries(struct archive_read *_a)
|
|
3136
|
+
{
|
|
3137
|
+
if (_a && _a->format) {
|
|
3138
|
+
struct zip * zip = (struct zip *)_a->format->data;
|
|
3139
|
+
if (zip) {
|
|
3140
|
+
return zip->has_encrypted_entries;
|
|
3141
|
+
}
|
|
3142
|
+
}
|
|
3143
|
+
return ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW;
|
|
3144
|
+
}
|
|
3145
|
+
|
|
3146
|
+
static int
|
|
3147
|
+
archive_read_format_zip_options(struct archive_read *a,
|
|
3148
|
+
const char *key, const char *val)
|
|
3149
|
+
{
|
|
3150
|
+
struct zip *zip;
|
|
3151
|
+
int ret = ARCHIVE_FAILED;
|
|
3152
|
+
|
|
3153
|
+
zip = (struct zip *)(a->format->data);
|
|
3154
|
+
if (strcmp(key, "compat-2x") == 0) {
|
|
3155
|
+
/* Handle filenames as libarchive 2.x */
|
|
3156
|
+
zip->init_default_conversion = (val != NULL) ? 1 : 0;
|
|
3157
|
+
return (ARCHIVE_OK);
|
|
3158
|
+
} else if (strcmp(key, "hdrcharset") == 0) {
|
|
3159
|
+
if (val == NULL || val[0] == 0)
|
|
3160
|
+
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
|
3161
|
+
"zip: hdrcharset option needs a character-set name"
|
|
3162
|
+
);
|
|
3163
|
+
else {
|
|
3164
|
+
zip->sconv = archive_string_conversion_from_charset(
|
|
3165
|
+
&a->archive, val, 0);
|
|
3166
|
+
if (zip->sconv != NULL) {
|
|
3167
|
+
if (strcmp(val, "UTF-8") == 0)
|
|
3168
|
+
zip->sconv_utf8 = zip->sconv;
|
|
3169
|
+
ret = ARCHIVE_OK;
|
|
3170
|
+
} else
|
|
3171
|
+
ret = ARCHIVE_FATAL;
|
|
3172
|
+
}
|
|
3173
|
+
return (ret);
|
|
3174
|
+
} else if (strcmp(key, "ignorecrc32") == 0) {
|
|
3175
|
+
/* Mostly useful for testing. */
|
|
3176
|
+
if (val == NULL || val[0] == 0) {
|
|
3177
|
+
zip->crc32func = real_crc32;
|
|
3178
|
+
zip->ignore_crc32 = 0;
|
|
3179
|
+
} else {
|
|
3180
|
+
zip->crc32func = fake_crc32;
|
|
3181
|
+
zip->ignore_crc32 = 1;
|
|
3182
|
+
}
|
|
3183
|
+
return (ARCHIVE_OK);
|
|
3184
|
+
} else if (strcmp(key, "mac-ext") == 0) {
|
|
3185
|
+
zip->process_mac_extensions = (val != NULL && val[0] != 0);
|
|
3186
|
+
return (ARCHIVE_OK);
|
|
3187
|
+
}
|
|
3188
|
+
|
|
3189
|
+
/* Note: The "warn" return is just to inform the options
|
|
3190
|
+
* supervisor that we didn't handle it. It will generate
|
|
3191
|
+
* a suitable error if no one used this option. */
|
|
3192
|
+
return (ARCHIVE_WARN);
|
|
3193
|
+
}
|
|
3194
|
+
|
|
3195
|
+
int
|
|
3196
|
+
archive_read_support_format_zip(struct archive *a)
|
|
3197
|
+
{
|
|
3198
|
+
int r;
|
|
3199
|
+
r = archive_read_support_format_zip_streamable(a);
|
|
3200
|
+
if (r != ARCHIVE_OK)
|
|
3201
|
+
return r;
|
|
3202
|
+
return (archive_read_support_format_zip_seekable(a));
|
|
3203
|
+
}
|
|
3204
|
+
|
|
3205
|
+
/* ------------------------------------------------------------------------ */
|
|
3206
|
+
|
|
3207
|
+
/*
|
|
3208
|
+
* Streaming-mode support
|
|
3209
|
+
*/
|
|
3210
|
+
|
|
3211
|
+
|
|
3212
|
+
static int
|
|
3213
|
+
archive_read_support_format_zip_capabilities_streamable(struct archive_read * a)
|
|
3214
|
+
{
|
|
3215
|
+
(void)a; /* UNUSED */
|
|
3216
|
+
return (ARCHIVE_READ_FORMAT_CAPS_ENCRYPT_DATA |
|
|
3217
|
+
ARCHIVE_READ_FORMAT_CAPS_ENCRYPT_METADATA);
|
|
3218
|
+
}
|
|
3219
|
+
|
|
3220
|
+
static int
|
|
3221
|
+
archive_read_format_zip_streamable_bid(struct archive_read *a, int best_bid)
|
|
3222
|
+
{
|
|
3223
|
+
const char *p;
|
|
3224
|
+
|
|
3225
|
+
(void)best_bid; /* UNUSED */
|
|
3226
|
+
|
|
3227
|
+
if ((p = __archive_read_ahead(a, 4, NULL)) == NULL)
|
|
3228
|
+
return (-1);
|
|
3229
|
+
|
|
3230
|
+
/*
|
|
3231
|
+
* Bid of 29 here comes from:
|
|
3232
|
+
* + 16 bits for "PK",
|
|
3233
|
+
* + next 16-bit field has 6 options so contributes
|
|
3234
|
+
* about 16 - log_2(6) ~= 16 - 2.6 ~= 13 bits
|
|
3235
|
+
*
|
|
3236
|
+
* So we've effectively verified ~29 total bits of check data.
|
|
3237
|
+
*/
|
|
3238
|
+
if (p[0] == 'P' && p[1] == 'K') {
|
|
3239
|
+
if ((p[2] == '\001' && p[3] == '\002')
|
|
3240
|
+
|| (p[2] == '\003' && p[3] == '\004')
|
|
3241
|
+
|| (p[2] == '\005' && p[3] == '\006')
|
|
3242
|
+
|| (p[2] == '\006' && p[3] == '\006')
|
|
3243
|
+
|| (p[2] == '\007' && p[3] == '\010')
|
|
3244
|
+
|| (p[2] == '0' && p[3] == '0'))
|
|
3245
|
+
return (29);
|
|
3246
|
+
}
|
|
3247
|
+
|
|
3248
|
+
/* TODO: It's worth looking ahead a little bit for a valid
|
|
3249
|
+
* PK signature. In particular, that would make it possible
|
|
3250
|
+
* to read some UUEncoded SFX files or SFX files coming from
|
|
3251
|
+
* a network socket. */
|
|
3252
|
+
|
|
3253
|
+
return (0);
|
|
3254
|
+
}
|
|
3255
|
+
|
|
3256
|
+
static int
|
|
3257
|
+
archive_read_format_zip_streamable_read_header(struct archive_read *a,
|
|
3258
|
+
struct archive_entry *entry)
|
|
3259
|
+
{
|
|
3260
|
+
struct zip *zip;
|
|
3261
|
+
|
|
3262
|
+
a->archive.archive_format = ARCHIVE_FORMAT_ZIP;
|
|
3263
|
+
if (a->archive.archive_format_name == NULL)
|
|
3264
|
+
a->archive.archive_format_name = "ZIP";
|
|
3265
|
+
|
|
3266
|
+
zip = (struct zip *)(a->format->data);
|
|
3267
|
+
|
|
3268
|
+
/*
|
|
3269
|
+
* It should be sufficient to call archive_read_next_header() for
|
|
3270
|
+
* a reader to determine if an entry is encrypted or not. If the
|
|
3271
|
+
* encryption of an entry is only detectable when calling
|
|
3272
|
+
* archive_read_data(), so be it. We'll do the same check there
|
|
3273
|
+
* as well.
|
|
3274
|
+
*/
|
|
3275
|
+
if (zip->has_encrypted_entries ==
|
|
3276
|
+
ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW)
|
|
3277
|
+
zip->has_encrypted_entries = 0;
|
|
3278
|
+
|
|
3279
|
+
/* Make sure we have a zip_entry structure to use. */
|
|
3280
|
+
if (zip->zip_entries == NULL) {
|
|
3281
|
+
zip->zip_entries = malloc(sizeof(struct zip_entry));
|
|
3282
|
+
if (zip->zip_entries == NULL) {
|
|
3283
|
+
archive_set_error(&a->archive, ENOMEM,
|
|
3284
|
+
"Out of memory");
|
|
3285
|
+
return ARCHIVE_FATAL;
|
|
3286
|
+
}
|
|
3287
|
+
}
|
|
3288
|
+
zip->entry = zip->zip_entries;
|
|
3289
|
+
memset(zip->entry, 0, sizeof(struct zip_entry));
|
|
3290
|
+
|
|
3291
|
+
if (zip->cctx_valid)
|
|
3292
|
+
archive_decrypto_aes_ctr_release(&zip->cctx);
|
|
3293
|
+
if (zip->hctx_valid)
|
|
3294
|
+
archive_hmac_sha1_cleanup(&zip->hctx);
|
|
3295
|
+
zip->tctx_valid = zip->cctx_valid = zip->hctx_valid = 0;
|
|
3296
|
+
__archive_read_reset_passphrase(a);
|
|
3297
|
+
|
|
3298
|
+
/* Search ahead for the next local file header. */
|
|
3299
|
+
__archive_read_consume(a, zip->unconsumed);
|
|
3300
|
+
zip->unconsumed = 0;
|
|
3301
|
+
for (;;) {
|
|
3302
|
+
int64_t skipped = 0;
|
|
3303
|
+
const char *p, *end;
|
|
3304
|
+
ssize_t bytes;
|
|
3305
|
+
|
|
3306
|
+
p = __archive_read_ahead(a, 4, &bytes);
|
|
3307
|
+
if (p == NULL)
|
|
3308
|
+
return (ARCHIVE_FATAL);
|
|
3309
|
+
end = p + bytes;
|
|
3310
|
+
|
|
3311
|
+
while (p + 4 <= end) {
|
|
3312
|
+
if (p[0] == 'P' && p[1] == 'K') {
|
|
3313
|
+
if (p[2] == '\003' && p[3] == '\004') {
|
|
3314
|
+
/* Regular file entry. */
|
|
3315
|
+
__archive_read_consume(a, skipped);
|
|
3316
|
+
return zip_read_local_file_header(a,
|
|
3317
|
+
entry, zip);
|
|
3318
|
+
}
|
|
3319
|
+
|
|
3320
|
+
/*
|
|
3321
|
+
* TODO: We cannot restore permissions
|
|
3322
|
+
* based only on the local file headers.
|
|
3323
|
+
* Consider scanning the central
|
|
3324
|
+
* directory and returning additional
|
|
3325
|
+
* entries for at least directories.
|
|
3326
|
+
* This would allow us to properly set
|
|
3327
|
+
* directory permissions.
|
|
3328
|
+
*
|
|
3329
|
+
* This won't help us fix symlinks
|
|
3330
|
+
* and may not help with regular file
|
|
3331
|
+
* permissions, either. <sigh>
|
|
3332
|
+
*/
|
|
3333
|
+
if (p[2] == '\001' && p[3] == '\002') {
|
|
3334
|
+
return (ARCHIVE_EOF);
|
|
3335
|
+
}
|
|
3336
|
+
|
|
3337
|
+
/* End of central directory? Must be an
|
|
3338
|
+
* empty archive. */
|
|
3339
|
+
if ((p[2] == '\005' && p[3] == '\006')
|
|
3340
|
+
|| (p[2] == '\006' && p[3] == '\006'))
|
|
3341
|
+
return (ARCHIVE_EOF);
|
|
3342
|
+
}
|
|
3343
|
+
++p;
|
|
3344
|
+
++skipped;
|
|
3345
|
+
}
|
|
3346
|
+
__archive_read_consume(a, skipped);
|
|
3347
|
+
}
|
|
3348
|
+
}
|
|
3349
|
+
|
|
3350
|
+
static int
|
|
3351
|
+
archive_read_format_zip_read_data_skip_streamable(struct archive_read *a)
|
|
3352
|
+
{
|
|
3353
|
+
struct zip *zip;
|
|
3354
|
+
int64_t bytes_skipped;
|
|
3355
|
+
|
|
3356
|
+
zip = (struct zip *)(a->format->data);
|
|
3357
|
+
bytes_skipped = __archive_read_consume(a, zip->unconsumed);
|
|
3358
|
+
zip->unconsumed = 0;
|
|
3359
|
+
if (bytes_skipped < 0)
|
|
3360
|
+
return (ARCHIVE_FATAL);
|
|
3361
|
+
|
|
3362
|
+
/* If we've already read to end of data, we're done. */
|
|
3363
|
+
if (zip->end_of_entry)
|
|
3364
|
+
return (ARCHIVE_OK);
|
|
3365
|
+
|
|
3366
|
+
/* So we know we're streaming... */
|
|
3367
|
+
if (0 == (zip->entry->zip_flags & ZIP_LENGTH_AT_END)
|
|
3368
|
+
|| zip->entry->compressed_size > 0) {
|
|
3369
|
+
/* We know the compressed length, so we can just skip. */
|
|
3370
|
+
bytes_skipped = __archive_read_consume(a,
|
|
3371
|
+
zip->entry_bytes_remaining);
|
|
3372
|
+
if (bytes_skipped < 0)
|
|
3373
|
+
return (ARCHIVE_FATAL);
|
|
3374
|
+
return (ARCHIVE_OK);
|
|
3375
|
+
}
|
|
3376
|
+
|
|
3377
|
+
if (zip->init_decryption) {
|
|
3378
|
+
int r;
|
|
3379
|
+
|
|
3380
|
+
zip->has_encrypted_entries = 1;
|
|
3381
|
+
if (zip->entry->zip_flags & ZIP_STRONG_ENCRYPTED)
|
|
3382
|
+
r = read_decryption_header(a);
|
|
3383
|
+
else if (zip->entry->compression == WINZIP_AES_ENCRYPTION)
|
|
3384
|
+
r = init_WinZip_AES_decryption(a);
|
|
3385
|
+
else
|
|
3386
|
+
r = init_traditional_PKWARE_decryption(a);
|
|
3387
|
+
if (r != ARCHIVE_OK)
|
|
3388
|
+
return (r);
|
|
3389
|
+
zip->init_decryption = 0;
|
|
3390
|
+
}
|
|
3391
|
+
|
|
3392
|
+
/* We're streaming and we don't know the length. */
|
|
3393
|
+
/* If the body is compressed and we know the format, we can
|
|
3394
|
+
* find an exact end-of-entry by decompressing it. */
|
|
3395
|
+
switch (zip->entry->compression) {
|
|
3396
|
+
#ifdef HAVE_ZLIB_H
|
|
3397
|
+
case 8: /* Deflate compression. */
|
|
3398
|
+
while (!zip->end_of_entry) {
|
|
3399
|
+
int64_t offset = 0;
|
|
3400
|
+
const void *buff = NULL;
|
|
3401
|
+
size_t size = 0;
|
|
3402
|
+
int r;
|
|
3403
|
+
r = zip_read_data_deflate(a, &buff, &size, &offset);
|
|
3404
|
+
if (r != ARCHIVE_OK)
|
|
3405
|
+
return (r);
|
|
3406
|
+
}
|
|
3407
|
+
return ARCHIVE_OK;
|
|
3408
|
+
#endif
|
|
3409
|
+
default: /* Uncompressed or unknown. */
|
|
3410
|
+
/* Scan for a PK\007\010 signature. */
|
|
3411
|
+
for (;;) {
|
|
3412
|
+
const char *p, *buff;
|
|
3413
|
+
ssize_t bytes_avail;
|
|
3414
|
+
buff = __archive_read_ahead(a, 16, &bytes_avail);
|
|
3415
|
+
if (bytes_avail < 16) {
|
|
3416
|
+
archive_set_error(&a->archive,
|
|
3417
|
+
ARCHIVE_ERRNO_FILE_FORMAT,
|
|
3418
|
+
"Truncated ZIP file data");
|
|
3419
|
+
return (ARCHIVE_FATAL);
|
|
3420
|
+
}
|
|
3421
|
+
p = buff;
|
|
3422
|
+
while (p <= buff + bytes_avail - 16) {
|
|
3423
|
+
if (p[3] == 'P') { p += 3; }
|
|
3424
|
+
else if (p[3] == 'K') { p += 2; }
|
|
3425
|
+
else if (p[3] == '\007') { p += 1; }
|
|
3426
|
+
else if (p[3] == '\010' && p[2] == '\007'
|
|
3427
|
+
&& p[1] == 'K' && p[0] == 'P') {
|
|
3428
|
+
if (zip->entry->flags & LA_USED_ZIP64)
|
|
3429
|
+
__archive_read_consume(a,
|
|
3430
|
+
p - buff + 24);
|
|
3431
|
+
else
|
|
3432
|
+
__archive_read_consume(a,
|
|
3433
|
+
p - buff + 16);
|
|
3434
|
+
return ARCHIVE_OK;
|
|
3435
|
+
} else { p += 4; }
|
|
3436
|
+
}
|
|
3437
|
+
__archive_read_consume(a, p - buff);
|
|
3438
|
+
}
|
|
3439
|
+
}
|
|
3440
|
+
}
|
|
3441
|
+
|
|
3442
|
+
int
|
|
3443
|
+
archive_read_support_format_zip_streamable(struct archive *_a)
|
|
3444
|
+
{
|
|
3445
|
+
struct archive_read *a = (struct archive_read *)_a;
|
|
3446
|
+
struct zip *zip;
|
|
3447
|
+
int r;
|
|
3448
|
+
|
|
3449
|
+
archive_check_magic(_a, ARCHIVE_READ_MAGIC,
|
|
3450
|
+
ARCHIVE_STATE_NEW, "archive_read_support_format_zip");
|
|
3451
|
+
|
|
3452
|
+
zip = (struct zip *)calloc(1, sizeof(*zip));
|
|
3453
|
+
if (zip == NULL) {
|
|
3454
|
+
archive_set_error(&a->archive, ENOMEM,
|
|
3455
|
+
"Can't allocate zip data");
|
|
3456
|
+
return (ARCHIVE_FATAL);
|
|
3457
|
+
}
|
|
3458
|
+
|
|
3459
|
+
/* Streamable reader doesn't support mac extensions. */
|
|
3460
|
+
zip->process_mac_extensions = 0;
|
|
3461
|
+
|
|
3462
|
+
/*
|
|
3463
|
+
* Until enough data has been read, we cannot tell about
|
|
3464
|
+
* any encrypted entries yet.
|
|
3465
|
+
*/
|
|
3466
|
+
zip->has_encrypted_entries = ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW;
|
|
3467
|
+
zip->crc32func = real_crc32;
|
|
3468
|
+
|
|
3469
|
+
r = __archive_read_register_format(a,
|
|
3470
|
+
zip,
|
|
3471
|
+
"zip",
|
|
3472
|
+
archive_read_format_zip_streamable_bid,
|
|
3473
|
+
archive_read_format_zip_options,
|
|
3474
|
+
archive_read_format_zip_streamable_read_header,
|
|
3475
|
+
archive_read_format_zip_read_data,
|
|
3476
|
+
archive_read_format_zip_read_data_skip_streamable,
|
|
3477
|
+
NULL,
|
|
3478
|
+
archive_read_format_zip_cleanup,
|
|
3479
|
+
archive_read_support_format_zip_capabilities_streamable,
|
|
3480
|
+
archive_read_format_zip_has_encrypted_entries);
|
|
3481
|
+
|
|
3482
|
+
if (r != ARCHIVE_OK)
|
|
3483
|
+
free(zip);
|
|
3484
|
+
return (ARCHIVE_OK);
|
|
3485
|
+
}
|
|
3486
|
+
|
|
3487
|
+
/* ------------------------------------------------------------------------ */
|
|
3488
|
+
|
|
3489
|
+
/*
|
|
3490
|
+
* Seeking-mode support
|
|
3491
|
+
*/
|
|
3492
|
+
|
|
3493
|
+
static int
|
|
3494
|
+
archive_read_support_format_zip_capabilities_seekable(struct archive_read * a)
|
|
3495
|
+
{
|
|
3496
|
+
(void)a; /* UNUSED */
|
|
3497
|
+
return (ARCHIVE_READ_FORMAT_CAPS_ENCRYPT_DATA |
|
|
3498
|
+
ARCHIVE_READ_FORMAT_CAPS_ENCRYPT_METADATA);
|
|
3499
|
+
}
|
|
3500
|
+
|
|
3501
|
+
/*
|
|
3502
|
+
* TODO: This is a performance sink because it forces the read core to
|
|
3503
|
+
* drop buffered data from the start of file, which will then have to
|
|
3504
|
+
* be re-read again if this bidder loses.
|
|
3505
|
+
*
|
|
3506
|
+
* We workaround this a little by passing in the best bid so far so
|
|
3507
|
+
* that later bidders can do nothing if they know they'll never
|
|
3508
|
+
* outbid. But we can certainly do better...
|
|
3509
|
+
*/
|
|
3510
|
+
static int
|
|
3511
|
+
read_eocd(struct zip *zip, const char *p, int64_t current_offset)
|
|
3512
|
+
{
|
|
3513
|
+
uint16_t disk_num;
|
|
3514
|
+
uint32_t cd_size, cd_offset;
|
|
3515
|
+
|
|
3516
|
+
disk_num = archive_le16dec(p + 4);
|
|
3517
|
+
cd_size = archive_le32dec(p + 12);
|
|
3518
|
+
cd_offset = archive_le32dec(p + 16);
|
|
3519
|
+
|
|
3520
|
+
/* Sanity-check the EOCD we've found. */
|
|
3521
|
+
|
|
3522
|
+
/* This must be the first volume. */
|
|
3523
|
+
if (disk_num != 0)
|
|
3524
|
+
return 0;
|
|
3525
|
+
/* Central directory must be on this volume. */
|
|
3526
|
+
if (disk_num != archive_le16dec(p + 6))
|
|
3527
|
+
return 0;
|
|
3528
|
+
/* All central directory entries must be on this volume. */
|
|
3529
|
+
if (archive_le16dec(p + 10) != archive_le16dec(p + 8))
|
|
3530
|
+
return 0;
|
|
3531
|
+
/* Central directory can't extend beyond start of EOCD record. */
|
|
3532
|
+
if (cd_offset + cd_size > current_offset)
|
|
3533
|
+
return 0;
|
|
3534
|
+
|
|
3535
|
+
/* Save the central directory location for later use. */
|
|
3536
|
+
zip->central_directory_offset = cd_offset;
|
|
3537
|
+
zip->central_directory_offset_adjusted = current_offset - cd_size;
|
|
3538
|
+
|
|
3539
|
+
/* This is just a tiny bit higher than the maximum
|
|
3540
|
+
returned by the streaming Zip bidder. This ensures
|
|
3541
|
+
that the more accurate seeking Zip parser wins
|
|
3542
|
+
whenever seek is available. */
|
|
3543
|
+
return 32;
|
|
3544
|
+
}
|
|
3545
|
+
|
|
3546
|
+
/*
|
|
3547
|
+
* Examine Zip64 EOCD locator: If it's valid, store the information
|
|
3548
|
+
* from it.
|
|
3549
|
+
*/
|
|
3550
|
+
static int
|
|
3551
|
+
read_zip64_eocd(struct archive_read *a, struct zip *zip, const char *p)
|
|
3552
|
+
{
|
|
3553
|
+
int64_t eocd64_offset;
|
|
3554
|
+
int64_t eocd64_size;
|
|
3555
|
+
|
|
3556
|
+
/* Sanity-check the locator record. */
|
|
3557
|
+
|
|
3558
|
+
/* Central dir must be on first volume. */
|
|
3559
|
+
if (archive_le32dec(p + 4) != 0)
|
|
3560
|
+
return 0;
|
|
3561
|
+
/* Must be only a single volume. */
|
|
3562
|
+
if (archive_le32dec(p + 16) != 1)
|
|
3563
|
+
return 0;
|
|
3564
|
+
|
|
3565
|
+
/* Find the Zip64 EOCD record. */
|
|
3566
|
+
eocd64_offset = archive_le64dec(p + 8);
|
|
3567
|
+
if (__archive_read_seek(a, eocd64_offset, SEEK_SET) < 0)
|
|
3568
|
+
return 0;
|
|
3569
|
+
if ((p = __archive_read_ahead(a, 56, NULL)) == NULL)
|
|
3570
|
+
return 0;
|
|
3571
|
+
/* Make sure we can read all of it. */
|
|
3572
|
+
eocd64_size = archive_le64dec(p + 4) + 12;
|
|
3573
|
+
if (eocd64_size < 56 || eocd64_size > 16384)
|
|
3574
|
+
return 0;
|
|
3575
|
+
if ((p = __archive_read_ahead(a, (size_t)eocd64_size, NULL)) == NULL)
|
|
3576
|
+
return 0;
|
|
3577
|
+
|
|
3578
|
+
/* Sanity-check the EOCD64 */
|
|
3579
|
+
if (archive_le32dec(p + 16) != 0) /* Must be disk #0 */
|
|
3580
|
+
return 0;
|
|
3581
|
+
if (archive_le32dec(p + 20) != 0) /* CD must be on disk #0 */
|
|
3582
|
+
return 0;
|
|
3583
|
+
/* CD can't be split. */
|
|
3584
|
+
if (archive_le64dec(p + 24) != archive_le64dec(p + 32))
|
|
3585
|
+
return 0;
|
|
3586
|
+
|
|
3587
|
+
/* Save the central directory offset for later use. */
|
|
3588
|
+
zip->central_directory_offset = archive_le64dec(p + 48);
|
|
3589
|
+
/* TODO: Needs scanning backwards to find the eocd64 instead of assuming */
|
|
3590
|
+
zip->central_directory_offset_adjusted = zip->central_directory_offset;
|
|
3591
|
+
|
|
3592
|
+
return 32;
|
|
3593
|
+
}
|
|
3594
|
+
|
|
3595
|
+
static int
|
|
3596
|
+
archive_read_format_zip_seekable_bid(struct archive_read *a, int best_bid)
|
|
3597
|
+
{
|
|
3598
|
+
struct zip *zip = (struct zip *)a->format->data;
|
|
3599
|
+
int64_t file_size, current_offset;
|
|
3600
|
+
const char *p;
|
|
3601
|
+
int i, tail;
|
|
3602
|
+
|
|
3603
|
+
/* If someone has already bid more than 32, then avoid
|
|
3604
|
+
trashing the look-ahead buffers with a seek. */
|
|
3605
|
+
if (best_bid > 32)
|
|
3606
|
+
return (-1);
|
|
3607
|
+
|
|
3608
|
+
file_size = __archive_read_seek(a, 0, SEEK_END);
|
|
3609
|
+
if (file_size <= 0)
|
|
3610
|
+
return 0;
|
|
3611
|
+
|
|
3612
|
+
/* Search last 16k of file for end-of-central-directory
|
|
3613
|
+
* record (which starts with PK\005\006) */
|
|
3614
|
+
tail = (int)zipmin(1024 * 16, file_size);
|
|
3615
|
+
current_offset = __archive_read_seek(a, -tail, SEEK_END);
|
|
3616
|
+
if (current_offset < 0)
|
|
3617
|
+
return 0;
|
|
3618
|
+
if ((p = __archive_read_ahead(a, (size_t)tail, NULL)) == NULL)
|
|
3619
|
+
return 0;
|
|
3620
|
+
/* Boyer-Moore search backwards from the end, since we want
|
|
3621
|
+
* to match the last EOCD in the file (there can be more than
|
|
3622
|
+
* one if there is an uncompressed Zip archive as a member
|
|
3623
|
+
* within this Zip archive). */
|
|
3624
|
+
for (i = tail - 22; i > 0;) {
|
|
3625
|
+
switch (p[i]) {
|
|
3626
|
+
case 'P':
|
|
3627
|
+
if (memcmp(p + i, "PK\005\006", 4) == 0) {
|
|
3628
|
+
int ret = read_eocd(zip, p + i,
|
|
3629
|
+
current_offset + i);
|
|
3630
|
+
/* Zip64 EOCD locator precedes
|
|
3631
|
+
* regular EOCD if present. */
|
|
3632
|
+
if (i >= 20 && memcmp(p + i - 20, "PK\006\007", 4) == 0) {
|
|
3633
|
+
int ret_zip64 = read_zip64_eocd(a, zip, p + i - 20);
|
|
3634
|
+
if (ret_zip64 > ret)
|
|
3635
|
+
ret = ret_zip64;
|
|
3636
|
+
}
|
|
3637
|
+
return (ret);
|
|
3638
|
+
}
|
|
3639
|
+
i -= 4;
|
|
3640
|
+
break;
|
|
3641
|
+
case 'K': i -= 1; break;
|
|
3642
|
+
case 005: i -= 2; break;
|
|
3643
|
+
case 006: i -= 3; break;
|
|
3644
|
+
default: i -= 4; break;
|
|
3645
|
+
}
|
|
3646
|
+
}
|
|
3647
|
+
return 0;
|
|
3648
|
+
}
|
|
3649
|
+
|
|
3650
|
+
/* The red-black trees are only used in seeking mode to manage
|
|
3651
|
+
* the in-memory copy of the central directory. */
|
|
3652
|
+
|
|
3653
|
+
static int
|
|
3654
|
+
cmp_node(const struct archive_rb_node *n1, const struct archive_rb_node *n2)
|
|
3655
|
+
{
|
|
3656
|
+
const struct zip_entry *e1 = (const struct zip_entry *)n1;
|
|
3657
|
+
const struct zip_entry *e2 = (const struct zip_entry *)n2;
|
|
3658
|
+
|
|
3659
|
+
if (e1->local_header_offset > e2->local_header_offset)
|
|
3660
|
+
return -1;
|
|
3661
|
+
if (e1->local_header_offset < e2->local_header_offset)
|
|
3662
|
+
return 1;
|
|
3663
|
+
return 0;
|
|
3664
|
+
}
|
|
3665
|
+
|
|
3666
|
+
static int
|
|
3667
|
+
cmp_key(const struct archive_rb_node *n, const void *key)
|
|
3668
|
+
{
|
|
3669
|
+
/* This function won't be called */
|
|
3670
|
+
(void)n; /* UNUSED */
|
|
3671
|
+
(void)key; /* UNUSED */
|
|
3672
|
+
return 1;
|
|
3673
|
+
}
|
|
3674
|
+
|
|
3675
|
+
static const struct archive_rb_tree_ops rb_ops = {
|
|
3676
|
+
&cmp_node, &cmp_key
|
|
3677
|
+
};
|
|
3678
|
+
|
|
3679
|
+
static int
|
|
3680
|
+
rsrc_cmp_node(const struct archive_rb_node *n1,
|
|
3681
|
+
const struct archive_rb_node *n2)
|
|
3682
|
+
{
|
|
3683
|
+
const struct zip_entry *e1 = (const struct zip_entry *)n1;
|
|
3684
|
+
const struct zip_entry *e2 = (const struct zip_entry *)n2;
|
|
3685
|
+
|
|
3686
|
+
return (strcmp(e2->rsrcname.s, e1->rsrcname.s));
|
|
3687
|
+
}
|
|
3688
|
+
|
|
3689
|
+
static int
|
|
3690
|
+
rsrc_cmp_key(const struct archive_rb_node *n, const void *key)
|
|
3691
|
+
{
|
|
3692
|
+
const struct zip_entry *e = (const struct zip_entry *)n;
|
|
3693
|
+
return (strcmp((const char *)key, e->rsrcname.s));
|
|
3694
|
+
}
|
|
3695
|
+
|
|
3696
|
+
static const struct archive_rb_tree_ops rb_rsrc_ops = {
|
|
3697
|
+
&rsrc_cmp_node, &rsrc_cmp_key
|
|
3698
|
+
};
|
|
3699
|
+
|
|
3700
|
+
static const char *
|
|
3701
|
+
rsrc_basename(const char *name, size_t name_length)
|
|
3702
|
+
{
|
|
3703
|
+
const char *s, *r;
|
|
3704
|
+
|
|
3705
|
+
r = s = name;
|
|
3706
|
+
for (;;) {
|
|
3707
|
+
s = memchr(s, '/', name_length - (s - name));
|
|
3708
|
+
if (s == NULL)
|
|
3709
|
+
break;
|
|
3710
|
+
r = ++s;
|
|
3711
|
+
}
|
|
3712
|
+
return (r);
|
|
3713
|
+
}
|
|
3714
|
+
|
|
3715
|
+
static void
|
|
3716
|
+
expose_parent_dirs(struct zip *zip, const char *name, size_t name_length)
|
|
3717
|
+
{
|
|
3718
|
+
struct archive_string str;
|
|
3719
|
+
struct zip_entry *dir;
|
|
3720
|
+
char *s;
|
|
3721
|
+
|
|
3722
|
+
archive_string_init(&str);
|
|
3723
|
+
archive_strncpy(&str, name, name_length);
|
|
3724
|
+
for (;;) {
|
|
3725
|
+
s = strrchr(str.s, '/');
|
|
3726
|
+
if (s == NULL)
|
|
3727
|
+
break;
|
|
3728
|
+
*s = '\0';
|
|
3729
|
+
/* Transfer the parent directory from zip->tree_rsrc RB
|
|
3730
|
+
* tree to zip->tree RB tree to expose. */
|
|
3731
|
+
dir = (struct zip_entry *)
|
|
3732
|
+
__archive_rb_tree_find_node(&zip->tree_rsrc, str.s);
|
|
3733
|
+
if (dir == NULL)
|
|
3734
|
+
break;
|
|
3735
|
+
__archive_rb_tree_remove_node(&zip->tree_rsrc, &dir->node);
|
|
3736
|
+
archive_string_free(&dir->rsrcname);
|
|
3737
|
+
__archive_rb_tree_insert_node(&zip->tree, &dir->node);
|
|
3738
|
+
}
|
|
3739
|
+
archive_string_free(&str);
|
|
3740
|
+
}
|
|
3741
|
+
|
|
3742
|
+
static int
|
|
3743
|
+
slurp_central_directory(struct archive_read *a, struct archive_entry* entry,
|
|
3744
|
+
struct zip *zip)
|
|
3745
|
+
{
|
|
3746
|
+
ssize_t i;
|
|
3747
|
+
unsigned found;
|
|
3748
|
+
int64_t correction;
|
|
3749
|
+
ssize_t bytes_avail;
|
|
3750
|
+
const char *p;
|
|
3751
|
+
|
|
3752
|
+
/*
|
|
3753
|
+
* Find the start of the central directory. The end-of-CD
|
|
3754
|
+
* record has our starting point, but there are lots of
|
|
3755
|
+
* Zip archives which have had other data prepended to the
|
|
3756
|
+
* file, which makes the recorded offsets all too small.
|
|
3757
|
+
* So we search forward from the specified offset until we
|
|
3758
|
+
* find the real start of the central directory. Then we
|
|
3759
|
+
* know the correction we need to apply to account for leading
|
|
3760
|
+
* padding.
|
|
3761
|
+
*/
|
|
3762
|
+
if (__archive_read_seek(a, zip->central_directory_offset_adjusted, SEEK_SET)
|
|
3763
|
+
< 0)
|
|
3764
|
+
return ARCHIVE_FATAL;
|
|
3765
|
+
|
|
3766
|
+
found = 0;
|
|
3767
|
+
while (!found) {
|
|
3768
|
+
if ((p = __archive_read_ahead(a, 20, &bytes_avail)) == NULL)
|
|
3769
|
+
return ARCHIVE_FATAL;
|
|
3770
|
+
for (found = 0, i = 0; !found && i < bytes_avail - 4;) {
|
|
3771
|
+
switch (p[i + 3]) {
|
|
3772
|
+
case 'P': i += 3; break;
|
|
3773
|
+
case 'K': i += 2; break;
|
|
3774
|
+
case 001: i += 1; break;
|
|
3775
|
+
case 002:
|
|
3776
|
+
if (memcmp(p + i, "PK\001\002", 4) == 0) {
|
|
3777
|
+
p += i;
|
|
3778
|
+
found = 1;
|
|
3779
|
+
} else
|
|
3780
|
+
i += 4;
|
|
3781
|
+
break;
|
|
3782
|
+
case 005: i += 1; break;
|
|
3783
|
+
case 006:
|
|
3784
|
+
if (memcmp(p + i, "PK\005\006", 4) == 0) {
|
|
3785
|
+
p += i;
|
|
3786
|
+
found = 1;
|
|
3787
|
+
} else if (memcmp(p + i, "PK\006\006", 4) == 0) {
|
|
3788
|
+
p += i;
|
|
3789
|
+
found = 1;
|
|
3790
|
+
} else
|
|
3791
|
+
i += 1;
|
|
3792
|
+
break;
|
|
3793
|
+
default: i += 4; break;
|
|
3794
|
+
}
|
|
3795
|
+
}
|
|
3796
|
+
__archive_read_consume(a, i);
|
|
3797
|
+
}
|
|
3798
|
+
correction = archive_filter_bytes(&a->archive, 0)
|
|
3799
|
+
- zip->central_directory_offset;
|
|
3800
|
+
|
|
3801
|
+
__archive_rb_tree_init(&zip->tree, &rb_ops);
|
|
3802
|
+
__archive_rb_tree_init(&zip->tree_rsrc, &rb_rsrc_ops);
|
|
3803
|
+
|
|
3804
|
+
zip->central_directory_entries_total = 0;
|
|
3805
|
+
while (1) {
|
|
3806
|
+
struct zip_entry *zip_entry;
|
|
3807
|
+
size_t filename_length, extra_length, comment_length;
|
|
3808
|
+
uint32_t external_attributes;
|
|
3809
|
+
const char *name, *r;
|
|
3810
|
+
|
|
3811
|
+
if ((p = __archive_read_ahead(a, 4, NULL)) == NULL)
|
|
3812
|
+
return ARCHIVE_FATAL;
|
|
3813
|
+
if (memcmp(p, "PK\006\006", 4) == 0
|
|
3814
|
+
|| memcmp(p, "PK\005\006", 4) == 0) {
|
|
3815
|
+
break;
|
|
3816
|
+
} else if (memcmp(p, "PK\001\002", 4) != 0) {
|
|
3817
|
+
archive_set_error(&a->archive,
|
|
3818
|
+
-1, "Invalid central directory signature");
|
|
3819
|
+
return ARCHIVE_FATAL;
|
|
3820
|
+
}
|
|
3821
|
+
if ((p = __archive_read_ahead(a, 46, NULL)) == NULL)
|
|
3822
|
+
return ARCHIVE_FATAL;
|
|
3823
|
+
|
|
3824
|
+
zip_entry = calloc(1, sizeof(struct zip_entry));
|
|
3825
|
+
if (zip_entry == NULL) {
|
|
3826
|
+
archive_set_error(&a->archive, ENOMEM,
|
|
3827
|
+
"Can't allocate zip entry");
|
|
3828
|
+
return ARCHIVE_FATAL;
|
|
3829
|
+
}
|
|
3830
|
+
zip_entry->next = zip->zip_entries;
|
|
3831
|
+
zip_entry->flags |= LA_FROM_CENTRAL_DIRECTORY;
|
|
3832
|
+
zip->zip_entries = zip_entry;
|
|
3833
|
+
zip->central_directory_entries_total++;
|
|
3834
|
+
|
|
3835
|
+
/* version = p[4]; */
|
|
3836
|
+
zip_entry->system = p[5];
|
|
3837
|
+
/* version_required = archive_le16dec(p + 6); */
|
|
3838
|
+
zip_entry->zip_flags = archive_le16dec(p + 8);
|
|
3839
|
+
if (zip_entry->zip_flags
|
|
3840
|
+
& (ZIP_ENCRYPTED | ZIP_STRONG_ENCRYPTED)){
|
|
3841
|
+
zip->has_encrypted_entries = 1;
|
|
3842
|
+
}
|
|
3843
|
+
zip_entry->compression = (char)archive_le16dec(p + 10);
|
|
3844
|
+
zip_entry->mtime = zip_time(p + 12);
|
|
3845
|
+
zip_entry->crc32 = archive_le32dec(p + 16);
|
|
3846
|
+
if (zip_entry->zip_flags & ZIP_LENGTH_AT_END)
|
|
3847
|
+
zip_entry->decdat = p[13];
|
|
3848
|
+
else
|
|
3849
|
+
zip_entry->decdat = p[19];
|
|
3850
|
+
zip_entry->compressed_size = archive_le32dec(p + 20);
|
|
3851
|
+
zip_entry->uncompressed_size = archive_le32dec(p + 24);
|
|
3852
|
+
filename_length = archive_le16dec(p + 28);
|
|
3853
|
+
extra_length = archive_le16dec(p + 30);
|
|
3854
|
+
comment_length = archive_le16dec(p + 32);
|
|
3855
|
+
/* disk_start = archive_le16dec(p + 34);
|
|
3856
|
+
* Better be zero.
|
|
3857
|
+
* internal_attributes = archive_le16dec(p + 36);
|
|
3858
|
+
* text bit */
|
|
3859
|
+
external_attributes = archive_le32dec(p + 38);
|
|
3860
|
+
zip_entry->local_header_offset =
|
|
3861
|
+
archive_le32dec(p + 42) + correction;
|
|
3862
|
+
|
|
3863
|
+
/* If we can't guess the mode, leave it zero here;
|
|
3864
|
+
when we read the local file header we might get
|
|
3865
|
+
more information. */
|
|
3866
|
+
if (zip_entry->system == 3) {
|
|
3867
|
+
zip_entry->mode = external_attributes >> 16;
|
|
3868
|
+
} else if (zip_entry->system == 0) {
|
|
3869
|
+
// Interpret MSDOS directory bit
|
|
3870
|
+
if (0x10 == (external_attributes & 0x10)) {
|
|
3871
|
+
zip_entry->mode = AE_IFDIR | 0775;
|
|
3872
|
+
} else {
|
|
3873
|
+
zip_entry->mode = AE_IFREG | 0664;
|
|
3874
|
+
}
|
|
3875
|
+
if (0x01 == (external_attributes & 0x01)) {
|
|
3876
|
+
// Read-only bit; strip write permissions
|
|
3877
|
+
zip_entry->mode &= 0555;
|
|
3878
|
+
}
|
|
3879
|
+
} else {
|
|
3880
|
+
zip_entry->mode = 0;
|
|
3881
|
+
}
|
|
3882
|
+
|
|
3883
|
+
/* We're done with the regular data; get the filename and
|
|
3884
|
+
* extra data. */
|
|
3885
|
+
__archive_read_consume(a, 46);
|
|
3886
|
+
p = __archive_read_ahead(a, filename_length + extra_length,
|
|
3887
|
+
NULL);
|
|
3888
|
+
if (p == NULL) {
|
|
3889
|
+
archive_set_error(&a->archive,
|
|
3890
|
+
ARCHIVE_ERRNO_FILE_FORMAT,
|
|
3891
|
+
"Truncated ZIP file header");
|
|
3892
|
+
return ARCHIVE_FATAL;
|
|
3893
|
+
}
|
|
3894
|
+
if (ARCHIVE_OK != process_extra(a, entry, p + filename_length,
|
|
3895
|
+
extra_length, zip_entry)) {
|
|
3896
|
+
return ARCHIVE_FATAL;
|
|
3897
|
+
}
|
|
3898
|
+
|
|
3899
|
+
/*
|
|
3900
|
+
* Mac resource fork files are stored under the
|
|
3901
|
+
* "__MACOSX/" directory, so we should check if
|
|
3902
|
+
* it is.
|
|
3903
|
+
*/
|
|
3904
|
+
if (!zip->process_mac_extensions) {
|
|
3905
|
+
/* Treat every entry as a regular entry. */
|
|
3906
|
+
__archive_rb_tree_insert_node(&zip->tree,
|
|
3907
|
+
&zip_entry->node);
|
|
3908
|
+
} else {
|
|
3909
|
+
name = p;
|
|
3910
|
+
r = rsrc_basename(name, filename_length);
|
|
3911
|
+
if (filename_length >= 9 &&
|
|
3912
|
+
strncmp("__MACOSX/", name, 9) == 0) {
|
|
3913
|
+
/* If this file is not a resource fork nor
|
|
3914
|
+
* a directory. We should treat it as a non
|
|
3915
|
+
* resource fork file to expose it. */
|
|
3916
|
+
if (name[filename_length-1] != '/' &&
|
|
3917
|
+
(r - name < 3 || r[0] != '.' ||
|
|
3918
|
+
r[1] != '_')) {
|
|
3919
|
+
__archive_rb_tree_insert_node(
|
|
3920
|
+
&zip->tree, &zip_entry->node);
|
|
3921
|
+
/* Expose its parent directories. */
|
|
3922
|
+
expose_parent_dirs(zip, name,
|
|
3923
|
+
filename_length);
|
|
3924
|
+
} else {
|
|
3925
|
+
/* This file is a resource fork file or
|
|
3926
|
+
* a directory. */
|
|
3927
|
+
archive_strncpy(&(zip_entry->rsrcname),
|
|
3928
|
+
name, filename_length);
|
|
3929
|
+
__archive_rb_tree_insert_node(
|
|
3930
|
+
&zip->tree_rsrc, &zip_entry->node);
|
|
3931
|
+
}
|
|
3932
|
+
} else {
|
|
3933
|
+
/* Generate resource fork name to find its
|
|
3934
|
+
* resource file at zip->tree_rsrc. */
|
|
3935
|
+
archive_strcpy(&(zip_entry->rsrcname),
|
|
3936
|
+
"__MACOSX/");
|
|
3937
|
+
archive_strncat(&(zip_entry->rsrcname),
|
|
3938
|
+
name, r - name);
|
|
3939
|
+
archive_strcat(&(zip_entry->rsrcname), "._");
|
|
3940
|
+
archive_strncat(&(zip_entry->rsrcname),
|
|
3941
|
+
name + (r - name),
|
|
3942
|
+
filename_length - (r - name));
|
|
3943
|
+
/* Register an entry to RB tree to sort it by
|
|
3944
|
+
* file offset. */
|
|
3945
|
+
__archive_rb_tree_insert_node(&zip->tree,
|
|
3946
|
+
&zip_entry->node);
|
|
3947
|
+
}
|
|
3948
|
+
}
|
|
3949
|
+
|
|
3950
|
+
/* Skip the comment too ... */
|
|
3951
|
+
__archive_read_consume(a,
|
|
3952
|
+
filename_length + extra_length + comment_length);
|
|
3953
|
+
}
|
|
3954
|
+
|
|
3955
|
+
return ARCHIVE_OK;
|
|
3956
|
+
}
|
|
3957
|
+
|
|
3958
|
+
static ssize_t
|
|
3959
|
+
zip_get_local_file_header_size(struct archive_read *a, size_t extra)
|
|
3960
|
+
{
|
|
3961
|
+
const char *p;
|
|
3962
|
+
ssize_t filename_length, extra_length;
|
|
3963
|
+
|
|
3964
|
+
if ((p = __archive_read_ahead(a, extra + 30, NULL)) == NULL) {
|
|
3965
|
+
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
|
3966
|
+
"Truncated ZIP file header");
|
|
3967
|
+
return (ARCHIVE_WARN);
|
|
3968
|
+
}
|
|
3969
|
+
p += extra;
|
|
3970
|
+
|
|
3971
|
+
if (memcmp(p, "PK\003\004", 4) != 0) {
|
|
3972
|
+
archive_set_error(&a->archive, -1, "Damaged Zip archive");
|
|
3973
|
+
return ARCHIVE_WARN;
|
|
3974
|
+
}
|
|
3975
|
+
filename_length = archive_le16dec(p + 26);
|
|
3976
|
+
extra_length = archive_le16dec(p + 28);
|
|
3977
|
+
|
|
3978
|
+
return (30 + filename_length + extra_length);
|
|
3979
|
+
}
|
|
3980
|
+
|
|
3981
|
+
static int
|
|
3982
|
+
zip_read_mac_metadata(struct archive_read *a, struct archive_entry *entry,
|
|
3983
|
+
struct zip_entry *rsrc)
|
|
3984
|
+
{
|
|
3985
|
+
struct zip *zip = (struct zip *)a->format->data;
|
|
3986
|
+
unsigned char *metadata, *mp;
|
|
3987
|
+
int64_t offset = archive_filter_bytes(&a->archive, 0);
|
|
3988
|
+
size_t remaining_bytes, metadata_bytes;
|
|
3989
|
+
ssize_t hsize;
|
|
3990
|
+
int ret = ARCHIVE_OK, eof;
|
|
3991
|
+
|
|
3992
|
+
switch(rsrc->compression) {
|
|
3993
|
+
case 0: /* No compression. */
|
|
3994
|
+
if (rsrc->uncompressed_size != rsrc->compressed_size) {
|
|
3995
|
+
archive_set_error(&a->archive,
|
|
3996
|
+
ARCHIVE_ERRNO_FILE_FORMAT,
|
|
3997
|
+
"Malformed OS X metadata entry: "
|
|
3998
|
+
"inconsistent size");
|
|
3999
|
+
return (ARCHIVE_FATAL);
|
|
4000
|
+
}
|
|
4001
|
+
#ifdef HAVE_ZLIB_H
|
|
4002
|
+
case 8: /* Deflate compression. */
|
|
4003
|
+
#endif
|
|
4004
|
+
break;
|
|
4005
|
+
default: /* Unsupported compression. */
|
|
4006
|
+
/* Return a warning. */
|
|
4007
|
+
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
|
4008
|
+
"Unsupported ZIP compression method (%s)",
|
|
4009
|
+
compression_name(rsrc->compression));
|
|
4010
|
+
/* We can't decompress this entry, but we will
|
|
4011
|
+
* be able to skip() it and try the next entry. */
|
|
4012
|
+
return (ARCHIVE_WARN);
|
|
4013
|
+
}
|
|
4014
|
+
|
|
4015
|
+
if (rsrc->uncompressed_size > (4 * 1024 * 1024)) {
|
|
4016
|
+
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
|
4017
|
+
"Mac metadata is too large: %jd > 4M bytes",
|
|
4018
|
+
(intmax_t)rsrc->uncompressed_size);
|
|
4019
|
+
return (ARCHIVE_WARN);
|
|
4020
|
+
}
|
|
4021
|
+
if (rsrc->compressed_size > (4 * 1024 * 1024)) {
|
|
4022
|
+
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
|
4023
|
+
"Mac metadata is too large: %jd > 4M bytes",
|
|
4024
|
+
(intmax_t)rsrc->compressed_size);
|
|
4025
|
+
return (ARCHIVE_WARN);
|
|
4026
|
+
}
|
|
4027
|
+
|
|
4028
|
+
metadata = malloc((size_t)rsrc->uncompressed_size);
|
|
4029
|
+
if (metadata == NULL) {
|
|
4030
|
+
archive_set_error(&a->archive, ENOMEM,
|
|
4031
|
+
"Can't allocate memory for Mac metadata");
|
|
4032
|
+
return (ARCHIVE_FATAL);
|
|
4033
|
+
}
|
|
4034
|
+
|
|
4035
|
+
if (offset < rsrc->local_header_offset)
|
|
4036
|
+
__archive_read_consume(a, rsrc->local_header_offset - offset);
|
|
4037
|
+
else if (offset != rsrc->local_header_offset) {
|
|
4038
|
+
__archive_read_seek(a, rsrc->local_header_offset, SEEK_SET);
|
|
4039
|
+
}
|
|
4040
|
+
|
|
4041
|
+
hsize = zip_get_local_file_header_size(a, 0);
|
|
4042
|
+
__archive_read_consume(a, hsize);
|
|
4043
|
+
|
|
4044
|
+
remaining_bytes = (size_t)rsrc->compressed_size;
|
|
4045
|
+
metadata_bytes = (size_t)rsrc->uncompressed_size;
|
|
4046
|
+
mp = metadata;
|
|
4047
|
+
eof = 0;
|
|
4048
|
+
while (!eof && remaining_bytes) {
|
|
4049
|
+
const unsigned char *p;
|
|
4050
|
+
ssize_t bytes_avail;
|
|
4051
|
+
size_t bytes_used;
|
|
4052
|
+
|
|
4053
|
+
p = __archive_read_ahead(a, 1, &bytes_avail);
|
|
4054
|
+
if (p == NULL) {
|
|
4055
|
+
archive_set_error(&a->archive,
|
|
4056
|
+
ARCHIVE_ERRNO_FILE_FORMAT,
|
|
4057
|
+
"Truncated ZIP file header");
|
|
4058
|
+
ret = ARCHIVE_WARN;
|
|
4059
|
+
goto exit_mac_metadata;
|
|
4060
|
+
}
|
|
4061
|
+
if ((size_t)bytes_avail > remaining_bytes)
|
|
4062
|
+
bytes_avail = remaining_bytes;
|
|
4063
|
+
switch(rsrc->compression) {
|
|
4064
|
+
case 0: /* No compression. */
|
|
4065
|
+
if ((size_t)bytes_avail > metadata_bytes)
|
|
4066
|
+
bytes_avail = metadata_bytes;
|
|
4067
|
+
memcpy(mp, p, bytes_avail);
|
|
4068
|
+
bytes_used = (size_t)bytes_avail;
|
|
4069
|
+
metadata_bytes -= bytes_used;
|
|
4070
|
+
mp += bytes_used;
|
|
4071
|
+
if (metadata_bytes == 0)
|
|
4072
|
+
eof = 1;
|
|
4073
|
+
break;
|
|
4074
|
+
#ifdef HAVE_ZLIB_H
|
|
4075
|
+
case 8: /* Deflate compression. */
|
|
4076
|
+
{
|
|
4077
|
+
int r;
|
|
4078
|
+
|
|
4079
|
+
ret = zip_deflate_init(a, zip);
|
|
4080
|
+
if (ret != ARCHIVE_OK)
|
|
4081
|
+
goto exit_mac_metadata;
|
|
4082
|
+
zip->stream.next_in =
|
|
4083
|
+
(Bytef *)(uintptr_t)(const void *)p;
|
|
4084
|
+
zip->stream.avail_in = (uInt)bytes_avail;
|
|
4085
|
+
zip->stream.total_in = 0;
|
|
4086
|
+
zip->stream.next_out = mp;
|
|
4087
|
+
zip->stream.avail_out = (uInt)metadata_bytes;
|
|
4088
|
+
zip->stream.total_out = 0;
|
|
4089
|
+
|
|
4090
|
+
r = inflate(&zip->stream, 0);
|
|
4091
|
+
switch (r) {
|
|
4092
|
+
case Z_OK:
|
|
4093
|
+
break;
|
|
4094
|
+
case Z_STREAM_END:
|
|
4095
|
+
eof = 1;
|
|
4096
|
+
break;
|
|
4097
|
+
case Z_MEM_ERROR:
|
|
4098
|
+
archive_set_error(&a->archive, ENOMEM,
|
|
4099
|
+
"Out of memory for ZIP decompression");
|
|
4100
|
+
ret = ARCHIVE_FATAL;
|
|
4101
|
+
goto exit_mac_metadata;
|
|
4102
|
+
default:
|
|
4103
|
+
archive_set_error(&a->archive,
|
|
4104
|
+
ARCHIVE_ERRNO_MISC,
|
|
4105
|
+
"ZIP decompression failed (%d)", r);
|
|
4106
|
+
ret = ARCHIVE_FATAL;
|
|
4107
|
+
goto exit_mac_metadata;
|
|
4108
|
+
}
|
|
4109
|
+
bytes_used = zip->stream.total_in;
|
|
4110
|
+
metadata_bytes -= zip->stream.total_out;
|
|
4111
|
+
mp += zip->stream.total_out;
|
|
4112
|
+
break;
|
|
4113
|
+
}
|
|
4114
|
+
#endif
|
|
4115
|
+
default:
|
|
4116
|
+
bytes_used = 0;
|
|
4117
|
+
break;
|
|
4118
|
+
}
|
|
4119
|
+
__archive_read_consume(a, bytes_used);
|
|
4120
|
+
remaining_bytes -= bytes_used;
|
|
4121
|
+
}
|
|
4122
|
+
archive_entry_copy_mac_metadata(entry, metadata,
|
|
4123
|
+
(size_t)rsrc->uncompressed_size - metadata_bytes);
|
|
4124
|
+
|
|
4125
|
+
exit_mac_metadata:
|
|
4126
|
+
__archive_read_seek(a, offset, SEEK_SET);
|
|
4127
|
+
zip->decompress_init = 0;
|
|
4128
|
+
free(metadata);
|
|
4129
|
+
return (ret);
|
|
4130
|
+
}
|
|
4131
|
+
|
|
4132
|
+
static int
|
|
4133
|
+
archive_read_format_zip_seekable_read_header(struct archive_read *a,
|
|
4134
|
+
struct archive_entry *entry)
|
|
4135
|
+
{
|
|
4136
|
+
struct zip *zip = (struct zip *)a->format->data;
|
|
4137
|
+
struct zip_entry *rsrc;
|
|
4138
|
+
int64_t offset;
|
|
4139
|
+
int r, ret = ARCHIVE_OK;
|
|
4140
|
+
|
|
4141
|
+
/*
|
|
4142
|
+
* It should be sufficient to call archive_read_next_header() for
|
|
4143
|
+
* a reader to determine if an entry is encrypted or not. If the
|
|
4144
|
+
* encryption of an entry is only detectable when calling
|
|
4145
|
+
* archive_read_data(), so be it. We'll do the same check there
|
|
4146
|
+
* as well.
|
|
4147
|
+
*/
|
|
4148
|
+
if (zip->has_encrypted_entries ==
|
|
4149
|
+
ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW)
|
|
4150
|
+
zip->has_encrypted_entries = 0;
|
|
4151
|
+
|
|
4152
|
+
a->archive.archive_format = ARCHIVE_FORMAT_ZIP;
|
|
4153
|
+
if (a->archive.archive_format_name == NULL)
|
|
4154
|
+
a->archive.archive_format_name = "ZIP";
|
|
4155
|
+
|
|
4156
|
+
if (zip->zip_entries == NULL) {
|
|
4157
|
+
r = slurp_central_directory(a, entry, zip);
|
|
4158
|
+
if (r != ARCHIVE_OK)
|
|
4159
|
+
return r;
|
|
4160
|
+
/* Get first entry whose local header offset is lower than
|
|
4161
|
+
* other entries in the archive file. */
|
|
4162
|
+
zip->entry =
|
|
4163
|
+
(struct zip_entry *)ARCHIVE_RB_TREE_MIN(&zip->tree);
|
|
4164
|
+
} else if (zip->entry != NULL) {
|
|
4165
|
+
/* Get next entry in local header offset order. */
|
|
4166
|
+
zip->entry = (struct zip_entry *)__archive_rb_tree_iterate(
|
|
4167
|
+
&zip->tree, &zip->entry->node, ARCHIVE_RB_DIR_RIGHT);
|
|
4168
|
+
}
|
|
4169
|
+
|
|
4170
|
+
if (zip->entry == NULL)
|
|
4171
|
+
return ARCHIVE_EOF;
|
|
4172
|
+
|
|
4173
|
+
if (zip->entry->rsrcname.s)
|
|
4174
|
+
rsrc = (struct zip_entry *)__archive_rb_tree_find_node(
|
|
4175
|
+
&zip->tree_rsrc, zip->entry->rsrcname.s);
|
|
4176
|
+
else
|
|
4177
|
+
rsrc = NULL;
|
|
4178
|
+
|
|
4179
|
+
if (zip->cctx_valid)
|
|
4180
|
+
archive_decrypto_aes_ctr_release(&zip->cctx);
|
|
4181
|
+
if (zip->hctx_valid)
|
|
4182
|
+
archive_hmac_sha1_cleanup(&zip->hctx);
|
|
4183
|
+
zip->tctx_valid = zip->cctx_valid = zip->hctx_valid = 0;
|
|
4184
|
+
__archive_read_reset_passphrase(a);
|
|
4185
|
+
|
|
4186
|
+
/* File entries are sorted by the header offset, we should mostly
|
|
4187
|
+
* use __archive_read_consume to advance a read point to avoid
|
|
4188
|
+
* redundant data reading. */
|
|
4189
|
+
offset = archive_filter_bytes(&a->archive, 0);
|
|
4190
|
+
if (offset < zip->entry->local_header_offset)
|
|
4191
|
+
__archive_read_consume(a,
|
|
4192
|
+
zip->entry->local_header_offset - offset);
|
|
4193
|
+
else if (offset != zip->entry->local_header_offset) {
|
|
4194
|
+
__archive_read_seek(a, zip->entry->local_header_offset,
|
|
4195
|
+
SEEK_SET);
|
|
4196
|
+
}
|
|
4197
|
+
zip->unconsumed = 0;
|
|
4198
|
+
r = zip_read_local_file_header(a, entry, zip);
|
|
4199
|
+
if (r != ARCHIVE_OK)
|
|
4200
|
+
return r;
|
|
4201
|
+
if (rsrc) {
|
|
4202
|
+
int ret2 = zip_read_mac_metadata(a, entry, rsrc);
|
|
4203
|
+
if (ret2 < ret)
|
|
4204
|
+
ret = ret2;
|
|
4205
|
+
}
|
|
4206
|
+
return (ret);
|
|
4207
|
+
}
|
|
4208
|
+
|
|
4209
|
+
/*
|
|
4210
|
+
* We're going to seek for the next header anyway, so we don't
|
|
4211
|
+
* need to bother doing anything here.
|
|
4212
|
+
*/
|
|
4213
|
+
static int
|
|
4214
|
+
archive_read_format_zip_read_data_skip_seekable(struct archive_read *a)
|
|
4215
|
+
{
|
|
4216
|
+
struct zip *zip;
|
|
4217
|
+
zip = (struct zip *)(a->format->data);
|
|
4218
|
+
|
|
4219
|
+
zip->unconsumed = 0;
|
|
4220
|
+
return (ARCHIVE_OK);
|
|
4221
|
+
}
|
|
4222
|
+
|
|
4223
|
+
int
|
|
4224
|
+
archive_read_support_format_zip_seekable(struct archive *_a)
|
|
4225
|
+
{
|
|
4226
|
+
struct archive_read *a = (struct archive_read *)_a;
|
|
4227
|
+
struct zip *zip;
|
|
4228
|
+
int r;
|
|
4229
|
+
|
|
4230
|
+
archive_check_magic(_a, ARCHIVE_READ_MAGIC,
|
|
4231
|
+
ARCHIVE_STATE_NEW, "archive_read_support_format_zip_seekable");
|
|
4232
|
+
|
|
4233
|
+
zip = (struct zip *)calloc(1, sizeof(*zip));
|
|
4234
|
+
if (zip == NULL) {
|
|
4235
|
+
archive_set_error(&a->archive, ENOMEM,
|
|
4236
|
+
"Can't allocate zip data");
|
|
4237
|
+
return (ARCHIVE_FATAL);
|
|
4238
|
+
}
|
|
4239
|
+
|
|
4240
|
+
#ifdef HAVE_COPYFILE_H
|
|
4241
|
+
/* Set this by default on Mac OS. */
|
|
4242
|
+
zip->process_mac_extensions = 1;
|
|
4243
|
+
#endif
|
|
4244
|
+
|
|
4245
|
+
/*
|
|
4246
|
+
* Until enough data has been read, we cannot tell about
|
|
4247
|
+
* any encrypted entries yet.
|
|
4248
|
+
*/
|
|
4249
|
+
zip->has_encrypted_entries = ARCHIVE_READ_FORMAT_ENCRYPTION_DONT_KNOW;
|
|
4250
|
+
zip->crc32func = real_crc32;
|
|
4251
|
+
|
|
4252
|
+
r = __archive_read_register_format(a,
|
|
4253
|
+
zip,
|
|
4254
|
+
"zip",
|
|
4255
|
+
archive_read_format_zip_seekable_bid,
|
|
4256
|
+
archive_read_format_zip_options,
|
|
4257
|
+
archive_read_format_zip_seekable_read_header,
|
|
4258
|
+
archive_read_format_zip_read_data,
|
|
4259
|
+
archive_read_format_zip_read_data_skip_seekable,
|
|
4260
|
+
NULL,
|
|
4261
|
+
archive_read_format_zip_cleanup,
|
|
4262
|
+
archive_read_support_format_zip_capabilities_seekable,
|
|
4263
|
+
archive_read_format_zip_has_encrypted_entries);
|
|
4264
|
+
|
|
4265
|
+
if (r != ARCHIVE_OK)
|
|
4266
|
+
free(zip);
|
|
4267
|
+
return (ARCHIVE_OK);
|
|
4268
|
+
}
|
|
4269
|
+
|
|
4270
|
+
/*# vim:set noet:*/
|