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,4251 @@
|
|
|
1
|
+
/*-
|
|
2
|
+
* Copyright (c) 2018 Grzegorz Antoniak (http://antoniak.org)
|
|
3
|
+
* All rights reserved.
|
|
4
|
+
*
|
|
5
|
+
* Redistribution and use in source and binary forms, with or without
|
|
6
|
+
* modification, are permitted provided that the following conditions
|
|
7
|
+
* are met:
|
|
8
|
+
* 1. Redistributions of source code must retain the above copyright
|
|
9
|
+
* notice, this list of conditions and the following disclaimer.
|
|
10
|
+
* 2. Redistributions in binary form must reproduce the above copyright
|
|
11
|
+
* notice, this list of conditions and the following disclaimer in the
|
|
12
|
+
* documentation and/or other materials provided with the distribution.
|
|
13
|
+
*
|
|
14
|
+
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
|
|
15
|
+
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
16
|
+
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
17
|
+
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
18
|
+
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
19
|
+
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
20
|
+
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
21
|
+
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
22
|
+
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
23
|
+
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
24
|
+
*/
|
|
25
|
+
|
|
26
|
+
#include "archive_platform.h"
|
|
27
|
+
#include "archive_endian.h"
|
|
28
|
+
|
|
29
|
+
#ifdef HAVE_ERRNO_H
|
|
30
|
+
#include <errno.h>
|
|
31
|
+
#endif
|
|
32
|
+
#include <time.h>
|
|
33
|
+
#ifdef HAVE_ZLIB_H
|
|
34
|
+
#include <zlib.h> /* crc32 */
|
|
35
|
+
#endif
|
|
36
|
+
#ifdef HAVE_LIMITS_H
|
|
37
|
+
#include <limits.h>
|
|
38
|
+
#endif
|
|
39
|
+
|
|
40
|
+
#include "archive.h"
|
|
41
|
+
#ifndef HAVE_ZLIB_H
|
|
42
|
+
#include "archive_crc32.h"
|
|
43
|
+
#endif
|
|
44
|
+
|
|
45
|
+
#include "archive_entry.h"
|
|
46
|
+
#include "archive_entry_locale.h"
|
|
47
|
+
#include "archive_ppmd7_private.h"
|
|
48
|
+
#include "archive_entry_private.h"
|
|
49
|
+
|
|
50
|
+
#ifdef HAVE_BLAKE2_H
|
|
51
|
+
#include <blake2.h>
|
|
52
|
+
#else
|
|
53
|
+
#include "archive_blake2.h"
|
|
54
|
+
#endif
|
|
55
|
+
|
|
56
|
+
/*#define CHECK_CRC_ON_SOLID_SKIP*/
|
|
57
|
+
/*#define DONT_FAIL_ON_CRC_ERROR*/
|
|
58
|
+
/*#define DEBUG*/
|
|
59
|
+
|
|
60
|
+
#define rar5_min(a, b) (((a) > (b)) ? (b) : (a))
|
|
61
|
+
#define rar5_max(a, b) (((a) > (b)) ? (a) : (b))
|
|
62
|
+
#define rar5_countof(X) ((const ssize_t) (sizeof(X) / sizeof(*X)))
|
|
63
|
+
|
|
64
|
+
#if defined DEBUG
|
|
65
|
+
#define DEBUG_CODE if(1)
|
|
66
|
+
#define LOG(...) do { printf("rar5: " __VA_ARGS__); puts(""); } while(0)
|
|
67
|
+
#else
|
|
68
|
+
#define DEBUG_CODE if(0)
|
|
69
|
+
#endif
|
|
70
|
+
|
|
71
|
+
/* Real RAR5 magic number is:
|
|
72
|
+
*
|
|
73
|
+
* 0x52, 0x61, 0x72, 0x21, 0x1a, 0x07, 0x01, 0x00
|
|
74
|
+
* "Rar!→•☺·\x00"
|
|
75
|
+
*
|
|
76
|
+
* Retrieved with `rar5_signature()` by XOR'ing it with 0xA1, because I don't
|
|
77
|
+
* want to put this magic sequence in each binary that uses libarchive, so
|
|
78
|
+
* applications that scan through the file for this marker won't trigger on
|
|
79
|
+
* this "false" one.
|
|
80
|
+
*
|
|
81
|
+
* The array itself is decrypted in `rar5_init` function. */
|
|
82
|
+
|
|
83
|
+
static unsigned char rar5_signature_xor[] = { 243, 192, 211, 128, 187, 166, 160, 161 };
|
|
84
|
+
static const size_t g_unpack_window_size = 0x20000;
|
|
85
|
+
|
|
86
|
+
/* These could have been static const's, but they aren't, because of
|
|
87
|
+
* Visual Studio. */
|
|
88
|
+
#define MAX_NAME_IN_CHARS 2048
|
|
89
|
+
#define MAX_NAME_IN_BYTES (4 * MAX_NAME_IN_CHARS)
|
|
90
|
+
|
|
91
|
+
struct file_header {
|
|
92
|
+
ssize_t bytes_remaining;
|
|
93
|
+
ssize_t unpacked_size;
|
|
94
|
+
int64_t last_offset; /* Used in sanity checks. */
|
|
95
|
+
int64_t last_size; /* Used in sanity checks. */
|
|
96
|
+
|
|
97
|
+
uint8_t solid : 1; /* Is this a solid stream? */
|
|
98
|
+
uint8_t service : 1; /* Is this file a service data? */
|
|
99
|
+
uint8_t eof : 1; /* Did we finish unpacking the file? */
|
|
100
|
+
uint8_t dir : 1; /* Is this file entry a directory? */
|
|
101
|
+
|
|
102
|
+
/* Optional time fields. */
|
|
103
|
+
uint64_t e_mtime;
|
|
104
|
+
uint64_t e_ctime;
|
|
105
|
+
uint64_t e_atime;
|
|
106
|
+
uint32_t e_unix_ns;
|
|
107
|
+
|
|
108
|
+
/* Optional hash fields. */
|
|
109
|
+
uint32_t stored_crc32;
|
|
110
|
+
uint32_t calculated_crc32;
|
|
111
|
+
uint8_t blake2sp[32];
|
|
112
|
+
blake2sp_state b2state;
|
|
113
|
+
char has_blake2;
|
|
114
|
+
|
|
115
|
+
/* Optional redir fields */
|
|
116
|
+
uint64_t redir_type;
|
|
117
|
+
uint64_t redir_flags;
|
|
118
|
+
|
|
119
|
+
ssize_t solid_window_size; /* Used in file format check. */
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
enum EXTRA {
|
|
123
|
+
EX_CRYPT = 0x01,
|
|
124
|
+
EX_HASH = 0x02,
|
|
125
|
+
EX_HTIME = 0x03,
|
|
126
|
+
EX_VERSION = 0x04,
|
|
127
|
+
EX_REDIR = 0x05,
|
|
128
|
+
EX_UOWNER = 0x06,
|
|
129
|
+
EX_SUBDATA = 0x07
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
#define REDIR_SYMLINK_IS_DIR 1
|
|
133
|
+
|
|
134
|
+
enum REDIR_TYPE {
|
|
135
|
+
REDIR_TYPE_NONE = 0,
|
|
136
|
+
REDIR_TYPE_UNIXSYMLINK = 1,
|
|
137
|
+
REDIR_TYPE_WINSYMLINK = 2,
|
|
138
|
+
REDIR_TYPE_JUNCTION = 3,
|
|
139
|
+
REDIR_TYPE_HARDLINK = 4,
|
|
140
|
+
REDIR_TYPE_FILECOPY = 5,
|
|
141
|
+
};
|
|
142
|
+
|
|
143
|
+
#define OWNER_USER_NAME 0x01
|
|
144
|
+
#define OWNER_GROUP_NAME 0x02
|
|
145
|
+
#define OWNER_USER_UID 0x04
|
|
146
|
+
#define OWNER_GROUP_GID 0x08
|
|
147
|
+
#define OWNER_MAXNAMELEN 256
|
|
148
|
+
|
|
149
|
+
enum FILTER_TYPE {
|
|
150
|
+
FILTER_DELTA = 0, /* Generic pattern. */
|
|
151
|
+
FILTER_E8 = 1, /* Intel x86 code. */
|
|
152
|
+
FILTER_E8E9 = 2, /* Intel x86 code. */
|
|
153
|
+
FILTER_ARM = 3, /* ARM code. */
|
|
154
|
+
FILTER_AUDIO = 4, /* Audio filter, not used in RARv5. */
|
|
155
|
+
FILTER_RGB = 5, /* Color palette, not used in RARv5. */
|
|
156
|
+
FILTER_ITANIUM = 6, /* Intel's Itanium, not used in RARv5. */
|
|
157
|
+
FILTER_PPM = 7, /* Predictive pattern matching, not used in
|
|
158
|
+
RARv5. */
|
|
159
|
+
FILTER_NONE = 8,
|
|
160
|
+
};
|
|
161
|
+
|
|
162
|
+
struct filter_info {
|
|
163
|
+
int type;
|
|
164
|
+
int channels;
|
|
165
|
+
int pos_r;
|
|
166
|
+
|
|
167
|
+
int64_t block_start;
|
|
168
|
+
ssize_t block_length;
|
|
169
|
+
uint16_t width;
|
|
170
|
+
};
|
|
171
|
+
|
|
172
|
+
struct data_ready {
|
|
173
|
+
char used;
|
|
174
|
+
const uint8_t* buf;
|
|
175
|
+
size_t size;
|
|
176
|
+
int64_t offset;
|
|
177
|
+
};
|
|
178
|
+
|
|
179
|
+
struct cdeque {
|
|
180
|
+
uint16_t beg_pos;
|
|
181
|
+
uint16_t end_pos;
|
|
182
|
+
uint16_t cap_mask;
|
|
183
|
+
uint16_t size;
|
|
184
|
+
size_t* arr;
|
|
185
|
+
};
|
|
186
|
+
|
|
187
|
+
struct decode_table {
|
|
188
|
+
uint32_t size;
|
|
189
|
+
int32_t decode_len[16];
|
|
190
|
+
uint32_t decode_pos[16];
|
|
191
|
+
uint32_t quick_bits;
|
|
192
|
+
uint8_t quick_len[1 << 10];
|
|
193
|
+
uint16_t quick_num[1 << 10];
|
|
194
|
+
uint16_t decode_num[306];
|
|
195
|
+
};
|
|
196
|
+
|
|
197
|
+
struct comp_state {
|
|
198
|
+
/* Flag used to specify if unpacker needs to reinitialize the
|
|
199
|
+
uncompression context. */
|
|
200
|
+
uint8_t initialized : 1;
|
|
201
|
+
|
|
202
|
+
/* Flag used when applying filters. */
|
|
203
|
+
uint8_t all_filters_applied : 1;
|
|
204
|
+
|
|
205
|
+
/* Flag used to skip file context reinitialization, used when unpacker
|
|
206
|
+
is skipping through different multivolume archives. */
|
|
207
|
+
uint8_t switch_multivolume : 1;
|
|
208
|
+
|
|
209
|
+
/* Flag used to specify if unpacker has processed the whole data block
|
|
210
|
+
or just a part of it. */
|
|
211
|
+
uint8_t block_parsing_finished : 1;
|
|
212
|
+
|
|
213
|
+
signed int notused : 4;
|
|
214
|
+
|
|
215
|
+
int flags; /* Uncompression flags. */
|
|
216
|
+
int method; /* Uncompression algorithm method. */
|
|
217
|
+
int version; /* Uncompression algorithm version. */
|
|
218
|
+
ssize_t window_size; /* Size of window_buf. */
|
|
219
|
+
uint8_t* window_buf; /* Circular buffer used during
|
|
220
|
+
decompression. */
|
|
221
|
+
uint8_t* filtered_buf; /* Buffer used when applying filters. */
|
|
222
|
+
const uint8_t* block_buf; /* Buffer used when merging blocks. */
|
|
223
|
+
size_t window_mask; /* Convenience field; window_size - 1. */
|
|
224
|
+
int64_t write_ptr; /* This amount of data has been unpacked
|
|
225
|
+
in the window buffer. */
|
|
226
|
+
int64_t last_write_ptr; /* This amount of data has been stored in
|
|
227
|
+
the output file. */
|
|
228
|
+
int64_t last_unstore_ptr; /* Counter of bytes extracted during
|
|
229
|
+
unstoring. This is separate from
|
|
230
|
+
last_write_ptr because of how SERVICE
|
|
231
|
+
base blocks are handled during skipping
|
|
232
|
+
in solid multiarchive archives. */
|
|
233
|
+
int64_t solid_offset; /* Additional offset inside the window
|
|
234
|
+
buffer, used in unpacking solid
|
|
235
|
+
archives. */
|
|
236
|
+
ssize_t cur_block_size; /* Size of current data block. */
|
|
237
|
+
int last_len; /* Flag used in lzss decompression. */
|
|
238
|
+
|
|
239
|
+
/* Decode tables used during lzss uncompression. */
|
|
240
|
+
|
|
241
|
+
#define HUFF_BC 20
|
|
242
|
+
struct decode_table bd; /* huffman bit lengths */
|
|
243
|
+
#define HUFF_NC 306
|
|
244
|
+
struct decode_table ld; /* literals */
|
|
245
|
+
#define HUFF_DC 64
|
|
246
|
+
struct decode_table dd; /* distances */
|
|
247
|
+
#define HUFF_LDC 16
|
|
248
|
+
struct decode_table ldd; /* lower bits of distances */
|
|
249
|
+
#define HUFF_RC 44
|
|
250
|
+
struct decode_table rd; /* repeating distances */
|
|
251
|
+
#define HUFF_TABLE_SIZE (HUFF_NC + HUFF_DC + HUFF_RC + HUFF_LDC)
|
|
252
|
+
|
|
253
|
+
/* Circular deque for storing filters. */
|
|
254
|
+
struct cdeque filters;
|
|
255
|
+
int64_t last_block_start; /* Used for sanity checking. */
|
|
256
|
+
ssize_t last_block_length; /* Used for sanity checking. */
|
|
257
|
+
|
|
258
|
+
/* Distance cache used during lzss uncompression. */
|
|
259
|
+
int dist_cache[4];
|
|
260
|
+
|
|
261
|
+
/* Data buffer stack. */
|
|
262
|
+
struct data_ready dready[2];
|
|
263
|
+
};
|
|
264
|
+
|
|
265
|
+
/* Bit reader state. */
|
|
266
|
+
struct bit_reader {
|
|
267
|
+
int8_t bit_addr; /* Current bit pointer inside current byte. */
|
|
268
|
+
int in_addr; /* Current byte pointer. */
|
|
269
|
+
};
|
|
270
|
+
|
|
271
|
+
/* RARv5 block header structure. Use bf_* functions to get values from
|
|
272
|
+
* block_flags_u8 field. I.e. bf_byte_count, etc. */
|
|
273
|
+
struct compressed_block_header {
|
|
274
|
+
/* block_flags_u8 contain fields encoded in little-endian bitfield:
|
|
275
|
+
*
|
|
276
|
+
* - table present flag (shr 7, and 1),
|
|
277
|
+
* - last block flag (shr 6, and 1),
|
|
278
|
+
* - byte_count (shr 3, and 7),
|
|
279
|
+
* - bit_size (shr 0, and 7).
|
|
280
|
+
*/
|
|
281
|
+
uint8_t block_flags_u8;
|
|
282
|
+
uint8_t block_cksum;
|
|
283
|
+
};
|
|
284
|
+
|
|
285
|
+
/* RARv5 main header structure. */
|
|
286
|
+
struct main_header {
|
|
287
|
+
/* Does the archive contain solid streams? */
|
|
288
|
+
uint8_t solid : 1;
|
|
289
|
+
|
|
290
|
+
/* If this a multi-file archive? */
|
|
291
|
+
uint8_t volume : 1;
|
|
292
|
+
uint8_t endarc : 1;
|
|
293
|
+
uint8_t notused : 5;
|
|
294
|
+
|
|
295
|
+
unsigned int vol_no;
|
|
296
|
+
};
|
|
297
|
+
|
|
298
|
+
struct generic_header {
|
|
299
|
+
uint8_t split_after : 1;
|
|
300
|
+
uint8_t split_before : 1;
|
|
301
|
+
uint8_t padding : 6;
|
|
302
|
+
int size;
|
|
303
|
+
int last_header_id;
|
|
304
|
+
};
|
|
305
|
+
|
|
306
|
+
struct multivolume {
|
|
307
|
+
unsigned int expected_vol_no;
|
|
308
|
+
uint8_t* push_buf;
|
|
309
|
+
};
|
|
310
|
+
|
|
311
|
+
/* Main context structure. */
|
|
312
|
+
struct rar5 {
|
|
313
|
+
int header_initialized;
|
|
314
|
+
|
|
315
|
+
/* Set to 1 if current file is positioned AFTER the magic value
|
|
316
|
+
* of the archive file. This is used in header reading functions. */
|
|
317
|
+
int skipped_magic;
|
|
318
|
+
|
|
319
|
+
/* Set to not zero if we're in skip mode (either by calling
|
|
320
|
+
* rar5_data_skip function or when skipping over solid streams).
|
|
321
|
+
* Set to 0 when in * extraction mode. This is used during checksum
|
|
322
|
+
* calculation functions. */
|
|
323
|
+
int skip_mode;
|
|
324
|
+
|
|
325
|
+
/* Set to not zero if we're in block merging mode (i.e. when switching
|
|
326
|
+
* to another file in multivolume archive, last block from 1st archive
|
|
327
|
+
* needs to be merged with 1st block from 2nd archive). This flag
|
|
328
|
+
* guards against recursive use of the merging function, which doesn't
|
|
329
|
+
* support recursive calls. */
|
|
330
|
+
int merge_mode;
|
|
331
|
+
|
|
332
|
+
/* An offset to QuickOpen list. This is not supported by this unpacker,
|
|
333
|
+
* because we're focusing on streaming interface. QuickOpen is designed
|
|
334
|
+
* to make things quicker for non-stream interfaces, so it's not our
|
|
335
|
+
* use case. */
|
|
336
|
+
uint64_t qlist_offset;
|
|
337
|
+
|
|
338
|
+
/* An offset to additional Recovery data. This is not supported by this
|
|
339
|
+
* unpacker. Recovery data are additional Reed-Solomon codes that could
|
|
340
|
+
* be used to calculate bytes that are missing in archive or are
|
|
341
|
+
* corrupted. */
|
|
342
|
+
uint64_t rr_offset;
|
|
343
|
+
|
|
344
|
+
/* Various context variables grouped to different structures. */
|
|
345
|
+
struct generic_header generic;
|
|
346
|
+
struct main_header main;
|
|
347
|
+
struct comp_state cstate;
|
|
348
|
+
struct file_header file;
|
|
349
|
+
struct bit_reader bits;
|
|
350
|
+
struct multivolume vol;
|
|
351
|
+
|
|
352
|
+
/* The header of currently processed RARv5 block. Used in main
|
|
353
|
+
* decompression logic loop. */
|
|
354
|
+
struct compressed_block_header last_block_hdr;
|
|
355
|
+
};
|
|
356
|
+
|
|
357
|
+
/* Forward function declarations. */
|
|
358
|
+
|
|
359
|
+
static void rar5_signature(char *buf);
|
|
360
|
+
static int verify_global_checksums(struct archive_read* a);
|
|
361
|
+
static int rar5_read_data_skip(struct archive_read *a);
|
|
362
|
+
static int push_data_ready(struct archive_read* a, struct rar5* rar,
|
|
363
|
+
const uint8_t* buf, size_t size, int64_t offset);
|
|
364
|
+
|
|
365
|
+
/* CDE_xxx = Circular Double Ended (Queue) return values. */
|
|
366
|
+
enum CDE_RETURN_VALUES {
|
|
367
|
+
CDE_OK, CDE_ALLOC, CDE_PARAM, CDE_OUT_OF_BOUNDS,
|
|
368
|
+
};
|
|
369
|
+
|
|
370
|
+
/* Clears the contents of this circular deque. */
|
|
371
|
+
static void cdeque_clear(struct cdeque* d) {
|
|
372
|
+
d->size = 0;
|
|
373
|
+
d->beg_pos = 0;
|
|
374
|
+
d->end_pos = 0;
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
/* Creates a new circular deque object. Capacity must be power of 2: 8, 16, 32,
|
|
378
|
+
* 64, 256, etc. When the user will add another item above current capacity,
|
|
379
|
+
* the circular deque will overwrite the oldest entry. */
|
|
380
|
+
static int cdeque_init(struct cdeque* d, int max_capacity_power_of_2) {
|
|
381
|
+
if(d == NULL || max_capacity_power_of_2 == 0)
|
|
382
|
+
return CDE_PARAM;
|
|
383
|
+
|
|
384
|
+
d->cap_mask = max_capacity_power_of_2 - 1;
|
|
385
|
+
d->arr = NULL;
|
|
386
|
+
|
|
387
|
+
if((max_capacity_power_of_2 & d->cap_mask) != 0)
|
|
388
|
+
return CDE_PARAM;
|
|
389
|
+
|
|
390
|
+
cdeque_clear(d);
|
|
391
|
+
d->arr = malloc(sizeof(void*) * max_capacity_power_of_2);
|
|
392
|
+
|
|
393
|
+
return d->arr ? CDE_OK : CDE_ALLOC;
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
/* Return the current size (not capacity) of circular deque `d`. */
|
|
397
|
+
static size_t cdeque_size(struct cdeque* d) {
|
|
398
|
+
return d->size;
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
/* Returns the first element of current circular deque. Note that this function
|
|
402
|
+
* doesn't perform any bounds checking. If you need bounds checking, use
|
|
403
|
+
* `cdeque_front()` function instead. */
|
|
404
|
+
static void cdeque_front_fast(struct cdeque* d, void** value) {
|
|
405
|
+
*value = (void*) d->arr[d->beg_pos];
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
/* Returns the first element of current circular deque. This function
|
|
409
|
+
* performs bounds checking. */
|
|
410
|
+
static int cdeque_front(struct cdeque* d, void** value) {
|
|
411
|
+
if(d->size > 0) {
|
|
412
|
+
cdeque_front_fast(d, value);
|
|
413
|
+
return CDE_OK;
|
|
414
|
+
} else
|
|
415
|
+
return CDE_OUT_OF_BOUNDS;
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
/* Pushes a new element into the end of this circular deque object. If current
|
|
419
|
+
* size will exceed capacity, the oldest element will be overwritten. */
|
|
420
|
+
static int cdeque_push_back(struct cdeque* d, void* item) {
|
|
421
|
+
if(d == NULL)
|
|
422
|
+
return CDE_PARAM;
|
|
423
|
+
|
|
424
|
+
if(d->size == d->cap_mask + 1)
|
|
425
|
+
return CDE_OUT_OF_BOUNDS;
|
|
426
|
+
|
|
427
|
+
d->arr[d->end_pos] = (size_t) item;
|
|
428
|
+
d->end_pos = (d->end_pos + 1) & d->cap_mask;
|
|
429
|
+
d->size++;
|
|
430
|
+
|
|
431
|
+
return CDE_OK;
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
/* Pops a front element of this circular deque object and returns its value.
|
|
435
|
+
* This function doesn't perform any bounds checking. */
|
|
436
|
+
static void cdeque_pop_front_fast(struct cdeque* d, void** value) {
|
|
437
|
+
*value = (void*) d->arr[d->beg_pos];
|
|
438
|
+
d->beg_pos = (d->beg_pos + 1) & d->cap_mask;
|
|
439
|
+
d->size--;
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
/* Pops a front element of this circular deque object and returns its value.
|
|
443
|
+
* This function performs bounds checking. */
|
|
444
|
+
static int cdeque_pop_front(struct cdeque* d, void** value) {
|
|
445
|
+
if(!d || !value)
|
|
446
|
+
return CDE_PARAM;
|
|
447
|
+
|
|
448
|
+
if(d->size == 0)
|
|
449
|
+
return CDE_OUT_OF_BOUNDS;
|
|
450
|
+
|
|
451
|
+
cdeque_pop_front_fast(d, value);
|
|
452
|
+
return CDE_OK;
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
/* Convenience function to cast filter_info** to void **. */
|
|
456
|
+
static void** cdeque_filter_p(struct filter_info** f) {
|
|
457
|
+
return (void**) (size_t) f;
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
/* Convenience function to cast filter_info* to void *. */
|
|
461
|
+
static void* cdeque_filter(struct filter_info* f) {
|
|
462
|
+
return (void**) (size_t) f;
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
/* Destroys this circular deque object. Deallocates the memory of the
|
|
466
|
+
* collection buffer, but doesn't deallocate the memory of any pointer passed
|
|
467
|
+
* to this deque as a value. */
|
|
468
|
+
static void cdeque_free(struct cdeque* d) {
|
|
469
|
+
if(!d)
|
|
470
|
+
return;
|
|
471
|
+
|
|
472
|
+
if(!d->arr)
|
|
473
|
+
return;
|
|
474
|
+
|
|
475
|
+
free(d->arr);
|
|
476
|
+
|
|
477
|
+
d->arr = NULL;
|
|
478
|
+
d->beg_pos = -1;
|
|
479
|
+
d->end_pos = -1;
|
|
480
|
+
d->cap_mask = 0;
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
static inline
|
|
484
|
+
uint8_t bf_bit_size(const struct compressed_block_header* hdr) {
|
|
485
|
+
return hdr->block_flags_u8 & 7;
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
static inline
|
|
489
|
+
uint8_t bf_byte_count(const struct compressed_block_header* hdr) {
|
|
490
|
+
return (hdr->block_flags_u8 >> 3) & 7;
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
static inline
|
|
494
|
+
uint8_t bf_is_table_present(const struct compressed_block_header* hdr) {
|
|
495
|
+
return (hdr->block_flags_u8 >> 7) & 1;
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
static inline struct rar5* get_context(struct archive_read* a) {
|
|
499
|
+
return (struct rar5*) a->format->data;
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
/* Convenience functions used by filter implementations. */
|
|
503
|
+
static void circular_memcpy(uint8_t* dst, uint8_t* window, const uint64_t mask,
|
|
504
|
+
int64_t start, int64_t end)
|
|
505
|
+
{
|
|
506
|
+
if((start & mask) > (end & mask)) {
|
|
507
|
+
ssize_t len1 = mask + 1 - (start & mask);
|
|
508
|
+
ssize_t len2 = end & mask;
|
|
509
|
+
|
|
510
|
+
memcpy(dst, &window[start & mask], len1);
|
|
511
|
+
memcpy(dst + len1, window, len2);
|
|
512
|
+
} else {
|
|
513
|
+
memcpy(dst, &window[start & mask], (size_t) (end - start));
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
static uint32_t read_filter_data(struct rar5* rar, uint32_t offset) {
|
|
518
|
+
uint8_t linear_buf[4];
|
|
519
|
+
circular_memcpy(linear_buf, rar->cstate.window_buf,
|
|
520
|
+
rar->cstate.window_mask, offset, offset + 4);
|
|
521
|
+
return archive_le32dec(linear_buf);
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
static void write_filter_data(struct rar5* rar, uint32_t offset,
|
|
525
|
+
uint32_t value)
|
|
526
|
+
{
|
|
527
|
+
archive_le32enc(&rar->cstate.filtered_buf[offset], value);
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
/* Allocates a new filter descriptor and adds it to the filter array. */
|
|
531
|
+
static struct filter_info* add_new_filter(struct rar5* rar) {
|
|
532
|
+
struct filter_info* f =
|
|
533
|
+
(struct filter_info*) calloc(1, sizeof(struct filter_info));
|
|
534
|
+
|
|
535
|
+
if(!f) {
|
|
536
|
+
return NULL;
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
cdeque_push_back(&rar->cstate.filters, cdeque_filter(f));
|
|
540
|
+
return f;
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
static int run_delta_filter(struct rar5* rar, struct filter_info* flt) {
|
|
544
|
+
int i;
|
|
545
|
+
ssize_t dest_pos, src_pos = 0;
|
|
546
|
+
|
|
547
|
+
for(i = 0; i < flt->channels; i++) {
|
|
548
|
+
uint8_t prev_byte = 0;
|
|
549
|
+
for(dest_pos = i;
|
|
550
|
+
dest_pos < flt->block_length;
|
|
551
|
+
dest_pos += flt->channels)
|
|
552
|
+
{
|
|
553
|
+
uint8_t byte;
|
|
554
|
+
|
|
555
|
+
byte = rar->cstate.window_buf[
|
|
556
|
+
(rar->cstate.solid_offset + flt->block_start +
|
|
557
|
+
src_pos) & rar->cstate.window_mask];
|
|
558
|
+
|
|
559
|
+
prev_byte -= byte;
|
|
560
|
+
rar->cstate.filtered_buf[dest_pos] = prev_byte;
|
|
561
|
+
src_pos++;
|
|
562
|
+
}
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
return ARCHIVE_OK;
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
static int run_e8e9_filter(struct rar5* rar, struct filter_info* flt,
|
|
569
|
+
int extended)
|
|
570
|
+
{
|
|
571
|
+
const uint32_t file_size = 0x1000000;
|
|
572
|
+
ssize_t i;
|
|
573
|
+
|
|
574
|
+
circular_memcpy(rar->cstate.filtered_buf,
|
|
575
|
+
rar->cstate.window_buf, rar->cstate.window_mask,
|
|
576
|
+
rar->cstate.solid_offset + flt->block_start,
|
|
577
|
+
rar->cstate.solid_offset + flt->block_start + flt->block_length);
|
|
578
|
+
|
|
579
|
+
for(i = 0; i < flt->block_length - 4;) {
|
|
580
|
+
uint8_t b = rar->cstate.window_buf[
|
|
581
|
+
(rar->cstate.solid_offset + flt->block_start +
|
|
582
|
+
i++) & rar->cstate.window_mask];
|
|
583
|
+
|
|
584
|
+
/*
|
|
585
|
+
* 0xE8 = x86's call <relative_addr_uint32> (function call)
|
|
586
|
+
* 0xE9 = x86's jmp <relative_addr_uint32> (unconditional jump)
|
|
587
|
+
*/
|
|
588
|
+
if(b == 0xE8 || (extended && b == 0xE9)) {
|
|
589
|
+
|
|
590
|
+
uint32_t addr;
|
|
591
|
+
uint32_t offset = (i + flt->block_start) % file_size;
|
|
592
|
+
|
|
593
|
+
addr = read_filter_data(rar,
|
|
594
|
+
(uint32_t)(rar->cstate.solid_offset +
|
|
595
|
+
flt->block_start + i) & rar->cstate.window_mask);
|
|
596
|
+
|
|
597
|
+
if(addr & 0x80000000) {
|
|
598
|
+
if(((addr + offset) & 0x80000000) == 0) {
|
|
599
|
+
write_filter_data(rar, (uint32_t)i,
|
|
600
|
+
addr + file_size);
|
|
601
|
+
}
|
|
602
|
+
} else {
|
|
603
|
+
if((addr - file_size) & 0x80000000) {
|
|
604
|
+
uint32_t naddr = addr - offset;
|
|
605
|
+
write_filter_data(rar, (uint32_t)i,
|
|
606
|
+
naddr);
|
|
607
|
+
}
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
i += 4;
|
|
611
|
+
}
|
|
612
|
+
}
|
|
613
|
+
|
|
614
|
+
return ARCHIVE_OK;
|
|
615
|
+
}
|
|
616
|
+
|
|
617
|
+
static int run_arm_filter(struct rar5* rar, struct filter_info* flt) {
|
|
618
|
+
ssize_t i = 0;
|
|
619
|
+
uint32_t offset;
|
|
620
|
+
|
|
621
|
+
circular_memcpy(rar->cstate.filtered_buf,
|
|
622
|
+
rar->cstate.window_buf, rar->cstate.window_mask,
|
|
623
|
+
rar->cstate.solid_offset + flt->block_start,
|
|
624
|
+
rar->cstate.solid_offset + flt->block_start + flt->block_length);
|
|
625
|
+
|
|
626
|
+
for(i = 0; i < flt->block_length - 3; i += 4) {
|
|
627
|
+
uint8_t* b = &rar->cstate.window_buf[
|
|
628
|
+
(rar->cstate.solid_offset +
|
|
629
|
+
flt->block_start + i + 3) & rar->cstate.window_mask];
|
|
630
|
+
|
|
631
|
+
if(*b == 0xEB) {
|
|
632
|
+
/* 0xEB = ARM's BL (branch + link) instruction. */
|
|
633
|
+
offset = read_filter_data(rar,
|
|
634
|
+
(rar->cstate.solid_offset + flt->block_start + i) &
|
|
635
|
+
(uint32_t)rar->cstate.window_mask) & 0x00ffffff;
|
|
636
|
+
|
|
637
|
+
offset -= (uint32_t) ((i + flt->block_start) / 4);
|
|
638
|
+
offset = (offset & 0x00ffffff) | 0xeb000000;
|
|
639
|
+
write_filter_data(rar, (uint32_t)i, offset);
|
|
640
|
+
}
|
|
641
|
+
}
|
|
642
|
+
|
|
643
|
+
return ARCHIVE_OK;
|
|
644
|
+
}
|
|
645
|
+
|
|
646
|
+
static int run_filter(struct archive_read* a, struct filter_info* flt) {
|
|
647
|
+
int ret;
|
|
648
|
+
struct rar5* rar = get_context(a);
|
|
649
|
+
|
|
650
|
+
free(rar->cstate.filtered_buf);
|
|
651
|
+
|
|
652
|
+
rar->cstate.filtered_buf = malloc(flt->block_length);
|
|
653
|
+
if(!rar->cstate.filtered_buf) {
|
|
654
|
+
archive_set_error(&a->archive, ENOMEM,
|
|
655
|
+
"Can't allocate memory for filter data.");
|
|
656
|
+
return ARCHIVE_FATAL;
|
|
657
|
+
}
|
|
658
|
+
|
|
659
|
+
switch(flt->type) {
|
|
660
|
+
case FILTER_DELTA:
|
|
661
|
+
ret = run_delta_filter(rar, flt);
|
|
662
|
+
break;
|
|
663
|
+
|
|
664
|
+
case FILTER_E8:
|
|
665
|
+
/* fallthrough */
|
|
666
|
+
case FILTER_E8E9:
|
|
667
|
+
ret = run_e8e9_filter(rar, flt,
|
|
668
|
+
flt->type == FILTER_E8E9);
|
|
669
|
+
break;
|
|
670
|
+
|
|
671
|
+
case FILTER_ARM:
|
|
672
|
+
ret = run_arm_filter(rar, flt);
|
|
673
|
+
break;
|
|
674
|
+
|
|
675
|
+
default:
|
|
676
|
+
archive_set_error(&a->archive,
|
|
677
|
+
ARCHIVE_ERRNO_FILE_FORMAT,
|
|
678
|
+
"Unsupported filter type: 0x%x", flt->type);
|
|
679
|
+
return ARCHIVE_FATAL;
|
|
680
|
+
}
|
|
681
|
+
|
|
682
|
+
if(ret != ARCHIVE_OK) {
|
|
683
|
+
/* Filter has failed. */
|
|
684
|
+
return ret;
|
|
685
|
+
}
|
|
686
|
+
|
|
687
|
+
if(ARCHIVE_OK != push_data_ready(a, rar, rar->cstate.filtered_buf,
|
|
688
|
+
flt->block_length, rar->cstate.last_write_ptr))
|
|
689
|
+
{
|
|
690
|
+
archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER,
|
|
691
|
+
"Stack overflow when submitting unpacked data");
|
|
692
|
+
|
|
693
|
+
return ARCHIVE_FATAL;
|
|
694
|
+
}
|
|
695
|
+
|
|
696
|
+
rar->cstate.last_write_ptr += flt->block_length;
|
|
697
|
+
return ARCHIVE_OK;
|
|
698
|
+
}
|
|
699
|
+
|
|
700
|
+
/* The `push_data` function submits the selected data range to the user.
|
|
701
|
+
* Next call of `use_data` will use the pointer, size and offset arguments
|
|
702
|
+
* that are specified here. These arguments are pushed to the FIFO stack here,
|
|
703
|
+
* and popped from the stack by the `use_data` function. */
|
|
704
|
+
static void push_data(struct archive_read* a, struct rar5* rar,
|
|
705
|
+
const uint8_t* buf, int64_t idx_begin, int64_t idx_end)
|
|
706
|
+
{
|
|
707
|
+
const uint64_t wmask = rar->cstate.window_mask;
|
|
708
|
+
const ssize_t solid_write_ptr = (rar->cstate.solid_offset +
|
|
709
|
+
rar->cstate.last_write_ptr) & wmask;
|
|
710
|
+
|
|
711
|
+
idx_begin += rar->cstate.solid_offset;
|
|
712
|
+
idx_end += rar->cstate.solid_offset;
|
|
713
|
+
|
|
714
|
+
/* Check if our unpacked data is wrapped inside the window circular
|
|
715
|
+
* buffer. If it's not wrapped, it can be copied out by using
|
|
716
|
+
* a single memcpy, but when it's wrapped, we need to copy the first
|
|
717
|
+
* part with one memcpy, and the second part with another memcpy. */
|
|
718
|
+
|
|
719
|
+
if((idx_begin & wmask) > (idx_end & wmask)) {
|
|
720
|
+
/* The data is wrapped (begin offset sis bigger than end
|
|
721
|
+
* offset). */
|
|
722
|
+
const ssize_t frag1_size = rar->cstate.window_size -
|
|
723
|
+
(idx_begin & wmask);
|
|
724
|
+
const ssize_t frag2_size = idx_end & wmask;
|
|
725
|
+
|
|
726
|
+
/* Copy the first part of the buffer first. */
|
|
727
|
+
push_data_ready(a, rar, buf + solid_write_ptr, frag1_size,
|
|
728
|
+
rar->cstate.last_write_ptr);
|
|
729
|
+
|
|
730
|
+
/* Copy the second part of the buffer. */
|
|
731
|
+
push_data_ready(a, rar, buf, frag2_size,
|
|
732
|
+
rar->cstate.last_write_ptr + frag1_size);
|
|
733
|
+
|
|
734
|
+
rar->cstate.last_write_ptr += frag1_size + frag2_size;
|
|
735
|
+
} else {
|
|
736
|
+
/* Data is not wrapped, so we can just use one call to copy the
|
|
737
|
+
* data. */
|
|
738
|
+
push_data_ready(a, rar,
|
|
739
|
+
buf + solid_write_ptr, (idx_end - idx_begin) & wmask,
|
|
740
|
+
rar->cstate.last_write_ptr);
|
|
741
|
+
|
|
742
|
+
rar->cstate.last_write_ptr += idx_end - idx_begin;
|
|
743
|
+
}
|
|
744
|
+
}
|
|
745
|
+
|
|
746
|
+
/* Convenience function that submits the data to the user. It uses the
|
|
747
|
+
* unpack window buffer as a source location. */
|
|
748
|
+
static void push_window_data(struct archive_read* a, struct rar5* rar,
|
|
749
|
+
int64_t idx_begin, int64_t idx_end)
|
|
750
|
+
{
|
|
751
|
+
push_data(a, rar, rar->cstate.window_buf, idx_begin, idx_end);
|
|
752
|
+
}
|
|
753
|
+
|
|
754
|
+
static int apply_filters(struct archive_read* a) {
|
|
755
|
+
struct filter_info* flt;
|
|
756
|
+
struct rar5* rar = get_context(a);
|
|
757
|
+
int ret;
|
|
758
|
+
|
|
759
|
+
rar->cstate.all_filters_applied = 0;
|
|
760
|
+
|
|
761
|
+
/* Get the first filter that can be applied to our data. The data
|
|
762
|
+
* needs to be fully unpacked before the filter can be run. */
|
|
763
|
+
if(CDE_OK == cdeque_front(&rar->cstate.filters,
|
|
764
|
+
cdeque_filter_p(&flt))) {
|
|
765
|
+
/* Check if our unpacked data fully covers this filter's
|
|
766
|
+
* range. */
|
|
767
|
+
if(rar->cstate.write_ptr > flt->block_start &&
|
|
768
|
+
rar->cstate.write_ptr >= flt->block_start +
|
|
769
|
+
flt->block_length) {
|
|
770
|
+
/* Check if we have some data pending to be written
|
|
771
|
+
* right before the filter's start offset. */
|
|
772
|
+
if(rar->cstate.last_write_ptr == flt->block_start) {
|
|
773
|
+
/* Run the filter specified by descriptor
|
|
774
|
+
* `flt`. */
|
|
775
|
+
ret = run_filter(a, flt);
|
|
776
|
+
if(ret != ARCHIVE_OK) {
|
|
777
|
+
/* Filter failure, return error. */
|
|
778
|
+
return ret;
|
|
779
|
+
}
|
|
780
|
+
|
|
781
|
+
/* Filter descriptor won't be needed anymore
|
|
782
|
+
* after it's used, * so remove it from the
|
|
783
|
+
* filter list and free its memory. */
|
|
784
|
+
(void) cdeque_pop_front(&rar->cstate.filters,
|
|
785
|
+
cdeque_filter_p(&flt));
|
|
786
|
+
|
|
787
|
+
free(flt);
|
|
788
|
+
} else {
|
|
789
|
+
/* We can't run filters yet, dump the memory
|
|
790
|
+
* right before the filter. */
|
|
791
|
+
push_window_data(a, rar,
|
|
792
|
+
rar->cstate.last_write_ptr,
|
|
793
|
+
flt->block_start);
|
|
794
|
+
}
|
|
795
|
+
|
|
796
|
+
/* Return 'filter applied or not needed' state to the
|
|
797
|
+
* caller. */
|
|
798
|
+
return ARCHIVE_RETRY;
|
|
799
|
+
}
|
|
800
|
+
}
|
|
801
|
+
|
|
802
|
+
rar->cstate.all_filters_applied = 1;
|
|
803
|
+
return ARCHIVE_OK;
|
|
804
|
+
}
|
|
805
|
+
|
|
806
|
+
static void dist_cache_push(struct rar5* rar, int value) {
|
|
807
|
+
int* q = rar->cstate.dist_cache;
|
|
808
|
+
|
|
809
|
+
q[3] = q[2];
|
|
810
|
+
q[2] = q[1];
|
|
811
|
+
q[1] = q[0];
|
|
812
|
+
q[0] = value;
|
|
813
|
+
}
|
|
814
|
+
|
|
815
|
+
static int dist_cache_touch(struct rar5* rar, int idx) {
|
|
816
|
+
int* q = rar->cstate.dist_cache;
|
|
817
|
+
int i, dist = q[idx];
|
|
818
|
+
|
|
819
|
+
for(i = idx; i > 0; i--)
|
|
820
|
+
q[i] = q[i - 1];
|
|
821
|
+
|
|
822
|
+
q[0] = dist;
|
|
823
|
+
return dist;
|
|
824
|
+
}
|
|
825
|
+
|
|
826
|
+
static void free_filters(struct rar5* rar) {
|
|
827
|
+
struct cdeque* d = &rar->cstate.filters;
|
|
828
|
+
|
|
829
|
+
/* Free any remaining filters. All filters should be naturally
|
|
830
|
+
* consumed by the unpacking function, so remaining filters after
|
|
831
|
+
* unpacking normally mean that unpacking wasn't successful.
|
|
832
|
+
* But still of course we shouldn't leak memory in such case. */
|
|
833
|
+
|
|
834
|
+
/* cdeque_size() is a fast operation, so we can use it as a loop
|
|
835
|
+
* expression. */
|
|
836
|
+
while(cdeque_size(d) > 0) {
|
|
837
|
+
struct filter_info* f = NULL;
|
|
838
|
+
|
|
839
|
+
/* Pop_front will also decrease the collection's size. */
|
|
840
|
+
if (CDE_OK == cdeque_pop_front(d, cdeque_filter_p(&f)))
|
|
841
|
+
free(f);
|
|
842
|
+
}
|
|
843
|
+
|
|
844
|
+
cdeque_clear(d);
|
|
845
|
+
|
|
846
|
+
/* Also clear out the variables needed for sanity checking. */
|
|
847
|
+
rar->cstate.last_block_start = 0;
|
|
848
|
+
rar->cstate.last_block_length = 0;
|
|
849
|
+
}
|
|
850
|
+
|
|
851
|
+
static void reset_file_context(struct rar5* rar) {
|
|
852
|
+
memset(&rar->file, 0, sizeof(rar->file));
|
|
853
|
+
blake2sp_init(&rar->file.b2state, 32);
|
|
854
|
+
|
|
855
|
+
if(rar->main.solid) {
|
|
856
|
+
rar->cstate.solid_offset += rar->cstate.write_ptr;
|
|
857
|
+
} else {
|
|
858
|
+
rar->cstate.solid_offset = 0;
|
|
859
|
+
}
|
|
860
|
+
|
|
861
|
+
rar->cstate.write_ptr = 0;
|
|
862
|
+
rar->cstate.last_write_ptr = 0;
|
|
863
|
+
rar->cstate.last_unstore_ptr = 0;
|
|
864
|
+
|
|
865
|
+
rar->file.redir_type = REDIR_TYPE_NONE;
|
|
866
|
+
rar->file.redir_flags = 0;
|
|
867
|
+
|
|
868
|
+
free_filters(rar);
|
|
869
|
+
}
|
|
870
|
+
|
|
871
|
+
static inline int get_archive_read(struct archive* a,
|
|
872
|
+
struct archive_read** ar)
|
|
873
|
+
{
|
|
874
|
+
*ar = (struct archive_read*) a;
|
|
875
|
+
archive_check_magic(a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_NEW,
|
|
876
|
+
"archive_read_support_format_rar5");
|
|
877
|
+
|
|
878
|
+
return ARCHIVE_OK;
|
|
879
|
+
}
|
|
880
|
+
|
|
881
|
+
static int read_ahead(struct archive_read* a, size_t how_many,
|
|
882
|
+
const uint8_t** ptr)
|
|
883
|
+
{
|
|
884
|
+
ssize_t avail = -1;
|
|
885
|
+
if(!ptr)
|
|
886
|
+
return 0;
|
|
887
|
+
|
|
888
|
+
*ptr = __archive_read_ahead(a, how_many, &avail);
|
|
889
|
+
if(*ptr == NULL) {
|
|
890
|
+
return 0;
|
|
891
|
+
}
|
|
892
|
+
|
|
893
|
+
return 1;
|
|
894
|
+
}
|
|
895
|
+
|
|
896
|
+
static int consume(struct archive_read* a, int64_t how_many) {
|
|
897
|
+
int ret;
|
|
898
|
+
|
|
899
|
+
ret = how_many == __archive_read_consume(a, how_many)
|
|
900
|
+
? ARCHIVE_OK
|
|
901
|
+
: ARCHIVE_FATAL;
|
|
902
|
+
|
|
903
|
+
return ret;
|
|
904
|
+
}
|
|
905
|
+
|
|
906
|
+
/**
|
|
907
|
+
* Read a RAR5 variable sized numeric value. This value will be stored in
|
|
908
|
+
* `pvalue`. The `pvalue_len` argument points to a variable that will receive
|
|
909
|
+
* the byte count that was consumed in order to decode the `pvalue` value, plus
|
|
910
|
+
* one.
|
|
911
|
+
*
|
|
912
|
+
* pvalue_len is optional and can be NULL.
|
|
913
|
+
*
|
|
914
|
+
* NOTE: if `pvalue_len` is NOT NULL, the caller needs to manually consume
|
|
915
|
+
* the number of bytes that `pvalue_len` value contains. If the `pvalue_len`
|
|
916
|
+
* is NULL, this consuming operation is done automatically.
|
|
917
|
+
*
|
|
918
|
+
* Returns 1 if *pvalue was successfully read.
|
|
919
|
+
* Returns 0 if there was an error. In this case, *pvalue contains an
|
|
920
|
+
* invalid value.
|
|
921
|
+
*/
|
|
922
|
+
|
|
923
|
+
static int read_var(struct archive_read* a, uint64_t* pvalue,
|
|
924
|
+
uint64_t* pvalue_len)
|
|
925
|
+
{
|
|
926
|
+
uint64_t result = 0;
|
|
927
|
+
size_t shift, i;
|
|
928
|
+
const uint8_t* p;
|
|
929
|
+
uint8_t b;
|
|
930
|
+
|
|
931
|
+
/* We will read maximum of 8 bytes. We don't have to handle the
|
|
932
|
+
* situation to read the RAR5 variable-sized value stored at the end of
|
|
933
|
+
* the file, because such situation will never happen. */
|
|
934
|
+
if(!read_ahead(a, 8, &p))
|
|
935
|
+
return 0;
|
|
936
|
+
|
|
937
|
+
for(shift = 0, i = 0; i < 8; i++, shift += 7) {
|
|
938
|
+
b = p[i];
|
|
939
|
+
|
|
940
|
+
/* Strip the MSB from the input byte and add the resulting
|
|
941
|
+
* number to the `result`. */
|
|
942
|
+
result += (b & (uint64_t)0x7F) << shift;
|
|
943
|
+
|
|
944
|
+
/* MSB set to 1 means we need to continue decoding process.
|
|
945
|
+
* MSB set to 0 means we're done.
|
|
946
|
+
*
|
|
947
|
+
* This conditional checks for the second case. */
|
|
948
|
+
if((b & 0x80) == 0) {
|
|
949
|
+
if(pvalue) {
|
|
950
|
+
*pvalue = result;
|
|
951
|
+
}
|
|
952
|
+
|
|
953
|
+
/* If the caller has passed the `pvalue_len` pointer,
|
|
954
|
+
* store the number of consumed bytes in it and do NOT
|
|
955
|
+
* consume those bytes, since the caller has all the
|
|
956
|
+
* information it needs to perform */
|
|
957
|
+
if(pvalue_len) {
|
|
958
|
+
*pvalue_len = 1 + i;
|
|
959
|
+
} else {
|
|
960
|
+
/* If the caller did not provide the
|
|
961
|
+
* `pvalue_len` pointer, it will not have the
|
|
962
|
+
* possibility to advance the file pointer,
|
|
963
|
+
* because it will not know how many bytes it
|
|
964
|
+
* needs to consume. This is why we handle
|
|
965
|
+
* such situation here automatically. */
|
|
966
|
+
if(ARCHIVE_OK != consume(a, 1 + i)) {
|
|
967
|
+
return 0;
|
|
968
|
+
}
|
|
969
|
+
}
|
|
970
|
+
|
|
971
|
+
/* End of decoding process, return success. */
|
|
972
|
+
return 1;
|
|
973
|
+
}
|
|
974
|
+
}
|
|
975
|
+
|
|
976
|
+
/* The decoded value takes the maximum number of 8 bytes.
|
|
977
|
+
* It's a maximum number of bytes, so end decoding process here
|
|
978
|
+
* even if the first bit of last byte is 1. */
|
|
979
|
+
if(pvalue) {
|
|
980
|
+
*pvalue = result;
|
|
981
|
+
}
|
|
982
|
+
|
|
983
|
+
if(pvalue_len) {
|
|
984
|
+
*pvalue_len = 9;
|
|
985
|
+
} else {
|
|
986
|
+
if(ARCHIVE_OK != consume(a, 9)) {
|
|
987
|
+
return 0;
|
|
988
|
+
}
|
|
989
|
+
}
|
|
990
|
+
|
|
991
|
+
return 1;
|
|
992
|
+
}
|
|
993
|
+
|
|
994
|
+
static int read_var_sized(struct archive_read* a, size_t* pvalue,
|
|
995
|
+
size_t* pvalue_len)
|
|
996
|
+
{
|
|
997
|
+
uint64_t v;
|
|
998
|
+
uint64_t v_size = 0;
|
|
999
|
+
|
|
1000
|
+
const int ret = pvalue_len ? read_var(a, &v, &v_size)
|
|
1001
|
+
: read_var(a, &v, NULL);
|
|
1002
|
+
|
|
1003
|
+
if(ret == 1 && pvalue) {
|
|
1004
|
+
*pvalue = (size_t) v;
|
|
1005
|
+
}
|
|
1006
|
+
|
|
1007
|
+
if(pvalue_len) {
|
|
1008
|
+
/* Possible data truncation should be safe. */
|
|
1009
|
+
*pvalue_len = (size_t) v_size;
|
|
1010
|
+
}
|
|
1011
|
+
|
|
1012
|
+
return ret;
|
|
1013
|
+
}
|
|
1014
|
+
|
|
1015
|
+
static int read_bits_32(struct archive_read* a, struct rar5* rar,
|
|
1016
|
+
const uint8_t* p, uint32_t* value)
|
|
1017
|
+
{
|
|
1018
|
+
if(rar->bits.in_addr >= rar->cstate.cur_block_size) {
|
|
1019
|
+
archive_set_error(&a->archive,
|
|
1020
|
+
ARCHIVE_ERRNO_PROGRAMMER,
|
|
1021
|
+
"Premature end of stream during extraction of data (#1)");
|
|
1022
|
+
return ARCHIVE_FATAL;
|
|
1023
|
+
}
|
|
1024
|
+
|
|
1025
|
+
uint32_t bits = ((uint32_t) p[rar->bits.in_addr]) << 24;
|
|
1026
|
+
bits |= p[rar->bits.in_addr + 1] << 16;
|
|
1027
|
+
bits |= p[rar->bits.in_addr + 2] << 8;
|
|
1028
|
+
bits |= p[rar->bits.in_addr + 3];
|
|
1029
|
+
bits <<= rar->bits.bit_addr;
|
|
1030
|
+
bits |= p[rar->bits.in_addr + 4] >> (8 - rar->bits.bit_addr);
|
|
1031
|
+
*value = bits;
|
|
1032
|
+
return ARCHIVE_OK;
|
|
1033
|
+
}
|
|
1034
|
+
|
|
1035
|
+
static int read_bits_16(struct archive_read* a, struct rar5* rar,
|
|
1036
|
+
const uint8_t* p, uint16_t* value)
|
|
1037
|
+
{
|
|
1038
|
+
if(rar->bits.in_addr >= rar->cstate.cur_block_size) {
|
|
1039
|
+
archive_set_error(&a->archive,
|
|
1040
|
+
ARCHIVE_ERRNO_PROGRAMMER,
|
|
1041
|
+
"Premature end of stream during extraction of data (#2)");
|
|
1042
|
+
return ARCHIVE_FATAL;
|
|
1043
|
+
}
|
|
1044
|
+
|
|
1045
|
+
int bits = (int) ((uint32_t) p[rar->bits.in_addr]) << 16;
|
|
1046
|
+
bits |= (int) p[rar->bits.in_addr + 1] << 8;
|
|
1047
|
+
bits |= (int) p[rar->bits.in_addr + 2];
|
|
1048
|
+
bits >>= (8 - rar->bits.bit_addr);
|
|
1049
|
+
*value = bits & 0xffff;
|
|
1050
|
+
return ARCHIVE_OK;
|
|
1051
|
+
}
|
|
1052
|
+
|
|
1053
|
+
static void skip_bits(struct rar5* rar, int bits) {
|
|
1054
|
+
const int new_bits = rar->bits.bit_addr + bits;
|
|
1055
|
+
rar->bits.in_addr += new_bits >> 3;
|
|
1056
|
+
rar->bits.bit_addr = new_bits & 7;
|
|
1057
|
+
}
|
|
1058
|
+
|
|
1059
|
+
/* n = up to 16 */
|
|
1060
|
+
static int read_consume_bits(struct archive_read* a, struct rar5* rar,
|
|
1061
|
+
const uint8_t* p, int n, int* value)
|
|
1062
|
+
{
|
|
1063
|
+
uint16_t v;
|
|
1064
|
+
int ret, num;
|
|
1065
|
+
|
|
1066
|
+
if(n == 0 || n > 16) {
|
|
1067
|
+
/* This is a programmer error and should never happen
|
|
1068
|
+
* in runtime. */
|
|
1069
|
+
return ARCHIVE_FATAL;
|
|
1070
|
+
}
|
|
1071
|
+
|
|
1072
|
+
ret = read_bits_16(a, rar, p, &v);
|
|
1073
|
+
if(ret != ARCHIVE_OK)
|
|
1074
|
+
return ret;
|
|
1075
|
+
|
|
1076
|
+
num = (int) v;
|
|
1077
|
+
num >>= 16 - n;
|
|
1078
|
+
|
|
1079
|
+
skip_bits(rar, n);
|
|
1080
|
+
|
|
1081
|
+
if(value)
|
|
1082
|
+
*value = num;
|
|
1083
|
+
|
|
1084
|
+
return ARCHIVE_OK;
|
|
1085
|
+
}
|
|
1086
|
+
|
|
1087
|
+
static int read_u32(struct archive_read* a, uint32_t* pvalue) {
|
|
1088
|
+
const uint8_t* p;
|
|
1089
|
+
if(!read_ahead(a, 4, &p))
|
|
1090
|
+
return 0;
|
|
1091
|
+
|
|
1092
|
+
*pvalue = archive_le32dec(p);
|
|
1093
|
+
return ARCHIVE_OK == consume(a, 4) ? 1 : 0;
|
|
1094
|
+
}
|
|
1095
|
+
|
|
1096
|
+
static int read_u64(struct archive_read* a, uint64_t* pvalue) {
|
|
1097
|
+
const uint8_t* p;
|
|
1098
|
+
if(!read_ahead(a, 8, &p))
|
|
1099
|
+
return 0;
|
|
1100
|
+
|
|
1101
|
+
*pvalue = archive_le64dec(p);
|
|
1102
|
+
return ARCHIVE_OK == consume(a, 8) ? 1 : 0;
|
|
1103
|
+
}
|
|
1104
|
+
|
|
1105
|
+
static int bid_standard(struct archive_read* a) {
|
|
1106
|
+
const uint8_t* p;
|
|
1107
|
+
char signature[sizeof(rar5_signature_xor)];
|
|
1108
|
+
|
|
1109
|
+
rar5_signature(signature);
|
|
1110
|
+
|
|
1111
|
+
if(!read_ahead(a, sizeof(rar5_signature_xor), &p))
|
|
1112
|
+
return -1;
|
|
1113
|
+
|
|
1114
|
+
if(!memcmp(signature, p, sizeof(rar5_signature_xor)))
|
|
1115
|
+
return 30;
|
|
1116
|
+
|
|
1117
|
+
return -1;
|
|
1118
|
+
}
|
|
1119
|
+
|
|
1120
|
+
static int bid_sfx(struct archive_read *a)
|
|
1121
|
+
{
|
|
1122
|
+
const char *p;
|
|
1123
|
+
|
|
1124
|
+
if ((p = __archive_read_ahead(a, 7, NULL)) == NULL)
|
|
1125
|
+
return -1;
|
|
1126
|
+
|
|
1127
|
+
if ((p[0] == 'M' && p[1] == 'Z') || memcmp(p, "\x7F\x45LF", 4) == 0) {
|
|
1128
|
+
/* This is a PE file */
|
|
1129
|
+
char signature[sizeof(rar5_signature_xor)];
|
|
1130
|
+
ssize_t offset = 0x10000;
|
|
1131
|
+
ssize_t window = 4096;
|
|
1132
|
+
ssize_t bytes_avail;
|
|
1133
|
+
|
|
1134
|
+
rar5_signature(signature);
|
|
1135
|
+
|
|
1136
|
+
while (offset + window <= (1024 * 512)) {
|
|
1137
|
+
const char *buff = __archive_read_ahead(a, offset + window, &bytes_avail);
|
|
1138
|
+
if (buff == NULL) {
|
|
1139
|
+
/* Remaining bytes are less than window. */
|
|
1140
|
+
window >>= 1;
|
|
1141
|
+
if (window < 0x40)
|
|
1142
|
+
return 0;
|
|
1143
|
+
continue;
|
|
1144
|
+
}
|
|
1145
|
+
p = buff + offset;
|
|
1146
|
+
while (p + 8 < buff + bytes_avail) {
|
|
1147
|
+
if (memcmp(p, signature, sizeof(signature)) == 0)
|
|
1148
|
+
return 30;
|
|
1149
|
+
p += 0x10;
|
|
1150
|
+
}
|
|
1151
|
+
offset = p - buff;
|
|
1152
|
+
}
|
|
1153
|
+
}
|
|
1154
|
+
|
|
1155
|
+
return 0;
|
|
1156
|
+
}
|
|
1157
|
+
|
|
1158
|
+
static int rar5_bid(struct archive_read* a, int best_bid) {
|
|
1159
|
+
int my_bid;
|
|
1160
|
+
|
|
1161
|
+
if(best_bid > 30)
|
|
1162
|
+
return -1;
|
|
1163
|
+
|
|
1164
|
+
my_bid = bid_standard(a);
|
|
1165
|
+
if(my_bid > -1) {
|
|
1166
|
+
return my_bid;
|
|
1167
|
+
}
|
|
1168
|
+
my_bid = bid_sfx(a);
|
|
1169
|
+
if (my_bid > -1) {
|
|
1170
|
+
return my_bid;
|
|
1171
|
+
}
|
|
1172
|
+
|
|
1173
|
+
return -1;
|
|
1174
|
+
}
|
|
1175
|
+
|
|
1176
|
+
static int rar5_options(struct archive_read *a, const char *key,
|
|
1177
|
+
const char *val) {
|
|
1178
|
+
(void) a;
|
|
1179
|
+
(void) key;
|
|
1180
|
+
(void) val;
|
|
1181
|
+
|
|
1182
|
+
/* No options supported in this version. Return the ARCHIVE_WARN code
|
|
1183
|
+
* to signal the options supervisor that the unpacker didn't handle
|
|
1184
|
+
* setting this option. */
|
|
1185
|
+
|
|
1186
|
+
return ARCHIVE_WARN;
|
|
1187
|
+
}
|
|
1188
|
+
|
|
1189
|
+
static void init_header(struct archive_read* a) {
|
|
1190
|
+
a->archive.archive_format = ARCHIVE_FORMAT_RAR_V5;
|
|
1191
|
+
a->archive.archive_format_name = "RAR5";
|
|
1192
|
+
}
|
|
1193
|
+
|
|
1194
|
+
static void init_window_mask(struct rar5* rar) {
|
|
1195
|
+
if (rar->cstate.window_size)
|
|
1196
|
+
rar->cstate.window_mask = rar->cstate.window_size - 1;
|
|
1197
|
+
else
|
|
1198
|
+
rar->cstate.window_mask = 0;
|
|
1199
|
+
}
|
|
1200
|
+
|
|
1201
|
+
enum HEADER_FLAGS {
|
|
1202
|
+
HFL_EXTRA_DATA = 0x0001,
|
|
1203
|
+
HFL_DATA = 0x0002,
|
|
1204
|
+
HFL_SKIP_IF_UNKNOWN = 0x0004,
|
|
1205
|
+
HFL_SPLIT_BEFORE = 0x0008,
|
|
1206
|
+
HFL_SPLIT_AFTER = 0x0010,
|
|
1207
|
+
HFL_CHILD = 0x0020,
|
|
1208
|
+
HFL_INHERITED = 0x0040
|
|
1209
|
+
};
|
|
1210
|
+
|
|
1211
|
+
static int process_main_locator_extra_block(struct archive_read* a,
|
|
1212
|
+
struct rar5* rar)
|
|
1213
|
+
{
|
|
1214
|
+
uint64_t locator_flags;
|
|
1215
|
+
|
|
1216
|
+
enum LOCATOR_FLAGS {
|
|
1217
|
+
QLIST = 0x01, RECOVERY = 0x02,
|
|
1218
|
+
};
|
|
1219
|
+
|
|
1220
|
+
if(!read_var(a, &locator_flags, NULL)) {
|
|
1221
|
+
return ARCHIVE_EOF;
|
|
1222
|
+
}
|
|
1223
|
+
|
|
1224
|
+
if(locator_flags & QLIST) {
|
|
1225
|
+
if(!read_var(a, &rar->qlist_offset, NULL)) {
|
|
1226
|
+
return ARCHIVE_EOF;
|
|
1227
|
+
}
|
|
1228
|
+
|
|
1229
|
+
/* qlist is not used */
|
|
1230
|
+
}
|
|
1231
|
+
|
|
1232
|
+
if(locator_flags & RECOVERY) {
|
|
1233
|
+
if(!read_var(a, &rar->rr_offset, NULL)) {
|
|
1234
|
+
return ARCHIVE_EOF;
|
|
1235
|
+
}
|
|
1236
|
+
|
|
1237
|
+
/* rr is not used */
|
|
1238
|
+
}
|
|
1239
|
+
|
|
1240
|
+
return ARCHIVE_OK;
|
|
1241
|
+
}
|
|
1242
|
+
|
|
1243
|
+
static int parse_file_extra_hash(struct archive_read* a, struct rar5* rar,
|
|
1244
|
+
ssize_t* extra_data_size)
|
|
1245
|
+
{
|
|
1246
|
+
size_t hash_type = 0;
|
|
1247
|
+
size_t value_len;
|
|
1248
|
+
|
|
1249
|
+
enum HASH_TYPE {
|
|
1250
|
+
BLAKE2sp = 0x00
|
|
1251
|
+
};
|
|
1252
|
+
|
|
1253
|
+
if(!read_var_sized(a, &hash_type, &value_len))
|
|
1254
|
+
return ARCHIVE_EOF;
|
|
1255
|
+
|
|
1256
|
+
*extra_data_size -= value_len;
|
|
1257
|
+
if(ARCHIVE_OK != consume(a, value_len)) {
|
|
1258
|
+
return ARCHIVE_EOF;
|
|
1259
|
+
}
|
|
1260
|
+
|
|
1261
|
+
/* The file uses BLAKE2sp checksum algorithm instead of plain old
|
|
1262
|
+
* CRC32. */
|
|
1263
|
+
if(hash_type == BLAKE2sp) {
|
|
1264
|
+
const uint8_t* p;
|
|
1265
|
+
const int hash_size = sizeof(rar->file.blake2sp);
|
|
1266
|
+
|
|
1267
|
+
if(!read_ahead(a, hash_size, &p))
|
|
1268
|
+
return ARCHIVE_EOF;
|
|
1269
|
+
|
|
1270
|
+
rar->file.has_blake2 = 1;
|
|
1271
|
+
memcpy(&rar->file.blake2sp, p, hash_size);
|
|
1272
|
+
|
|
1273
|
+
if(ARCHIVE_OK != consume(a, hash_size)) {
|
|
1274
|
+
return ARCHIVE_EOF;
|
|
1275
|
+
}
|
|
1276
|
+
|
|
1277
|
+
*extra_data_size -= hash_size;
|
|
1278
|
+
} else {
|
|
1279
|
+
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
|
1280
|
+
"Unsupported hash type (0x%x)", (int) hash_type);
|
|
1281
|
+
return ARCHIVE_FATAL;
|
|
1282
|
+
}
|
|
1283
|
+
|
|
1284
|
+
return ARCHIVE_OK;
|
|
1285
|
+
}
|
|
1286
|
+
|
|
1287
|
+
static uint64_t time_win_to_unix(uint64_t win_time) {
|
|
1288
|
+
const size_t ns_in_sec = 10000000;
|
|
1289
|
+
const uint64_t sec_to_unix = 11644473600LL;
|
|
1290
|
+
return win_time / ns_in_sec - sec_to_unix;
|
|
1291
|
+
}
|
|
1292
|
+
|
|
1293
|
+
static int parse_htime_item(struct archive_read* a, char unix_time,
|
|
1294
|
+
uint64_t* where, ssize_t* extra_data_size)
|
|
1295
|
+
{
|
|
1296
|
+
if(unix_time) {
|
|
1297
|
+
uint32_t time_val;
|
|
1298
|
+
if(!read_u32(a, &time_val))
|
|
1299
|
+
return ARCHIVE_EOF;
|
|
1300
|
+
|
|
1301
|
+
*extra_data_size -= 4;
|
|
1302
|
+
*where = (uint64_t) time_val;
|
|
1303
|
+
} else {
|
|
1304
|
+
uint64_t windows_time;
|
|
1305
|
+
if(!read_u64(a, &windows_time))
|
|
1306
|
+
return ARCHIVE_EOF;
|
|
1307
|
+
|
|
1308
|
+
*where = time_win_to_unix(windows_time);
|
|
1309
|
+
*extra_data_size -= 8;
|
|
1310
|
+
}
|
|
1311
|
+
|
|
1312
|
+
return ARCHIVE_OK;
|
|
1313
|
+
}
|
|
1314
|
+
|
|
1315
|
+
static int parse_file_extra_version(struct archive_read* a,
|
|
1316
|
+
struct archive_entry* e, ssize_t* extra_data_size)
|
|
1317
|
+
{
|
|
1318
|
+
size_t flags = 0;
|
|
1319
|
+
size_t version = 0;
|
|
1320
|
+
size_t value_len = 0;
|
|
1321
|
+
struct archive_string version_string;
|
|
1322
|
+
struct archive_string name_utf8_string;
|
|
1323
|
+
const char* cur_filename;
|
|
1324
|
+
|
|
1325
|
+
/* Flags are ignored. */
|
|
1326
|
+
if(!read_var_sized(a, &flags, &value_len))
|
|
1327
|
+
return ARCHIVE_EOF;
|
|
1328
|
+
|
|
1329
|
+
*extra_data_size -= value_len;
|
|
1330
|
+
if(ARCHIVE_OK != consume(a, value_len))
|
|
1331
|
+
return ARCHIVE_EOF;
|
|
1332
|
+
|
|
1333
|
+
if(!read_var_sized(a, &version, &value_len))
|
|
1334
|
+
return ARCHIVE_EOF;
|
|
1335
|
+
|
|
1336
|
+
*extra_data_size -= value_len;
|
|
1337
|
+
if(ARCHIVE_OK != consume(a, value_len))
|
|
1338
|
+
return ARCHIVE_EOF;
|
|
1339
|
+
|
|
1340
|
+
/* extra_data_size should be zero here. */
|
|
1341
|
+
|
|
1342
|
+
cur_filename = archive_entry_pathname_utf8(e);
|
|
1343
|
+
if(cur_filename == NULL) {
|
|
1344
|
+
archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER,
|
|
1345
|
+
"Version entry without file name");
|
|
1346
|
+
return ARCHIVE_FATAL;
|
|
1347
|
+
}
|
|
1348
|
+
|
|
1349
|
+
archive_string_init(&version_string);
|
|
1350
|
+
archive_string_init(&name_utf8_string);
|
|
1351
|
+
|
|
1352
|
+
/* Prepare a ;123 suffix for the filename, where '123' is the version
|
|
1353
|
+
* value of this file. */
|
|
1354
|
+
archive_string_sprintf(&version_string, ";%zu", version);
|
|
1355
|
+
|
|
1356
|
+
/* Build the new filename. */
|
|
1357
|
+
archive_strcat(&name_utf8_string, cur_filename);
|
|
1358
|
+
archive_strcat(&name_utf8_string, version_string.s);
|
|
1359
|
+
|
|
1360
|
+
/* Apply the new filename into this file's context. */
|
|
1361
|
+
archive_entry_update_pathname_utf8(e, name_utf8_string.s);
|
|
1362
|
+
|
|
1363
|
+
/* Free buffers. */
|
|
1364
|
+
archive_string_free(&version_string);
|
|
1365
|
+
archive_string_free(&name_utf8_string);
|
|
1366
|
+
return ARCHIVE_OK;
|
|
1367
|
+
}
|
|
1368
|
+
|
|
1369
|
+
static int parse_file_extra_htime(struct archive_read* a,
|
|
1370
|
+
struct archive_entry* e, struct rar5* rar, ssize_t* extra_data_size)
|
|
1371
|
+
{
|
|
1372
|
+
char unix_time = 0;
|
|
1373
|
+
size_t flags = 0;
|
|
1374
|
+
size_t value_len;
|
|
1375
|
+
|
|
1376
|
+
enum HTIME_FLAGS {
|
|
1377
|
+
IS_UNIX = 0x01,
|
|
1378
|
+
HAS_MTIME = 0x02,
|
|
1379
|
+
HAS_CTIME = 0x04,
|
|
1380
|
+
HAS_ATIME = 0x08,
|
|
1381
|
+
HAS_UNIX_NS = 0x10,
|
|
1382
|
+
};
|
|
1383
|
+
|
|
1384
|
+
if(!read_var_sized(a, &flags, &value_len))
|
|
1385
|
+
return ARCHIVE_EOF;
|
|
1386
|
+
|
|
1387
|
+
*extra_data_size -= value_len;
|
|
1388
|
+
if(ARCHIVE_OK != consume(a, value_len)) {
|
|
1389
|
+
return ARCHIVE_EOF;
|
|
1390
|
+
}
|
|
1391
|
+
|
|
1392
|
+
unix_time = flags & IS_UNIX;
|
|
1393
|
+
|
|
1394
|
+
if(flags & HAS_MTIME) {
|
|
1395
|
+
parse_htime_item(a, unix_time, &rar->file.e_mtime,
|
|
1396
|
+
extra_data_size);
|
|
1397
|
+
archive_entry_set_mtime(e, rar->file.e_mtime, 0);
|
|
1398
|
+
}
|
|
1399
|
+
|
|
1400
|
+
if(flags & HAS_CTIME) {
|
|
1401
|
+
parse_htime_item(a, unix_time, &rar->file.e_ctime,
|
|
1402
|
+
extra_data_size);
|
|
1403
|
+
archive_entry_set_ctime(e, rar->file.e_ctime, 0);
|
|
1404
|
+
}
|
|
1405
|
+
|
|
1406
|
+
if(flags & HAS_ATIME) {
|
|
1407
|
+
parse_htime_item(a, unix_time, &rar->file.e_atime,
|
|
1408
|
+
extra_data_size);
|
|
1409
|
+
archive_entry_set_atime(e, rar->file.e_atime, 0);
|
|
1410
|
+
}
|
|
1411
|
+
|
|
1412
|
+
if(flags & HAS_UNIX_NS) {
|
|
1413
|
+
if(!read_u32(a, &rar->file.e_unix_ns))
|
|
1414
|
+
return ARCHIVE_EOF;
|
|
1415
|
+
|
|
1416
|
+
*extra_data_size -= 4;
|
|
1417
|
+
}
|
|
1418
|
+
|
|
1419
|
+
return ARCHIVE_OK;
|
|
1420
|
+
}
|
|
1421
|
+
|
|
1422
|
+
static int parse_file_extra_redir(struct archive_read* a,
|
|
1423
|
+
struct archive_entry* e, struct rar5* rar, ssize_t* extra_data_size)
|
|
1424
|
+
{
|
|
1425
|
+
uint64_t value_size = 0;
|
|
1426
|
+
size_t target_size = 0;
|
|
1427
|
+
char target_utf8_buf[MAX_NAME_IN_BYTES];
|
|
1428
|
+
const uint8_t* p;
|
|
1429
|
+
|
|
1430
|
+
if(!read_var(a, &rar->file.redir_type, &value_size))
|
|
1431
|
+
return ARCHIVE_EOF;
|
|
1432
|
+
if(ARCHIVE_OK != consume(a, (int64_t)value_size))
|
|
1433
|
+
return ARCHIVE_EOF;
|
|
1434
|
+
*extra_data_size -= value_size;
|
|
1435
|
+
|
|
1436
|
+
if(!read_var(a, &rar->file.redir_flags, &value_size))
|
|
1437
|
+
return ARCHIVE_EOF;
|
|
1438
|
+
if(ARCHIVE_OK != consume(a, (int64_t)value_size))
|
|
1439
|
+
return ARCHIVE_EOF;
|
|
1440
|
+
*extra_data_size -= value_size;
|
|
1441
|
+
|
|
1442
|
+
if(!read_var_sized(a, &target_size, NULL))
|
|
1443
|
+
return ARCHIVE_EOF;
|
|
1444
|
+
*extra_data_size -= target_size + 1;
|
|
1445
|
+
|
|
1446
|
+
if(!read_ahead(a, target_size, &p))
|
|
1447
|
+
return ARCHIVE_EOF;
|
|
1448
|
+
|
|
1449
|
+
if(target_size > (MAX_NAME_IN_CHARS - 1)) {
|
|
1450
|
+
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
|
1451
|
+
"Link target is too long");
|
|
1452
|
+
return ARCHIVE_FATAL;
|
|
1453
|
+
}
|
|
1454
|
+
|
|
1455
|
+
if(target_size == 0) {
|
|
1456
|
+
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
|
1457
|
+
"No link target specified");
|
|
1458
|
+
return ARCHIVE_FATAL;
|
|
1459
|
+
}
|
|
1460
|
+
|
|
1461
|
+
memcpy(target_utf8_buf, p, target_size);
|
|
1462
|
+
target_utf8_buf[target_size] = 0;
|
|
1463
|
+
|
|
1464
|
+
if(ARCHIVE_OK != consume(a, (int64_t)target_size))
|
|
1465
|
+
return ARCHIVE_EOF;
|
|
1466
|
+
|
|
1467
|
+
switch(rar->file.redir_type) {
|
|
1468
|
+
case REDIR_TYPE_UNIXSYMLINK:
|
|
1469
|
+
case REDIR_TYPE_WINSYMLINK:
|
|
1470
|
+
archive_entry_set_filetype(e, AE_IFLNK);
|
|
1471
|
+
archive_entry_update_symlink_utf8(e, target_utf8_buf);
|
|
1472
|
+
if (rar->file.redir_flags & REDIR_SYMLINK_IS_DIR) {
|
|
1473
|
+
archive_entry_set_symlink_type(e,
|
|
1474
|
+
AE_SYMLINK_TYPE_DIRECTORY);
|
|
1475
|
+
} else {
|
|
1476
|
+
archive_entry_set_symlink_type(e,
|
|
1477
|
+
AE_SYMLINK_TYPE_FILE);
|
|
1478
|
+
}
|
|
1479
|
+
break;
|
|
1480
|
+
|
|
1481
|
+
case REDIR_TYPE_HARDLINK:
|
|
1482
|
+
archive_entry_set_filetype(e, AE_IFREG);
|
|
1483
|
+
archive_entry_update_hardlink_utf8(e, target_utf8_buf);
|
|
1484
|
+
break;
|
|
1485
|
+
|
|
1486
|
+
default:
|
|
1487
|
+
/* Unknown redir type, skip it. */
|
|
1488
|
+
break;
|
|
1489
|
+
}
|
|
1490
|
+
return ARCHIVE_OK;
|
|
1491
|
+
}
|
|
1492
|
+
|
|
1493
|
+
static int parse_file_extra_owner(struct archive_read* a,
|
|
1494
|
+
struct archive_entry* e, ssize_t* extra_data_size)
|
|
1495
|
+
{
|
|
1496
|
+
uint64_t flags = 0;
|
|
1497
|
+
uint64_t value_size = 0;
|
|
1498
|
+
uint64_t id = 0;
|
|
1499
|
+
size_t name_len = 0;
|
|
1500
|
+
size_t name_size = 0;
|
|
1501
|
+
char namebuf[OWNER_MAXNAMELEN];
|
|
1502
|
+
const uint8_t* p;
|
|
1503
|
+
|
|
1504
|
+
if(!read_var(a, &flags, &value_size))
|
|
1505
|
+
return ARCHIVE_EOF;
|
|
1506
|
+
if(ARCHIVE_OK != consume(a, (int64_t)value_size))
|
|
1507
|
+
return ARCHIVE_EOF;
|
|
1508
|
+
*extra_data_size -= value_size;
|
|
1509
|
+
|
|
1510
|
+
if ((flags & OWNER_USER_NAME) != 0) {
|
|
1511
|
+
if(!read_var_sized(a, &name_size, NULL))
|
|
1512
|
+
return ARCHIVE_EOF;
|
|
1513
|
+
*extra_data_size -= name_size + 1;
|
|
1514
|
+
|
|
1515
|
+
if(!read_ahead(a, name_size, &p))
|
|
1516
|
+
return ARCHIVE_EOF;
|
|
1517
|
+
|
|
1518
|
+
if (name_size >= OWNER_MAXNAMELEN) {
|
|
1519
|
+
name_len = OWNER_MAXNAMELEN - 1;
|
|
1520
|
+
} else {
|
|
1521
|
+
name_len = name_size;
|
|
1522
|
+
}
|
|
1523
|
+
|
|
1524
|
+
memcpy(namebuf, p, name_len);
|
|
1525
|
+
namebuf[name_len] = 0;
|
|
1526
|
+
if(ARCHIVE_OK != consume(a, (int64_t)name_size))
|
|
1527
|
+
return ARCHIVE_EOF;
|
|
1528
|
+
|
|
1529
|
+
archive_entry_set_uname(e, namebuf);
|
|
1530
|
+
}
|
|
1531
|
+
if ((flags & OWNER_GROUP_NAME) != 0) {
|
|
1532
|
+
if(!read_var_sized(a, &name_size, NULL))
|
|
1533
|
+
return ARCHIVE_EOF;
|
|
1534
|
+
*extra_data_size -= name_size + 1;
|
|
1535
|
+
|
|
1536
|
+
if(!read_ahead(a, name_size, &p))
|
|
1537
|
+
return ARCHIVE_EOF;
|
|
1538
|
+
|
|
1539
|
+
if (name_size >= OWNER_MAXNAMELEN) {
|
|
1540
|
+
name_len = OWNER_MAXNAMELEN - 1;
|
|
1541
|
+
} else {
|
|
1542
|
+
name_len = name_size;
|
|
1543
|
+
}
|
|
1544
|
+
|
|
1545
|
+
memcpy(namebuf, p, name_len);
|
|
1546
|
+
namebuf[name_len] = 0;
|
|
1547
|
+
if(ARCHIVE_OK != consume(a, (int64_t)name_size))
|
|
1548
|
+
return ARCHIVE_EOF;
|
|
1549
|
+
|
|
1550
|
+
archive_entry_set_gname(e, namebuf);
|
|
1551
|
+
}
|
|
1552
|
+
if ((flags & OWNER_USER_UID) != 0) {
|
|
1553
|
+
if(!read_var(a, &id, &value_size))
|
|
1554
|
+
return ARCHIVE_EOF;
|
|
1555
|
+
if(ARCHIVE_OK != consume(a, (int64_t)value_size))
|
|
1556
|
+
return ARCHIVE_EOF;
|
|
1557
|
+
*extra_data_size -= value_size;
|
|
1558
|
+
|
|
1559
|
+
archive_entry_set_uid(e, (la_int64_t)id);
|
|
1560
|
+
}
|
|
1561
|
+
if ((flags & OWNER_GROUP_GID) != 0) {
|
|
1562
|
+
if(!read_var(a, &id, &value_size))
|
|
1563
|
+
return ARCHIVE_EOF;
|
|
1564
|
+
if(ARCHIVE_OK != consume(a, (int64_t)value_size))
|
|
1565
|
+
return ARCHIVE_EOF;
|
|
1566
|
+
*extra_data_size -= value_size;
|
|
1567
|
+
|
|
1568
|
+
archive_entry_set_gid(e, (la_int64_t)id);
|
|
1569
|
+
}
|
|
1570
|
+
return ARCHIVE_OK;
|
|
1571
|
+
}
|
|
1572
|
+
|
|
1573
|
+
static int process_head_file_extra(struct archive_read* a,
|
|
1574
|
+
struct archive_entry* e, struct rar5* rar, ssize_t extra_data_size)
|
|
1575
|
+
{
|
|
1576
|
+
size_t extra_field_size;
|
|
1577
|
+
size_t extra_field_id = 0;
|
|
1578
|
+
int ret = ARCHIVE_FATAL;
|
|
1579
|
+
size_t var_size;
|
|
1580
|
+
|
|
1581
|
+
while(extra_data_size > 0) {
|
|
1582
|
+
if(!read_var_sized(a, &extra_field_size, &var_size))
|
|
1583
|
+
return ARCHIVE_EOF;
|
|
1584
|
+
|
|
1585
|
+
extra_data_size -= var_size;
|
|
1586
|
+
if(ARCHIVE_OK != consume(a, var_size)) {
|
|
1587
|
+
return ARCHIVE_EOF;
|
|
1588
|
+
}
|
|
1589
|
+
|
|
1590
|
+
if(!read_var_sized(a, &extra_field_id, &var_size))
|
|
1591
|
+
return ARCHIVE_EOF;
|
|
1592
|
+
|
|
1593
|
+
extra_data_size -= var_size;
|
|
1594
|
+
if(ARCHIVE_OK != consume(a, var_size)) {
|
|
1595
|
+
return ARCHIVE_EOF;
|
|
1596
|
+
}
|
|
1597
|
+
|
|
1598
|
+
switch(extra_field_id) {
|
|
1599
|
+
case EX_HASH:
|
|
1600
|
+
ret = parse_file_extra_hash(a, rar,
|
|
1601
|
+
&extra_data_size);
|
|
1602
|
+
break;
|
|
1603
|
+
case EX_HTIME:
|
|
1604
|
+
ret = parse_file_extra_htime(a, e, rar,
|
|
1605
|
+
&extra_data_size);
|
|
1606
|
+
break;
|
|
1607
|
+
case EX_REDIR:
|
|
1608
|
+
ret = parse_file_extra_redir(a, e, rar,
|
|
1609
|
+
&extra_data_size);
|
|
1610
|
+
break;
|
|
1611
|
+
case EX_UOWNER:
|
|
1612
|
+
ret = parse_file_extra_owner(a, e,
|
|
1613
|
+
&extra_data_size);
|
|
1614
|
+
break;
|
|
1615
|
+
case EX_VERSION:
|
|
1616
|
+
ret = parse_file_extra_version(a, e,
|
|
1617
|
+
&extra_data_size);
|
|
1618
|
+
break;
|
|
1619
|
+
case EX_CRYPT:
|
|
1620
|
+
/* fallthrough */
|
|
1621
|
+
case EX_SUBDATA:
|
|
1622
|
+
/* fallthrough */
|
|
1623
|
+
default:
|
|
1624
|
+
/* Skip unsupported entry. */
|
|
1625
|
+
return consume(a, extra_data_size);
|
|
1626
|
+
}
|
|
1627
|
+
}
|
|
1628
|
+
|
|
1629
|
+
if(ret != ARCHIVE_OK) {
|
|
1630
|
+
/* Attribute not implemented. */
|
|
1631
|
+
return ret;
|
|
1632
|
+
}
|
|
1633
|
+
|
|
1634
|
+
return ARCHIVE_OK;
|
|
1635
|
+
}
|
|
1636
|
+
|
|
1637
|
+
static int process_head_file(struct archive_read* a, struct rar5* rar,
|
|
1638
|
+
struct archive_entry* entry, size_t block_flags)
|
|
1639
|
+
{
|
|
1640
|
+
ssize_t extra_data_size = 0;
|
|
1641
|
+
size_t data_size = 0;
|
|
1642
|
+
size_t file_flags = 0;
|
|
1643
|
+
size_t file_attr = 0;
|
|
1644
|
+
size_t compression_info = 0;
|
|
1645
|
+
size_t host_os = 0;
|
|
1646
|
+
size_t name_size = 0;
|
|
1647
|
+
uint64_t unpacked_size, window_size;
|
|
1648
|
+
uint32_t mtime = 0, crc = 0;
|
|
1649
|
+
int c_method = 0, c_version = 0;
|
|
1650
|
+
char name_utf8_buf[MAX_NAME_IN_BYTES];
|
|
1651
|
+
const uint8_t* p;
|
|
1652
|
+
|
|
1653
|
+
enum FILE_FLAGS {
|
|
1654
|
+
DIRECTORY = 0x0001, UTIME = 0x0002, CRC32 = 0x0004,
|
|
1655
|
+
UNKNOWN_UNPACKED_SIZE = 0x0008,
|
|
1656
|
+
};
|
|
1657
|
+
|
|
1658
|
+
enum FILE_ATTRS {
|
|
1659
|
+
ATTR_READONLY = 0x1, ATTR_HIDDEN = 0x2, ATTR_SYSTEM = 0x4,
|
|
1660
|
+
ATTR_DIRECTORY = 0x10,
|
|
1661
|
+
};
|
|
1662
|
+
|
|
1663
|
+
enum COMP_INFO_FLAGS {
|
|
1664
|
+
SOLID = 0x0040,
|
|
1665
|
+
};
|
|
1666
|
+
|
|
1667
|
+
enum HOST_OS {
|
|
1668
|
+
HOST_WINDOWS = 0,
|
|
1669
|
+
HOST_UNIX = 1,
|
|
1670
|
+
};
|
|
1671
|
+
|
|
1672
|
+
archive_entry_clear(entry);
|
|
1673
|
+
|
|
1674
|
+
/* Do not reset file context if we're switching archives. */
|
|
1675
|
+
if(!rar->cstate.switch_multivolume) {
|
|
1676
|
+
reset_file_context(rar);
|
|
1677
|
+
}
|
|
1678
|
+
|
|
1679
|
+
if(block_flags & HFL_EXTRA_DATA) {
|
|
1680
|
+
size_t edata_size = 0;
|
|
1681
|
+
if(!read_var_sized(a, &edata_size, NULL))
|
|
1682
|
+
return ARCHIVE_EOF;
|
|
1683
|
+
|
|
1684
|
+
/* Intentional type cast from unsigned to signed. */
|
|
1685
|
+
extra_data_size = (ssize_t) edata_size;
|
|
1686
|
+
}
|
|
1687
|
+
|
|
1688
|
+
if(block_flags & HFL_DATA) {
|
|
1689
|
+
if(!read_var_sized(a, &data_size, NULL))
|
|
1690
|
+
return ARCHIVE_EOF;
|
|
1691
|
+
|
|
1692
|
+
rar->file.bytes_remaining = data_size;
|
|
1693
|
+
} else {
|
|
1694
|
+
rar->file.bytes_remaining = 0;
|
|
1695
|
+
|
|
1696
|
+
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
|
1697
|
+
"no data found in file/service block");
|
|
1698
|
+
return ARCHIVE_FATAL;
|
|
1699
|
+
}
|
|
1700
|
+
|
|
1701
|
+
if(!read_var_sized(a, &file_flags, NULL))
|
|
1702
|
+
return ARCHIVE_EOF;
|
|
1703
|
+
|
|
1704
|
+
if(!read_var(a, &unpacked_size, NULL))
|
|
1705
|
+
return ARCHIVE_EOF;
|
|
1706
|
+
|
|
1707
|
+
if(file_flags & UNKNOWN_UNPACKED_SIZE) {
|
|
1708
|
+
archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER,
|
|
1709
|
+
"Files with unknown unpacked size are not supported");
|
|
1710
|
+
return ARCHIVE_FATAL;
|
|
1711
|
+
}
|
|
1712
|
+
|
|
1713
|
+
rar->file.dir = (uint8_t) ((file_flags & DIRECTORY) > 0);
|
|
1714
|
+
|
|
1715
|
+
if(!read_var_sized(a, &file_attr, NULL))
|
|
1716
|
+
return ARCHIVE_EOF;
|
|
1717
|
+
|
|
1718
|
+
if(file_flags & UTIME) {
|
|
1719
|
+
if(!read_u32(a, &mtime))
|
|
1720
|
+
return ARCHIVE_EOF;
|
|
1721
|
+
}
|
|
1722
|
+
|
|
1723
|
+
if(file_flags & CRC32) {
|
|
1724
|
+
if(!read_u32(a, &crc))
|
|
1725
|
+
return ARCHIVE_EOF;
|
|
1726
|
+
}
|
|
1727
|
+
|
|
1728
|
+
if(!read_var_sized(a, &compression_info, NULL))
|
|
1729
|
+
return ARCHIVE_EOF;
|
|
1730
|
+
|
|
1731
|
+
c_method = (int) (compression_info >> 7) & 0x7;
|
|
1732
|
+
c_version = (int) (compression_info & 0x3f);
|
|
1733
|
+
|
|
1734
|
+
/* RAR5 seems to limit the dictionary size to 64MB. */
|
|
1735
|
+
window_size = (rar->file.dir > 0) ?
|
|
1736
|
+
0 :
|
|
1737
|
+
g_unpack_window_size << ((compression_info >> 10) & 15);
|
|
1738
|
+
rar->cstate.method = c_method;
|
|
1739
|
+
rar->cstate.version = c_version + 50;
|
|
1740
|
+
rar->file.solid = (compression_info & SOLID) > 0;
|
|
1741
|
+
|
|
1742
|
+
/* Archives which declare solid files without initializing the window
|
|
1743
|
+
* buffer first are invalid. */
|
|
1744
|
+
|
|
1745
|
+
if(rar->file.solid > 0 && rar->cstate.window_buf == NULL) {
|
|
1746
|
+
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
|
1747
|
+
"Declared solid file, but no window buffer "
|
|
1748
|
+
"initialized yet.");
|
|
1749
|
+
return ARCHIVE_FATAL;
|
|
1750
|
+
}
|
|
1751
|
+
|
|
1752
|
+
/* Check if window_size is a sane value. Also, if the file is not
|
|
1753
|
+
* declared as a directory, disallow window_size == 0. */
|
|
1754
|
+
if(window_size > (64 * 1024 * 1024) ||
|
|
1755
|
+
(rar->file.dir == 0 && window_size == 0))
|
|
1756
|
+
{
|
|
1757
|
+
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
|
1758
|
+
"Declared dictionary size is not supported.");
|
|
1759
|
+
return ARCHIVE_FATAL;
|
|
1760
|
+
}
|
|
1761
|
+
|
|
1762
|
+
if(rar->file.solid > 0) {
|
|
1763
|
+
/* Re-check if current window size is the same as previous
|
|
1764
|
+
* window size (for solid files only). */
|
|
1765
|
+
if(rar->file.solid_window_size > 0 &&
|
|
1766
|
+
rar->file.solid_window_size != (ssize_t) window_size)
|
|
1767
|
+
{
|
|
1768
|
+
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
|
1769
|
+
"Window size for this solid file doesn't match "
|
|
1770
|
+
"the window size used in previous solid file. ");
|
|
1771
|
+
return ARCHIVE_FATAL;
|
|
1772
|
+
}
|
|
1773
|
+
}
|
|
1774
|
+
|
|
1775
|
+
if(rar->cstate.window_size < (ssize_t) window_size &&
|
|
1776
|
+
rar->cstate.window_buf)
|
|
1777
|
+
{
|
|
1778
|
+
/* If window_buf has been allocated before, reallocate it, so
|
|
1779
|
+
* that its size will match new window_size. */
|
|
1780
|
+
|
|
1781
|
+
uint8_t* new_window_buf =
|
|
1782
|
+
realloc(rar->cstate.window_buf, window_size);
|
|
1783
|
+
|
|
1784
|
+
if(!new_window_buf) {
|
|
1785
|
+
archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER,
|
|
1786
|
+
"Not enough memory when trying to realloc the window "
|
|
1787
|
+
"buffer.");
|
|
1788
|
+
return ARCHIVE_FATAL;
|
|
1789
|
+
}
|
|
1790
|
+
|
|
1791
|
+
rar->cstate.window_buf = new_window_buf;
|
|
1792
|
+
}
|
|
1793
|
+
|
|
1794
|
+
/* Values up to 64M should fit into ssize_t on every
|
|
1795
|
+
* architecture. */
|
|
1796
|
+
rar->cstate.window_size = (ssize_t) window_size;
|
|
1797
|
+
|
|
1798
|
+
if(rar->file.solid > 0 && rar->file.solid_window_size == 0) {
|
|
1799
|
+
/* Solid files have to have the same window_size across
|
|
1800
|
+
whole archive. Remember the window_size parameter
|
|
1801
|
+
for first solid file found. */
|
|
1802
|
+
rar->file.solid_window_size = rar->cstate.window_size;
|
|
1803
|
+
}
|
|
1804
|
+
|
|
1805
|
+
init_window_mask(rar);
|
|
1806
|
+
|
|
1807
|
+
rar->file.service = 0;
|
|
1808
|
+
|
|
1809
|
+
if(!read_var_sized(a, &host_os, NULL))
|
|
1810
|
+
return ARCHIVE_EOF;
|
|
1811
|
+
|
|
1812
|
+
if(host_os == HOST_WINDOWS) {
|
|
1813
|
+
/* Host OS is Windows */
|
|
1814
|
+
|
|
1815
|
+
__LA_MODE_T mode;
|
|
1816
|
+
|
|
1817
|
+
if(file_attr & ATTR_DIRECTORY) {
|
|
1818
|
+
if (file_attr & ATTR_READONLY) {
|
|
1819
|
+
mode = 0555 | AE_IFDIR;
|
|
1820
|
+
} else {
|
|
1821
|
+
mode = 0755 | AE_IFDIR;
|
|
1822
|
+
}
|
|
1823
|
+
} else {
|
|
1824
|
+
if (file_attr & ATTR_READONLY) {
|
|
1825
|
+
mode = 0444 | AE_IFREG;
|
|
1826
|
+
} else {
|
|
1827
|
+
mode = 0644 | AE_IFREG;
|
|
1828
|
+
}
|
|
1829
|
+
}
|
|
1830
|
+
|
|
1831
|
+
archive_entry_set_mode(entry, mode);
|
|
1832
|
+
|
|
1833
|
+
if (file_attr & (ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM)) {
|
|
1834
|
+
char *fflags_text, *ptr;
|
|
1835
|
+
/* allocate for "rdonly,hidden,system," */
|
|
1836
|
+
fflags_text = malloc(22 * sizeof(char));
|
|
1837
|
+
if (fflags_text != NULL) {
|
|
1838
|
+
ptr = fflags_text;
|
|
1839
|
+
if (file_attr & ATTR_READONLY) {
|
|
1840
|
+
strcpy(ptr, "rdonly,");
|
|
1841
|
+
ptr = ptr + 7;
|
|
1842
|
+
}
|
|
1843
|
+
if (file_attr & ATTR_HIDDEN) {
|
|
1844
|
+
strcpy(ptr, "hidden,");
|
|
1845
|
+
ptr = ptr + 7;
|
|
1846
|
+
}
|
|
1847
|
+
if (file_attr & ATTR_SYSTEM) {
|
|
1848
|
+
strcpy(ptr, "system,");
|
|
1849
|
+
ptr = ptr + 7;
|
|
1850
|
+
}
|
|
1851
|
+
if (ptr > fflags_text) {
|
|
1852
|
+
/* Delete trailing comma */
|
|
1853
|
+
*(ptr - 1) = '\0';
|
|
1854
|
+
archive_entry_copy_fflags_text(entry,
|
|
1855
|
+
fflags_text);
|
|
1856
|
+
}
|
|
1857
|
+
free(fflags_text);
|
|
1858
|
+
}
|
|
1859
|
+
}
|
|
1860
|
+
} else if(host_os == HOST_UNIX) {
|
|
1861
|
+
/* Host OS is Unix */
|
|
1862
|
+
archive_entry_set_mode(entry, (__LA_MODE_T) file_attr);
|
|
1863
|
+
} else {
|
|
1864
|
+
/* Unknown host OS */
|
|
1865
|
+
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
|
1866
|
+
"Unsupported Host OS: 0x%x", (int) host_os);
|
|
1867
|
+
|
|
1868
|
+
return ARCHIVE_FATAL;
|
|
1869
|
+
}
|
|
1870
|
+
|
|
1871
|
+
if(!read_var_sized(a, &name_size, NULL))
|
|
1872
|
+
return ARCHIVE_EOF;
|
|
1873
|
+
|
|
1874
|
+
if(!read_ahead(a, name_size, &p))
|
|
1875
|
+
return ARCHIVE_EOF;
|
|
1876
|
+
|
|
1877
|
+
if(name_size > (MAX_NAME_IN_CHARS - 1)) {
|
|
1878
|
+
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
|
1879
|
+
"Filename is too long");
|
|
1880
|
+
|
|
1881
|
+
return ARCHIVE_FATAL;
|
|
1882
|
+
}
|
|
1883
|
+
|
|
1884
|
+
if(name_size == 0) {
|
|
1885
|
+
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
|
1886
|
+
"No filename specified");
|
|
1887
|
+
|
|
1888
|
+
return ARCHIVE_FATAL;
|
|
1889
|
+
}
|
|
1890
|
+
|
|
1891
|
+
memcpy(name_utf8_buf, p, name_size);
|
|
1892
|
+
name_utf8_buf[name_size] = 0;
|
|
1893
|
+
if(ARCHIVE_OK != consume(a, name_size)) {
|
|
1894
|
+
return ARCHIVE_EOF;
|
|
1895
|
+
}
|
|
1896
|
+
|
|
1897
|
+
archive_entry_update_pathname_utf8(entry, name_utf8_buf);
|
|
1898
|
+
|
|
1899
|
+
if(extra_data_size > 0) {
|
|
1900
|
+
int ret = process_head_file_extra(a, entry, rar,
|
|
1901
|
+
extra_data_size);
|
|
1902
|
+
|
|
1903
|
+
/*
|
|
1904
|
+
* TODO: rewrite or remove useless sanity check
|
|
1905
|
+
* as extra_data_size is not passed as a pointer
|
|
1906
|
+
*
|
|
1907
|
+
if(extra_data_size < 0) {
|
|
1908
|
+
archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER,
|
|
1909
|
+
"File extra data size is not zero");
|
|
1910
|
+
return ARCHIVE_FATAL;
|
|
1911
|
+
}
|
|
1912
|
+
*/
|
|
1913
|
+
|
|
1914
|
+
if(ret != ARCHIVE_OK)
|
|
1915
|
+
return ret;
|
|
1916
|
+
}
|
|
1917
|
+
|
|
1918
|
+
if((file_flags & UNKNOWN_UNPACKED_SIZE) == 0) {
|
|
1919
|
+
rar->file.unpacked_size = (ssize_t) unpacked_size;
|
|
1920
|
+
if(rar->file.redir_type == REDIR_TYPE_NONE)
|
|
1921
|
+
archive_entry_set_size(entry, unpacked_size);
|
|
1922
|
+
}
|
|
1923
|
+
|
|
1924
|
+
if(file_flags & UTIME) {
|
|
1925
|
+
archive_entry_set_mtime(entry, (time_t) mtime, 0);
|
|
1926
|
+
}
|
|
1927
|
+
|
|
1928
|
+
if(file_flags & CRC32) {
|
|
1929
|
+
rar->file.stored_crc32 = crc;
|
|
1930
|
+
}
|
|
1931
|
+
|
|
1932
|
+
if(!rar->cstate.switch_multivolume) {
|
|
1933
|
+
/* Do not reinitialize unpacking state if we're switching
|
|
1934
|
+
* archives. */
|
|
1935
|
+
rar->cstate.block_parsing_finished = 1;
|
|
1936
|
+
rar->cstate.all_filters_applied = 1;
|
|
1937
|
+
rar->cstate.initialized = 0;
|
|
1938
|
+
}
|
|
1939
|
+
|
|
1940
|
+
if(rar->generic.split_before > 0) {
|
|
1941
|
+
/* If now we're standing on a header that has a 'split before'
|
|
1942
|
+
* mark, it means we're standing on a 'continuation' file
|
|
1943
|
+
* header. Signal the caller that if it wants to move to
|
|
1944
|
+
* another file, it must call rar5_read_header() function
|
|
1945
|
+
* again. */
|
|
1946
|
+
|
|
1947
|
+
return ARCHIVE_RETRY;
|
|
1948
|
+
} else {
|
|
1949
|
+
return ARCHIVE_OK;
|
|
1950
|
+
}
|
|
1951
|
+
}
|
|
1952
|
+
|
|
1953
|
+
static int process_head_service(struct archive_read* a, struct rar5* rar,
|
|
1954
|
+
struct archive_entry* entry, size_t block_flags)
|
|
1955
|
+
{
|
|
1956
|
+
/* Process this SERVICE block the same way as FILE blocks. */
|
|
1957
|
+
int ret = process_head_file(a, rar, entry, block_flags);
|
|
1958
|
+
if(ret != ARCHIVE_OK)
|
|
1959
|
+
return ret;
|
|
1960
|
+
|
|
1961
|
+
rar->file.service = 1;
|
|
1962
|
+
|
|
1963
|
+
/* But skip the data part automatically. It's no use for the user
|
|
1964
|
+
* anyway. It contains only service data, not even needed to
|
|
1965
|
+
* properly unpack the file. */
|
|
1966
|
+
ret = rar5_read_data_skip(a);
|
|
1967
|
+
if(ret != ARCHIVE_OK)
|
|
1968
|
+
return ret;
|
|
1969
|
+
|
|
1970
|
+
/* After skipping, try parsing another block automatically. */
|
|
1971
|
+
return ARCHIVE_RETRY;
|
|
1972
|
+
}
|
|
1973
|
+
|
|
1974
|
+
static int process_head_main(struct archive_read* a, struct rar5* rar,
|
|
1975
|
+
struct archive_entry* entry, size_t block_flags)
|
|
1976
|
+
{
|
|
1977
|
+
int ret;
|
|
1978
|
+
size_t extra_data_size = 0;
|
|
1979
|
+
size_t extra_field_size = 0;
|
|
1980
|
+
size_t extra_field_id = 0;
|
|
1981
|
+
size_t archive_flags = 0;
|
|
1982
|
+
|
|
1983
|
+
enum MAIN_FLAGS {
|
|
1984
|
+
VOLUME = 0x0001, /* multi-volume archive */
|
|
1985
|
+
VOLUME_NUMBER = 0x0002, /* volume number, first vol doesn't
|
|
1986
|
+
* have it */
|
|
1987
|
+
SOLID = 0x0004, /* solid archive */
|
|
1988
|
+
PROTECT = 0x0008, /* contains Recovery info */
|
|
1989
|
+
LOCK = 0x0010, /* readonly flag, not used */
|
|
1990
|
+
};
|
|
1991
|
+
|
|
1992
|
+
enum MAIN_EXTRA {
|
|
1993
|
+
// Just one attribute here.
|
|
1994
|
+
LOCATOR = 0x01,
|
|
1995
|
+
};
|
|
1996
|
+
|
|
1997
|
+
(void) entry;
|
|
1998
|
+
|
|
1999
|
+
if(block_flags & HFL_EXTRA_DATA) {
|
|
2000
|
+
if(!read_var_sized(a, &extra_data_size, NULL))
|
|
2001
|
+
return ARCHIVE_EOF;
|
|
2002
|
+
} else {
|
|
2003
|
+
extra_data_size = 0;
|
|
2004
|
+
}
|
|
2005
|
+
|
|
2006
|
+
if(!read_var_sized(a, &archive_flags, NULL)) {
|
|
2007
|
+
return ARCHIVE_EOF;
|
|
2008
|
+
}
|
|
2009
|
+
|
|
2010
|
+
rar->main.volume = (archive_flags & VOLUME) > 0;
|
|
2011
|
+
rar->main.solid = (archive_flags & SOLID) > 0;
|
|
2012
|
+
|
|
2013
|
+
if(archive_flags & VOLUME_NUMBER) {
|
|
2014
|
+
size_t v = 0;
|
|
2015
|
+
if(!read_var_sized(a, &v, NULL)) {
|
|
2016
|
+
return ARCHIVE_EOF;
|
|
2017
|
+
}
|
|
2018
|
+
|
|
2019
|
+
if (v > UINT_MAX) {
|
|
2020
|
+
archive_set_error(&a->archive,
|
|
2021
|
+
ARCHIVE_ERRNO_FILE_FORMAT,
|
|
2022
|
+
"Invalid volume number");
|
|
2023
|
+
return ARCHIVE_FATAL;
|
|
2024
|
+
}
|
|
2025
|
+
|
|
2026
|
+
rar->main.vol_no = (unsigned int) v;
|
|
2027
|
+
} else {
|
|
2028
|
+
rar->main.vol_no = 0;
|
|
2029
|
+
}
|
|
2030
|
+
|
|
2031
|
+
if(rar->vol.expected_vol_no > 0 &&
|
|
2032
|
+
rar->main.vol_no != rar->vol.expected_vol_no)
|
|
2033
|
+
{
|
|
2034
|
+
/* Returning EOF instead of FATAL because of strange
|
|
2035
|
+
* libarchive behavior. When opening multiple files via
|
|
2036
|
+
* archive_read_open_filenames(), after reading up the whole
|
|
2037
|
+
* last file, the __archive_read_ahead function wraps up to
|
|
2038
|
+
* the first archive instead of returning EOF. */
|
|
2039
|
+
return ARCHIVE_EOF;
|
|
2040
|
+
}
|
|
2041
|
+
|
|
2042
|
+
if(extra_data_size == 0) {
|
|
2043
|
+
/* Early return. */
|
|
2044
|
+
return ARCHIVE_OK;
|
|
2045
|
+
}
|
|
2046
|
+
|
|
2047
|
+
if(!read_var_sized(a, &extra_field_size, NULL)) {
|
|
2048
|
+
return ARCHIVE_EOF;
|
|
2049
|
+
}
|
|
2050
|
+
|
|
2051
|
+
if(!read_var_sized(a, &extra_field_id, NULL)) {
|
|
2052
|
+
return ARCHIVE_EOF;
|
|
2053
|
+
}
|
|
2054
|
+
|
|
2055
|
+
if(extra_field_size == 0) {
|
|
2056
|
+
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
|
2057
|
+
"Invalid extra field size");
|
|
2058
|
+
return ARCHIVE_FATAL;
|
|
2059
|
+
}
|
|
2060
|
+
|
|
2061
|
+
switch(extra_field_id) {
|
|
2062
|
+
case LOCATOR:
|
|
2063
|
+
ret = process_main_locator_extra_block(a, rar);
|
|
2064
|
+
if(ret != ARCHIVE_OK) {
|
|
2065
|
+
/* Error while parsing main locator extra
|
|
2066
|
+
* block. */
|
|
2067
|
+
return ret;
|
|
2068
|
+
}
|
|
2069
|
+
|
|
2070
|
+
break;
|
|
2071
|
+
default:
|
|
2072
|
+
archive_set_error(&a->archive,
|
|
2073
|
+
ARCHIVE_ERRNO_FILE_FORMAT,
|
|
2074
|
+
"Unsupported extra type (0x%x)",
|
|
2075
|
+
(int) extra_field_id);
|
|
2076
|
+
return ARCHIVE_FATAL;
|
|
2077
|
+
}
|
|
2078
|
+
|
|
2079
|
+
return ARCHIVE_OK;
|
|
2080
|
+
}
|
|
2081
|
+
|
|
2082
|
+
static int skip_unprocessed_bytes(struct archive_read* a) {
|
|
2083
|
+
struct rar5* rar = get_context(a);
|
|
2084
|
+
int ret;
|
|
2085
|
+
|
|
2086
|
+
if(rar->file.bytes_remaining) {
|
|
2087
|
+
/* Use different skipping method in block merging mode than in
|
|
2088
|
+
* normal mode. If merge mode is active, rar5_read_data_skip
|
|
2089
|
+
* can't be used, because it could allow recursive use of
|
|
2090
|
+
* merge_block() * function, and this function doesn't support
|
|
2091
|
+
* recursive use. */
|
|
2092
|
+
if(rar->merge_mode) {
|
|
2093
|
+
/* Discard whole merged block. This is valid in solid
|
|
2094
|
+
* mode as well, because the code will discard blocks
|
|
2095
|
+
* only if those blocks are safe to discard (i.e.
|
|
2096
|
+
* they're not FILE blocks). */
|
|
2097
|
+
ret = consume(a, rar->file.bytes_remaining);
|
|
2098
|
+
if(ret != ARCHIVE_OK) {
|
|
2099
|
+
return ret;
|
|
2100
|
+
}
|
|
2101
|
+
rar->file.bytes_remaining = 0;
|
|
2102
|
+
} else {
|
|
2103
|
+
/* If we're not in merge mode, use safe skipping code.
|
|
2104
|
+
* This will ensure we'll handle solid archives
|
|
2105
|
+
* properly. */
|
|
2106
|
+
ret = rar5_read_data_skip(a);
|
|
2107
|
+
if(ret != ARCHIVE_OK) {
|
|
2108
|
+
return ret;
|
|
2109
|
+
}
|
|
2110
|
+
}
|
|
2111
|
+
}
|
|
2112
|
+
|
|
2113
|
+
return ARCHIVE_OK;
|
|
2114
|
+
}
|
|
2115
|
+
|
|
2116
|
+
static int scan_for_signature(struct archive_read* a);
|
|
2117
|
+
|
|
2118
|
+
/* Base block processing function. A 'base block' is a RARv5 header block
|
|
2119
|
+
* that tells the reader what kind of data is stored inside the block.
|
|
2120
|
+
*
|
|
2121
|
+
* From the birds-eye view a RAR file looks file this:
|
|
2122
|
+
*
|
|
2123
|
+
* <magic><base_block_1><base_block_2>...<base_block_n>
|
|
2124
|
+
*
|
|
2125
|
+
* There are a few types of base blocks. Those types are specified inside
|
|
2126
|
+
* the 'switch' statement in this function. For example purposes, I'll write
|
|
2127
|
+
* how a standard RARv5 file could look like here:
|
|
2128
|
+
*
|
|
2129
|
+
* <magic><MAIN><FILE><FILE><FILE><SERVICE><ENDARC>
|
|
2130
|
+
*
|
|
2131
|
+
* The structure above could describe an archive file with 3 files in it,
|
|
2132
|
+
* one service "QuickOpen" block (that is ignored by this parser), and an
|
|
2133
|
+
* end of file base block marker.
|
|
2134
|
+
*
|
|
2135
|
+
* If the file is stored in multiple archive files ("multiarchive"), it might
|
|
2136
|
+
* look like this:
|
|
2137
|
+
*
|
|
2138
|
+
* .part01.rar: <magic><MAIN><FILE><ENDARC>
|
|
2139
|
+
* .part02.rar: <magic><MAIN><FILE><ENDARC>
|
|
2140
|
+
* .part03.rar: <magic><MAIN><FILE><ENDARC>
|
|
2141
|
+
*
|
|
2142
|
+
* This example could describe 3 RAR files that contain ONE archived file.
|
|
2143
|
+
* Or it could describe 3 RAR files that contain 3 different files. Or 3
|
|
2144
|
+
* RAR files than contain 2 files. It all depends what metadata is stored in
|
|
2145
|
+
* the headers of <FILE> blocks.
|
|
2146
|
+
*
|
|
2147
|
+
* Each <FILE> block contains info about its size, the name of the file it's
|
|
2148
|
+
* storing inside, and whether this FILE block is a continuation block of
|
|
2149
|
+
* previous archive ('split before'), and is this FILE block should be
|
|
2150
|
+
* continued in another archive ('split after'). By parsing the 'split before'
|
|
2151
|
+
* and 'split after' flags, we're able to tell if multiple <FILE> base blocks
|
|
2152
|
+
* are describing one file, or multiple files (with the same filename, for
|
|
2153
|
+
* example).
|
|
2154
|
+
*
|
|
2155
|
+
* One thing to note is that if we're parsing the first <FILE> block, and
|
|
2156
|
+
* we see 'split after' flag, then we need to jump over to another <FILE>
|
|
2157
|
+
* block to be able to decompress rest of the data. To do this, we need
|
|
2158
|
+
* to skip the <ENDARC> block, then switch to another file, then skip the
|
|
2159
|
+
* <magic> block, <MAIN> block, and then we're standing on the proper
|
|
2160
|
+
* <FILE> block.
|
|
2161
|
+
*/
|
|
2162
|
+
|
|
2163
|
+
static int process_base_block(struct archive_read* a,
|
|
2164
|
+
struct archive_entry* entry)
|
|
2165
|
+
{
|
|
2166
|
+
const size_t SMALLEST_RAR5_BLOCK_SIZE = 3;
|
|
2167
|
+
|
|
2168
|
+
struct rar5* rar = get_context(a);
|
|
2169
|
+
uint32_t hdr_crc, computed_crc;
|
|
2170
|
+
size_t raw_hdr_size = 0, hdr_size_len, hdr_size;
|
|
2171
|
+
size_t header_id = 0;
|
|
2172
|
+
size_t header_flags = 0;
|
|
2173
|
+
const uint8_t* p;
|
|
2174
|
+
int ret;
|
|
2175
|
+
|
|
2176
|
+
enum HEADER_TYPE {
|
|
2177
|
+
HEAD_MARK = 0x00, HEAD_MAIN = 0x01, HEAD_FILE = 0x02,
|
|
2178
|
+
HEAD_SERVICE = 0x03, HEAD_CRYPT = 0x04, HEAD_ENDARC = 0x05,
|
|
2179
|
+
HEAD_UNKNOWN = 0xff,
|
|
2180
|
+
};
|
|
2181
|
+
|
|
2182
|
+
/* Skip any unprocessed data for this file. */
|
|
2183
|
+
ret = skip_unprocessed_bytes(a);
|
|
2184
|
+
if(ret != ARCHIVE_OK)
|
|
2185
|
+
return ret;
|
|
2186
|
+
|
|
2187
|
+
/* Read the expected CRC32 checksum. */
|
|
2188
|
+
if(!read_u32(a, &hdr_crc)) {
|
|
2189
|
+
return ARCHIVE_EOF;
|
|
2190
|
+
}
|
|
2191
|
+
|
|
2192
|
+
/* Read header size. */
|
|
2193
|
+
if(!read_var_sized(a, &raw_hdr_size, &hdr_size_len)) {
|
|
2194
|
+
return ARCHIVE_EOF;
|
|
2195
|
+
}
|
|
2196
|
+
|
|
2197
|
+
hdr_size = raw_hdr_size + hdr_size_len;
|
|
2198
|
+
|
|
2199
|
+
/* Sanity check, maximum header size for RAR5 is 2MB. */
|
|
2200
|
+
if(hdr_size > (2 * 1024 * 1024)) {
|
|
2201
|
+
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
|
2202
|
+
"Base block header is too large");
|
|
2203
|
+
|
|
2204
|
+
return ARCHIVE_FATAL;
|
|
2205
|
+
}
|
|
2206
|
+
|
|
2207
|
+
/* Additional sanity checks to weed out invalid files. */
|
|
2208
|
+
if(raw_hdr_size == 0 || hdr_size_len == 0 ||
|
|
2209
|
+
hdr_size < SMALLEST_RAR5_BLOCK_SIZE)
|
|
2210
|
+
{
|
|
2211
|
+
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
|
2212
|
+
"Too small block encountered (%zu bytes)",
|
|
2213
|
+
raw_hdr_size);
|
|
2214
|
+
|
|
2215
|
+
return ARCHIVE_FATAL;
|
|
2216
|
+
}
|
|
2217
|
+
|
|
2218
|
+
/* Read the whole header data into memory, maximum memory use here is
|
|
2219
|
+
* 2MB. */
|
|
2220
|
+
if(!read_ahead(a, hdr_size, &p)) {
|
|
2221
|
+
return ARCHIVE_EOF;
|
|
2222
|
+
}
|
|
2223
|
+
|
|
2224
|
+
/* Verify the CRC32 of the header data. */
|
|
2225
|
+
computed_crc = (uint32_t) crc32(0, p, (int) hdr_size);
|
|
2226
|
+
if(computed_crc != hdr_crc) {
|
|
2227
|
+
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
|
2228
|
+
"Header CRC error");
|
|
2229
|
+
|
|
2230
|
+
return ARCHIVE_FATAL;
|
|
2231
|
+
}
|
|
2232
|
+
|
|
2233
|
+
/* If the checksum is OK, we proceed with parsing. */
|
|
2234
|
+
if(ARCHIVE_OK != consume(a, hdr_size_len)) {
|
|
2235
|
+
return ARCHIVE_EOF;
|
|
2236
|
+
}
|
|
2237
|
+
|
|
2238
|
+
if(!read_var_sized(a, &header_id, NULL))
|
|
2239
|
+
return ARCHIVE_EOF;
|
|
2240
|
+
|
|
2241
|
+
if(!read_var_sized(a, &header_flags, NULL))
|
|
2242
|
+
return ARCHIVE_EOF;
|
|
2243
|
+
|
|
2244
|
+
rar->generic.split_after = (header_flags & HFL_SPLIT_AFTER) > 0;
|
|
2245
|
+
rar->generic.split_before = (header_flags & HFL_SPLIT_BEFORE) > 0;
|
|
2246
|
+
rar->generic.size = (int)hdr_size;
|
|
2247
|
+
rar->generic.last_header_id = (int)header_id;
|
|
2248
|
+
rar->main.endarc = 0;
|
|
2249
|
+
|
|
2250
|
+
/* Those are possible header ids in RARv5. */
|
|
2251
|
+
switch(header_id) {
|
|
2252
|
+
case HEAD_MAIN:
|
|
2253
|
+
ret = process_head_main(a, rar, entry, header_flags);
|
|
2254
|
+
|
|
2255
|
+
/* Main header doesn't have any files in it, so it's
|
|
2256
|
+
* pointless to return to the caller. Retry to next
|
|
2257
|
+
* header, which should be HEAD_FILE/HEAD_SERVICE. */
|
|
2258
|
+
if(ret == ARCHIVE_OK)
|
|
2259
|
+
return ARCHIVE_RETRY;
|
|
2260
|
+
|
|
2261
|
+
return ret;
|
|
2262
|
+
case HEAD_SERVICE:
|
|
2263
|
+
ret = process_head_service(a, rar, entry, header_flags);
|
|
2264
|
+
return ret;
|
|
2265
|
+
case HEAD_FILE:
|
|
2266
|
+
ret = process_head_file(a, rar, entry, header_flags);
|
|
2267
|
+
return ret;
|
|
2268
|
+
case HEAD_CRYPT:
|
|
2269
|
+
archive_set_error(&a->archive,
|
|
2270
|
+
ARCHIVE_ERRNO_FILE_FORMAT,
|
|
2271
|
+
"Encryption is not supported");
|
|
2272
|
+
return ARCHIVE_FATAL;
|
|
2273
|
+
case HEAD_ENDARC:
|
|
2274
|
+
rar->main.endarc = 1;
|
|
2275
|
+
|
|
2276
|
+
/* After encountering an end of file marker, we need
|
|
2277
|
+
* to take into consideration if this archive is
|
|
2278
|
+
* continued in another file (i.e. is it part01.rar:
|
|
2279
|
+
* is there a part02.rar?) */
|
|
2280
|
+
if(rar->main.volume) {
|
|
2281
|
+
/* In case there is part02.rar, position the
|
|
2282
|
+
* read pointer in a proper place, so we can
|
|
2283
|
+
* resume parsing. */
|
|
2284
|
+
ret = scan_for_signature(a);
|
|
2285
|
+
if(ret == ARCHIVE_FATAL) {
|
|
2286
|
+
return ARCHIVE_EOF;
|
|
2287
|
+
} else {
|
|
2288
|
+
if(rar->vol.expected_vol_no ==
|
|
2289
|
+
UINT_MAX) {
|
|
2290
|
+
archive_set_error(&a->archive,
|
|
2291
|
+
ARCHIVE_ERRNO_FILE_FORMAT,
|
|
2292
|
+
"Header error");
|
|
2293
|
+
return ARCHIVE_FATAL;
|
|
2294
|
+
}
|
|
2295
|
+
|
|
2296
|
+
rar->vol.expected_vol_no =
|
|
2297
|
+
rar->main.vol_no + 1;
|
|
2298
|
+
return ARCHIVE_OK;
|
|
2299
|
+
}
|
|
2300
|
+
} else {
|
|
2301
|
+
return ARCHIVE_EOF;
|
|
2302
|
+
}
|
|
2303
|
+
case HEAD_MARK:
|
|
2304
|
+
return ARCHIVE_EOF;
|
|
2305
|
+
default:
|
|
2306
|
+
if((header_flags & HFL_SKIP_IF_UNKNOWN) == 0) {
|
|
2307
|
+
archive_set_error(&a->archive,
|
|
2308
|
+
ARCHIVE_ERRNO_FILE_FORMAT,
|
|
2309
|
+
"Header type error");
|
|
2310
|
+
return ARCHIVE_FATAL;
|
|
2311
|
+
} else {
|
|
2312
|
+
/* If the block is marked as 'skip if unknown',
|
|
2313
|
+
* do as the flag says: skip the block
|
|
2314
|
+
* instead on failing on it. */
|
|
2315
|
+
return ARCHIVE_RETRY;
|
|
2316
|
+
}
|
|
2317
|
+
}
|
|
2318
|
+
|
|
2319
|
+
#if !defined WIN32
|
|
2320
|
+
// Not reached.
|
|
2321
|
+
archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER,
|
|
2322
|
+
"Internal unpacker error");
|
|
2323
|
+
return ARCHIVE_FATAL;
|
|
2324
|
+
#endif
|
|
2325
|
+
}
|
|
2326
|
+
|
|
2327
|
+
static int skip_base_block(struct archive_read* a) {
|
|
2328
|
+
int ret;
|
|
2329
|
+
struct rar5* rar = get_context(a);
|
|
2330
|
+
|
|
2331
|
+
/* Create a new local archive_entry structure that will be operated on
|
|
2332
|
+
* by header reader; operations on this archive_entry will be discarded.
|
|
2333
|
+
*/
|
|
2334
|
+
struct archive_entry* entry = archive_entry_new();
|
|
2335
|
+
ret = process_base_block(a, entry);
|
|
2336
|
+
|
|
2337
|
+
/* Discard operations on this archive_entry structure. */
|
|
2338
|
+
archive_entry_free(entry);
|
|
2339
|
+
if(ret == ARCHIVE_FATAL)
|
|
2340
|
+
return ret;
|
|
2341
|
+
|
|
2342
|
+
if(rar->generic.last_header_id == 2 && rar->generic.split_before > 0)
|
|
2343
|
+
return ARCHIVE_OK;
|
|
2344
|
+
|
|
2345
|
+
if(ret == ARCHIVE_OK)
|
|
2346
|
+
return ARCHIVE_RETRY;
|
|
2347
|
+
else
|
|
2348
|
+
return ret;
|
|
2349
|
+
}
|
|
2350
|
+
|
|
2351
|
+
static int try_skip_sfx(struct archive_read *a)
|
|
2352
|
+
{
|
|
2353
|
+
const char *p;
|
|
2354
|
+
|
|
2355
|
+
if ((p = __archive_read_ahead(a, 7, NULL)) == NULL)
|
|
2356
|
+
return ARCHIVE_EOF;
|
|
2357
|
+
|
|
2358
|
+
if ((p[0] == 'M' && p[1] == 'Z') || memcmp(p, "\x7F\x45LF", 4) == 0)
|
|
2359
|
+
{
|
|
2360
|
+
char signature[sizeof(rar5_signature_xor)];
|
|
2361
|
+
const void *h;
|
|
2362
|
+
const char *q;
|
|
2363
|
+
size_t skip, total = 0;
|
|
2364
|
+
ssize_t bytes, window = 4096;
|
|
2365
|
+
|
|
2366
|
+
rar5_signature(signature);
|
|
2367
|
+
|
|
2368
|
+
while (total + window <= (1024 * 512)) {
|
|
2369
|
+
h = __archive_read_ahead(a, window, &bytes);
|
|
2370
|
+
if (h == NULL) {
|
|
2371
|
+
/* Remaining bytes are less than window. */
|
|
2372
|
+
window >>= 1;
|
|
2373
|
+
if (window < 0x40)
|
|
2374
|
+
goto fatal;
|
|
2375
|
+
continue;
|
|
2376
|
+
}
|
|
2377
|
+
if (bytes < 0x40)
|
|
2378
|
+
goto fatal;
|
|
2379
|
+
p = h;
|
|
2380
|
+
q = p + bytes;
|
|
2381
|
+
|
|
2382
|
+
/*
|
|
2383
|
+
* Scan ahead until we find something that looks
|
|
2384
|
+
* like the RAR header.
|
|
2385
|
+
*/
|
|
2386
|
+
while (p + 8 < q) {
|
|
2387
|
+
if (memcmp(p, signature, sizeof(signature)) == 0) {
|
|
2388
|
+
skip = p - (const char *)h;
|
|
2389
|
+
__archive_read_consume(a, skip);
|
|
2390
|
+
return (ARCHIVE_OK);
|
|
2391
|
+
}
|
|
2392
|
+
p += 0x10;
|
|
2393
|
+
}
|
|
2394
|
+
skip = p - (const char *)h;
|
|
2395
|
+
__archive_read_consume(a, skip);
|
|
2396
|
+
total += skip;
|
|
2397
|
+
}
|
|
2398
|
+
}
|
|
2399
|
+
|
|
2400
|
+
return ARCHIVE_OK;
|
|
2401
|
+
fatal:
|
|
2402
|
+
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
|
2403
|
+
"Couldn't find out RAR header");
|
|
2404
|
+
return (ARCHIVE_FATAL);
|
|
2405
|
+
}
|
|
2406
|
+
|
|
2407
|
+
static int rar5_read_header(struct archive_read *a,
|
|
2408
|
+
struct archive_entry *entry)
|
|
2409
|
+
{
|
|
2410
|
+
struct rar5* rar = get_context(a);
|
|
2411
|
+
int ret;
|
|
2412
|
+
|
|
2413
|
+
if(rar->header_initialized == 0) {
|
|
2414
|
+
init_header(a);
|
|
2415
|
+
if ((ret = try_skip_sfx(a)) < ARCHIVE_WARN)
|
|
2416
|
+
return ret;
|
|
2417
|
+
rar->header_initialized = 1;
|
|
2418
|
+
}
|
|
2419
|
+
|
|
2420
|
+
if(rar->skipped_magic == 0) {
|
|
2421
|
+
if(ARCHIVE_OK != consume(a, sizeof(rar5_signature_xor))) {
|
|
2422
|
+
return ARCHIVE_EOF;
|
|
2423
|
+
}
|
|
2424
|
+
|
|
2425
|
+
rar->skipped_magic = 1;
|
|
2426
|
+
}
|
|
2427
|
+
|
|
2428
|
+
do {
|
|
2429
|
+
ret = process_base_block(a, entry);
|
|
2430
|
+
} while(ret == ARCHIVE_RETRY ||
|
|
2431
|
+
(rar->main.endarc > 0 && ret == ARCHIVE_OK));
|
|
2432
|
+
|
|
2433
|
+
return ret;
|
|
2434
|
+
}
|
|
2435
|
+
|
|
2436
|
+
static void init_unpack(struct rar5* rar) {
|
|
2437
|
+
rar->file.calculated_crc32 = 0;
|
|
2438
|
+
init_window_mask(rar);
|
|
2439
|
+
|
|
2440
|
+
free(rar->cstate.window_buf);
|
|
2441
|
+
free(rar->cstate.filtered_buf);
|
|
2442
|
+
|
|
2443
|
+
if(rar->cstate.window_size > 0) {
|
|
2444
|
+
rar->cstate.window_buf = calloc(1, rar->cstate.window_size);
|
|
2445
|
+
rar->cstate.filtered_buf = calloc(1, rar->cstate.window_size);
|
|
2446
|
+
} else {
|
|
2447
|
+
rar->cstate.window_buf = NULL;
|
|
2448
|
+
rar->cstate.filtered_buf = NULL;
|
|
2449
|
+
}
|
|
2450
|
+
|
|
2451
|
+
rar->cstate.write_ptr = 0;
|
|
2452
|
+
rar->cstate.last_write_ptr = 0;
|
|
2453
|
+
|
|
2454
|
+
memset(&rar->cstate.bd, 0, sizeof(rar->cstate.bd));
|
|
2455
|
+
memset(&rar->cstate.ld, 0, sizeof(rar->cstate.ld));
|
|
2456
|
+
memset(&rar->cstate.dd, 0, sizeof(rar->cstate.dd));
|
|
2457
|
+
memset(&rar->cstate.ldd, 0, sizeof(rar->cstate.ldd));
|
|
2458
|
+
memset(&rar->cstate.rd, 0, sizeof(rar->cstate.rd));
|
|
2459
|
+
}
|
|
2460
|
+
|
|
2461
|
+
static void update_crc(struct rar5* rar, const uint8_t* p, size_t to_read) {
|
|
2462
|
+
int verify_crc;
|
|
2463
|
+
|
|
2464
|
+
if(rar->skip_mode) {
|
|
2465
|
+
#if defined CHECK_CRC_ON_SOLID_SKIP
|
|
2466
|
+
verify_crc = 1;
|
|
2467
|
+
#else
|
|
2468
|
+
verify_crc = 0;
|
|
2469
|
+
#endif
|
|
2470
|
+
} else
|
|
2471
|
+
verify_crc = 1;
|
|
2472
|
+
|
|
2473
|
+
if(verify_crc) {
|
|
2474
|
+
/* Don't update CRC32 if the file doesn't have the
|
|
2475
|
+
* `stored_crc32` info filled in. */
|
|
2476
|
+
if(rar->file.stored_crc32 > 0) {
|
|
2477
|
+
rar->file.calculated_crc32 =
|
|
2478
|
+
crc32(rar->file.calculated_crc32, p, to_read);
|
|
2479
|
+
}
|
|
2480
|
+
|
|
2481
|
+
/* Check if the file uses an optional BLAKE2sp checksum
|
|
2482
|
+
* algorithm. */
|
|
2483
|
+
if(rar->file.has_blake2 > 0) {
|
|
2484
|
+
/* Return value of the `update` function is always 0,
|
|
2485
|
+
* so we can explicitly ignore it here. */
|
|
2486
|
+
(void) blake2sp_update(&rar->file.b2state, p, to_read);
|
|
2487
|
+
}
|
|
2488
|
+
}
|
|
2489
|
+
}
|
|
2490
|
+
|
|
2491
|
+
static int create_decode_tables(uint8_t* bit_length,
|
|
2492
|
+
struct decode_table* table, int size)
|
|
2493
|
+
{
|
|
2494
|
+
int code, upper_limit = 0, i, lc[16];
|
|
2495
|
+
uint32_t decode_pos_clone[rar5_countof(table->decode_pos)];
|
|
2496
|
+
ssize_t cur_len, quick_data_size;
|
|
2497
|
+
|
|
2498
|
+
memset(&lc, 0, sizeof(lc));
|
|
2499
|
+
memset(table->decode_num, 0, sizeof(table->decode_num));
|
|
2500
|
+
table->size = size;
|
|
2501
|
+
table->quick_bits = size == HUFF_NC ? 10 : 7;
|
|
2502
|
+
|
|
2503
|
+
for(i = 0; i < size; i++) {
|
|
2504
|
+
lc[bit_length[i] & 15]++;
|
|
2505
|
+
}
|
|
2506
|
+
|
|
2507
|
+
lc[0] = 0;
|
|
2508
|
+
table->decode_pos[0] = 0;
|
|
2509
|
+
table->decode_len[0] = 0;
|
|
2510
|
+
|
|
2511
|
+
for(i = 1; i < 16; i++) {
|
|
2512
|
+
upper_limit += lc[i];
|
|
2513
|
+
|
|
2514
|
+
table->decode_len[i] = upper_limit << (16 - i);
|
|
2515
|
+
table->decode_pos[i] = table->decode_pos[i - 1] + lc[i - 1];
|
|
2516
|
+
|
|
2517
|
+
upper_limit <<= 1;
|
|
2518
|
+
}
|
|
2519
|
+
|
|
2520
|
+
memcpy(decode_pos_clone, table->decode_pos, sizeof(decode_pos_clone));
|
|
2521
|
+
|
|
2522
|
+
for(i = 0; i < size; i++) {
|
|
2523
|
+
uint8_t clen = bit_length[i] & 15;
|
|
2524
|
+
if(clen > 0) {
|
|
2525
|
+
int last_pos = decode_pos_clone[clen];
|
|
2526
|
+
table->decode_num[last_pos] = i;
|
|
2527
|
+
decode_pos_clone[clen]++;
|
|
2528
|
+
}
|
|
2529
|
+
}
|
|
2530
|
+
|
|
2531
|
+
quick_data_size = (int64_t)1 << table->quick_bits;
|
|
2532
|
+
cur_len = 1;
|
|
2533
|
+
for(code = 0; code < quick_data_size; code++) {
|
|
2534
|
+
int bit_field = code << (16 - table->quick_bits);
|
|
2535
|
+
int dist, pos;
|
|
2536
|
+
|
|
2537
|
+
while(cur_len < rar5_countof(table->decode_len) &&
|
|
2538
|
+
bit_field >= table->decode_len[cur_len]) {
|
|
2539
|
+
cur_len++;
|
|
2540
|
+
}
|
|
2541
|
+
|
|
2542
|
+
table->quick_len[code] = (uint8_t) cur_len;
|
|
2543
|
+
|
|
2544
|
+
dist = bit_field - table->decode_len[cur_len - 1];
|
|
2545
|
+
dist >>= (16 - cur_len);
|
|
2546
|
+
|
|
2547
|
+
pos = table->decode_pos[cur_len & 15] + dist;
|
|
2548
|
+
if(cur_len < rar5_countof(table->decode_pos) && pos < size) {
|
|
2549
|
+
table->quick_num[code] = table->decode_num[pos];
|
|
2550
|
+
} else {
|
|
2551
|
+
table->quick_num[code] = 0;
|
|
2552
|
+
}
|
|
2553
|
+
}
|
|
2554
|
+
|
|
2555
|
+
return ARCHIVE_OK;
|
|
2556
|
+
}
|
|
2557
|
+
|
|
2558
|
+
static int decode_number(struct archive_read* a, struct decode_table* table,
|
|
2559
|
+
const uint8_t* p, uint16_t* num)
|
|
2560
|
+
{
|
|
2561
|
+
int i, bits, dist, ret;
|
|
2562
|
+
uint16_t bitfield;
|
|
2563
|
+
uint32_t pos;
|
|
2564
|
+
struct rar5* rar = get_context(a);
|
|
2565
|
+
|
|
2566
|
+
if(ARCHIVE_OK != (ret = read_bits_16(a, rar, p, &bitfield))) {
|
|
2567
|
+
return ret;
|
|
2568
|
+
}
|
|
2569
|
+
|
|
2570
|
+
bitfield &= 0xfffe;
|
|
2571
|
+
|
|
2572
|
+
if(bitfield < table->decode_len[table->quick_bits]) {
|
|
2573
|
+
int code = bitfield >> (16 - table->quick_bits);
|
|
2574
|
+
skip_bits(rar, table->quick_len[code]);
|
|
2575
|
+
*num = table->quick_num[code];
|
|
2576
|
+
return ARCHIVE_OK;
|
|
2577
|
+
}
|
|
2578
|
+
|
|
2579
|
+
bits = 15;
|
|
2580
|
+
|
|
2581
|
+
for(i = table->quick_bits + 1; i < 15; i++) {
|
|
2582
|
+
if(bitfield < table->decode_len[i]) {
|
|
2583
|
+
bits = i;
|
|
2584
|
+
break;
|
|
2585
|
+
}
|
|
2586
|
+
}
|
|
2587
|
+
|
|
2588
|
+
skip_bits(rar, bits);
|
|
2589
|
+
|
|
2590
|
+
dist = bitfield - table->decode_len[bits - 1];
|
|
2591
|
+
dist >>= (16 - bits);
|
|
2592
|
+
pos = table->decode_pos[bits] + dist;
|
|
2593
|
+
|
|
2594
|
+
if(pos >= table->size)
|
|
2595
|
+
pos = 0;
|
|
2596
|
+
|
|
2597
|
+
*num = table->decode_num[pos];
|
|
2598
|
+
return ARCHIVE_OK;
|
|
2599
|
+
}
|
|
2600
|
+
|
|
2601
|
+
/* Reads and parses Huffman tables from the beginning of the block. */
|
|
2602
|
+
static int parse_tables(struct archive_read* a, struct rar5* rar,
|
|
2603
|
+
const uint8_t* p)
|
|
2604
|
+
{
|
|
2605
|
+
int ret, value, i, w, idx = 0;
|
|
2606
|
+
uint8_t bit_length[HUFF_BC],
|
|
2607
|
+
table[HUFF_TABLE_SIZE],
|
|
2608
|
+
nibble_mask = 0xF0,
|
|
2609
|
+
nibble_shift = 4;
|
|
2610
|
+
|
|
2611
|
+
enum { ESCAPE = 15 };
|
|
2612
|
+
|
|
2613
|
+
/* The data for table generation is compressed using a simple RLE-like
|
|
2614
|
+
* algorithm when storing zeroes, so we need to unpack it first. */
|
|
2615
|
+
for(w = 0, i = 0; w < HUFF_BC;) {
|
|
2616
|
+
if(i >= rar->cstate.cur_block_size) {
|
|
2617
|
+
/* Truncated data, can't continue. */
|
|
2618
|
+
archive_set_error(&a->archive,
|
|
2619
|
+
ARCHIVE_ERRNO_FILE_FORMAT,
|
|
2620
|
+
"Truncated data in huffman tables");
|
|
2621
|
+
return ARCHIVE_FATAL;
|
|
2622
|
+
}
|
|
2623
|
+
|
|
2624
|
+
value = (p[i] & nibble_mask) >> nibble_shift;
|
|
2625
|
+
|
|
2626
|
+
if(nibble_mask == 0x0F)
|
|
2627
|
+
++i;
|
|
2628
|
+
|
|
2629
|
+
nibble_mask ^= 0xFF;
|
|
2630
|
+
nibble_shift ^= 4;
|
|
2631
|
+
|
|
2632
|
+
/* Values smaller than 15 is data, so we write it directly.
|
|
2633
|
+
* Value 15 is a flag telling us that we need to unpack more
|
|
2634
|
+
* bytes. */
|
|
2635
|
+
if(value == ESCAPE) {
|
|
2636
|
+
value = (p[i] & nibble_mask) >> nibble_shift;
|
|
2637
|
+
if(nibble_mask == 0x0F)
|
|
2638
|
+
++i;
|
|
2639
|
+
nibble_mask ^= 0xFF;
|
|
2640
|
+
nibble_shift ^= 4;
|
|
2641
|
+
|
|
2642
|
+
if(value == 0) {
|
|
2643
|
+
/* We sometimes need to write the actual value
|
|
2644
|
+
* of 15, so this case handles that. */
|
|
2645
|
+
bit_length[w++] = ESCAPE;
|
|
2646
|
+
} else {
|
|
2647
|
+
int k;
|
|
2648
|
+
|
|
2649
|
+
/* Fill zeroes. */
|
|
2650
|
+
for(k = 0; (k < value + 2) && (w < HUFF_BC);
|
|
2651
|
+
k++) {
|
|
2652
|
+
bit_length[w++] = 0;
|
|
2653
|
+
}
|
|
2654
|
+
}
|
|
2655
|
+
} else {
|
|
2656
|
+
bit_length[w++] = value;
|
|
2657
|
+
}
|
|
2658
|
+
}
|
|
2659
|
+
|
|
2660
|
+
rar->bits.in_addr = i;
|
|
2661
|
+
rar->bits.bit_addr = nibble_shift ^ 4;
|
|
2662
|
+
|
|
2663
|
+
ret = create_decode_tables(bit_length, &rar->cstate.bd, HUFF_BC);
|
|
2664
|
+
if(ret != ARCHIVE_OK) {
|
|
2665
|
+
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
|
2666
|
+
"Decoding huffman tables failed");
|
|
2667
|
+
return ARCHIVE_FATAL;
|
|
2668
|
+
}
|
|
2669
|
+
|
|
2670
|
+
for(i = 0; i < HUFF_TABLE_SIZE;) {
|
|
2671
|
+
uint16_t num;
|
|
2672
|
+
|
|
2673
|
+
ret = decode_number(a, &rar->cstate.bd, p, &num);
|
|
2674
|
+
if(ret != ARCHIVE_OK) {
|
|
2675
|
+
archive_set_error(&a->archive,
|
|
2676
|
+
ARCHIVE_ERRNO_FILE_FORMAT,
|
|
2677
|
+
"Decoding huffman tables failed");
|
|
2678
|
+
return ARCHIVE_FATAL;
|
|
2679
|
+
}
|
|
2680
|
+
|
|
2681
|
+
if(num < 16) {
|
|
2682
|
+
/* 0..15: store directly */
|
|
2683
|
+
table[i] = (uint8_t) num;
|
|
2684
|
+
i++;
|
|
2685
|
+
} else if(num < 18) {
|
|
2686
|
+
/* 16..17: repeat previous code */
|
|
2687
|
+
uint16_t n;
|
|
2688
|
+
|
|
2689
|
+
if(ARCHIVE_OK != (ret = read_bits_16(a, rar, p, &n)))
|
|
2690
|
+
return ret;
|
|
2691
|
+
|
|
2692
|
+
if(num == 16) {
|
|
2693
|
+
n >>= 13;
|
|
2694
|
+
n += 3;
|
|
2695
|
+
skip_bits(rar, 3);
|
|
2696
|
+
} else {
|
|
2697
|
+
n >>= 9;
|
|
2698
|
+
n += 11;
|
|
2699
|
+
skip_bits(rar, 7);
|
|
2700
|
+
}
|
|
2701
|
+
|
|
2702
|
+
if(i > 0) {
|
|
2703
|
+
while(n-- > 0 && i < HUFF_TABLE_SIZE) {
|
|
2704
|
+
table[i] = table[i - 1];
|
|
2705
|
+
i++;
|
|
2706
|
+
}
|
|
2707
|
+
} else {
|
|
2708
|
+
archive_set_error(&a->archive,
|
|
2709
|
+
ARCHIVE_ERRNO_FILE_FORMAT,
|
|
2710
|
+
"Unexpected error when decoding "
|
|
2711
|
+
"huffman tables");
|
|
2712
|
+
return ARCHIVE_FATAL;
|
|
2713
|
+
}
|
|
2714
|
+
} else {
|
|
2715
|
+
/* other codes: fill with zeroes `n` times */
|
|
2716
|
+
uint16_t n;
|
|
2717
|
+
|
|
2718
|
+
if(ARCHIVE_OK != (ret = read_bits_16(a, rar, p, &n)))
|
|
2719
|
+
return ret;
|
|
2720
|
+
|
|
2721
|
+
if(num == 18) {
|
|
2722
|
+
n >>= 13;
|
|
2723
|
+
n += 3;
|
|
2724
|
+
skip_bits(rar, 3);
|
|
2725
|
+
} else {
|
|
2726
|
+
n >>= 9;
|
|
2727
|
+
n += 11;
|
|
2728
|
+
skip_bits(rar, 7);
|
|
2729
|
+
}
|
|
2730
|
+
|
|
2731
|
+
while(n-- > 0 && i < HUFF_TABLE_SIZE)
|
|
2732
|
+
table[i++] = 0;
|
|
2733
|
+
}
|
|
2734
|
+
}
|
|
2735
|
+
|
|
2736
|
+
ret = create_decode_tables(&table[idx], &rar->cstate.ld, HUFF_NC);
|
|
2737
|
+
if(ret != ARCHIVE_OK) {
|
|
2738
|
+
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
|
2739
|
+
"Failed to create literal table");
|
|
2740
|
+
return ARCHIVE_FATAL;
|
|
2741
|
+
}
|
|
2742
|
+
|
|
2743
|
+
idx += HUFF_NC;
|
|
2744
|
+
|
|
2745
|
+
ret = create_decode_tables(&table[idx], &rar->cstate.dd, HUFF_DC);
|
|
2746
|
+
if(ret != ARCHIVE_OK) {
|
|
2747
|
+
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
|
2748
|
+
"Failed to create distance table");
|
|
2749
|
+
return ARCHIVE_FATAL;
|
|
2750
|
+
}
|
|
2751
|
+
|
|
2752
|
+
idx += HUFF_DC;
|
|
2753
|
+
|
|
2754
|
+
ret = create_decode_tables(&table[idx], &rar->cstate.ldd, HUFF_LDC);
|
|
2755
|
+
if(ret != ARCHIVE_OK) {
|
|
2756
|
+
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
|
2757
|
+
"Failed to create lower bits of distances table");
|
|
2758
|
+
return ARCHIVE_FATAL;
|
|
2759
|
+
}
|
|
2760
|
+
|
|
2761
|
+
idx += HUFF_LDC;
|
|
2762
|
+
|
|
2763
|
+
ret = create_decode_tables(&table[idx], &rar->cstate.rd, HUFF_RC);
|
|
2764
|
+
if(ret != ARCHIVE_OK) {
|
|
2765
|
+
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
|
2766
|
+
"Failed to create repeating distances table");
|
|
2767
|
+
return ARCHIVE_FATAL;
|
|
2768
|
+
}
|
|
2769
|
+
|
|
2770
|
+
return ARCHIVE_OK;
|
|
2771
|
+
}
|
|
2772
|
+
|
|
2773
|
+
/* Parses the block header, verifies its CRC byte, and saves the header
|
|
2774
|
+
* fields inside the `hdr` pointer. */
|
|
2775
|
+
static int parse_block_header(struct archive_read* a, const uint8_t* p,
|
|
2776
|
+
ssize_t* block_size, struct compressed_block_header* hdr)
|
|
2777
|
+
{
|
|
2778
|
+
uint8_t calculated_cksum;
|
|
2779
|
+
memcpy(hdr, p, sizeof(struct compressed_block_header));
|
|
2780
|
+
|
|
2781
|
+
if(bf_byte_count(hdr) > 2) {
|
|
2782
|
+
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
|
2783
|
+
"Unsupported block header size (was %d, max is 2)",
|
|
2784
|
+
bf_byte_count(hdr));
|
|
2785
|
+
return ARCHIVE_FATAL;
|
|
2786
|
+
}
|
|
2787
|
+
|
|
2788
|
+
/* This should probably use bit reader interface in order to be more
|
|
2789
|
+
* future-proof. */
|
|
2790
|
+
*block_size = 0;
|
|
2791
|
+
switch(bf_byte_count(hdr)) {
|
|
2792
|
+
/* 1-byte block size */
|
|
2793
|
+
case 0:
|
|
2794
|
+
*block_size = *(const uint8_t*) &p[2];
|
|
2795
|
+
break;
|
|
2796
|
+
|
|
2797
|
+
/* 2-byte block size */
|
|
2798
|
+
case 1:
|
|
2799
|
+
*block_size = archive_le16dec(&p[2]);
|
|
2800
|
+
break;
|
|
2801
|
+
|
|
2802
|
+
/* 3-byte block size */
|
|
2803
|
+
case 2:
|
|
2804
|
+
*block_size = archive_le32dec(&p[2]);
|
|
2805
|
+
*block_size &= 0x00FFFFFF;
|
|
2806
|
+
break;
|
|
2807
|
+
|
|
2808
|
+
/* Other block sizes are not supported. This case is not
|
|
2809
|
+
* reached, because we have an 'if' guard before the switch
|
|
2810
|
+
* that makes sure of it. */
|
|
2811
|
+
default:
|
|
2812
|
+
return ARCHIVE_FATAL;
|
|
2813
|
+
}
|
|
2814
|
+
|
|
2815
|
+
/* Verify the block header checksum. 0x5A is a magic value and is
|
|
2816
|
+
* always * constant. */
|
|
2817
|
+
calculated_cksum = 0x5A
|
|
2818
|
+
^ (uint8_t) hdr->block_flags_u8
|
|
2819
|
+
^ (uint8_t) *block_size
|
|
2820
|
+
^ (uint8_t) (*block_size >> 8)
|
|
2821
|
+
^ (uint8_t) (*block_size >> 16);
|
|
2822
|
+
|
|
2823
|
+
if(calculated_cksum != hdr->block_cksum) {
|
|
2824
|
+
#ifndef DONT_FAIL_ON_CRC_ERROR
|
|
2825
|
+
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
|
2826
|
+
"Block checksum error: got 0x%x, expected 0x%x",
|
|
2827
|
+
hdr->block_cksum, calculated_cksum);
|
|
2828
|
+
|
|
2829
|
+
return ARCHIVE_FATAL;
|
|
2830
|
+
#endif
|
|
2831
|
+
}
|
|
2832
|
+
|
|
2833
|
+
return ARCHIVE_OK;
|
|
2834
|
+
}
|
|
2835
|
+
|
|
2836
|
+
/* Convenience function used during filter processing. */
|
|
2837
|
+
static int parse_filter_data(struct archive_read* a, struct rar5* rar,
|
|
2838
|
+
const uint8_t* p, uint32_t* filter_data)
|
|
2839
|
+
{
|
|
2840
|
+
int i, bytes, ret;
|
|
2841
|
+
uint32_t data = 0;
|
|
2842
|
+
|
|
2843
|
+
if(ARCHIVE_OK != (ret = read_consume_bits(a, rar, p, 2, &bytes)))
|
|
2844
|
+
return ret;
|
|
2845
|
+
|
|
2846
|
+
bytes++;
|
|
2847
|
+
|
|
2848
|
+
for(i = 0; i < bytes; i++) {
|
|
2849
|
+
uint16_t byte;
|
|
2850
|
+
|
|
2851
|
+
if(ARCHIVE_OK != (ret = read_bits_16(a, rar, p, &byte))) {
|
|
2852
|
+
return ret;
|
|
2853
|
+
}
|
|
2854
|
+
|
|
2855
|
+
/* Cast to uint32_t will ensure the shift operation will not
|
|
2856
|
+
* produce undefined result. */
|
|
2857
|
+
data += ((uint32_t) byte >> 8) << (i * 8);
|
|
2858
|
+
skip_bits(rar, 8);
|
|
2859
|
+
}
|
|
2860
|
+
|
|
2861
|
+
*filter_data = data;
|
|
2862
|
+
return ARCHIVE_OK;
|
|
2863
|
+
}
|
|
2864
|
+
|
|
2865
|
+
/* Function is used during sanity checking. */
|
|
2866
|
+
static int is_valid_filter_block_start(struct rar5* rar,
|
|
2867
|
+
uint32_t start)
|
|
2868
|
+
{
|
|
2869
|
+
const int64_t block_start = (ssize_t) start + rar->cstate.write_ptr;
|
|
2870
|
+
const int64_t last_bs = rar->cstate.last_block_start;
|
|
2871
|
+
const ssize_t last_bl = rar->cstate.last_block_length;
|
|
2872
|
+
|
|
2873
|
+
if(last_bs == 0 || last_bl == 0) {
|
|
2874
|
+
/* We didn't have any filters yet, so accept this offset. */
|
|
2875
|
+
return 1;
|
|
2876
|
+
}
|
|
2877
|
+
|
|
2878
|
+
if(block_start >= last_bs + last_bl) {
|
|
2879
|
+
/* Current offset is bigger than last block's end offset, so
|
|
2880
|
+
* accept current offset. */
|
|
2881
|
+
return 1;
|
|
2882
|
+
}
|
|
2883
|
+
|
|
2884
|
+
/* Any other case is not a normal situation and we should fail. */
|
|
2885
|
+
return 0;
|
|
2886
|
+
}
|
|
2887
|
+
|
|
2888
|
+
/* The function will create a new filter, read its parameters from the input
|
|
2889
|
+
* stream and add it to the filter collection. */
|
|
2890
|
+
static int parse_filter(struct archive_read* ar, const uint8_t* p) {
|
|
2891
|
+
uint32_t block_start, block_length;
|
|
2892
|
+
uint16_t filter_type;
|
|
2893
|
+
struct filter_info* filt = NULL;
|
|
2894
|
+
struct rar5* rar = get_context(ar);
|
|
2895
|
+
int ret;
|
|
2896
|
+
|
|
2897
|
+
/* Read the parameters from the input stream. */
|
|
2898
|
+
if(ARCHIVE_OK != (ret = parse_filter_data(ar, rar, p, &block_start)))
|
|
2899
|
+
return ret;
|
|
2900
|
+
|
|
2901
|
+
if(ARCHIVE_OK != (ret = parse_filter_data(ar, rar, p, &block_length)))
|
|
2902
|
+
return ret;
|
|
2903
|
+
|
|
2904
|
+
if(ARCHIVE_OK != (ret = read_bits_16(ar, rar, p, &filter_type)))
|
|
2905
|
+
return ret;
|
|
2906
|
+
|
|
2907
|
+
filter_type >>= 13;
|
|
2908
|
+
skip_bits(rar, 3);
|
|
2909
|
+
|
|
2910
|
+
/* Perform some sanity checks on this filter parameters. Note that we
|
|
2911
|
+
* allow only DELTA, E8/E9 and ARM filters here, because rest of
|
|
2912
|
+
* filters are not used in RARv5. */
|
|
2913
|
+
|
|
2914
|
+
if(block_length < 4 ||
|
|
2915
|
+
block_length > 0x400000 ||
|
|
2916
|
+
filter_type > FILTER_ARM ||
|
|
2917
|
+
!is_valid_filter_block_start(rar, block_start))
|
|
2918
|
+
{
|
|
2919
|
+
archive_set_error(&ar->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
|
2920
|
+
"Invalid filter encountered");
|
|
2921
|
+
return ARCHIVE_FATAL;
|
|
2922
|
+
}
|
|
2923
|
+
|
|
2924
|
+
/* Allocate a new filter. */
|
|
2925
|
+
filt = add_new_filter(rar);
|
|
2926
|
+
if(filt == NULL) {
|
|
2927
|
+
archive_set_error(&ar->archive, ENOMEM,
|
|
2928
|
+
"Can't allocate memory for a filter descriptor.");
|
|
2929
|
+
return ARCHIVE_FATAL;
|
|
2930
|
+
}
|
|
2931
|
+
|
|
2932
|
+
filt->type = filter_type;
|
|
2933
|
+
filt->block_start = rar->cstate.write_ptr + block_start;
|
|
2934
|
+
filt->block_length = block_length;
|
|
2935
|
+
|
|
2936
|
+
rar->cstate.last_block_start = filt->block_start;
|
|
2937
|
+
rar->cstate.last_block_length = filt->block_length;
|
|
2938
|
+
|
|
2939
|
+
/* Read some more data in case this is a DELTA filter. Other filter
|
|
2940
|
+
* types don't require any additional data over what was already
|
|
2941
|
+
* read. */
|
|
2942
|
+
if(filter_type == FILTER_DELTA) {
|
|
2943
|
+
int channels;
|
|
2944
|
+
|
|
2945
|
+
if(ARCHIVE_OK != (ret = read_consume_bits(ar, rar, p, 5, &channels)))
|
|
2946
|
+
return ret;
|
|
2947
|
+
|
|
2948
|
+
filt->channels = channels + 1;
|
|
2949
|
+
}
|
|
2950
|
+
|
|
2951
|
+
return ARCHIVE_OK;
|
|
2952
|
+
}
|
|
2953
|
+
|
|
2954
|
+
static int decode_code_length(struct archive_read* a, struct rar5* rar,
|
|
2955
|
+
const uint8_t* p, uint16_t code)
|
|
2956
|
+
{
|
|
2957
|
+
int lbits, length = 2;
|
|
2958
|
+
|
|
2959
|
+
if(code < 8) {
|
|
2960
|
+
lbits = 0;
|
|
2961
|
+
length += code;
|
|
2962
|
+
} else {
|
|
2963
|
+
lbits = code / 4 - 1;
|
|
2964
|
+
length += (4 | (code & 3)) << lbits;
|
|
2965
|
+
}
|
|
2966
|
+
|
|
2967
|
+
if(lbits > 0) {
|
|
2968
|
+
int add;
|
|
2969
|
+
|
|
2970
|
+
if(ARCHIVE_OK != read_consume_bits(a, rar, p, lbits, &add))
|
|
2971
|
+
return -1;
|
|
2972
|
+
|
|
2973
|
+
length += add;
|
|
2974
|
+
}
|
|
2975
|
+
|
|
2976
|
+
return length;
|
|
2977
|
+
}
|
|
2978
|
+
|
|
2979
|
+
static int copy_string(struct archive_read* a, int len, int dist) {
|
|
2980
|
+
struct rar5* rar = get_context(a);
|
|
2981
|
+
const uint64_t cmask = rar->cstate.window_mask;
|
|
2982
|
+
const uint64_t write_ptr = rar->cstate.write_ptr +
|
|
2983
|
+
rar->cstate.solid_offset;
|
|
2984
|
+
int i;
|
|
2985
|
+
|
|
2986
|
+
if (rar->cstate.window_buf == NULL)
|
|
2987
|
+
return ARCHIVE_FATAL;
|
|
2988
|
+
|
|
2989
|
+
/* The unpacker spends most of the time in this function. It would be
|
|
2990
|
+
* a good idea to introduce some optimizations here.
|
|
2991
|
+
*
|
|
2992
|
+
* Just remember that this loop treats buffers that overlap differently
|
|
2993
|
+
* than buffers that do not overlap. This is why a simple memcpy(3)
|
|
2994
|
+
* call will not be enough. */
|
|
2995
|
+
|
|
2996
|
+
for(i = 0; i < len; i++) {
|
|
2997
|
+
const ssize_t write_idx = (write_ptr + i) & cmask;
|
|
2998
|
+
const ssize_t read_idx = (write_ptr + i - dist) & cmask;
|
|
2999
|
+
rar->cstate.window_buf[write_idx] =
|
|
3000
|
+
rar->cstate.window_buf[read_idx];
|
|
3001
|
+
}
|
|
3002
|
+
|
|
3003
|
+
rar->cstate.write_ptr += len;
|
|
3004
|
+
return ARCHIVE_OK;
|
|
3005
|
+
}
|
|
3006
|
+
|
|
3007
|
+
static int do_uncompress_block(struct archive_read* a, const uint8_t* p) {
|
|
3008
|
+
struct rar5* rar = get_context(a);
|
|
3009
|
+
uint16_t num;
|
|
3010
|
+
int ret;
|
|
3011
|
+
|
|
3012
|
+
const uint64_t cmask = rar->cstate.window_mask;
|
|
3013
|
+
const struct compressed_block_header* hdr = &rar->last_block_hdr;
|
|
3014
|
+
const uint8_t bit_size = 1 + bf_bit_size(hdr);
|
|
3015
|
+
|
|
3016
|
+
while(1) {
|
|
3017
|
+
if(rar->cstate.write_ptr - rar->cstate.last_write_ptr >
|
|
3018
|
+
(rar->cstate.window_size >> 1)) {
|
|
3019
|
+
/* Don't allow growing data by more than half of the
|
|
3020
|
+
* window size at a time. In such case, break the loop;
|
|
3021
|
+
* next call to this function will continue processing
|
|
3022
|
+
* from this moment. */
|
|
3023
|
+
break;
|
|
3024
|
+
}
|
|
3025
|
+
|
|
3026
|
+
if(rar->bits.in_addr > rar->cstate.cur_block_size - 1 ||
|
|
3027
|
+
(rar->bits.in_addr == rar->cstate.cur_block_size - 1 &&
|
|
3028
|
+
rar->bits.bit_addr >= bit_size))
|
|
3029
|
+
{
|
|
3030
|
+
/* If the program counter is here, it means the
|
|
3031
|
+
* function has finished processing the block. */
|
|
3032
|
+
rar->cstate.block_parsing_finished = 1;
|
|
3033
|
+
break;
|
|
3034
|
+
}
|
|
3035
|
+
|
|
3036
|
+
/* Decode the next literal. */
|
|
3037
|
+
if(ARCHIVE_OK != decode_number(a, &rar->cstate.ld, p, &num)) {
|
|
3038
|
+
return ARCHIVE_EOF;
|
|
3039
|
+
}
|
|
3040
|
+
|
|
3041
|
+
/* Num holds a decompression literal, or 'command code'.
|
|
3042
|
+
*
|
|
3043
|
+
* - Values lower than 256 are just bytes. Those codes
|
|
3044
|
+
* can be stored in the output buffer directly.
|
|
3045
|
+
*
|
|
3046
|
+
* - Code 256 defines a new filter, which is later used to
|
|
3047
|
+
* ransform the data block accordingly to the filter type.
|
|
3048
|
+
* The data block needs to be fully uncompressed first.
|
|
3049
|
+
*
|
|
3050
|
+
* - Code bigger than 257 and smaller than 262 define
|
|
3051
|
+
* a repetition pattern that should be copied from
|
|
3052
|
+
* an already uncompressed chunk of data.
|
|
3053
|
+
*/
|
|
3054
|
+
|
|
3055
|
+
if(num < 256) {
|
|
3056
|
+
/* Directly store the byte. */
|
|
3057
|
+
int64_t write_idx = rar->cstate.solid_offset +
|
|
3058
|
+
rar->cstate.write_ptr++;
|
|
3059
|
+
|
|
3060
|
+
rar->cstate.window_buf[write_idx & cmask] =
|
|
3061
|
+
(uint8_t) num;
|
|
3062
|
+
continue;
|
|
3063
|
+
} else if(num >= 262) {
|
|
3064
|
+
uint16_t dist_slot;
|
|
3065
|
+
int len = decode_code_length(a, rar, p, num - 262),
|
|
3066
|
+
dbits,
|
|
3067
|
+
dist = 1;
|
|
3068
|
+
|
|
3069
|
+
if(len == -1) {
|
|
3070
|
+
archive_set_error(&a->archive,
|
|
3071
|
+
ARCHIVE_ERRNO_PROGRAMMER,
|
|
3072
|
+
"Failed to decode the code length");
|
|
3073
|
+
|
|
3074
|
+
return ARCHIVE_FATAL;
|
|
3075
|
+
}
|
|
3076
|
+
|
|
3077
|
+
if(ARCHIVE_OK != decode_number(a, &rar->cstate.dd, p,
|
|
3078
|
+
&dist_slot))
|
|
3079
|
+
{
|
|
3080
|
+
archive_set_error(&a->archive,
|
|
3081
|
+
ARCHIVE_ERRNO_PROGRAMMER,
|
|
3082
|
+
"Failed to decode the distance slot");
|
|
3083
|
+
|
|
3084
|
+
return ARCHIVE_FATAL;
|
|
3085
|
+
}
|
|
3086
|
+
|
|
3087
|
+
if(dist_slot < 4) {
|
|
3088
|
+
dbits = 0;
|
|
3089
|
+
dist += dist_slot;
|
|
3090
|
+
} else {
|
|
3091
|
+
dbits = dist_slot / 2 - 1;
|
|
3092
|
+
|
|
3093
|
+
/* Cast to uint32_t will make sure the shift
|
|
3094
|
+
* left operation won't produce undefined
|
|
3095
|
+
* result. Then, the uint32_t type will
|
|
3096
|
+
* be implicitly casted to int. */
|
|
3097
|
+
dist += (uint32_t) (2 |
|
|
3098
|
+
(dist_slot & 1)) << dbits;
|
|
3099
|
+
}
|
|
3100
|
+
|
|
3101
|
+
if(dbits > 0) {
|
|
3102
|
+
if(dbits >= 4) {
|
|
3103
|
+
uint32_t add = 0;
|
|
3104
|
+
uint16_t low_dist;
|
|
3105
|
+
|
|
3106
|
+
if(dbits > 4) {
|
|
3107
|
+
if(ARCHIVE_OK != (ret = read_bits_32(
|
|
3108
|
+
a, rar, p, &add))) {
|
|
3109
|
+
/* Return EOF if we
|
|
3110
|
+
* can't read more
|
|
3111
|
+
* data. */
|
|
3112
|
+
return ret;
|
|
3113
|
+
}
|
|
3114
|
+
|
|
3115
|
+
skip_bits(rar, dbits - 4);
|
|
3116
|
+
add = (add >> (
|
|
3117
|
+
36 - dbits)) << 4;
|
|
3118
|
+
dist += add;
|
|
3119
|
+
}
|
|
3120
|
+
|
|
3121
|
+
if(ARCHIVE_OK != decode_number(a,
|
|
3122
|
+
&rar->cstate.ldd, p, &low_dist))
|
|
3123
|
+
{
|
|
3124
|
+
archive_set_error(&a->archive,
|
|
3125
|
+
ARCHIVE_ERRNO_PROGRAMMER,
|
|
3126
|
+
"Failed to decode the "
|
|
3127
|
+
"distance slot");
|
|
3128
|
+
|
|
3129
|
+
return ARCHIVE_FATAL;
|
|
3130
|
+
}
|
|
3131
|
+
|
|
3132
|
+
if(dist >= INT_MAX - low_dist - 1) {
|
|
3133
|
+
/* This only happens in
|
|
3134
|
+
* invalid archives. */
|
|
3135
|
+
archive_set_error(&a->archive,
|
|
3136
|
+
ARCHIVE_ERRNO_FILE_FORMAT,
|
|
3137
|
+
"Distance pointer "
|
|
3138
|
+
"overflow");
|
|
3139
|
+
return ARCHIVE_FATAL;
|
|
3140
|
+
}
|
|
3141
|
+
|
|
3142
|
+
dist += low_dist;
|
|
3143
|
+
} else {
|
|
3144
|
+
/* dbits is one of [0,1,2,3] */
|
|
3145
|
+
int add;
|
|
3146
|
+
|
|
3147
|
+
if(ARCHIVE_OK != (ret = read_consume_bits(a, rar,
|
|
3148
|
+
p, dbits, &add))) {
|
|
3149
|
+
/* Return EOF if we can't read
|
|
3150
|
+
* more data. */
|
|
3151
|
+
return ret;
|
|
3152
|
+
}
|
|
3153
|
+
|
|
3154
|
+
dist += add;
|
|
3155
|
+
}
|
|
3156
|
+
}
|
|
3157
|
+
|
|
3158
|
+
if(dist > 0x100) {
|
|
3159
|
+
len++;
|
|
3160
|
+
|
|
3161
|
+
if(dist > 0x2000) {
|
|
3162
|
+
len++;
|
|
3163
|
+
|
|
3164
|
+
if(dist > 0x40000) {
|
|
3165
|
+
len++;
|
|
3166
|
+
}
|
|
3167
|
+
}
|
|
3168
|
+
}
|
|
3169
|
+
|
|
3170
|
+
dist_cache_push(rar, dist);
|
|
3171
|
+
rar->cstate.last_len = len;
|
|
3172
|
+
|
|
3173
|
+
if(ARCHIVE_OK != copy_string(a, len, dist))
|
|
3174
|
+
return ARCHIVE_FATAL;
|
|
3175
|
+
|
|
3176
|
+
continue;
|
|
3177
|
+
} else if(num == 256) {
|
|
3178
|
+
/* Create a filter. */
|
|
3179
|
+
ret = parse_filter(a, p);
|
|
3180
|
+
if(ret != ARCHIVE_OK)
|
|
3181
|
+
return ret;
|
|
3182
|
+
|
|
3183
|
+
continue;
|
|
3184
|
+
} else if(num == 257) {
|
|
3185
|
+
if(rar->cstate.last_len != 0) {
|
|
3186
|
+
if(ARCHIVE_OK != copy_string(a,
|
|
3187
|
+
rar->cstate.last_len,
|
|
3188
|
+
rar->cstate.dist_cache[0]))
|
|
3189
|
+
{
|
|
3190
|
+
return ARCHIVE_FATAL;
|
|
3191
|
+
}
|
|
3192
|
+
}
|
|
3193
|
+
|
|
3194
|
+
continue;
|
|
3195
|
+
} else {
|
|
3196
|
+
/* num < 262 */
|
|
3197
|
+
const int idx = num - 258;
|
|
3198
|
+
const int dist = dist_cache_touch(rar, idx);
|
|
3199
|
+
|
|
3200
|
+
uint16_t len_slot;
|
|
3201
|
+
int len;
|
|
3202
|
+
|
|
3203
|
+
if(ARCHIVE_OK != decode_number(a, &rar->cstate.rd, p,
|
|
3204
|
+
&len_slot)) {
|
|
3205
|
+
return ARCHIVE_FATAL;
|
|
3206
|
+
}
|
|
3207
|
+
|
|
3208
|
+
len = decode_code_length(a, rar, p, len_slot);
|
|
3209
|
+
if (len == -1) {
|
|
3210
|
+
return ARCHIVE_FATAL;
|
|
3211
|
+
}
|
|
3212
|
+
|
|
3213
|
+
rar->cstate.last_len = len;
|
|
3214
|
+
|
|
3215
|
+
if(ARCHIVE_OK != copy_string(a, len, dist))
|
|
3216
|
+
return ARCHIVE_FATAL;
|
|
3217
|
+
|
|
3218
|
+
continue;
|
|
3219
|
+
}
|
|
3220
|
+
}
|
|
3221
|
+
|
|
3222
|
+
return ARCHIVE_OK;
|
|
3223
|
+
}
|
|
3224
|
+
|
|
3225
|
+
/* Binary search for the RARv5 signature. */
|
|
3226
|
+
static int scan_for_signature(struct archive_read* a) {
|
|
3227
|
+
const uint8_t* p;
|
|
3228
|
+
const int chunk_size = 512;
|
|
3229
|
+
ssize_t i;
|
|
3230
|
+
char signature[sizeof(rar5_signature_xor)];
|
|
3231
|
+
|
|
3232
|
+
/* If we're here, it means we're on an 'unknown territory' data.
|
|
3233
|
+
* There's no indication what kind of data we're reading here.
|
|
3234
|
+
* It could be some text comment, any kind of binary data,
|
|
3235
|
+
* digital sign, dragons, etc.
|
|
3236
|
+
*
|
|
3237
|
+
* We want to find a valid RARv5 magic header inside this unknown
|
|
3238
|
+
* data. */
|
|
3239
|
+
|
|
3240
|
+
/* Is it possible in libarchive to just skip everything until the
|
|
3241
|
+
* end of the file? If so, it would be a better approach than the
|
|
3242
|
+
* current implementation of this function. */
|
|
3243
|
+
|
|
3244
|
+
rar5_signature(signature);
|
|
3245
|
+
|
|
3246
|
+
while(1) {
|
|
3247
|
+
if(!read_ahead(a, chunk_size, &p))
|
|
3248
|
+
return ARCHIVE_EOF;
|
|
3249
|
+
|
|
3250
|
+
for(i = 0; i < chunk_size - (int)sizeof(rar5_signature_xor);
|
|
3251
|
+
i++) {
|
|
3252
|
+
if(memcmp(&p[i], signature,
|
|
3253
|
+
sizeof(rar5_signature_xor)) == 0) {
|
|
3254
|
+
/* Consume the number of bytes we've used to
|
|
3255
|
+
* search for the signature, as well as the
|
|
3256
|
+
* number of bytes used by the signature
|
|
3257
|
+
* itself. After this we should be standing
|
|
3258
|
+
* on a valid base block header. */
|
|
3259
|
+
(void) consume(a,
|
|
3260
|
+
i + sizeof(rar5_signature_xor));
|
|
3261
|
+
return ARCHIVE_OK;
|
|
3262
|
+
}
|
|
3263
|
+
}
|
|
3264
|
+
|
|
3265
|
+
consume(a, chunk_size);
|
|
3266
|
+
}
|
|
3267
|
+
|
|
3268
|
+
return ARCHIVE_FATAL;
|
|
3269
|
+
}
|
|
3270
|
+
|
|
3271
|
+
/* This function will switch the multivolume archive file to another file,
|
|
3272
|
+
* i.e. from part03 to part 04. */
|
|
3273
|
+
static int advance_multivolume(struct archive_read* a) {
|
|
3274
|
+
int lret;
|
|
3275
|
+
struct rar5* rar = get_context(a);
|
|
3276
|
+
|
|
3277
|
+
/* A small state machine that will skip unnecessary data, needed to
|
|
3278
|
+
* switch from one multivolume to another. Such skipping is needed if
|
|
3279
|
+
* we want to be an stream-oriented (instead of file-oriented)
|
|
3280
|
+
* unpacker.
|
|
3281
|
+
*
|
|
3282
|
+
* The state machine starts with `rar->main.endarc` == 0. It also
|
|
3283
|
+
* assumes that current stream pointer points to some base block
|
|
3284
|
+
* header.
|
|
3285
|
+
*
|
|
3286
|
+
* The `endarc` field is being set when the base block parsing
|
|
3287
|
+
* function encounters the 'end of archive' marker.
|
|
3288
|
+
*/
|
|
3289
|
+
|
|
3290
|
+
while(1) {
|
|
3291
|
+
if(rar->main.endarc == 1) {
|
|
3292
|
+
int looping = 1;
|
|
3293
|
+
|
|
3294
|
+
rar->main.endarc = 0;
|
|
3295
|
+
|
|
3296
|
+
while(looping) {
|
|
3297
|
+
lret = skip_base_block(a);
|
|
3298
|
+
switch(lret) {
|
|
3299
|
+
case ARCHIVE_RETRY:
|
|
3300
|
+
/* Continue looping. */
|
|
3301
|
+
break;
|
|
3302
|
+
case ARCHIVE_OK:
|
|
3303
|
+
/* Break loop. */
|
|
3304
|
+
looping = 0;
|
|
3305
|
+
break;
|
|
3306
|
+
default:
|
|
3307
|
+
/* Forward any errors to the
|
|
3308
|
+
* caller. */
|
|
3309
|
+
return lret;
|
|
3310
|
+
}
|
|
3311
|
+
}
|
|
3312
|
+
|
|
3313
|
+
break;
|
|
3314
|
+
} else {
|
|
3315
|
+
/* Skip current base block. In order to properly skip
|
|
3316
|
+
* it, we really need to simply parse it and discard
|
|
3317
|
+
* the results. */
|
|
3318
|
+
|
|
3319
|
+
lret = skip_base_block(a);
|
|
3320
|
+
if(lret == ARCHIVE_FATAL || lret == ARCHIVE_FAILED)
|
|
3321
|
+
return lret;
|
|
3322
|
+
|
|
3323
|
+
/* The `skip_base_block` function tells us if we
|
|
3324
|
+
* should continue with skipping, or we should stop
|
|
3325
|
+
* skipping. We're trying to skip everything up to
|
|
3326
|
+
* a base FILE block. */
|
|
3327
|
+
|
|
3328
|
+
if(lret != ARCHIVE_RETRY) {
|
|
3329
|
+
/* If there was an error during skipping, or we
|
|
3330
|
+
* have just skipped a FILE base block... */
|
|
3331
|
+
|
|
3332
|
+
if(rar->main.endarc == 0) {
|
|
3333
|
+
return lret;
|
|
3334
|
+
} else {
|
|
3335
|
+
continue;
|
|
3336
|
+
}
|
|
3337
|
+
}
|
|
3338
|
+
}
|
|
3339
|
+
}
|
|
3340
|
+
|
|
3341
|
+
return ARCHIVE_OK;
|
|
3342
|
+
}
|
|
3343
|
+
|
|
3344
|
+
/* Merges the partial block from the first multivolume archive file, and
|
|
3345
|
+
* partial block from the second multivolume archive file. The result is
|
|
3346
|
+
* a chunk of memory containing the whole block, and the stream pointer
|
|
3347
|
+
* is advanced to the next block in the second multivolume archive file. */
|
|
3348
|
+
static int merge_block(struct archive_read* a, ssize_t block_size,
|
|
3349
|
+
const uint8_t** p)
|
|
3350
|
+
{
|
|
3351
|
+
struct rar5* rar = get_context(a);
|
|
3352
|
+
ssize_t cur_block_size, partial_offset = 0;
|
|
3353
|
+
const uint8_t* lp;
|
|
3354
|
+
int ret;
|
|
3355
|
+
|
|
3356
|
+
if(rar->merge_mode) {
|
|
3357
|
+
archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER,
|
|
3358
|
+
"Recursive merge is not allowed");
|
|
3359
|
+
|
|
3360
|
+
return ARCHIVE_FATAL;
|
|
3361
|
+
}
|
|
3362
|
+
|
|
3363
|
+
/* Set a flag that we're in the switching mode. */
|
|
3364
|
+
rar->cstate.switch_multivolume = 1;
|
|
3365
|
+
|
|
3366
|
+
/* Reallocate the memory which will hold the whole block. */
|
|
3367
|
+
if(rar->vol.push_buf)
|
|
3368
|
+
free((void*) rar->vol.push_buf);
|
|
3369
|
+
|
|
3370
|
+
/* Increasing the allocation block by 8 is due to bit reading functions,
|
|
3371
|
+
* which are using additional 2 or 4 bytes. Allocating the block size
|
|
3372
|
+
* by exact value would make bit reader perform reads from invalid
|
|
3373
|
+
* memory block when reading the last byte from the buffer. */
|
|
3374
|
+
rar->vol.push_buf = malloc(block_size + 8);
|
|
3375
|
+
if(!rar->vol.push_buf) {
|
|
3376
|
+
archive_set_error(&a->archive, ENOMEM,
|
|
3377
|
+
"Can't allocate memory for a merge block buffer.");
|
|
3378
|
+
return ARCHIVE_FATAL;
|
|
3379
|
+
}
|
|
3380
|
+
|
|
3381
|
+
/* Valgrind complains if the extension block for bit reader is not
|
|
3382
|
+
* initialized, so initialize it. */
|
|
3383
|
+
memset(&rar->vol.push_buf[block_size], 0, 8);
|
|
3384
|
+
|
|
3385
|
+
/* A single block can span across multiple multivolume archive files,
|
|
3386
|
+
* so we use a loop here. This loop will consume enough multivolume
|
|
3387
|
+
* archive files until the whole block is read. */
|
|
3388
|
+
|
|
3389
|
+
while(1) {
|
|
3390
|
+
/* Get the size of current block chunk in this multivolume
|
|
3391
|
+
* archive file and read it. */
|
|
3392
|
+
cur_block_size = rar5_min(rar->file.bytes_remaining,
|
|
3393
|
+
block_size - partial_offset);
|
|
3394
|
+
|
|
3395
|
+
if(cur_block_size == 0) {
|
|
3396
|
+
archive_set_error(&a->archive,
|
|
3397
|
+
ARCHIVE_ERRNO_FILE_FORMAT,
|
|
3398
|
+
"Encountered block size == 0 during block merge");
|
|
3399
|
+
return ARCHIVE_FATAL;
|
|
3400
|
+
}
|
|
3401
|
+
|
|
3402
|
+
if(!read_ahead(a, cur_block_size, &lp))
|
|
3403
|
+
return ARCHIVE_EOF;
|
|
3404
|
+
|
|
3405
|
+
/* Sanity check; there should never be a situation where this
|
|
3406
|
+
* function reads more data than the block's size. */
|
|
3407
|
+
if(partial_offset + cur_block_size > block_size) {
|
|
3408
|
+
archive_set_error(&a->archive,
|
|
3409
|
+
ARCHIVE_ERRNO_PROGRAMMER,
|
|
3410
|
+
"Consumed too much data when merging blocks.");
|
|
3411
|
+
return ARCHIVE_FATAL;
|
|
3412
|
+
}
|
|
3413
|
+
|
|
3414
|
+
/* Merge previous block chunk with current block chunk,
|
|
3415
|
+
* or create first block chunk if this is our first
|
|
3416
|
+
* iteration. */
|
|
3417
|
+
memcpy(&rar->vol.push_buf[partial_offset], lp, cur_block_size);
|
|
3418
|
+
|
|
3419
|
+
/* Advance the stream read pointer by this block chunk size. */
|
|
3420
|
+
if(ARCHIVE_OK != consume(a, cur_block_size))
|
|
3421
|
+
return ARCHIVE_EOF;
|
|
3422
|
+
|
|
3423
|
+
/* Update the pointers. `partial_offset` contains information
|
|
3424
|
+
* about the sum of merged block chunks. */
|
|
3425
|
+
partial_offset += cur_block_size;
|
|
3426
|
+
rar->file.bytes_remaining -= cur_block_size;
|
|
3427
|
+
|
|
3428
|
+
/* If `partial_offset` is the same as `block_size`, this means
|
|
3429
|
+
* we've merged all block chunks and we have a valid full
|
|
3430
|
+
* block. */
|
|
3431
|
+
if(partial_offset == block_size) {
|
|
3432
|
+
break;
|
|
3433
|
+
}
|
|
3434
|
+
|
|
3435
|
+
/* If we don't have any bytes to read, this means we should
|
|
3436
|
+
* switch to another multivolume archive file. */
|
|
3437
|
+
if(rar->file.bytes_remaining == 0) {
|
|
3438
|
+
rar->merge_mode++;
|
|
3439
|
+
ret = advance_multivolume(a);
|
|
3440
|
+
rar->merge_mode--;
|
|
3441
|
+
if(ret != ARCHIVE_OK) {
|
|
3442
|
+
return ret;
|
|
3443
|
+
}
|
|
3444
|
+
}
|
|
3445
|
+
}
|
|
3446
|
+
|
|
3447
|
+
*p = rar->vol.push_buf;
|
|
3448
|
+
|
|
3449
|
+
/* If we're here, we can resume unpacking by processing the block
|
|
3450
|
+
* pointed to by the `*p` memory pointer. */
|
|
3451
|
+
|
|
3452
|
+
return ARCHIVE_OK;
|
|
3453
|
+
}
|
|
3454
|
+
|
|
3455
|
+
static int process_block(struct archive_read* a) {
|
|
3456
|
+
const uint8_t* p;
|
|
3457
|
+
struct rar5* rar = get_context(a);
|
|
3458
|
+
int ret;
|
|
3459
|
+
|
|
3460
|
+
/* If we don't have any data to be processed, this most probably means
|
|
3461
|
+
* we need to switch to the next volume. */
|
|
3462
|
+
if(rar->main.volume && rar->file.bytes_remaining == 0) {
|
|
3463
|
+
ret = advance_multivolume(a);
|
|
3464
|
+
if(ret != ARCHIVE_OK)
|
|
3465
|
+
return ret;
|
|
3466
|
+
}
|
|
3467
|
+
|
|
3468
|
+
if(rar->cstate.block_parsing_finished) {
|
|
3469
|
+
ssize_t block_size;
|
|
3470
|
+
ssize_t to_skip;
|
|
3471
|
+
ssize_t cur_block_size;
|
|
3472
|
+
|
|
3473
|
+
/* The header size won't be bigger than 6 bytes. */
|
|
3474
|
+
if(!read_ahead(a, 6, &p)) {
|
|
3475
|
+
/* Failed to prefetch data block header. */
|
|
3476
|
+
return ARCHIVE_EOF;
|
|
3477
|
+
}
|
|
3478
|
+
|
|
3479
|
+
/*
|
|
3480
|
+
* Read block_size by parsing block header. Validate the header
|
|
3481
|
+
* by calculating CRC byte stored inside the header. Size of
|
|
3482
|
+
* the header is not constant (block size can be stored either
|
|
3483
|
+
* in 1 or 2 bytes), that's why block size is left out from the
|
|
3484
|
+
* `compressed_block_header` structure and returned by
|
|
3485
|
+
* `parse_block_header` as the second argument. */
|
|
3486
|
+
|
|
3487
|
+
ret = parse_block_header(a, p, &block_size,
|
|
3488
|
+
&rar->last_block_hdr);
|
|
3489
|
+
if(ret != ARCHIVE_OK) {
|
|
3490
|
+
return ret;
|
|
3491
|
+
}
|
|
3492
|
+
|
|
3493
|
+
/* Skip block header. Next data is huffman tables,
|
|
3494
|
+
* if present. */
|
|
3495
|
+
to_skip = sizeof(struct compressed_block_header) +
|
|
3496
|
+
bf_byte_count(&rar->last_block_hdr) + 1;
|
|
3497
|
+
|
|
3498
|
+
if(ARCHIVE_OK != consume(a, to_skip))
|
|
3499
|
+
return ARCHIVE_EOF;
|
|
3500
|
+
|
|
3501
|
+
rar->file.bytes_remaining -= to_skip;
|
|
3502
|
+
|
|
3503
|
+
/* The block size gives information about the whole block size,
|
|
3504
|
+
* but the block could be stored in split form when using
|
|
3505
|
+
* multi-volume archives. In this case, the block size will be
|
|
3506
|
+
* bigger than the actual data stored in this file. Remaining
|
|
3507
|
+
* part of the data will be in another file. */
|
|
3508
|
+
|
|
3509
|
+
cur_block_size =
|
|
3510
|
+
rar5_min(rar->file.bytes_remaining, block_size);
|
|
3511
|
+
|
|
3512
|
+
if(block_size > rar->file.bytes_remaining) {
|
|
3513
|
+
/* If current blocks' size is bigger than our data
|
|
3514
|
+
* size, this means we have a multivolume archive.
|
|
3515
|
+
* In this case, skip all base headers until the end
|
|
3516
|
+
* of the file, proceed to next "partXXX.rar" volume,
|
|
3517
|
+
* find its signature, skip all headers up to the first
|
|
3518
|
+
* FILE base header, and continue from there.
|
|
3519
|
+
*
|
|
3520
|
+
* Note that `merge_block` will update the `rar`
|
|
3521
|
+
* context structure quite extensively. */
|
|
3522
|
+
|
|
3523
|
+
ret = merge_block(a, block_size, &p);
|
|
3524
|
+
if(ret != ARCHIVE_OK) {
|
|
3525
|
+
return ret;
|
|
3526
|
+
}
|
|
3527
|
+
|
|
3528
|
+
cur_block_size = block_size;
|
|
3529
|
+
|
|
3530
|
+
/* Current stream pointer should be now directly
|
|
3531
|
+
* *after* the block that spanned through multiple
|
|
3532
|
+
* archive files. `p` pointer should have the data of
|
|
3533
|
+
* the *whole* block (merged from partial blocks
|
|
3534
|
+
* stored in multiple archives files). */
|
|
3535
|
+
} else {
|
|
3536
|
+
rar->cstate.switch_multivolume = 0;
|
|
3537
|
+
|
|
3538
|
+
/* Read the whole block size into memory. This can take
|
|
3539
|
+
* up to 8 megabytes of memory in theoretical cases.
|
|
3540
|
+
* Might be worth to optimize this and use a standard
|
|
3541
|
+
* chunk of 4kb's. */
|
|
3542
|
+
if(!read_ahead(a, 4 + cur_block_size, &p)) {
|
|
3543
|
+
/* Failed to prefetch block data. */
|
|
3544
|
+
return ARCHIVE_EOF;
|
|
3545
|
+
}
|
|
3546
|
+
}
|
|
3547
|
+
|
|
3548
|
+
rar->cstate.block_buf = p;
|
|
3549
|
+
rar->cstate.cur_block_size = cur_block_size;
|
|
3550
|
+
rar->cstate.block_parsing_finished = 0;
|
|
3551
|
+
|
|
3552
|
+
rar->bits.in_addr = 0;
|
|
3553
|
+
rar->bits.bit_addr = 0;
|
|
3554
|
+
|
|
3555
|
+
if(bf_is_table_present(&rar->last_block_hdr)) {
|
|
3556
|
+
/* Load Huffman tables. */
|
|
3557
|
+
ret = parse_tables(a, rar, p);
|
|
3558
|
+
if(ret != ARCHIVE_OK) {
|
|
3559
|
+
/* Error during decompression of Huffman
|
|
3560
|
+
* tables. */
|
|
3561
|
+
return ret;
|
|
3562
|
+
}
|
|
3563
|
+
}
|
|
3564
|
+
} else {
|
|
3565
|
+
/* Block parsing not finished, reuse previous memory buffer. */
|
|
3566
|
+
p = rar->cstate.block_buf;
|
|
3567
|
+
}
|
|
3568
|
+
|
|
3569
|
+
/* Uncompress the block, or a part of it, depending on how many bytes
|
|
3570
|
+
* will be generated by uncompressing the block.
|
|
3571
|
+
*
|
|
3572
|
+
* In case too many bytes will be generated, calling this function
|
|
3573
|
+
* again will resume the uncompression operation. */
|
|
3574
|
+
ret = do_uncompress_block(a, p);
|
|
3575
|
+
if(ret != ARCHIVE_OK) {
|
|
3576
|
+
return ret;
|
|
3577
|
+
}
|
|
3578
|
+
|
|
3579
|
+
if(rar->cstate.block_parsing_finished &&
|
|
3580
|
+
rar->cstate.switch_multivolume == 0 &&
|
|
3581
|
+
rar->cstate.cur_block_size > 0)
|
|
3582
|
+
{
|
|
3583
|
+
/* If we're processing a normal block, consume the whole
|
|
3584
|
+
* block. We can do this because we've already read the whole
|
|
3585
|
+
* block to memory. */
|
|
3586
|
+
if(ARCHIVE_OK != consume(a, rar->cstate.cur_block_size))
|
|
3587
|
+
return ARCHIVE_FATAL;
|
|
3588
|
+
|
|
3589
|
+
rar->file.bytes_remaining -= rar->cstate.cur_block_size;
|
|
3590
|
+
} else if(rar->cstate.switch_multivolume) {
|
|
3591
|
+
/* Don't consume the block if we're doing multivolume
|
|
3592
|
+
* processing. The volume switching function will consume
|
|
3593
|
+
* the proper count of bytes instead. */
|
|
3594
|
+
rar->cstate.switch_multivolume = 0;
|
|
3595
|
+
}
|
|
3596
|
+
|
|
3597
|
+
return ARCHIVE_OK;
|
|
3598
|
+
}
|
|
3599
|
+
|
|
3600
|
+
/* Pops the `buf`, `size` and `offset` from the "data ready" stack.
|
|
3601
|
+
*
|
|
3602
|
+
* Returns ARCHIVE_OK when those arguments can be used, ARCHIVE_RETRY
|
|
3603
|
+
* when there is no data on the stack. */
|
|
3604
|
+
static int use_data(struct rar5* rar, const void** buf, size_t* size,
|
|
3605
|
+
int64_t* offset)
|
|
3606
|
+
{
|
|
3607
|
+
int i;
|
|
3608
|
+
|
|
3609
|
+
for(i = 0; i < rar5_countof(rar->cstate.dready); i++) {
|
|
3610
|
+
struct data_ready *d = &rar->cstate.dready[i];
|
|
3611
|
+
|
|
3612
|
+
if(d->used) {
|
|
3613
|
+
if(buf) *buf = d->buf;
|
|
3614
|
+
if(size) *size = d->size;
|
|
3615
|
+
if(offset) *offset = d->offset;
|
|
3616
|
+
|
|
3617
|
+
d->used = 0;
|
|
3618
|
+
return ARCHIVE_OK;
|
|
3619
|
+
}
|
|
3620
|
+
}
|
|
3621
|
+
|
|
3622
|
+
return ARCHIVE_RETRY;
|
|
3623
|
+
}
|
|
3624
|
+
|
|
3625
|
+
/* Pushes the `buf`, `size` and `offset` arguments to the rar->cstate.dready
|
|
3626
|
+
* FIFO stack. Those values will be popped from this stack by the `use_data`
|
|
3627
|
+
* function. */
|
|
3628
|
+
static int push_data_ready(struct archive_read* a, struct rar5* rar,
|
|
3629
|
+
const uint8_t* buf, size_t size, int64_t offset)
|
|
3630
|
+
{
|
|
3631
|
+
int i;
|
|
3632
|
+
|
|
3633
|
+
/* Don't push if we're in skip mode. This is needed because solid
|
|
3634
|
+
* streams need full processing even if we're skipping data. After
|
|
3635
|
+
* fully processing the stream, we need to discard the generated bytes,
|
|
3636
|
+
* because we're interested only in the side effect: building up the
|
|
3637
|
+
* internal window circular buffer. This window buffer will be used
|
|
3638
|
+
* later during unpacking of requested data. */
|
|
3639
|
+
if(rar->skip_mode)
|
|
3640
|
+
return ARCHIVE_OK;
|
|
3641
|
+
|
|
3642
|
+
/* Sanity check. */
|
|
3643
|
+
if(offset != rar->file.last_offset + rar->file.last_size) {
|
|
3644
|
+
archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER,
|
|
3645
|
+
"Sanity check error: output stream is not continuous");
|
|
3646
|
+
return ARCHIVE_FATAL;
|
|
3647
|
+
}
|
|
3648
|
+
|
|
3649
|
+
for(i = 0; i < rar5_countof(rar->cstate.dready); i++) {
|
|
3650
|
+
struct data_ready* d = &rar->cstate.dready[i];
|
|
3651
|
+
if(!d->used) {
|
|
3652
|
+
d->used = 1;
|
|
3653
|
+
d->buf = buf;
|
|
3654
|
+
d->size = size;
|
|
3655
|
+
d->offset = offset;
|
|
3656
|
+
|
|
3657
|
+
/* These fields are used only in sanity checking. */
|
|
3658
|
+
rar->file.last_offset = offset;
|
|
3659
|
+
rar->file.last_size = size;
|
|
3660
|
+
|
|
3661
|
+
/* Calculate the checksum of this new block before
|
|
3662
|
+
* submitting data to libarchive's engine. */
|
|
3663
|
+
update_crc(rar, d->buf, d->size);
|
|
3664
|
+
|
|
3665
|
+
return ARCHIVE_OK;
|
|
3666
|
+
}
|
|
3667
|
+
}
|
|
3668
|
+
|
|
3669
|
+
/* Program counter will reach this code if the `rar->cstate.data_ready`
|
|
3670
|
+
* stack will be filled up so that no new entries will be allowed. The
|
|
3671
|
+
* code shouldn't allow such situation to occur. So we treat this case
|
|
3672
|
+
* as an internal error. */
|
|
3673
|
+
|
|
3674
|
+
archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER,
|
|
3675
|
+
"Error: premature end of data_ready stack");
|
|
3676
|
+
return ARCHIVE_FATAL;
|
|
3677
|
+
}
|
|
3678
|
+
|
|
3679
|
+
/* This function uncompresses the data that is stored in the <FILE> base
|
|
3680
|
+
* block.
|
|
3681
|
+
*
|
|
3682
|
+
* The FILE base block looks like this:
|
|
3683
|
+
*
|
|
3684
|
+
* <header><huffman tables><block_1><block_2>...<block_n>
|
|
3685
|
+
*
|
|
3686
|
+
* The <header> is a block header, that is parsed in parse_block_header().
|
|
3687
|
+
* It's a "compressed_block_header" structure, containing metadata needed
|
|
3688
|
+
* to know when we should stop looking for more <block_n> blocks.
|
|
3689
|
+
*
|
|
3690
|
+
* <huffman tables> contain data needed to set up the huffman tables, needed
|
|
3691
|
+
* for the actual decompression.
|
|
3692
|
+
*
|
|
3693
|
+
* Each <block_n> consists of series of literals:
|
|
3694
|
+
*
|
|
3695
|
+
* <literal><literal><literal>...<literal>
|
|
3696
|
+
*
|
|
3697
|
+
* Those literals generate the uncompression data. They operate on a circular
|
|
3698
|
+
* buffer, sometimes writing raw data into it, sometimes referencing
|
|
3699
|
+
* some previous data inside this buffer, and sometimes declaring a filter
|
|
3700
|
+
* that will need to be executed on the data stored in the circular buffer.
|
|
3701
|
+
* It all depends on the literal that is used.
|
|
3702
|
+
*
|
|
3703
|
+
* Sometimes blocks produce output data, sometimes they don't. For example, for
|
|
3704
|
+
* some huge files that use lots of filters, sometimes a block is filled with
|
|
3705
|
+
* only filter declaration literals. Such blocks won't produce any data in the
|
|
3706
|
+
* circular buffer.
|
|
3707
|
+
*
|
|
3708
|
+
* Sometimes blocks will produce 4 bytes of data, and sometimes 1 megabyte,
|
|
3709
|
+
* because a literal can reference previously decompressed data. For example,
|
|
3710
|
+
* there can be a literal that says: 'append a byte 0xFE here', and after
|
|
3711
|
+
* it another literal can say 'append 1 megabyte of data from circular buffer
|
|
3712
|
+
* offset 0x12345'. This is how RAR format handles compressing repeated
|
|
3713
|
+
* patterns.
|
|
3714
|
+
*
|
|
3715
|
+
* The RAR compressor creates those literals and the actual efficiency of
|
|
3716
|
+
* compression depends on what those literals are. The literals can also
|
|
3717
|
+
* be seen as a kind of a non-turing-complete virtual machine that simply
|
|
3718
|
+
* tells the decompressor what it should do.
|
|
3719
|
+
* */
|
|
3720
|
+
|
|
3721
|
+
static int do_uncompress_file(struct archive_read* a) {
|
|
3722
|
+
struct rar5* rar = get_context(a);
|
|
3723
|
+
int ret;
|
|
3724
|
+
int64_t max_end_pos;
|
|
3725
|
+
|
|
3726
|
+
if(!rar->cstate.initialized) {
|
|
3727
|
+
/* Don't perform full context reinitialization if we're
|
|
3728
|
+
* processing a solid archive. */
|
|
3729
|
+
if(!rar->main.solid || !rar->cstate.window_buf) {
|
|
3730
|
+
init_unpack(rar);
|
|
3731
|
+
}
|
|
3732
|
+
|
|
3733
|
+
rar->cstate.initialized = 1;
|
|
3734
|
+
}
|
|
3735
|
+
|
|
3736
|
+
/* Don't allow extraction if window_size is invalid. */
|
|
3737
|
+
if(rar->cstate.window_size == 0) {
|
|
3738
|
+
archive_set_error(&a->archive,
|
|
3739
|
+
ARCHIVE_ERRNO_FILE_FORMAT,
|
|
3740
|
+
"Invalid window size declaration in this file");
|
|
3741
|
+
|
|
3742
|
+
/* This should never happen in valid files. */
|
|
3743
|
+
return ARCHIVE_FATAL;
|
|
3744
|
+
}
|
|
3745
|
+
|
|
3746
|
+
if(rar->cstate.all_filters_applied == 1) {
|
|
3747
|
+
/* We use while(1) here, but standard case allows for just 1
|
|
3748
|
+
* iteration. The loop will iterate if process_block() didn't
|
|
3749
|
+
* generate any data at all. This can happen if the block
|
|
3750
|
+
* contains only filter definitions (this is common in big
|
|
3751
|
+
* files). */
|
|
3752
|
+
while(1) {
|
|
3753
|
+
ret = process_block(a);
|
|
3754
|
+
if(ret == ARCHIVE_EOF || ret == ARCHIVE_FATAL)
|
|
3755
|
+
return ret;
|
|
3756
|
+
|
|
3757
|
+
if(rar->cstate.last_write_ptr ==
|
|
3758
|
+
rar->cstate.write_ptr) {
|
|
3759
|
+
/* The block didn't generate any new data,
|
|
3760
|
+
* so just process a new block. */
|
|
3761
|
+
continue;
|
|
3762
|
+
}
|
|
3763
|
+
|
|
3764
|
+
/* The block has generated some new data, so break
|
|
3765
|
+
* the loop. */
|
|
3766
|
+
break;
|
|
3767
|
+
}
|
|
3768
|
+
}
|
|
3769
|
+
|
|
3770
|
+
/* Try to run filters. If filters won't be applied, it means that
|
|
3771
|
+
* insufficient data was generated. */
|
|
3772
|
+
ret = apply_filters(a);
|
|
3773
|
+
if(ret == ARCHIVE_RETRY) {
|
|
3774
|
+
return ARCHIVE_OK;
|
|
3775
|
+
} else if(ret == ARCHIVE_FATAL) {
|
|
3776
|
+
return ARCHIVE_FATAL;
|
|
3777
|
+
}
|
|
3778
|
+
|
|
3779
|
+
/* If apply_filters() will return ARCHIVE_OK, we can continue here. */
|
|
3780
|
+
|
|
3781
|
+
if(cdeque_size(&rar->cstate.filters) > 0) {
|
|
3782
|
+
/* Check if we can write something before hitting first
|
|
3783
|
+
* filter. */
|
|
3784
|
+
struct filter_info* flt;
|
|
3785
|
+
|
|
3786
|
+
/* Get the block_start offset from the first filter. */
|
|
3787
|
+
if(CDE_OK != cdeque_front(&rar->cstate.filters,
|
|
3788
|
+
cdeque_filter_p(&flt)))
|
|
3789
|
+
{
|
|
3790
|
+
archive_set_error(&a->archive,
|
|
3791
|
+
ARCHIVE_ERRNO_PROGRAMMER,
|
|
3792
|
+
"Can't read first filter");
|
|
3793
|
+
return ARCHIVE_FATAL;
|
|
3794
|
+
}
|
|
3795
|
+
|
|
3796
|
+
max_end_pos = rar5_min(flt->block_start,
|
|
3797
|
+
rar->cstate.write_ptr);
|
|
3798
|
+
} else {
|
|
3799
|
+
/* There are no filters defined, or all filters were applied.
|
|
3800
|
+
* This means we can just store the data without any
|
|
3801
|
+
* postprocessing. */
|
|
3802
|
+
max_end_pos = rar->cstate.write_ptr;
|
|
3803
|
+
}
|
|
3804
|
+
|
|
3805
|
+
if(max_end_pos == rar->cstate.last_write_ptr) {
|
|
3806
|
+
/* We can't write anything yet. The block uncompression
|
|
3807
|
+
* function did not generate enough data, and no filter can be
|
|
3808
|
+
* applied. At the same time we don't have any data that can be
|
|
3809
|
+
* stored without filter postprocessing. This means we need to
|
|
3810
|
+
* wait for more data to be generated, so we can apply the
|
|
3811
|
+
* filters.
|
|
3812
|
+
*
|
|
3813
|
+
* Signal the caller that we need more data to be able to do
|
|
3814
|
+
* anything.
|
|
3815
|
+
*/
|
|
3816
|
+
return ARCHIVE_RETRY;
|
|
3817
|
+
} else {
|
|
3818
|
+
/* We can write the data before hitting the first filter.
|
|
3819
|
+
* So let's do it. The push_window_data() function will
|
|
3820
|
+
* effectively return the selected data block to the user
|
|
3821
|
+
* application. */
|
|
3822
|
+
push_window_data(a, rar, rar->cstate.last_write_ptr,
|
|
3823
|
+
max_end_pos);
|
|
3824
|
+
rar->cstate.last_write_ptr = max_end_pos;
|
|
3825
|
+
}
|
|
3826
|
+
|
|
3827
|
+
return ARCHIVE_OK;
|
|
3828
|
+
}
|
|
3829
|
+
|
|
3830
|
+
static int uncompress_file(struct archive_read* a) {
|
|
3831
|
+
int ret;
|
|
3832
|
+
|
|
3833
|
+
while(1) {
|
|
3834
|
+
/* Sometimes the uncompression function will return a
|
|
3835
|
+
* 'retry' signal. If this will happen, we have to retry
|
|
3836
|
+
* the function. */
|
|
3837
|
+
ret = do_uncompress_file(a);
|
|
3838
|
+
if(ret != ARCHIVE_RETRY)
|
|
3839
|
+
return ret;
|
|
3840
|
+
}
|
|
3841
|
+
}
|
|
3842
|
+
|
|
3843
|
+
|
|
3844
|
+
static int do_unstore_file(struct archive_read* a,
|
|
3845
|
+
struct rar5* rar, const void** buf, size_t* size, int64_t* offset)
|
|
3846
|
+
{
|
|
3847
|
+
size_t to_read;
|
|
3848
|
+
const uint8_t* p;
|
|
3849
|
+
|
|
3850
|
+
if(rar->file.bytes_remaining == 0 && rar->main.volume > 0 &&
|
|
3851
|
+
rar->generic.split_after > 0)
|
|
3852
|
+
{
|
|
3853
|
+
int ret;
|
|
3854
|
+
|
|
3855
|
+
rar->cstate.switch_multivolume = 1;
|
|
3856
|
+
ret = advance_multivolume(a);
|
|
3857
|
+
rar->cstate.switch_multivolume = 0;
|
|
3858
|
+
|
|
3859
|
+
if(ret != ARCHIVE_OK) {
|
|
3860
|
+
/* Failed to advance to next multivolume archive
|
|
3861
|
+
* file. */
|
|
3862
|
+
return ret;
|
|
3863
|
+
}
|
|
3864
|
+
}
|
|
3865
|
+
|
|
3866
|
+
to_read = rar5_min(rar->file.bytes_remaining, 64 * 1024);
|
|
3867
|
+
if(to_read == 0) {
|
|
3868
|
+
return ARCHIVE_EOF;
|
|
3869
|
+
}
|
|
3870
|
+
|
|
3871
|
+
if(!read_ahead(a, to_read, &p)) {
|
|
3872
|
+
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
|
3873
|
+
"I/O error when unstoring file");
|
|
3874
|
+
return ARCHIVE_FATAL;
|
|
3875
|
+
}
|
|
3876
|
+
|
|
3877
|
+
if(ARCHIVE_OK != consume(a, to_read)) {
|
|
3878
|
+
return ARCHIVE_EOF;
|
|
3879
|
+
}
|
|
3880
|
+
|
|
3881
|
+
if(buf) *buf = p;
|
|
3882
|
+
if(size) *size = to_read;
|
|
3883
|
+
if(offset) *offset = rar->cstate.last_unstore_ptr;
|
|
3884
|
+
|
|
3885
|
+
rar->file.bytes_remaining -= to_read;
|
|
3886
|
+
rar->cstate.last_unstore_ptr += to_read;
|
|
3887
|
+
|
|
3888
|
+
update_crc(rar, p, to_read);
|
|
3889
|
+
return ARCHIVE_OK;
|
|
3890
|
+
}
|
|
3891
|
+
|
|
3892
|
+
static int do_unpack(struct archive_read* a, struct rar5* rar,
|
|
3893
|
+
const void** buf, size_t* size, int64_t* offset)
|
|
3894
|
+
{
|
|
3895
|
+
enum COMPRESSION_METHOD {
|
|
3896
|
+
STORE = 0, FASTEST = 1, FAST = 2, NORMAL = 3, GOOD = 4,
|
|
3897
|
+
BEST = 5
|
|
3898
|
+
};
|
|
3899
|
+
|
|
3900
|
+
if(rar->file.service > 0) {
|
|
3901
|
+
return do_unstore_file(a, rar, buf, size, offset);
|
|
3902
|
+
} else {
|
|
3903
|
+
switch(rar->cstate.method) {
|
|
3904
|
+
case STORE:
|
|
3905
|
+
return do_unstore_file(a, rar, buf, size,
|
|
3906
|
+
offset);
|
|
3907
|
+
case FASTEST:
|
|
3908
|
+
/* fallthrough */
|
|
3909
|
+
case FAST:
|
|
3910
|
+
/* fallthrough */
|
|
3911
|
+
case NORMAL:
|
|
3912
|
+
/* fallthrough */
|
|
3913
|
+
case GOOD:
|
|
3914
|
+
/* fallthrough */
|
|
3915
|
+
case BEST:
|
|
3916
|
+
/* No data is returned here. But because a sparse-file aware
|
|
3917
|
+
* caller (like archive_read_data_into_fd) may treat zero-size
|
|
3918
|
+
* as a sparse file block, we need to update the offset
|
|
3919
|
+
* accordingly. At this point the decoder doesn't have any
|
|
3920
|
+
* pending uncompressed data blocks, so the current position in
|
|
3921
|
+
* the output file should be last_write_ptr. */
|
|
3922
|
+
if (offset) *offset = rar->cstate.last_write_ptr;
|
|
3923
|
+
return uncompress_file(a);
|
|
3924
|
+
default:
|
|
3925
|
+
archive_set_error(&a->archive,
|
|
3926
|
+
ARCHIVE_ERRNO_FILE_FORMAT,
|
|
3927
|
+
"Compression method not supported: 0x%x",
|
|
3928
|
+
rar->cstate.method);
|
|
3929
|
+
|
|
3930
|
+
return ARCHIVE_FATAL;
|
|
3931
|
+
}
|
|
3932
|
+
}
|
|
3933
|
+
|
|
3934
|
+
#if !defined WIN32
|
|
3935
|
+
/* Not reached. */
|
|
3936
|
+
return ARCHIVE_OK;
|
|
3937
|
+
#endif
|
|
3938
|
+
}
|
|
3939
|
+
|
|
3940
|
+
static int verify_checksums(struct archive_read* a) {
|
|
3941
|
+
int verify_crc;
|
|
3942
|
+
struct rar5* rar = get_context(a);
|
|
3943
|
+
|
|
3944
|
+
/* Check checksums only when actually unpacking the data. There's no
|
|
3945
|
+
* need to calculate checksum when we're skipping data in solid archives
|
|
3946
|
+
* (skipping in solid archives is the same thing as unpacking compressed
|
|
3947
|
+
* data and discarding the result). */
|
|
3948
|
+
|
|
3949
|
+
if(!rar->skip_mode) {
|
|
3950
|
+
/* Always check checksums if we're not in skip mode */
|
|
3951
|
+
verify_crc = 1;
|
|
3952
|
+
} else {
|
|
3953
|
+
/* We can override the logic above with a compile-time option
|
|
3954
|
+
* NO_CRC_ON_SOLID_SKIP. This option is used during debugging,
|
|
3955
|
+
* and it will check checksums of unpacked data even when
|
|
3956
|
+
* we're skipping it. */
|
|
3957
|
+
|
|
3958
|
+
#if defined CHECK_CRC_ON_SOLID_SKIP
|
|
3959
|
+
/* Debug case */
|
|
3960
|
+
verify_crc = 1;
|
|
3961
|
+
#else
|
|
3962
|
+
/* Normal case */
|
|
3963
|
+
verify_crc = 0;
|
|
3964
|
+
#endif
|
|
3965
|
+
}
|
|
3966
|
+
|
|
3967
|
+
if(verify_crc) {
|
|
3968
|
+
/* During unpacking, on each unpacked block we're calling the
|
|
3969
|
+
* update_crc() function. Since we are here, the unpacking
|
|
3970
|
+
* process is already over and we can check if calculated
|
|
3971
|
+
* checksum (CRC32 or BLAKE2sp) is the same as what is stored
|
|
3972
|
+
* in the archive. */
|
|
3973
|
+
if(rar->file.stored_crc32 > 0) {
|
|
3974
|
+
/* Check CRC32 only when the file contains a CRC32
|
|
3975
|
+
* value for this file. */
|
|
3976
|
+
|
|
3977
|
+
if(rar->file.calculated_crc32 !=
|
|
3978
|
+
rar->file.stored_crc32) {
|
|
3979
|
+
/* Checksums do not match; the unpacked file
|
|
3980
|
+
* is corrupted. */
|
|
3981
|
+
|
|
3982
|
+
DEBUG_CODE {
|
|
3983
|
+
printf("Checksum error: CRC32 "
|
|
3984
|
+
"(was: %08" PRIx32 ", expected: %08" PRIx32 ")\n",
|
|
3985
|
+
rar->file.calculated_crc32,
|
|
3986
|
+
rar->file.stored_crc32);
|
|
3987
|
+
}
|
|
3988
|
+
|
|
3989
|
+
#ifndef DONT_FAIL_ON_CRC_ERROR
|
|
3990
|
+
archive_set_error(&a->archive,
|
|
3991
|
+
ARCHIVE_ERRNO_FILE_FORMAT,
|
|
3992
|
+
"Checksum error: CRC32");
|
|
3993
|
+
return ARCHIVE_FATAL;
|
|
3994
|
+
#endif
|
|
3995
|
+
} else {
|
|
3996
|
+
DEBUG_CODE {
|
|
3997
|
+
printf("Checksum OK: CRC32 "
|
|
3998
|
+
"(%08" PRIx32 "/%08" PRIx32 ")\n",
|
|
3999
|
+
rar->file.stored_crc32,
|
|
4000
|
+
rar->file.calculated_crc32);
|
|
4001
|
+
}
|
|
4002
|
+
}
|
|
4003
|
+
}
|
|
4004
|
+
|
|
4005
|
+
if(rar->file.has_blake2 > 0) {
|
|
4006
|
+
/* BLAKE2sp is an optional checksum algorithm that is
|
|
4007
|
+
* added to RARv5 archives when using the `-htb` switch
|
|
4008
|
+
* during creation of archive.
|
|
4009
|
+
*
|
|
4010
|
+
* We now finalize the hash calculation by calling the
|
|
4011
|
+
* `final` function. This will generate the final hash
|
|
4012
|
+
* value we can use to compare it with the BLAKE2sp
|
|
4013
|
+
* checksum that is stored in the archive.
|
|
4014
|
+
*
|
|
4015
|
+
* The return value of this `final` function is not
|
|
4016
|
+
* very helpful, as it guards only against improper use.
|
|
4017
|
+
* This is why we're explicitly ignoring it. */
|
|
4018
|
+
|
|
4019
|
+
uint8_t b2_buf[32];
|
|
4020
|
+
(void) blake2sp_final(&rar->file.b2state, b2_buf, 32);
|
|
4021
|
+
|
|
4022
|
+
if(memcmp(&rar->file.blake2sp, b2_buf, 32) != 0) {
|
|
4023
|
+
#ifndef DONT_FAIL_ON_CRC_ERROR
|
|
4024
|
+
archive_set_error(&a->archive,
|
|
4025
|
+
ARCHIVE_ERRNO_FILE_FORMAT,
|
|
4026
|
+
"Checksum error: BLAKE2");
|
|
4027
|
+
|
|
4028
|
+
return ARCHIVE_FATAL;
|
|
4029
|
+
#endif
|
|
4030
|
+
}
|
|
4031
|
+
}
|
|
4032
|
+
}
|
|
4033
|
+
|
|
4034
|
+
/* Finalization for this file has been successfully completed. */
|
|
4035
|
+
return ARCHIVE_OK;
|
|
4036
|
+
}
|
|
4037
|
+
|
|
4038
|
+
static int verify_global_checksums(struct archive_read* a) {
|
|
4039
|
+
return verify_checksums(a);
|
|
4040
|
+
}
|
|
4041
|
+
|
|
4042
|
+
/*
|
|
4043
|
+
* Decryption function for the magic signature pattern. Check the comment near
|
|
4044
|
+
* the `rar5_signature_xor` symbol to read the rationale behind this.
|
|
4045
|
+
*/
|
|
4046
|
+
static void rar5_signature(char *buf) {
|
|
4047
|
+
size_t i;
|
|
4048
|
+
|
|
4049
|
+
for(i = 0; i < sizeof(rar5_signature_xor); i++) {
|
|
4050
|
+
buf[i] = rar5_signature_xor[i] ^ 0xA1;
|
|
4051
|
+
}
|
|
4052
|
+
}
|
|
4053
|
+
|
|
4054
|
+
static int rar5_read_data(struct archive_read *a, const void **buff,
|
|
4055
|
+
size_t *size, int64_t *offset) {
|
|
4056
|
+
int ret;
|
|
4057
|
+
struct rar5* rar = get_context(a);
|
|
4058
|
+
|
|
4059
|
+
if (size)
|
|
4060
|
+
*size = 0;
|
|
4061
|
+
|
|
4062
|
+
if(rar->file.dir > 0) {
|
|
4063
|
+
/* Don't process any data if this file entry was declared
|
|
4064
|
+
* as a directory. This is needed, because entries marked as
|
|
4065
|
+
* directory doesn't have any dictionary buffer allocated, so
|
|
4066
|
+
* it's impossible to perform any decompression. */
|
|
4067
|
+
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
|
4068
|
+
"Can't decompress an entry marked as a directory");
|
|
4069
|
+
return ARCHIVE_FAILED;
|
|
4070
|
+
}
|
|
4071
|
+
|
|
4072
|
+
if(!rar->skip_mode && (rar->cstate.last_write_ptr > rar->file.unpacked_size)) {
|
|
4073
|
+
archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER,
|
|
4074
|
+
"Unpacker has written too many bytes");
|
|
4075
|
+
return ARCHIVE_FATAL;
|
|
4076
|
+
}
|
|
4077
|
+
|
|
4078
|
+
ret = use_data(rar, buff, size, offset);
|
|
4079
|
+
if(ret == ARCHIVE_OK) {
|
|
4080
|
+
return ret;
|
|
4081
|
+
}
|
|
4082
|
+
|
|
4083
|
+
if(rar->file.eof == 1) {
|
|
4084
|
+
return ARCHIVE_EOF;
|
|
4085
|
+
}
|
|
4086
|
+
|
|
4087
|
+
ret = do_unpack(a, rar, buff, size, offset);
|
|
4088
|
+
if(ret != ARCHIVE_OK) {
|
|
4089
|
+
return ret;
|
|
4090
|
+
}
|
|
4091
|
+
|
|
4092
|
+
if(rar->file.bytes_remaining == 0 &&
|
|
4093
|
+
rar->cstate.last_write_ptr == rar->file.unpacked_size)
|
|
4094
|
+
{
|
|
4095
|
+
/* If all bytes of current file were processed, run
|
|
4096
|
+
* finalization.
|
|
4097
|
+
*
|
|
4098
|
+
* Finalization will check checksum against proper values. If
|
|
4099
|
+
* some of the checksums will not match, we'll return an error
|
|
4100
|
+
* value in the last `archive_read_data` call to signal an error
|
|
4101
|
+
* to the user. */
|
|
4102
|
+
|
|
4103
|
+
rar->file.eof = 1;
|
|
4104
|
+
return verify_global_checksums(a);
|
|
4105
|
+
}
|
|
4106
|
+
|
|
4107
|
+
return ARCHIVE_OK;
|
|
4108
|
+
}
|
|
4109
|
+
|
|
4110
|
+
static int rar5_read_data_skip(struct archive_read *a) {
|
|
4111
|
+
struct rar5* rar = get_context(a);
|
|
4112
|
+
|
|
4113
|
+
if(rar->main.solid) {
|
|
4114
|
+
/* In solid archives, instead of skipping the data, we need to
|
|
4115
|
+
* extract it, and dispose the result. The side effect of this
|
|
4116
|
+
* operation will be setting up the initial window buffer state
|
|
4117
|
+
* needed to be able to extract the selected file. */
|
|
4118
|
+
|
|
4119
|
+
int ret;
|
|
4120
|
+
|
|
4121
|
+
/* Make sure to process all blocks in the compressed stream. */
|
|
4122
|
+
while(rar->file.bytes_remaining > 0) {
|
|
4123
|
+
/* Setting the "skip mode" will allow us to skip
|
|
4124
|
+
* checksum checks during data skipping. Checking the
|
|
4125
|
+
* checksum of skipped data isn't really necessary and
|
|
4126
|
+
* it's only slowing things down.
|
|
4127
|
+
*
|
|
4128
|
+
* This is incremented instead of setting to 1 because
|
|
4129
|
+
* this data skipping function can be called
|
|
4130
|
+
* recursively. */
|
|
4131
|
+
rar->skip_mode++;
|
|
4132
|
+
|
|
4133
|
+
/* We're disposing 1 block of data, so we use triple
|
|
4134
|
+
* NULLs in arguments. */
|
|
4135
|
+
ret = rar5_read_data(a, NULL, NULL, NULL);
|
|
4136
|
+
|
|
4137
|
+
/* Turn off "skip mode". */
|
|
4138
|
+
rar->skip_mode--;
|
|
4139
|
+
|
|
4140
|
+
if(ret < 0 || ret == ARCHIVE_EOF) {
|
|
4141
|
+
/* Propagate any potential error conditions
|
|
4142
|
+
* to the caller. */
|
|
4143
|
+
return ret;
|
|
4144
|
+
}
|
|
4145
|
+
}
|
|
4146
|
+
} else {
|
|
4147
|
+
/* In standard archives, we can just jump over the compressed
|
|
4148
|
+
* stream. Each file in non-solid archives starts from an empty
|
|
4149
|
+
* window buffer. */
|
|
4150
|
+
|
|
4151
|
+
if(ARCHIVE_OK != consume(a, rar->file.bytes_remaining)) {
|
|
4152
|
+
return ARCHIVE_FATAL;
|
|
4153
|
+
}
|
|
4154
|
+
|
|
4155
|
+
rar->file.bytes_remaining = 0;
|
|
4156
|
+
}
|
|
4157
|
+
|
|
4158
|
+
return ARCHIVE_OK;
|
|
4159
|
+
}
|
|
4160
|
+
|
|
4161
|
+
static int64_t rar5_seek_data(struct archive_read *a, int64_t offset,
|
|
4162
|
+
int whence)
|
|
4163
|
+
{
|
|
4164
|
+
(void) a;
|
|
4165
|
+
(void) offset;
|
|
4166
|
+
(void) whence;
|
|
4167
|
+
|
|
4168
|
+
/* We're a streaming unpacker, and we don't support seeking. */
|
|
4169
|
+
|
|
4170
|
+
return ARCHIVE_FATAL;
|
|
4171
|
+
}
|
|
4172
|
+
|
|
4173
|
+
static int rar5_cleanup(struct archive_read *a) {
|
|
4174
|
+
struct rar5* rar = get_context(a);
|
|
4175
|
+
|
|
4176
|
+
free(rar->cstate.window_buf);
|
|
4177
|
+
free(rar->cstate.filtered_buf);
|
|
4178
|
+
|
|
4179
|
+
free(rar->vol.push_buf);
|
|
4180
|
+
|
|
4181
|
+
free_filters(rar);
|
|
4182
|
+
cdeque_free(&rar->cstate.filters);
|
|
4183
|
+
|
|
4184
|
+
free(rar);
|
|
4185
|
+
a->format->data = NULL;
|
|
4186
|
+
|
|
4187
|
+
return ARCHIVE_OK;
|
|
4188
|
+
}
|
|
4189
|
+
|
|
4190
|
+
static int rar5_capabilities(struct archive_read * a) {
|
|
4191
|
+
(void) a;
|
|
4192
|
+
return 0;
|
|
4193
|
+
}
|
|
4194
|
+
|
|
4195
|
+
static int rar5_has_encrypted_entries(struct archive_read *_a) {
|
|
4196
|
+
(void) _a;
|
|
4197
|
+
|
|
4198
|
+
/* Unsupported for now. */
|
|
4199
|
+
return ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED;
|
|
4200
|
+
}
|
|
4201
|
+
|
|
4202
|
+
static int rar5_init(struct rar5* rar) {
|
|
4203
|
+
memset(rar, 0, sizeof(struct rar5));
|
|
4204
|
+
|
|
4205
|
+
if(CDE_OK != cdeque_init(&rar->cstate.filters, 8192))
|
|
4206
|
+
return ARCHIVE_FATAL;
|
|
4207
|
+
|
|
4208
|
+
return ARCHIVE_OK;
|
|
4209
|
+
}
|
|
4210
|
+
|
|
4211
|
+
int archive_read_support_format_rar5(struct archive *_a) {
|
|
4212
|
+
struct archive_read* ar;
|
|
4213
|
+
int ret;
|
|
4214
|
+
struct rar5* rar;
|
|
4215
|
+
|
|
4216
|
+
if(ARCHIVE_OK != (ret = get_archive_read(_a, &ar)))
|
|
4217
|
+
return ret;
|
|
4218
|
+
|
|
4219
|
+
rar = malloc(sizeof(*rar));
|
|
4220
|
+
if(rar == NULL) {
|
|
4221
|
+
archive_set_error(&ar->archive, ENOMEM,
|
|
4222
|
+
"Can't allocate rar5 data");
|
|
4223
|
+
return ARCHIVE_FATAL;
|
|
4224
|
+
}
|
|
4225
|
+
|
|
4226
|
+
if(ARCHIVE_OK != rar5_init(rar)) {
|
|
4227
|
+
archive_set_error(&ar->archive, ENOMEM,
|
|
4228
|
+
"Can't allocate rar5 filter buffer");
|
|
4229
|
+
free(rar);
|
|
4230
|
+
return ARCHIVE_FATAL;
|
|
4231
|
+
}
|
|
4232
|
+
|
|
4233
|
+
ret = __archive_read_register_format(ar,
|
|
4234
|
+
rar,
|
|
4235
|
+
"rar5",
|
|
4236
|
+
rar5_bid,
|
|
4237
|
+
rar5_options,
|
|
4238
|
+
rar5_read_header,
|
|
4239
|
+
rar5_read_data,
|
|
4240
|
+
rar5_read_data_skip,
|
|
4241
|
+
rar5_seek_data,
|
|
4242
|
+
rar5_cleanup,
|
|
4243
|
+
rar5_capabilities,
|
|
4244
|
+
rar5_has_encrypted_entries);
|
|
4245
|
+
|
|
4246
|
+
if(ret != ARCHIVE_OK) {
|
|
4247
|
+
(void) rar5_cleanup(ar);
|
|
4248
|
+
}
|
|
4249
|
+
|
|
4250
|
+
return ret;
|
|
4251
|
+
}
|