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
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
/*-
|
|
2
2
|
* Copyright (c) 2003-2007 Tim Kientzle
|
|
3
|
+
* Copyright (c) 2011-2012 Michihiro NAKAJIMA
|
|
4
|
+
* Copyright (c) 2016 Martin Matuska
|
|
3
5
|
* All rights reserved.
|
|
4
6
|
*
|
|
5
7
|
* Redistribution and use in source and binary forms, with or without
|
|
@@ -30,7 +32,6 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_read_support_format_tar.c 201161
|
|
|
30
32
|
#include <errno.h>
|
|
31
33
|
#endif
|
|
32
34
|
#include <stddef.h>
|
|
33
|
-
/* #include <stdint.h> */ /* See archive_platform.h */
|
|
34
35
|
#ifdef HAVE_STDLIB_H
|
|
35
36
|
#include <stdlib.h>
|
|
36
37
|
#endif
|
|
@@ -38,37 +39,10 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_read_support_format_tar.c 201161
|
|
|
38
39
|
#include <string.h>
|
|
39
40
|
#endif
|
|
40
41
|
|
|
41
|
-
/* Obtain suitable wide-character manipulation functions. */
|
|
42
|
-
#ifdef HAVE_WCHAR_H
|
|
43
|
-
#include <wchar.h>
|
|
44
|
-
#else
|
|
45
|
-
/* Good enough for equality testing, which is all we need. */
|
|
46
|
-
static int wcscmp(const wchar_t *s1, const wchar_t *s2)
|
|
47
|
-
{
|
|
48
|
-
int diff = *s1 - *s2;
|
|
49
|
-
while (*s1 && diff == 0)
|
|
50
|
-
diff = (int)*++s1 - (int)*++s2;
|
|
51
|
-
return diff;
|
|
52
|
-
}
|
|
53
|
-
/* Good enough for equality testing, which is all we need. */
|
|
54
|
-
static int wcsncmp(const wchar_t *s1, const wchar_t *s2, size_t n)
|
|
55
|
-
{
|
|
56
|
-
int diff = *s1 - *s2;
|
|
57
|
-
while (*s1 && diff == 0 && n-- > 0)
|
|
58
|
-
diff = (int)*++s1 - (int)*++s2;
|
|
59
|
-
return diff;
|
|
60
|
-
}
|
|
61
|
-
static size_t wcslen(const wchar_t *s)
|
|
62
|
-
{
|
|
63
|
-
const wchar_t *p = s;
|
|
64
|
-
while (*p)
|
|
65
|
-
p++;
|
|
66
|
-
return p - s;
|
|
67
|
-
}
|
|
68
|
-
#endif
|
|
69
|
-
|
|
70
42
|
#include "archive.h"
|
|
43
|
+
#include "archive_acl_private.h" /* For ACL parsing routines. */
|
|
71
44
|
#include "archive_entry.h"
|
|
45
|
+
#include "archive_entry_locale.h"
|
|
72
46
|
#include "archive_private.h"
|
|
73
47
|
#include "archive_read_private.h"
|
|
74
48
|
|
|
@@ -138,8 +112,9 @@ struct archive_entry_header_gnutar {
|
|
|
138
112
|
*/
|
|
139
113
|
struct sparse_block {
|
|
140
114
|
struct sparse_block *next;
|
|
141
|
-
|
|
142
|
-
|
|
115
|
+
int64_t offset;
|
|
116
|
+
int64_t remaining;
|
|
117
|
+
int hole;
|
|
143
118
|
};
|
|
144
119
|
|
|
145
120
|
struct tar {
|
|
@@ -156,13 +131,13 @@ struct tar {
|
|
|
156
131
|
struct archive_string pax_global;
|
|
157
132
|
struct archive_string line;
|
|
158
133
|
int pax_hdrcharset_binary;
|
|
159
|
-
wchar_t *pax_entry;
|
|
160
|
-
size_t pax_entry_length;
|
|
161
134
|
int header_recursion_depth;
|
|
162
135
|
int64_t entry_bytes_remaining;
|
|
163
136
|
int64_t entry_offset;
|
|
164
137
|
int64_t entry_padding;
|
|
138
|
+
int64_t entry_bytes_unconsumed;
|
|
165
139
|
int64_t realsize;
|
|
140
|
+
int sparse_allowed;
|
|
166
141
|
struct sparse_block *sparse_list;
|
|
167
142
|
struct sparse_block *sparse_last;
|
|
168
143
|
int64_t sparse_offset;
|
|
@@ -170,70 +145,97 @@ struct tar {
|
|
|
170
145
|
int sparse_gnu_major;
|
|
171
146
|
int sparse_gnu_minor;
|
|
172
147
|
char sparse_gnu_pending;
|
|
148
|
+
|
|
149
|
+
struct archive_string localname;
|
|
150
|
+
struct archive_string_conv *opt_sconv;
|
|
151
|
+
struct archive_string_conv *sconv;
|
|
152
|
+
struct archive_string_conv *sconv_acl;
|
|
153
|
+
struct archive_string_conv *sconv_default;
|
|
154
|
+
int init_default_conversion;
|
|
155
|
+
int compat_2x;
|
|
156
|
+
int process_mac_extensions;
|
|
157
|
+
int read_concatenated_archives;
|
|
158
|
+
int realsize_override;
|
|
173
159
|
};
|
|
174
160
|
|
|
175
|
-
static
|
|
176
|
-
static int archive_block_is_null(const unsigned char *p);
|
|
161
|
+
static int archive_block_is_null(const char *p);
|
|
177
162
|
static char *base64_decode(const char *, size_t, size_t *);
|
|
178
|
-
static
|
|
179
|
-
|
|
163
|
+
static int gnu_add_sparse_entry(struct archive_read *, struct tar *,
|
|
164
|
+
int64_t offset, int64_t remaining);
|
|
165
|
+
|
|
180
166
|
static void gnu_clear_sparse_list(struct tar *);
|
|
181
167
|
static int gnu_sparse_old_read(struct archive_read *, struct tar *,
|
|
182
|
-
const struct archive_entry_header_gnutar *header);
|
|
183
|
-
static
|
|
168
|
+
const struct archive_entry_header_gnutar *header, size_t *);
|
|
169
|
+
static int gnu_sparse_old_parse(struct archive_read *, struct tar *,
|
|
184
170
|
const struct gnu_sparse *sparse, int length);
|
|
185
|
-
static int gnu_sparse_01_parse(struct
|
|
186
|
-
|
|
171
|
+
static int gnu_sparse_01_parse(struct archive_read *, struct tar *,
|
|
172
|
+
const char *);
|
|
173
|
+
static ssize_t gnu_sparse_10_read(struct archive_read *, struct tar *,
|
|
174
|
+
size_t *);
|
|
187
175
|
static int header_Solaris_ACL(struct archive_read *, struct tar *,
|
|
188
|
-
struct archive_entry *, const void *);
|
|
176
|
+
struct archive_entry *, const void *, size_t *);
|
|
189
177
|
static int header_common(struct archive_read *, struct tar *,
|
|
190
178
|
struct archive_entry *, const void *);
|
|
191
179
|
static int header_old_tar(struct archive_read *, struct tar *,
|
|
192
180
|
struct archive_entry *, const void *);
|
|
193
181
|
static int header_pax_extensions(struct archive_read *, struct tar *,
|
|
194
|
-
struct archive_entry *, const void *);
|
|
182
|
+
struct archive_entry *, const void *, size_t *);
|
|
195
183
|
static int header_pax_global(struct archive_read *, struct tar *,
|
|
196
|
-
struct archive_entry *, const void *h);
|
|
184
|
+
struct archive_entry *, const void *h, size_t *);
|
|
197
185
|
static int header_longlink(struct archive_read *, struct tar *,
|
|
198
|
-
struct archive_entry *, const void *h);
|
|
186
|
+
struct archive_entry *, const void *h, size_t *);
|
|
199
187
|
static int header_longname(struct archive_read *, struct tar *,
|
|
200
|
-
struct archive_entry *, const void *h);
|
|
188
|
+
struct archive_entry *, const void *h, size_t *);
|
|
189
|
+
static int read_mac_metadata_blob(struct archive_read *, struct tar *,
|
|
190
|
+
struct archive_entry *, const void *h, size_t *);
|
|
201
191
|
static int header_volume(struct archive_read *, struct tar *,
|
|
202
|
-
struct archive_entry *, const void *h);
|
|
192
|
+
struct archive_entry *, const void *h, size_t *);
|
|
203
193
|
static int header_ustar(struct archive_read *, struct tar *,
|
|
204
194
|
struct archive_entry *, const void *h);
|
|
205
195
|
static int header_gnutar(struct archive_read *, struct tar *,
|
|
206
|
-
struct archive_entry *, const void *h);
|
|
207
|
-
static int archive_read_format_tar_bid(struct archive_read
|
|
196
|
+
struct archive_entry *, const void *h, size_t *);
|
|
197
|
+
static int archive_read_format_tar_bid(struct archive_read *, int);
|
|
198
|
+
static int archive_read_format_tar_options(struct archive_read *,
|
|
199
|
+
const char *, const char *);
|
|
208
200
|
static int archive_read_format_tar_cleanup(struct archive_read *);
|
|
209
201
|
static int archive_read_format_tar_read_data(struct archive_read *a,
|
|
210
|
-
const void **buff, size_t *size,
|
|
202
|
+
const void **buff, size_t *size, int64_t *offset);
|
|
211
203
|
static int archive_read_format_tar_skip(struct archive_read *a);
|
|
212
204
|
static int archive_read_format_tar_read_header(struct archive_read *,
|
|
213
205
|
struct archive_entry *);
|
|
214
206
|
static int checksum(struct archive_read *, const void *);
|
|
215
|
-
static int pax_attribute(struct
|
|
216
|
-
char *key, char *value
|
|
207
|
+
static int pax_attribute(struct archive_read *, struct tar *,
|
|
208
|
+
struct archive_entry *, const char *key, const char *value,
|
|
209
|
+
size_t value_length);
|
|
210
|
+
static int pax_attribute_acl(struct archive_read *, struct tar *,
|
|
211
|
+
struct archive_entry *, const char *, int);
|
|
212
|
+
static int pax_attribute_xattr(struct archive_entry *, const char *,
|
|
213
|
+
const char *);
|
|
217
214
|
static int pax_header(struct archive_read *, struct tar *,
|
|
218
|
-
struct archive_entry *,
|
|
215
|
+
struct archive_entry *, struct archive_string *);
|
|
219
216
|
static void pax_time(const char *, int64_t *sec, long *nanos);
|
|
220
217
|
static ssize_t readline(struct archive_read *, struct tar *, const char **,
|
|
221
|
-
ssize_t limit);
|
|
218
|
+
ssize_t limit, size_t *);
|
|
222
219
|
static int read_body_to_string(struct archive_read *, struct tar *,
|
|
223
|
-
struct archive_string *, const void *h);
|
|
224
|
-
static
|
|
225
|
-
|
|
226
|
-
static int64_t
|
|
227
|
-
static int64_t
|
|
220
|
+
struct archive_string *, const void *h, size_t *);
|
|
221
|
+
static int solaris_sparse_parse(struct archive_read *, struct tar *,
|
|
222
|
+
struct archive_entry *, const char *);
|
|
223
|
+
static int64_t tar_atol(const char *, size_t);
|
|
224
|
+
static int64_t tar_atol10(const char *, size_t);
|
|
225
|
+
static int64_t tar_atol256(const char *, size_t);
|
|
226
|
+
static int64_t tar_atol8(const char *, size_t);
|
|
228
227
|
static int tar_read_header(struct archive_read *, struct tar *,
|
|
229
|
-
struct archive_entry *);
|
|
228
|
+
struct archive_entry *, size_t *);
|
|
230
229
|
static int tohex(int c);
|
|
231
230
|
static char *url_decode(const char *);
|
|
232
|
-
static
|
|
231
|
+
static void tar_flush_unconsumed(struct archive_read *, size_t *);
|
|
232
|
+
|
|
233
233
|
|
|
234
234
|
int
|
|
235
235
|
archive_read_support_format_gnutar(struct archive *a)
|
|
236
236
|
{
|
|
237
|
+
archive_check_magic(a, ARCHIVE_READ_MAGIC,
|
|
238
|
+
ARCHIVE_STATE_NEW, "archive_read_support_format_gnutar");
|
|
237
239
|
return (archive_read_support_format_tar(a));
|
|
238
240
|
}
|
|
239
241
|
|
|
@@ -245,21 +247,30 @@ archive_read_support_format_tar(struct archive *_a)
|
|
|
245
247
|
struct tar *tar;
|
|
246
248
|
int r;
|
|
247
249
|
|
|
248
|
-
|
|
250
|
+
archive_check_magic(_a, ARCHIVE_READ_MAGIC,
|
|
251
|
+
ARCHIVE_STATE_NEW, "archive_read_support_format_tar");
|
|
252
|
+
|
|
253
|
+
tar = (struct tar *)calloc(1, sizeof(*tar));
|
|
249
254
|
if (tar == NULL) {
|
|
250
255
|
archive_set_error(&a->archive, ENOMEM,
|
|
251
256
|
"Can't allocate tar data");
|
|
252
257
|
return (ARCHIVE_FATAL);
|
|
253
258
|
}
|
|
254
|
-
|
|
259
|
+
#ifdef HAVE_COPYFILE_H
|
|
260
|
+
/* Set this by default on Mac OS. */
|
|
261
|
+
tar->process_mac_extensions = 1;
|
|
262
|
+
#endif
|
|
255
263
|
|
|
256
264
|
r = __archive_read_register_format(a, tar, "tar",
|
|
257
265
|
archive_read_format_tar_bid,
|
|
258
|
-
|
|
266
|
+
archive_read_format_tar_options,
|
|
259
267
|
archive_read_format_tar_read_header,
|
|
260
268
|
archive_read_format_tar_read_data,
|
|
261
269
|
archive_read_format_tar_skip,
|
|
262
|
-
|
|
270
|
+
NULL,
|
|
271
|
+
archive_read_format_tar_cleanup,
|
|
272
|
+
NULL,
|
|
273
|
+
NULL);
|
|
263
274
|
|
|
264
275
|
if (r != ARCHIVE_OK)
|
|
265
276
|
free(tar);
|
|
@@ -284,20 +295,73 @@ archive_read_format_tar_cleanup(struct archive_read *a)
|
|
|
284
295
|
archive_string_free(&tar->pax_header);
|
|
285
296
|
archive_string_free(&tar->longname);
|
|
286
297
|
archive_string_free(&tar->longlink);
|
|
287
|
-
|
|
298
|
+
archive_string_free(&tar->localname);
|
|
288
299
|
free(tar);
|
|
289
300
|
(a->format->data) = NULL;
|
|
290
301
|
return (ARCHIVE_OK);
|
|
291
302
|
}
|
|
292
303
|
|
|
304
|
+
/*
|
|
305
|
+
* Validate number field
|
|
306
|
+
*
|
|
307
|
+
* This has to be pretty lenient in order to accommodate the enormous
|
|
308
|
+
* variety of tar writers in the world:
|
|
309
|
+
* = POSIX (IEEE Std 1003.1-1988) ustar requires octal values with leading
|
|
310
|
+
* zeros and allows fields to be terminated with space or null characters
|
|
311
|
+
* = Many writers use different termination (in particular, libarchive
|
|
312
|
+
* omits terminator bytes to squeeze one or two more digits)
|
|
313
|
+
* = Many writers pad with space and omit leading zeros
|
|
314
|
+
* = GNU tar and star write base-256 values if numbers are too
|
|
315
|
+
* big to be represented in octal
|
|
316
|
+
*
|
|
317
|
+
* Examples of specific tar headers that we should support:
|
|
318
|
+
* = Perl Archive::Tar terminates uid, gid, devminor and devmajor with two
|
|
319
|
+
* null bytes, pads size with spaces and other numeric fields with zeroes
|
|
320
|
+
* = plexus-archiver prior to 2.6.3 (before switching to commons-compress)
|
|
321
|
+
* may have uid and gid fields filled with spaces without any octal digits
|
|
322
|
+
* at all and pads all numeric fields with spaces
|
|
323
|
+
*
|
|
324
|
+
* This should tolerate all variants in use. It will reject a field
|
|
325
|
+
* where the writer just left garbage after a trailing NUL.
|
|
326
|
+
*/
|
|
327
|
+
static int
|
|
328
|
+
validate_number_field(const char* p_field, size_t i_size)
|
|
329
|
+
{
|
|
330
|
+
unsigned char marker = (unsigned char)p_field[0];
|
|
331
|
+
if (marker == 128 || marker == 255 || marker == 0) {
|
|
332
|
+
/* Base-256 marker, there's nothing we can check. */
|
|
333
|
+
return 1;
|
|
334
|
+
} else {
|
|
335
|
+
/* Must be octal */
|
|
336
|
+
size_t i = 0;
|
|
337
|
+
/* Skip any leading spaces */
|
|
338
|
+
while (i < i_size && p_field[i] == ' ') {
|
|
339
|
+
++i;
|
|
340
|
+
}
|
|
341
|
+
/* Skip octal digits. */
|
|
342
|
+
while (i < i_size && p_field[i] >= '0' && p_field[i] <= '7') {
|
|
343
|
+
++i;
|
|
344
|
+
}
|
|
345
|
+
/* Any remaining characters must be space or NUL padding. */
|
|
346
|
+
while (i < i_size) {
|
|
347
|
+
if (p_field[i] != ' ' && p_field[i] != 0) {
|
|
348
|
+
return 0;
|
|
349
|
+
}
|
|
350
|
+
++i;
|
|
351
|
+
}
|
|
352
|
+
return 1;
|
|
353
|
+
}
|
|
354
|
+
}
|
|
293
355
|
|
|
294
356
|
static int
|
|
295
|
-
archive_read_format_tar_bid(struct archive_read *a)
|
|
357
|
+
archive_read_format_tar_bid(struct archive_read *a, int best_bid)
|
|
296
358
|
{
|
|
297
359
|
int bid;
|
|
298
|
-
const
|
|
360
|
+
const char *h;
|
|
299
361
|
const struct archive_entry_header_ustar *header;
|
|
300
362
|
|
|
363
|
+
(void)best_bid; /* UNUSED */
|
|
364
|
+
|
|
301
365
|
bid = 0;
|
|
302
366
|
|
|
303
367
|
/* Now let's look at the actual header and see if it matches. */
|
|
@@ -306,8 +370,7 @@ archive_read_format_tar_bid(struct archive_read *a)
|
|
|
306
370
|
return (-1);
|
|
307
371
|
|
|
308
372
|
/* If it's an end-of-archive mark, we can handle it. */
|
|
309
|
-
if (
|
|
310
|
-
&& archive_block_is_null((const unsigned char *)h)) {
|
|
373
|
+
if (h[0] == 0 && archive_block_is_null(h)) {
|
|
311
374
|
/*
|
|
312
375
|
* Usually, I bid the number of bits verified, but
|
|
313
376
|
* in this case, 4096 seems excessive so I picked 10 as
|
|
@@ -325,12 +388,12 @@ archive_read_format_tar_bid(struct archive_read *a)
|
|
|
325
388
|
|
|
326
389
|
/* Recognize POSIX formats. */
|
|
327
390
|
if ((memcmp(header->magic, "ustar\0", 6) == 0)
|
|
328
|
-
&&(memcmp(header->version, "00", 2)==0))
|
|
391
|
+
&& (memcmp(header->version, "00", 2) == 0))
|
|
329
392
|
bid += 56;
|
|
330
393
|
|
|
331
394
|
/* Recognize GNU tar format. */
|
|
332
395
|
if ((memcmp(header->magic, "ustar ", 6) == 0)
|
|
333
|
-
&&(memcmp(header->version, " \0", 2)==0))
|
|
396
|
+
&& (memcmp(header->version, " \0", 2) == 0))
|
|
334
397
|
bid += 56;
|
|
335
398
|
|
|
336
399
|
/* Type flag must be null, digit or A-Z, a-z. */
|
|
@@ -341,29 +404,87 @@ archive_read_format_tar_bid(struct archive_read *a)
|
|
|
341
404
|
return (0);
|
|
342
405
|
bid += 2; /* 6 bits of variation in an 8-bit field leaves 2 bits. */
|
|
343
406
|
|
|
344
|
-
/*
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
break;
|
|
356
|
-
default:
|
|
357
|
-
/* Not a valid mode; bail out here. */
|
|
358
|
-
return (0);
|
|
407
|
+
/*
|
|
408
|
+
* Check format of mode/uid/gid/mtime/size/rdevmajor/rdevminor fields.
|
|
409
|
+
*/
|
|
410
|
+
if (validate_number_field(header->mode, sizeof(header->mode)) == 0
|
|
411
|
+
|| validate_number_field(header->uid, sizeof(header->uid)) == 0
|
|
412
|
+
|| validate_number_field(header->gid, sizeof(header->gid)) == 0
|
|
413
|
+
|| validate_number_field(header->mtime, sizeof(header->mtime)) == 0
|
|
414
|
+
|| validate_number_field(header->size, sizeof(header->size)) == 0
|
|
415
|
+
|| validate_number_field(header->rdevmajor, sizeof(header->rdevmajor)) == 0
|
|
416
|
+
|| validate_number_field(header->rdevminor, sizeof(header->rdevminor)) == 0) {
|
|
417
|
+
bid = 0;
|
|
359
418
|
}
|
|
360
|
-
/* TODO: Sanity test uid/gid/size/mtime/rdevmajor/rdevminor fields. */
|
|
361
419
|
|
|
362
420
|
return (bid);
|
|
363
421
|
}
|
|
364
422
|
|
|
423
|
+
static int
|
|
424
|
+
archive_read_format_tar_options(struct archive_read *a,
|
|
425
|
+
const char *key, const char *val)
|
|
426
|
+
{
|
|
427
|
+
struct tar *tar;
|
|
428
|
+
int ret = ARCHIVE_FAILED;
|
|
429
|
+
|
|
430
|
+
tar = (struct tar *)(a->format->data);
|
|
431
|
+
if (strcmp(key, "compat-2x") == 0) {
|
|
432
|
+
/* Handle UTF-8 filenames as libarchive 2.x */
|
|
433
|
+
tar->compat_2x = (val != NULL && val[0] != 0);
|
|
434
|
+
tar->init_default_conversion = tar->compat_2x;
|
|
435
|
+
return (ARCHIVE_OK);
|
|
436
|
+
} else if (strcmp(key, "hdrcharset") == 0) {
|
|
437
|
+
if (val == NULL || val[0] == 0)
|
|
438
|
+
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
|
439
|
+
"tar: hdrcharset option needs a character-set name");
|
|
440
|
+
else {
|
|
441
|
+
tar->opt_sconv =
|
|
442
|
+
archive_string_conversion_from_charset(
|
|
443
|
+
&a->archive, val, 0);
|
|
444
|
+
if (tar->opt_sconv != NULL)
|
|
445
|
+
ret = ARCHIVE_OK;
|
|
446
|
+
else
|
|
447
|
+
ret = ARCHIVE_FATAL;
|
|
448
|
+
}
|
|
449
|
+
return (ret);
|
|
450
|
+
} else if (strcmp(key, "mac-ext") == 0) {
|
|
451
|
+
tar->process_mac_extensions = (val != NULL && val[0] != 0);
|
|
452
|
+
return (ARCHIVE_OK);
|
|
453
|
+
} else if (strcmp(key, "read_concatenated_archives") == 0) {
|
|
454
|
+
tar->read_concatenated_archives = (val != NULL && val[0] != 0);
|
|
455
|
+
return (ARCHIVE_OK);
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
/* Note: The "warn" return is just to inform the options
|
|
459
|
+
* supervisor that we didn't handle it. It will generate
|
|
460
|
+
* a suitable error if no one used this option. */
|
|
461
|
+
return (ARCHIVE_WARN);
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
/* utility function- this exists to centralize the logic of tracking
|
|
465
|
+
* how much unconsumed data we have floating around, and to consume
|
|
466
|
+
* anything outstanding since we're going to do read_aheads
|
|
467
|
+
*/
|
|
468
|
+
static void
|
|
469
|
+
tar_flush_unconsumed(struct archive_read *a, size_t *unconsumed)
|
|
470
|
+
{
|
|
471
|
+
if (*unconsumed) {
|
|
472
|
+
/*
|
|
473
|
+
void *data = (void *)__archive_read_ahead(a, *unconsumed, NULL);
|
|
474
|
+
* this block of code is to poison claimed unconsumed space, ensuring
|
|
475
|
+
* things break if it is in use still.
|
|
476
|
+
* currently it WILL break things, so enable it only for debugging this issue
|
|
477
|
+
if (data) {
|
|
478
|
+
memset(data, 0xff, *unconsumed);
|
|
479
|
+
}
|
|
480
|
+
*/
|
|
481
|
+
__archive_read_consume(a, *unconsumed);
|
|
482
|
+
*unconsumed = 0;
|
|
483
|
+
}
|
|
484
|
+
}
|
|
485
|
+
|
|
365
486
|
/*
|
|
366
|
-
* The function invoked by
|
|
487
|
+
* The function invoked by archive_read_next_header(). This
|
|
367
488
|
* just sets up a few things and then calls the internal
|
|
368
489
|
* tar_read_header() function below.
|
|
369
490
|
*/
|
|
@@ -388,10 +509,10 @@ archive_read_format_tar_read_header(struct archive_read *a,
|
|
|
388
509
|
static int default_inode;
|
|
389
510
|
static int default_dev;
|
|
390
511
|
struct tar *tar;
|
|
391
|
-
struct sparse_block *sp;
|
|
392
512
|
const char *p;
|
|
513
|
+
const wchar_t *wp;
|
|
393
514
|
int r;
|
|
394
|
-
size_t l;
|
|
515
|
+
size_t l, unconsumed = 0;
|
|
395
516
|
|
|
396
517
|
/* Assign default device/inode values. */
|
|
397
518
|
archive_entry_set_dev(entry, 1 + default_dev); /* Don't use zero. */
|
|
@@ -404,41 +525,71 @@ archive_read_format_tar_read_header(struct archive_read *a,
|
|
|
404
525
|
|
|
405
526
|
tar = (struct tar *)(a->format->data);
|
|
406
527
|
tar->entry_offset = 0;
|
|
407
|
-
|
|
408
|
-
sp = tar->sparse_list;
|
|
409
|
-
tar->sparse_list = sp->next;
|
|
410
|
-
free(sp);
|
|
411
|
-
}
|
|
412
|
-
tar->sparse_last = NULL;
|
|
528
|
+
gnu_clear_sparse_list(tar);
|
|
413
529
|
tar->realsize = -1; /* Mark this as "unset" */
|
|
530
|
+
tar->realsize_override = 0;
|
|
531
|
+
|
|
532
|
+
/* Setup default string conversion. */
|
|
533
|
+
tar->sconv = tar->opt_sconv;
|
|
534
|
+
if (tar->sconv == NULL) {
|
|
535
|
+
if (!tar->init_default_conversion) {
|
|
536
|
+
tar->sconv_default =
|
|
537
|
+
archive_string_default_conversion_for_read(&(a->archive));
|
|
538
|
+
tar->init_default_conversion = 1;
|
|
539
|
+
}
|
|
540
|
+
tar->sconv = tar->sconv_default;
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
r = tar_read_header(a, tar, entry, &unconsumed);
|
|
414
544
|
|
|
415
|
-
|
|
545
|
+
tar_flush_unconsumed(a, &unconsumed);
|
|
416
546
|
|
|
417
547
|
/*
|
|
418
548
|
* "non-sparse" files are really just sparse files with
|
|
419
549
|
* a single block.
|
|
420
550
|
*/
|
|
421
|
-
if (tar->sparse_list == NULL)
|
|
422
|
-
gnu_add_sparse_entry(tar, 0, tar->entry_bytes_remaining)
|
|
551
|
+
if (tar->sparse_list == NULL) {
|
|
552
|
+
if (gnu_add_sparse_entry(a, tar, 0, tar->entry_bytes_remaining)
|
|
553
|
+
!= ARCHIVE_OK)
|
|
554
|
+
return (ARCHIVE_FATAL);
|
|
555
|
+
} else {
|
|
556
|
+
struct sparse_block *sb;
|
|
423
557
|
|
|
424
|
-
|
|
558
|
+
for (sb = tar->sparse_list; sb != NULL; sb = sb->next) {
|
|
559
|
+
if (!sb->hole)
|
|
560
|
+
archive_entry_sparse_add_entry(entry,
|
|
561
|
+
sb->offset, sb->remaining);
|
|
562
|
+
}
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
if (r == ARCHIVE_OK && archive_entry_filetype(entry) == AE_IFREG) {
|
|
425
566
|
/*
|
|
426
567
|
* "Regular" entry with trailing '/' is really
|
|
427
568
|
* directory: This is needed for certain old tar
|
|
428
569
|
* variants and even for some broken newer ones.
|
|
429
570
|
*/
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
571
|
+
if ((wp = archive_entry_pathname_w(entry)) != NULL) {
|
|
572
|
+
l = wcslen(wp);
|
|
573
|
+
if (l > 0 && wp[l - 1] == L'/') {
|
|
574
|
+
archive_entry_set_filetype(entry, AE_IFDIR);
|
|
575
|
+
tar->entry_bytes_remaining = 0;
|
|
576
|
+
tar->entry_padding = 0;
|
|
577
|
+
}
|
|
578
|
+
} else if ((p = archive_entry_pathname(entry)) != NULL) {
|
|
579
|
+
l = strlen(p);
|
|
580
|
+
if (l > 0 && p[l - 1] == '/') {
|
|
581
|
+
archive_entry_set_filetype(entry, AE_IFDIR);
|
|
582
|
+
tar->entry_bytes_remaining = 0;
|
|
583
|
+
tar->entry_padding = 0;
|
|
584
|
+
}
|
|
585
|
+
}
|
|
435
586
|
}
|
|
436
587
|
return (r);
|
|
437
588
|
}
|
|
438
589
|
|
|
439
590
|
static int
|
|
440
591
|
archive_read_format_tar_read_data(struct archive_read *a,
|
|
441
|
-
const void **buff, size_t *size,
|
|
592
|
+
const void **buff, size_t *size, int64_t *offset)
|
|
442
593
|
{
|
|
443
594
|
ssize_t bytes_read;
|
|
444
595
|
struct tar *tar;
|
|
@@ -446,85 +597,89 @@ archive_read_format_tar_read_data(struct archive_read *a,
|
|
|
446
597
|
|
|
447
598
|
tar = (struct tar *)(a->format->data);
|
|
448
599
|
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
tar->
|
|
455
|
-
|
|
456
|
-
return (bytes_read);
|
|
457
|
-
} else {
|
|
458
|
-
*size = 0;
|
|
459
|
-
*offset = 0;
|
|
460
|
-
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
|
461
|
-
"Unrecognized GNU sparse file format");
|
|
462
|
-
return (ARCHIVE_WARN);
|
|
600
|
+
for (;;) {
|
|
601
|
+
/* Remove exhausted entries from sparse list. */
|
|
602
|
+
while (tar->sparse_list != NULL &&
|
|
603
|
+
tar->sparse_list->remaining == 0) {
|
|
604
|
+
p = tar->sparse_list;
|
|
605
|
+
tar->sparse_list = p->next;
|
|
606
|
+
free(p);
|
|
463
607
|
}
|
|
464
|
-
tar->sparse_gnu_pending = 0;
|
|
465
|
-
}
|
|
466
608
|
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
tar->sparse_list = p->next;
|
|
472
|
-
free(p);
|
|
473
|
-
}
|
|
609
|
+
if (tar->entry_bytes_unconsumed) {
|
|
610
|
+
__archive_read_consume(a, tar->entry_bytes_unconsumed);
|
|
611
|
+
tar->entry_bytes_unconsumed = 0;
|
|
612
|
+
}
|
|
474
613
|
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
614
|
+
/* If we're at end of file, return EOF. */
|
|
615
|
+
if (tar->sparse_list == NULL ||
|
|
616
|
+
tar->entry_bytes_remaining == 0) {
|
|
617
|
+
if (__archive_read_consume(a, tar->entry_padding) < 0)
|
|
618
|
+
return (ARCHIVE_FATAL);
|
|
619
|
+
tar->entry_padding = 0;
|
|
620
|
+
*buff = NULL;
|
|
621
|
+
*size = 0;
|
|
622
|
+
*offset = tar->realsize;
|
|
623
|
+
return (ARCHIVE_EOF);
|
|
624
|
+
}
|
|
485
625
|
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
626
|
+
*buff = __archive_read_ahead(a, 1, &bytes_read);
|
|
627
|
+
if (bytes_read < 0)
|
|
628
|
+
return (ARCHIVE_FATAL);
|
|
629
|
+
if (*buff == NULL) {
|
|
630
|
+
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
|
631
|
+
"Truncated tar archive");
|
|
632
|
+
return (ARCHIVE_FATAL);
|
|
633
|
+
}
|
|
634
|
+
if (bytes_read > tar->entry_bytes_remaining)
|
|
635
|
+
bytes_read = (ssize_t)tar->entry_bytes_remaining;
|
|
636
|
+
/* Don't read more than is available in the
|
|
637
|
+
* current sparse block. */
|
|
638
|
+
if (tar->sparse_list->remaining < bytes_read)
|
|
639
|
+
bytes_read = (ssize_t)tar->sparse_list->remaining;
|
|
640
|
+
*size = bytes_read;
|
|
641
|
+
*offset = tar->sparse_list->offset;
|
|
642
|
+
tar->sparse_list->remaining -= bytes_read;
|
|
643
|
+
tar->sparse_list->offset += bytes_read;
|
|
644
|
+
tar->entry_bytes_remaining -= bytes_read;
|
|
645
|
+
tar->entry_bytes_unconsumed = bytes_read;
|
|
646
|
+
|
|
647
|
+
if (!tar->sparse_list->hole)
|
|
648
|
+
return (ARCHIVE_OK);
|
|
649
|
+
/* Current is hole data and skip this. */
|
|
493
650
|
}
|
|
494
|
-
if (bytes_read > tar->entry_bytes_remaining)
|
|
495
|
-
bytes_read = tar->entry_bytes_remaining;
|
|
496
|
-
/* Don't read more than is available in the
|
|
497
|
-
* current sparse block. */
|
|
498
|
-
if (tar->sparse_list->remaining < bytes_read)
|
|
499
|
-
bytes_read = tar->sparse_list->remaining;
|
|
500
|
-
*size = bytes_read;
|
|
501
|
-
*offset = tar->sparse_list->offset;
|
|
502
|
-
tar->sparse_list->remaining -= bytes_read;
|
|
503
|
-
tar->sparse_list->offset += bytes_read;
|
|
504
|
-
tar->entry_bytes_remaining -= bytes_read;
|
|
505
|
-
__archive_read_consume(a, bytes_read);
|
|
506
|
-
return (ARCHIVE_OK);
|
|
507
651
|
}
|
|
508
652
|
|
|
509
653
|
static int
|
|
510
654
|
archive_read_format_tar_skip(struct archive_read *a)
|
|
511
655
|
{
|
|
512
656
|
int64_t bytes_skipped;
|
|
657
|
+
int64_t request;
|
|
658
|
+
struct sparse_block *p;
|
|
513
659
|
struct tar* tar;
|
|
514
660
|
|
|
515
661
|
tar = (struct tar *)(a->format->data);
|
|
516
662
|
|
|
517
|
-
/*
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
663
|
+
/* Do not consume the hole of a sparse file. */
|
|
664
|
+
request = 0;
|
|
665
|
+
for (p = tar->sparse_list; p != NULL; p = p->next) {
|
|
666
|
+
if (!p->hole) {
|
|
667
|
+
if (p->remaining >= INT64_MAX - request) {
|
|
668
|
+
return ARCHIVE_FATAL;
|
|
669
|
+
}
|
|
670
|
+
request += p->remaining;
|
|
671
|
+
}
|
|
672
|
+
}
|
|
673
|
+
if (request > tar->entry_bytes_remaining)
|
|
674
|
+
request = tar->entry_bytes_remaining;
|
|
675
|
+
request += tar->entry_padding + tar->entry_bytes_unconsumed;
|
|
676
|
+
|
|
677
|
+
bytes_skipped = __archive_read_consume(a, request);
|
|
524
678
|
if (bytes_skipped < 0)
|
|
525
679
|
return (ARCHIVE_FATAL);
|
|
526
680
|
|
|
527
681
|
tar->entry_bytes_remaining = 0;
|
|
682
|
+
tar->entry_bytes_unconsumed = 0;
|
|
528
683
|
tar->entry_padding = 0;
|
|
529
684
|
|
|
530
685
|
/* Free the sparse list. */
|
|
@@ -539,49 +694,60 @@ archive_read_format_tar_skip(struct archive_read *a)
|
|
|
539
694
|
*/
|
|
540
695
|
static int
|
|
541
696
|
tar_read_header(struct archive_read *a, struct tar *tar,
|
|
542
|
-
struct archive_entry *entry)
|
|
697
|
+
struct archive_entry *entry, size_t *unconsumed)
|
|
543
698
|
{
|
|
544
699
|
ssize_t bytes;
|
|
545
|
-
int err;
|
|
546
|
-
const
|
|
700
|
+
int err, eof_vol_header;
|
|
701
|
+
const char *h;
|
|
547
702
|
const struct archive_entry_header_ustar *header;
|
|
703
|
+
const struct archive_entry_header_gnutar *gnuheader;
|
|
548
704
|
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
* hold our nose and accept it.
|
|
562
|
-
*/
|
|
705
|
+
eof_vol_header = 0;
|
|
706
|
+
|
|
707
|
+
/* Loop until we find a workable header record. */
|
|
708
|
+
for (;;) {
|
|
709
|
+
tar_flush_unconsumed(a, unconsumed);
|
|
710
|
+
|
|
711
|
+
/* Read 512-byte header record */
|
|
712
|
+
h = __archive_read_ahead(a, 512, &bytes);
|
|
713
|
+
if (bytes < 0)
|
|
714
|
+
return ((int)bytes);
|
|
715
|
+
if (bytes == 0) { /* EOF at a block boundary. */
|
|
716
|
+
/* Some writers do omit the block of nulls. <sigh> */
|
|
563
717
|
return (ARCHIVE_EOF);
|
|
564
718
|
}
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
719
|
+
if (bytes < 512) { /* Short block at EOF; this is bad. */
|
|
720
|
+
archive_set_error(&a->archive,
|
|
721
|
+
ARCHIVE_ERRNO_FILE_FORMAT,
|
|
722
|
+
"Truncated tar archive");
|
|
723
|
+
return (ARCHIVE_FATAL);
|
|
724
|
+
}
|
|
725
|
+
*unconsumed = 512;
|
|
571
726
|
|
|
727
|
+
/* Header is workable if it's not an end-of-archive mark. */
|
|
728
|
+
if (h[0] != 0 || !archive_block_is_null(h))
|
|
729
|
+
break;
|
|
572
730
|
|
|
573
|
-
|
|
574
|
-
if (((*(const char *)h)==0) && archive_block_is_null((const unsigned char *)h)) {
|
|
575
|
-
/* Try to consume a second all-null record, as well. */
|
|
576
|
-
h = __archive_read_ahead(a, 512, NULL);
|
|
577
|
-
if (h != NULL)
|
|
578
|
-
__archive_read_consume(a, 512);
|
|
579
|
-
archive_set_error(&a->archive, 0, NULL);
|
|
731
|
+
/* Ensure format is set for archives with only null blocks. */
|
|
580
732
|
if (a->archive.archive_format_name == NULL) {
|
|
581
733
|
a->archive.archive_format = ARCHIVE_FORMAT_TAR;
|
|
582
734
|
a->archive.archive_format_name = "tar";
|
|
583
735
|
}
|
|
584
|
-
|
|
736
|
+
|
|
737
|
+
if (!tar->read_concatenated_archives) {
|
|
738
|
+
/* Try to consume a second all-null record, as well. */
|
|
739
|
+
tar_flush_unconsumed(a, unconsumed);
|
|
740
|
+
h = __archive_read_ahead(a, 512, NULL);
|
|
741
|
+
if (h != NULL && h[0] == 0 && archive_block_is_null(h))
|
|
742
|
+
__archive_read_consume(a, 512);
|
|
743
|
+
archive_clear_error(&a->archive);
|
|
744
|
+
return (ARCHIVE_EOF);
|
|
745
|
+
}
|
|
746
|
+
|
|
747
|
+
/*
|
|
748
|
+
* We're reading concatenated archives, ignore this block and
|
|
749
|
+
* loop to get the next.
|
|
750
|
+
*/
|
|
585
751
|
}
|
|
586
752
|
|
|
587
753
|
/*
|
|
@@ -592,53 +758,61 @@ tar_read_header(struct archive_read *a, struct tar *tar,
|
|
|
592
758
|
* TODO: Improve this by implementing a real header scan.
|
|
593
759
|
*/
|
|
594
760
|
if (!checksum(a, h)) {
|
|
761
|
+
tar_flush_unconsumed(a, unconsumed);
|
|
595
762
|
archive_set_error(&a->archive, EINVAL, "Damaged tar archive");
|
|
596
763
|
return (ARCHIVE_RETRY); /* Retryable: Invalid header */
|
|
597
764
|
}
|
|
598
765
|
|
|
599
766
|
if (++tar->header_recursion_depth > 32) {
|
|
767
|
+
tar_flush_unconsumed(a, unconsumed);
|
|
600
768
|
archive_set_error(&a->archive, EINVAL, "Too many special headers");
|
|
601
769
|
return (ARCHIVE_WARN);
|
|
602
770
|
}
|
|
603
771
|
|
|
604
772
|
/* Determine the format variant. */
|
|
605
773
|
header = (const struct archive_entry_header_ustar *)h;
|
|
774
|
+
|
|
606
775
|
switch(header->typeflag[0]) {
|
|
607
776
|
case 'A': /* Solaris tar ACL */
|
|
608
777
|
a->archive.archive_format = ARCHIVE_FORMAT_TAR_PAX_INTERCHANGE;
|
|
609
778
|
a->archive.archive_format_name = "Solaris tar";
|
|
610
|
-
err = header_Solaris_ACL(a, tar, entry, h);
|
|
779
|
+
err = header_Solaris_ACL(a, tar, entry, h, unconsumed);
|
|
611
780
|
break;
|
|
612
781
|
case 'g': /* POSIX-standard 'g' header. */
|
|
613
782
|
a->archive.archive_format = ARCHIVE_FORMAT_TAR_PAX_INTERCHANGE;
|
|
614
783
|
a->archive.archive_format_name = "POSIX pax interchange format";
|
|
615
|
-
err = header_pax_global(a, tar, entry, h);
|
|
784
|
+
err = header_pax_global(a, tar, entry, h, unconsumed);
|
|
785
|
+
if (err == ARCHIVE_EOF)
|
|
786
|
+
return (err);
|
|
616
787
|
break;
|
|
617
788
|
case 'K': /* Long link name (GNU tar, others) */
|
|
618
|
-
err = header_longlink(a, tar, entry, h);
|
|
789
|
+
err = header_longlink(a, tar, entry, h, unconsumed);
|
|
619
790
|
break;
|
|
620
791
|
case 'L': /* Long filename (GNU tar, others) */
|
|
621
|
-
err = header_longname(a, tar, entry, h);
|
|
792
|
+
err = header_longname(a, tar, entry, h, unconsumed);
|
|
622
793
|
break;
|
|
623
794
|
case 'V': /* GNU volume header */
|
|
624
|
-
err = header_volume(a, tar, entry, h);
|
|
795
|
+
err = header_volume(a, tar, entry, h, unconsumed);
|
|
796
|
+
if (err == ARCHIVE_EOF)
|
|
797
|
+
eof_vol_header = 1;
|
|
625
798
|
break;
|
|
626
799
|
case 'X': /* Used by SUN tar; same as 'x'. */
|
|
627
800
|
a->archive.archive_format = ARCHIVE_FORMAT_TAR_PAX_INTERCHANGE;
|
|
628
801
|
a->archive.archive_format_name =
|
|
629
802
|
"POSIX pax interchange format (Sun variant)";
|
|
630
|
-
err = header_pax_extensions(a, tar, entry, h);
|
|
803
|
+
err = header_pax_extensions(a, tar, entry, h, unconsumed);
|
|
631
804
|
break;
|
|
632
805
|
case 'x': /* POSIX-standard 'x' header. */
|
|
633
806
|
a->archive.archive_format = ARCHIVE_FORMAT_TAR_PAX_INTERCHANGE;
|
|
634
807
|
a->archive.archive_format_name = "POSIX pax interchange format";
|
|
635
|
-
err = header_pax_extensions(a, tar, entry, h);
|
|
808
|
+
err = header_pax_extensions(a, tar, entry, h, unconsumed);
|
|
636
809
|
break;
|
|
637
810
|
default:
|
|
638
|
-
|
|
811
|
+
gnuheader = (const struct archive_entry_header_gnutar *)h;
|
|
812
|
+
if (memcmp(gnuheader->magic, "ustar \0", 8) == 0) {
|
|
639
813
|
a->archive.archive_format = ARCHIVE_FORMAT_TAR_GNUTAR;
|
|
640
814
|
a->archive.archive_format_name = "GNU tar format";
|
|
641
|
-
err = header_gnutar(a, tar, entry, h);
|
|
815
|
+
err = header_gnutar(a, tar, entry, h, unconsumed);
|
|
642
816
|
} else if (memcmp(header->magic, "ustar", 5) == 0) {
|
|
643
817
|
if (a->archive.archive_format != ARCHIVE_FORMAT_TAR_PAX_INTERCHANGE) {
|
|
644
818
|
a->archive.archive_format = ARCHIVE_FORMAT_TAR_USTAR;
|
|
@@ -651,13 +825,61 @@ tar_read_header(struct archive_read *a, struct tar *tar,
|
|
|
651
825
|
err = header_old_tar(a, tar, entry, h);
|
|
652
826
|
}
|
|
653
827
|
}
|
|
828
|
+
if (err == ARCHIVE_FATAL)
|
|
829
|
+
return (err);
|
|
830
|
+
|
|
831
|
+
tar_flush_unconsumed(a, unconsumed);
|
|
832
|
+
|
|
833
|
+
h = NULL;
|
|
834
|
+
header = NULL;
|
|
835
|
+
|
|
654
836
|
--tar->header_recursion_depth;
|
|
837
|
+
/* Yuck. Apple's design here ends up storing long pathname
|
|
838
|
+
* extensions for both the AppleDouble extension entry and the
|
|
839
|
+
* regular entry.
|
|
840
|
+
*/
|
|
841
|
+
if ((err == ARCHIVE_WARN || err == ARCHIVE_OK) &&
|
|
842
|
+
tar->header_recursion_depth == 0 &&
|
|
843
|
+
tar->process_mac_extensions) {
|
|
844
|
+
int err2 = read_mac_metadata_blob(a, tar, entry, h, unconsumed);
|
|
845
|
+
if (err2 < err)
|
|
846
|
+
err = err2;
|
|
847
|
+
}
|
|
848
|
+
|
|
655
849
|
/* We return warnings or success as-is. Anything else is fatal. */
|
|
656
|
-
if (err == ARCHIVE_WARN || err == ARCHIVE_OK)
|
|
850
|
+
if (err == ARCHIVE_WARN || err == ARCHIVE_OK) {
|
|
851
|
+
if (tar->sparse_gnu_pending) {
|
|
852
|
+
if (tar->sparse_gnu_major == 1 &&
|
|
853
|
+
tar->sparse_gnu_minor == 0) {
|
|
854
|
+
ssize_t bytes_read;
|
|
855
|
+
|
|
856
|
+
tar->sparse_gnu_pending = 0;
|
|
857
|
+
/* Read initial sparse map. */
|
|
858
|
+
bytes_read = gnu_sparse_10_read(a, tar, unconsumed);
|
|
859
|
+
if (bytes_read < 0)
|
|
860
|
+
return ((int)bytes_read);
|
|
861
|
+
tar->entry_bytes_remaining -= bytes_read;
|
|
862
|
+
} else {
|
|
863
|
+
archive_set_error(&a->archive,
|
|
864
|
+
ARCHIVE_ERRNO_MISC,
|
|
865
|
+
"Unrecognized GNU sparse file format");
|
|
866
|
+
return (ARCHIVE_WARN);
|
|
867
|
+
}
|
|
868
|
+
tar->sparse_gnu_pending = 0;
|
|
869
|
+
}
|
|
657
870
|
return (err);
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
871
|
+
}
|
|
872
|
+
if (err == ARCHIVE_EOF) {
|
|
873
|
+
if (!eof_vol_header) {
|
|
874
|
+
/* EOF when recursively reading a header is bad. */
|
|
875
|
+
archive_set_error(&a->archive, EINVAL,
|
|
876
|
+
"Damaged tar archive");
|
|
877
|
+
} else {
|
|
878
|
+
/* If we encounter just a GNU volume header treat
|
|
879
|
+
* this situation as an empty archive */
|
|
880
|
+
return (ARCHIVE_EOF);
|
|
881
|
+
}
|
|
882
|
+
}
|
|
661
883
|
return (ARCHIVE_FATAL);
|
|
662
884
|
}
|
|
663
885
|
|
|
@@ -669,17 +891,25 @@ checksum(struct archive_read *a, const void *h)
|
|
|
669
891
|
{
|
|
670
892
|
const unsigned char *bytes;
|
|
671
893
|
const struct archive_entry_header_ustar *header;
|
|
672
|
-
int check,
|
|
894
|
+
int check, sum;
|
|
895
|
+
size_t i;
|
|
673
896
|
|
|
674
897
|
(void)a; /* UNUSED */
|
|
675
898
|
bytes = (const unsigned char *)h;
|
|
676
899
|
header = (const struct archive_entry_header_ustar *)h;
|
|
677
900
|
|
|
901
|
+
/* Checksum field must hold an octal number */
|
|
902
|
+
for (i = 0; i < sizeof(header->checksum); ++i) {
|
|
903
|
+
char c = header->checksum[i];
|
|
904
|
+
if (c != ' ' && c != '\0' && (c < '0' || c > '7'))
|
|
905
|
+
return 0;
|
|
906
|
+
}
|
|
907
|
+
|
|
678
908
|
/*
|
|
679
909
|
* Test the checksum. Note that POSIX specifies _unsigned_
|
|
680
910
|
* bytes for this calculation.
|
|
681
911
|
*/
|
|
682
|
-
sum = tar_atol(header->checksum, sizeof(header->checksum));
|
|
912
|
+
sum = (int)tar_atol(header->checksum, sizeof(header->checksum));
|
|
683
913
|
check = 0;
|
|
684
914
|
for (i = 0; i < 148; i++)
|
|
685
915
|
check += (unsigned char)bytes[i];
|
|
@@ -712,7 +942,7 @@ checksum(struct archive_read *a, const void *h)
|
|
|
712
942
|
* Return true if this block contains only nulls.
|
|
713
943
|
*/
|
|
714
944
|
static int
|
|
715
|
-
archive_block_is_null(const
|
|
945
|
+
archive_block_is_null(const char *p)
|
|
716
946
|
{
|
|
717
947
|
unsigned i;
|
|
718
948
|
|
|
@@ -727,26 +957,26 @@ archive_block_is_null(const unsigned char *p)
|
|
|
727
957
|
*/
|
|
728
958
|
static int
|
|
729
959
|
header_Solaris_ACL(struct archive_read *a, struct tar *tar,
|
|
730
|
-
struct archive_entry *entry, const void *h)
|
|
960
|
+
struct archive_entry *entry, const void *h, size_t *unconsumed)
|
|
731
961
|
{
|
|
732
962
|
const struct archive_entry_header_ustar *header;
|
|
733
963
|
size_t size;
|
|
734
|
-
int err;
|
|
964
|
+
int err, acl_type;
|
|
735
965
|
int64_t type;
|
|
736
966
|
char *acl, *p;
|
|
737
|
-
wchar_t *wp;
|
|
738
967
|
|
|
739
968
|
/*
|
|
740
969
|
* read_body_to_string adds a NUL terminator, but we need a little
|
|
741
970
|
* more to make sure that we don't overrun acl_text later.
|
|
742
971
|
*/
|
|
743
972
|
header = (const struct archive_entry_header_ustar *)h;
|
|
744
|
-
size = tar_atol(header->size, sizeof(header->size));
|
|
745
|
-
err = read_body_to_string(a, tar, &(tar->acl_text), h);
|
|
973
|
+
size = (size_t)tar_atol(header->size, sizeof(header->size));
|
|
974
|
+
err = read_body_to_string(a, tar, &(tar->acl_text), h, unconsumed);
|
|
746
975
|
if (err != ARCHIVE_OK)
|
|
747
976
|
return (err);
|
|
977
|
+
|
|
748
978
|
/* Recursively read next header */
|
|
749
|
-
err = tar_read_header(a, tar, entry);
|
|
979
|
+
err = tar_read_header(a, tar, entry, unconsumed);
|
|
750
980
|
if ((err != ARCHIVE_OK) && (err != ARCHIVE_WARN))
|
|
751
981
|
return (err);
|
|
752
982
|
|
|
@@ -776,11 +1006,12 @@ header_Solaris_ACL(struct archive_read *a, struct tar *tar,
|
|
|
776
1006
|
switch ((int)type & ~0777777) {
|
|
777
1007
|
case 01000000:
|
|
778
1008
|
/* POSIX.1e ACL */
|
|
1009
|
+
acl_type = ARCHIVE_ENTRY_ACL_TYPE_ACCESS;
|
|
779
1010
|
break;
|
|
780
1011
|
case 03000000:
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
1012
|
+
/* NFSv4 ACL */
|
|
1013
|
+
acl_type = ARCHIVE_ENTRY_ACL_TYPE_NFS4;
|
|
1014
|
+
break;
|
|
784
1015
|
default:
|
|
785
1016
|
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
|
786
1017
|
"Malformed Solaris ACL attribute (unsupported type %o)",
|
|
@@ -802,12 +1033,23 @@ header_Solaris_ACL(struct archive_read *a, struct tar *tar,
|
|
|
802
1033
|
while (*p != '\0' && p < acl + size)
|
|
803
1034
|
p++;
|
|
804
1035
|
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
1036
|
+
if (tar->sconv_acl == NULL) {
|
|
1037
|
+
tar->sconv_acl = archive_string_conversion_from_charset(
|
|
1038
|
+
&(a->archive), "UTF-8", 1);
|
|
1039
|
+
if (tar->sconv_acl == NULL)
|
|
1040
|
+
return (ARCHIVE_FATAL);
|
|
1041
|
+
}
|
|
1042
|
+
archive_strncpy(&(tar->localname), acl, p - acl);
|
|
1043
|
+
err = archive_acl_from_text_l(archive_entry_acl(entry),
|
|
1044
|
+
tar->localname.s, acl_type, tar->sconv_acl);
|
|
1045
|
+
if (err != ARCHIVE_OK) {
|
|
1046
|
+
if (errno == ENOMEM) {
|
|
1047
|
+
archive_set_error(&a->archive, ENOMEM,
|
|
1048
|
+
"Can't allocate memory for ACL");
|
|
1049
|
+
} else
|
|
1050
|
+
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
|
1051
|
+
"Malformed Solaris ACL attribute (unparsable)");
|
|
1052
|
+
}
|
|
811
1053
|
return (err);
|
|
812
1054
|
}
|
|
813
1055
|
|
|
@@ -816,14 +1058,14 @@ header_Solaris_ACL(struct archive_read *a, struct tar *tar,
|
|
|
816
1058
|
*/
|
|
817
1059
|
static int
|
|
818
1060
|
header_longlink(struct archive_read *a, struct tar *tar,
|
|
819
|
-
struct archive_entry *entry, const void *h)
|
|
1061
|
+
struct archive_entry *entry, const void *h, size_t *unconsumed)
|
|
820
1062
|
{
|
|
821
1063
|
int err;
|
|
822
1064
|
|
|
823
|
-
err = read_body_to_string(a, tar, &(tar->longlink), h);
|
|
1065
|
+
err = read_body_to_string(a, tar, &(tar->longlink), h, unconsumed);
|
|
824
1066
|
if (err != ARCHIVE_OK)
|
|
825
1067
|
return (err);
|
|
826
|
-
err = tar_read_header(a, tar, entry);
|
|
1068
|
+
err = tar_read_header(a, tar, entry, unconsumed);
|
|
827
1069
|
if ((err != ARCHIVE_OK) && (err != ARCHIVE_WARN))
|
|
828
1070
|
return (err);
|
|
829
1071
|
/* Set symlink if symlink already set, else hardlink. */
|
|
@@ -831,24 +1073,41 @@ header_longlink(struct archive_read *a, struct tar *tar,
|
|
|
831
1073
|
return (ARCHIVE_OK);
|
|
832
1074
|
}
|
|
833
1075
|
|
|
1076
|
+
static int
|
|
1077
|
+
set_conversion_failed_error(struct archive_read *a,
|
|
1078
|
+
struct archive_string_conv *sconv, const char *name)
|
|
1079
|
+
{
|
|
1080
|
+
if (errno == ENOMEM) {
|
|
1081
|
+
archive_set_error(&a->archive, ENOMEM,
|
|
1082
|
+
"Can't allocate memory for %s", name);
|
|
1083
|
+
return (ARCHIVE_FATAL);
|
|
1084
|
+
}
|
|
1085
|
+
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
|
1086
|
+
"%s can't be converted from %s to current locale.",
|
|
1087
|
+
name, archive_string_conversion_charset_name(sconv));
|
|
1088
|
+
return (ARCHIVE_WARN);
|
|
1089
|
+
}
|
|
1090
|
+
|
|
834
1091
|
/*
|
|
835
1092
|
* Interpret 'L' long filename header.
|
|
836
1093
|
*/
|
|
837
1094
|
static int
|
|
838
1095
|
header_longname(struct archive_read *a, struct tar *tar,
|
|
839
|
-
struct archive_entry *entry, const void *h)
|
|
1096
|
+
struct archive_entry *entry, const void *h, size_t *unconsumed)
|
|
840
1097
|
{
|
|
841
1098
|
int err;
|
|
842
1099
|
|
|
843
|
-
err = read_body_to_string(a, tar, &(tar->longname), h);
|
|
1100
|
+
err = read_body_to_string(a, tar, &(tar->longname), h, unconsumed);
|
|
844
1101
|
if (err != ARCHIVE_OK)
|
|
845
1102
|
return (err);
|
|
846
1103
|
/* Read and parse "real" header, then override name. */
|
|
847
|
-
err = tar_read_header(a, tar, entry);
|
|
1104
|
+
err = tar_read_header(a, tar, entry, unconsumed);
|
|
848
1105
|
if ((err != ARCHIVE_OK) && (err != ARCHIVE_WARN))
|
|
849
1106
|
return (err);
|
|
850
|
-
|
|
851
|
-
|
|
1107
|
+
if (archive_entry_copy_pathname_l(entry, tar->longname.s,
|
|
1108
|
+
archive_strlen(&(tar->longname)), tar->sconv) != 0)
|
|
1109
|
+
err = set_conversion_failed_error(a, tar->sconv, "Pathname");
|
|
1110
|
+
return (err);
|
|
852
1111
|
}
|
|
853
1112
|
|
|
854
1113
|
|
|
@@ -857,12 +1116,12 @@ header_longname(struct archive_read *a, struct tar *tar,
|
|
|
857
1116
|
*/
|
|
858
1117
|
static int
|
|
859
1118
|
header_volume(struct archive_read *a, struct tar *tar,
|
|
860
|
-
struct archive_entry *entry, const void *h)
|
|
1119
|
+
struct archive_entry *entry, const void *h, size_t *unconsumed)
|
|
861
1120
|
{
|
|
862
1121
|
(void)h;
|
|
863
1122
|
|
|
864
1123
|
/* Just skip this and read the next header. */
|
|
865
|
-
return (tar_read_header(a, tar, entry));
|
|
1124
|
+
return (tar_read_header(a, tar, entry, unconsumed));
|
|
866
1125
|
}
|
|
867
1126
|
|
|
868
1127
|
/*
|
|
@@ -870,9 +1129,9 @@ header_volume(struct archive_read *a, struct tar *tar,
|
|
|
870
1129
|
*/
|
|
871
1130
|
static int
|
|
872
1131
|
read_body_to_string(struct archive_read *a, struct tar *tar,
|
|
873
|
-
struct archive_string *as, const void *h)
|
|
1132
|
+
struct archive_string *as, const void *h, size_t *unconsumed)
|
|
874
1133
|
{
|
|
875
|
-
|
|
1134
|
+
int64_t size;
|
|
876
1135
|
const struct archive_entry_header_ustar *header;
|
|
877
1136
|
const void *src;
|
|
878
1137
|
|
|
@@ -886,20 +1145,24 @@ read_body_to_string(struct archive_read *a, struct tar *tar,
|
|
|
886
1145
|
}
|
|
887
1146
|
|
|
888
1147
|
/* Fail if we can't make our buffer big enough. */
|
|
889
|
-
if (archive_string_ensure(as, size+1) == NULL) {
|
|
1148
|
+
if (archive_string_ensure(as, (size_t)size+1) == NULL) {
|
|
890
1149
|
archive_set_error(&a->archive, ENOMEM,
|
|
891
1150
|
"No memory");
|
|
892
1151
|
return (ARCHIVE_FATAL);
|
|
893
1152
|
}
|
|
894
1153
|
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
1154
|
+
tar_flush_unconsumed(a, unconsumed);
|
|
1155
|
+
|
|
1156
|
+
/* Read the body into the string. */
|
|
1157
|
+
*unconsumed = (size_t)((size + 511) & ~ 511);
|
|
1158
|
+
src = __archive_read_ahead(a, *unconsumed, NULL);
|
|
1159
|
+
if (src == NULL) {
|
|
1160
|
+
*unconsumed = 0;
|
|
899
1161
|
return (ARCHIVE_FATAL);
|
|
900
|
-
|
|
901
|
-
|
|
1162
|
+
}
|
|
1163
|
+
memcpy(as->s, src, (size_t)size);
|
|
902
1164
|
as->s[size] = '\0';
|
|
1165
|
+
as->length = (size_t)size;
|
|
903
1166
|
return (ARCHIVE_OK);
|
|
904
1167
|
}
|
|
905
1168
|
|
|
@@ -919,21 +1182,34 @@ header_common(struct archive_read *a, struct tar *tar,
|
|
|
919
1182
|
{
|
|
920
1183
|
const struct archive_entry_header_ustar *header;
|
|
921
1184
|
char tartype;
|
|
922
|
-
|
|
923
|
-
(void)a; /* UNUSED */
|
|
1185
|
+
int err = ARCHIVE_OK;
|
|
924
1186
|
|
|
925
1187
|
header = (const struct archive_entry_header_ustar *)h;
|
|
926
1188
|
if (header->linkname[0])
|
|
927
|
-
archive_strncpy(&(tar->entry_linkpath),
|
|
928
|
-
sizeof(header->linkname));
|
|
1189
|
+
archive_strncpy(&(tar->entry_linkpath),
|
|
1190
|
+
header->linkname, sizeof(header->linkname));
|
|
929
1191
|
else
|
|
930
1192
|
archive_string_empty(&(tar->entry_linkpath));
|
|
931
1193
|
|
|
932
1194
|
/* Parse out the numeric fields (all are octal) */
|
|
933
|
-
archive_entry_set_mode(entry,
|
|
1195
|
+
archive_entry_set_mode(entry,
|
|
1196
|
+
(mode_t)tar_atol(header->mode, sizeof(header->mode)));
|
|
934
1197
|
archive_entry_set_uid(entry, tar_atol(header->uid, sizeof(header->uid)));
|
|
935
1198
|
archive_entry_set_gid(entry, tar_atol(header->gid, sizeof(header->gid)));
|
|
936
1199
|
tar->entry_bytes_remaining = tar_atol(header->size, sizeof(header->size));
|
|
1200
|
+
if (tar->entry_bytes_remaining < 0) {
|
|
1201
|
+
tar->entry_bytes_remaining = 0;
|
|
1202
|
+
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
|
1203
|
+
"Tar entry has negative size");
|
|
1204
|
+
return (ARCHIVE_FATAL);
|
|
1205
|
+
}
|
|
1206
|
+
if (tar->entry_bytes_remaining == INT64_MAX) {
|
|
1207
|
+
/* Note: tar_atol returns INT64_MAX on overflow */
|
|
1208
|
+
tar->entry_bytes_remaining = 0;
|
|
1209
|
+
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
|
1210
|
+
"Tar entry size overflow");
|
|
1211
|
+
return (ARCHIVE_FATAL);
|
|
1212
|
+
}
|
|
937
1213
|
tar->realsize = tar->entry_bytes_remaining;
|
|
938
1214
|
archive_entry_set_size(entry, tar->entry_bytes_remaining);
|
|
939
1215
|
archive_entry_set_mtime(entry, tar_atol(header->mtime, sizeof(header->mtime)), 0);
|
|
@@ -943,7 +1219,13 @@ header_common(struct archive_read *a, struct tar *tar,
|
|
|
943
1219
|
|
|
944
1220
|
switch (tartype) {
|
|
945
1221
|
case '1': /* Hard link */
|
|
946
|
-
|
|
1222
|
+
if (archive_entry_copy_hardlink_l(entry, tar->entry_linkpath.s,
|
|
1223
|
+
archive_strlen(&(tar->entry_linkpath)), tar->sconv) != 0) {
|
|
1224
|
+
err = set_conversion_failed_error(a, tar->sconv,
|
|
1225
|
+
"Linkname");
|
|
1226
|
+
if (err == ARCHIVE_FATAL)
|
|
1227
|
+
return (err);
|
|
1228
|
+
}
|
|
947
1229
|
/*
|
|
948
1230
|
* The following may seem odd, but: Technically, tar
|
|
949
1231
|
* does not store the file type for a "hard link"
|
|
@@ -980,7 +1262,7 @@ header_common(struct archive_read *a, struct tar *tar,
|
|
|
980
1262
|
/* Old-style or GNU tar: we must ignore the size. */
|
|
981
1263
|
archive_entry_set_size(entry, 0);
|
|
982
1264
|
tar->entry_bytes_remaining = 0;
|
|
983
|
-
} else if (archive_read_format_tar_bid(a) > 50) {
|
|
1265
|
+
} else if (archive_read_format_tar_bid(a, 50) > 50) {
|
|
984
1266
|
/*
|
|
985
1267
|
* We don't know if it's pax: If the bid
|
|
986
1268
|
* function sees a valid ustar header
|
|
@@ -1005,7 +1287,13 @@ header_common(struct archive_read *a, struct tar *tar,
|
|
|
1005
1287
|
archive_entry_set_filetype(entry, AE_IFLNK);
|
|
1006
1288
|
archive_entry_set_size(entry, 0);
|
|
1007
1289
|
tar->entry_bytes_remaining = 0;
|
|
1008
|
-
|
|
1290
|
+
if (archive_entry_copy_symlink_l(entry, tar->entry_linkpath.s,
|
|
1291
|
+
archive_strlen(&(tar->entry_linkpath)), tar->sconv) != 0) {
|
|
1292
|
+
err = set_conversion_failed_error(a, tar->sconv,
|
|
1293
|
+
"Linkname");
|
|
1294
|
+
if (err == ARCHIVE_FATAL)
|
|
1295
|
+
return (err);
|
|
1296
|
+
}
|
|
1009
1297
|
break;
|
|
1010
1298
|
case '3': /* Character device */
|
|
1011
1299
|
archive_entry_set_filetype(entry, AE_IFCHR);
|
|
@@ -1055,6 +1343,14 @@ header_common(struct archive_read *a, struct tar *tar,
|
|
|
1055
1343
|
* sparse information in the extended area.
|
|
1056
1344
|
*/
|
|
1057
1345
|
/* FALLTHROUGH */
|
|
1346
|
+
case '0':
|
|
1347
|
+
/*
|
|
1348
|
+
* Enable sparse file "read" support only for regular
|
|
1349
|
+
* files and explicit GNU sparse files. However, we
|
|
1350
|
+
* don't allow non-standard file types to be sparse.
|
|
1351
|
+
*/
|
|
1352
|
+
tar->sparse_allowed = 1;
|
|
1353
|
+
/* FALLTHROUGH */
|
|
1058
1354
|
default: /* Regular file and non-standard types */
|
|
1059
1355
|
/*
|
|
1060
1356
|
* Per POSIX: non-recognized types should always be
|
|
@@ -1063,7 +1359,7 @@ header_common(struct archive_read *a, struct tar *tar,
|
|
|
1063
1359
|
archive_entry_set_filetype(entry, AE_IFREG);
|
|
1064
1360
|
break;
|
|
1065
1361
|
}
|
|
1066
|
-
return (
|
|
1362
|
+
return (err);
|
|
1067
1363
|
}
|
|
1068
1364
|
|
|
1069
1365
|
/*
|
|
@@ -1074,17 +1370,101 @@ header_old_tar(struct archive_read *a, struct tar *tar,
|
|
|
1074
1370
|
struct archive_entry *entry, const void *h)
|
|
1075
1371
|
{
|
|
1076
1372
|
const struct archive_entry_header_ustar *header;
|
|
1373
|
+
int err = ARCHIVE_OK, err2;
|
|
1077
1374
|
|
|
1078
1375
|
/* Copy filename over (to ensure null termination). */
|
|
1079
1376
|
header = (const struct archive_entry_header_ustar *)h;
|
|
1080
|
-
|
|
1081
|
-
|
|
1377
|
+
if (archive_entry_copy_pathname_l(entry,
|
|
1378
|
+
header->name, sizeof(header->name), tar->sconv) != 0) {
|
|
1379
|
+
err = set_conversion_failed_error(a, tar->sconv, "Pathname");
|
|
1380
|
+
if (err == ARCHIVE_FATAL)
|
|
1381
|
+
return (err);
|
|
1382
|
+
}
|
|
1082
1383
|
|
|
1083
1384
|
/* Grab rest of common fields */
|
|
1084
|
-
header_common(a, tar, entry, h);
|
|
1385
|
+
err2 = header_common(a, tar, entry, h);
|
|
1386
|
+
if (err > err2)
|
|
1387
|
+
err = err2;
|
|
1085
1388
|
|
|
1086
1389
|
tar->entry_padding = 0x1ff & (-tar->entry_bytes_remaining);
|
|
1087
|
-
return (
|
|
1390
|
+
return (err);
|
|
1391
|
+
}
|
|
1392
|
+
|
|
1393
|
+
/*
|
|
1394
|
+
* Read a Mac AppleDouble-encoded blob of file metadata,
|
|
1395
|
+
* if there is one.
|
|
1396
|
+
*/
|
|
1397
|
+
static int
|
|
1398
|
+
read_mac_metadata_blob(struct archive_read *a, struct tar *tar,
|
|
1399
|
+
struct archive_entry *entry, const void *h, size_t *unconsumed)
|
|
1400
|
+
{
|
|
1401
|
+
int64_t size;
|
|
1402
|
+
size_t msize;
|
|
1403
|
+
const void *data;
|
|
1404
|
+
const char *p, *name;
|
|
1405
|
+
const wchar_t *wp, *wname;
|
|
1406
|
+
|
|
1407
|
+
(void)h; /* UNUSED */
|
|
1408
|
+
|
|
1409
|
+
wname = wp = archive_entry_pathname_w(entry);
|
|
1410
|
+
if (wp != NULL) {
|
|
1411
|
+
/* Find the last path element. */
|
|
1412
|
+
for (; *wp != L'\0'; ++wp) {
|
|
1413
|
+
if (wp[0] == '/' && wp[1] != L'\0')
|
|
1414
|
+
wname = wp + 1;
|
|
1415
|
+
}
|
|
1416
|
+
/*
|
|
1417
|
+
* If last path element starts with "._", then
|
|
1418
|
+
* this is a Mac extension.
|
|
1419
|
+
*/
|
|
1420
|
+
if (wname[0] != L'.' || wname[1] != L'_' || wname[2] == L'\0')
|
|
1421
|
+
return ARCHIVE_OK;
|
|
1422
|
+
} else {
|
|
1423
|
+
/* Find the last path element. */
|
|
1424
|
+
name = p = archive_entry_pathname(entry);
|
|
1425
|
+
if (p == NULL)
|
|
1426
|
+
return (ARCHIVE_FAILED);
|
|
1427
|
+
for (; *p != '\0'; ++p) {
|
|
1428
|
+
if (p[0] == '/' && p[1] != '\0')
|
|
1429
|
+
name = p + 1;
|
|
1430
|
+
}
|
|
1431
|
+
/*
|
|
1432
|
+
* If last path element starts with "._", then
|
|
1433
|
+
* this is a Mac extension.
|
|
1434
|
+
*/
|
|
1435
|
+
if (name[0] != '.' || name[1] != '_' || name[2] == '\0')
|
|
1436
|
+
return ARCHIVE_OK;
|
|
1437
|
+
}
|
|
1438
|
+
|
|
1439
|
+
/* Read the body as a Mac OS metadata blob. */
|
|
1440
|
+
size = archive_entry_size(entry);
|
|
1441
|
+
msize = (size_t)size;
|
|
1442
|
+
if (size < 0 || (uintmax_t)msize != (uintmax_t)size) {
|
|
1443
|
+
*unconsumed = 0;
|
|
1444
|
+
return (ARCHIVE_FATAL);
|
|
1445
|
+
}
|
|
1446
|
+
|
|
1447
|
+
/*
|
|
1448
|
+
* TODO: Look beyond the body here to peek at the next header.
|
|
1449
|
+
* If it's a regular header (not an extension header)
|
|
1450
|
+
* that has the wrong name, just return the current
|
|
1451
|
+
* entry as-is, without consuming the body here.
|
|
1452
|
+
* That would reduce the risk of us mis-identifying
|
|
1453
|
+
* an ordinary file that just happened to have
|
|
1454
|
+
* a name starting with "._".
|
|
1455
|
+
*
|
|
1456
|
+
* Q: Is the above idea really possible? Even
|
|
1457
|
+
* when there are GNU or pax extension entries?
|
|
1458
|
+
*/
|
|
1459
|
+
data = __archive_read_ahead(a, msize, NULL);
|
|
1460
|
+
if (data == NULL) {
|
|
1461
|
+
*unconsumed = 0;
|
|
1462
|
+
return (ARCHIVE_FATAL);
|
|
1463
|
+
}
|
|
1464
|
+
archive_entry_copy_mac_metadata(entry, data, msize);
|
|
1465
|
+
*unconsumed = (msize + 511) & ~ 511;
|
|
1466
|
+
tar_flush_unconsumed(a, unconsumed);
|
|
1467
|
+
return (tar_read_header(a, tar, entry, unconsumed));
|
|
1088
1468
|
}
|
|
1089
1469
|
|
|
1090
1470
|
/*
|
|
@@ -1092,29 +1472,29 @@ header_old_tar(struct archive_read *a, struct tar *tar,
|
|
|
1092
1472
|
*/
|
|
1093
1473
|
static int
|
|
1094
1474
|
header_pax_global(struct archive_read *a, struct tar *tar,
|
|
1095
|
-
struct archive_entry *entry, const void *h)
|
|
1475
|
+
struct archive_entry *entry, const void *h, size_t *unconsumed)
|
|
1096
1476
|
{
|
|
1097
1477
|
int err;
|
|
1098
1478
|
|
|
1099
|
-
err = read_body_to_string(a, tar, &(tar->pax_global), h);
|
|
1479
|
+
err = read_body_to_string(a, tar, &(tar->pax_global), h, unconsumed);
|
|
1100
1480
|
if (err != ARCHIVE_OK)
|
|
1101
1481
|
return (err);
|
|
1102
|
-
err = tar_read_header(a, tar, entry);
|
|
1482
|
+
err = tar_read_header(a, tar, entry, unconsumed);
|
|
1103
1483
|
return (err);
|
|
1104
1484
|
}
|
|
1105
1485
|
|
|
1106
1486
|
static int
|
|
1107
1487
|
header_pax_extensions(struct archive_read *a, struct tar *tar,
|
|
1108
|
-
struct archive_entry *entry, const void *h)
|
|
1488
|
+
struct archive_entry *entry, const void *h, size_t *unconsumed)
|
|
1109
1489
|
{
|
|
1110
1490
|
int err, err2;
|
|
1111
1491
|
|
|
1112
|
-
err = read_body_to_string(a, tar, &(tar->pax_header), h);
|
|
1492
|
+
err = read_body_to_string(a, tar, &(tar->pax_header), h, unconsumed);
|
|
1113
1493
|
if (err != ARCHIVE_OK)
|
|
1114
1494
|
return (err);
|
|
1115
1495
|
|
|
1116
1496
|
/* Parse the next header. */
|
|
1117
|
-
err = tar_read_header(a, tar, entry);
|
|
1497
|
+
err = tar_read_header(a, tar, entry, unconsumed);
|
|
1118
1498
|
if ((err != ARCHIVE_OK) && (err != ARCHIVE_WARN))
|
|
1119
1499
|
return (err);
|
|
1120
1500
|
|
|
@@ -1128,7 +1508,7 @@ header_pax_extensions(struct archive_read *a, struct tar *tar,
|
|
|
1128
1508
|
* and then skip any fields in the standard header that were
|
|
1129
1509
|
* defined in the pax header.
|
|
1130
1510
|
*/
|
|
1131
|
-
err2 = pax_header(a, tar, entry, tar->pax_header
|
|
1511
|
+
err2 = pax_header(a, tar, entry, &tar->pax_header);
|
|
1132
1512
|
err = err_combine(err, err2);
|
|
1133
1513
|
tar->entry_padding = 0x1ff & (-tar->entry_bytes_remaining);
|
|
1134
1514
|
return (err);
|
|
@@ -1145,6 +1525,7 @@ header_ustar(struct archive_read *a, struct tar *tar,
|
|
|
1145
1525
|
{
|
|
1146
1526
|
const struct archive_entry_header_ustar *header;
|
|
1147
1527
|
struct archive_string *as;
|
|
1528
|
+
int err = ARCHIVE_OK, r;
|
|
1148
1529
|
|
|
1149
1530
|
header = (const struct archive_entry_header_ustar *)h;
|
|
1150
1531
|
|
|
@@ -1155,34 +1536,49 @@ header_ustar(struct archive_read *a, struct tar *tar,
|
|
|
1155
1536
|
if (as->s[archive_strlen(as) - 1] != '/')
|
|
1156
1537
|
archive_strappend_char(as, '/');
|
|
1157
1538
|
archive_strncat(as, header->name, sizeof(header->name));
|
|
1158
|
-
} else
|
|
1539
|
+
} else {
|
|
1159
1540
|
archive_strncpy(as, header->name, sizeof(header->name));
|
|
1160
|
-
|
|
1161
|
-
|
|
1541
|
+
}
|
|
1542
|
+
if (archive_entry_copy_pathname_l(entry, as->s, archive_strlen(as),
|
|
1543
|
+
tar->sconv) != 0) {
|
|
1544
|
+
err = set_conversion_failed_error(a, tar->sconv, "Pathname");
|
|
1545
|
+
if (err == ARCHIVE_FATAL)
|
|
1546
|
+
return (err);
|
|
1547
|
+
}
|
|
1162
1548
|
|
|
1163
1549
|
/* Handle rest of common fields. */
|
|
1164
|
-
header_common(a, tar, entry, h);
|
|
1550
|
+
r = header_common(a, tar, entry, h);
|
|
1551
|
+
if (r == ARCHIVE_FATAL)
|
|
1552
|
+
return (r);
|
|
1553
|
+
if (r < err)
|
|
1554
|
+
err = r;
|
|
1165
1555
|
|
|
1166
1556
|
/* Handle POSIX ustar fields. */
|
|
1167
|
-
|
|
1168
|
-
sizeof(header->uname))
|
|
1169
|
-
|
|
1557
|
+
if (archive_entry_copy_uname_l(entry,
|
|
1558
|
+
header->uname, sizeof(header->uname), tar->sconv) != 0) {
|
|
1559
|
+
err = set_conversion_failed_error(a, tar->sconv, "Uname");
|
|
1560
|
+
if (err == ARCHIVE_FATAL)
|
|
1561
|
+
return (err);
|
|
1562
|
+
}
|
|
1170
1563
|
|
|
1171
|
-
|
|
1172
|
-
sizeof(header->gname))
|
|
1173
|
-
|
|
1564
|
+
if (archive_entry_copy_gname_l(entry,
|
|
1565
|
+
header->gname, sizeof(header->gname), tar->sconv) != 0) {
|
|
1566
|
+
err = set_conversion_failed_error(a, tar->sconv, "Gname");
|
|
1567
|
+
if (err == ARCHIVE_FATAL)
|
|
1568
|
+
return (err);
|
|
1569
|
+
}
|
|
1174
1570
|
|
|
1175
1571
|
/* Parse out device numbers only for char and block specials. */
|
|
1176
1572
|
if (header->typeflag[0] == '3' || header->typeflag[0] == '4') {
|
|
1177
|
-
archive_entry_set_rdevmajor(entry,
|
|
1573
|
+
archive_entry_set_rdevmajor(entry, (dev_t)
|
|
1178
1574
|
tar_atol(header->rdevmajor, sizeof(header->rdevmajor)));
|
|
1179
|
-
archive_entry_set_rdevminor(entry,
|
|
1575
|
+
archive_entry_set_rdevminor(entry, (dev_t)
|
|
1180
1576
|
tar_atol(header->rdevminor, sizeof(header->rdevminor)));
|
|
1181
1577
|
}
|
|
1182
1578
|
|
|
1183
1579
|
tar->entry_padding = 0x1ff & (-tar->entry_bytes_remaining);
|
|
1184
1580
|
|
|
1185
|
-
return (
|
|
1581
|
+
return (err);
|
|
1186
1582
|
}
|
|
1187
1583
|
|
|
1188
1584
|
|
|
@@ -1193,14 +1589,17 @@ header_ustar(struct archive_read *a, struct tar *tar,
|
|
|
1193
1589
|
*/
|
|
1194
1590
|
static int
|
|
1195
1591
|
pax_header(struct archive_read *a, struct tar *tar,
|
|
1196
|
-
struct archive_entry *entry,
|
|
1592
|
+
struct archive_entry *entry, struct archive_string *in_as)
|
|
1197
1593
|
{
|
|
1198
|
-
size_t attr_length, l, line_length;
|
|
1594
|
+
size_t attr_length, l, line_length, value_length;
|
|
1199
1595
|
char *p;
|
|
1200
1596
|
char *key, *value;
|
|
1597
|
+
struct archive_string *as;
|
|
1598
|
+
struct archive_string_conv *sconv;
|
|
1201
1599
|
int err, err2;
|
|
1600
|
+
char *attr = in_as->s;
|
|
1202
1601
|
|
|
1203
|
-
attr_length =
|
|
1602
|
+
attr_length = in_as->length;
|
|
1204
1603
|
tar->pax_hdrcharset_binary = 0;
|
|
1205
1604
|
archive_string_empty(&(tar->entry_gname));
|
|
1206
1605
|
archive_string_empty(&(tar->entry_linkpath));
|
|
@@ -1265,43 +1664,61 @@ pax_header(struct archive_read *a, struct tar *tar,
|
|
|
1265
1664
|
}
|
|
1266
1665
|
*p = '\0';
|
|
1267
1666
|
|
|
1268
|
-
/* Identify null-terminated 'value' portion. */
|
|
1269
1667
|
value = p + 1;
|
|
1270
1668
|
|
|
1669
|
+
/* Some values may be binary data */
|
|
1670
|
+
value_length = attr + line_length - 1 - value;
|
|
1671
|
+
|
|
1271
1672
|
/* Identify this attribute and set it in the entry. */
|
|
1272
|
-
err2 = pax_attribute(tar, entry, key, value);
|
|
1673
|
+
err2 = pax_attribute(a, tar, entry, key, value, value_length);
|
|
1674
|
+
if (err2 == ARCHIVE_FATAL)
|
|
1675
|
+
return (err2);
|
|
1273
1676
|
err = err_combine(err, err2);
|
|
1274
1677
|
|
|
1275
1678
|
/* Skip to next line */
|
|
1276
1679
|
attr += line_length;
|
|
1277
1680
|
attr_length -= line_length;
|
|
1278
1681
|
}
|
|
1682
|
+
|
|
1683
|
+
/*
|
|
1684
|
+
* PAX format uses UTF-8 as default charset for its metadata
|
|
1685
|
+
* unless hdrcharset=BINARY is present in its header.
|
|
1686
|
+
* We apply the charset specified by the hdrcharset option only
|
|
1687
|
+
* when the hdrcharset attribute(in PAX header) is BINARY because
|
|
1688
|
+
* we respect the charset described in PAX header and BINARY also
|
|
1689
|
+
* means that metadata(filename,uname and gname) character-set
|
|
1690
|
+
* is unknown.
|
|
1691
|
+
*/
|
|
1692
|
+
if (tar->pax_hdrcharset_binary)
|
|
1693
|
+
sconv = tar->opt_sconv;
|
|
1694
|
+
else {
|
|
1695
|
+
sconv = archive_string_conversion_from_charset(
|
|
1696
|
+
&(a->archive), "UTF-8", 1);
|
|
1697
|
+
if (sconv == NULL)
|
|
1698
|
+
return (ARCHIVE_FATAL);
|
|
1699
|
+
if (tar->compat_2x)
|
|
1700
|
+
archive_string_conversion_set_opt(sconv,
|
|
1701
|
+
SCONV_SET_OPT_UTF8_LIBARCHIVE2X);
|
|
1702
|
+
}
|
|
1703
|
+
|
|
1279
1704
|
if (archive_strlen(&(tar->entry_gname)) > 0) {
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
ARCHIVE_ERRNO_FILE_FORMAT,
|
|
1288
|
-
"Gname in pax header can't "
|
|
1289
|
-
"be converted to current locale.");
|
|
1290
|
-
}
|
|
1705
|
+
if (archive_entry_copy_gname_l(entry, tar->entry_gname.s,
|
|
1706
|
+
archive_strlen(&(tar->entry_gname)), sconv) != 0) {
|
|
1707
|
+
err = set_conversion_failed_error(a, sconv, "Gname");
|
|
1708
|
+
if (err == ARCHIVE_FATAL)
|
|
1709
|
+
return (err);
|
|
1710
|
+
/* Use a converted an original name. */
|
|
1711
|
+
archive_entry_copy_gname(entry, tar->entry_gname.s);
|
|
1291
1712
|
}
|
|
1292
1713
|
}
|
|
1293
1714
|
if (archive_strlen(&(tar->entry_linkpath)) > 0) {
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
ARCHIVE_ERRNO_FILE_FORMAT,
|
|
1302
|
-
"Linkname in pax header can't "
|
|
1303
|
-
"be converted to current locale.");
|
|
1304
|
-
}
|
|
1715
|
+
if (archive_entry_copy_link_l(entry, tar->entry_linkpath.s,
|
|
1716
|
+
archive_strlen(&(tar->entry_linkpath)), sconv) != 0) {
|
|
1717
|
+
err = set_conversion_failed_error(a, sconv, "Linkname");
|
|
1718
|
+
if (err == ARCHIVE_FATAL)
|
|
1719
|
+
return (err);
|
|
1720
|
+
/* Use a converted an original name. */
|
|
1721
|
+
archive_entry_copy_link(entry, tar->entry_linkpath.s);
|
|
1305
1722
|
}
|
|
1306
1723
|
}
|
|
1307
1724
|
/*
|
|
@@ -1313,36 +1730,29 @@ pax_header(struct archive_read *a, struct tar *tar,
|
|
|
1313
1730
|
* we find and figure it all out afterwards. This is the
|
|
1314
1731
|
* figuring out part.
|
|
1315
1732
|
*/
|
|
1316
|
-
|
|
1733
|
+
as = NULL;
|
|
1317
1734
|
if (archive_strlen(&(tar->entry_pathname_override)) > 0)
|
|
1318
|
-
|
|
1735
|
+
as = &(tar->entry_pathname_override);
|
|
1319
1736
|
else if (archive_strlen(&(tar->entry_pathname)) > 0)
|
|
1320
|
-
|
|
1321
|
-
if (
|
|
1322
|
-
if (
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
if (
|
|
1326
|
-
err
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
"Pathname in pax header can't be "
|
|
1330
|
-
"converted to current locale.");
|
|
1331
|
-
}
|
|
1737
|
+
as = &(tar->entry_pathname);
|
|
1738
|
+
if (as != NULL) {
|
|
1739
|
+
if (archive_entry_copy_pathname_l(entry, as->s,
|
|
1740
|
+
archive_strlen(as), sconv) != 0) {
|
|
1741
|
+
err = set_conversion_failed_error(a, sconv, "Pathname");
|
|
1742
|
+
if (err == ARCHIVE_FATAL)
|
|
1743
|
+
return (err);
|
|
1744
|
+
/* Use a converted an original name. */
|
|
1745
|
+
archive_entry_copy_pathname(entry, as->s);
|
|
1332
1746
|
}
|
|
1333
1747
|
}
|
|
1334
1748
|
if (archive_strlen(&(tar->entry_uname)) > 0) {
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
ARCHIVE_ERRNO_FILE_FORMAT,
|
|
1343
|
-
"Uname in pax header can't "
|
|
1344
|
-
"be converted to current locale.");
|
|
1345
|
-
}
|
|
1749
|
+
if (archive_entry_copy_uname_l(entry, tar->entry_uname.s,
|
|
1750
|
+
archive_strlen(&(tar->entry_uname)), sconv) != 0) {
|
|
1751
|
+
err = set_conversion_failed_error(a, sconv, "Uname");
|
|
1752
|
+
if (err == ARCHIVE_FATAL)
|
|
1753
|
+
return (err);
|
|
1754
|
+
/* Use a converted an original name. */
|
|
1755
|
+
archive_entry_copy_uname(entry, tar->entry_uname.s);
|
|
1346
1756
|
}
|
|
1347
1757
|
}
|
|
1348
1758
|
return (err);
|
|
@@ -1350,13 +1760,13 @@ pax_header(struct archive_read *a, struct tar *tar,
|
|
|
1350
1760
|
|
|
1351
1761
|
static int
|
|
1352
1762
|
pax_attribute_xattr(struct archive_entry *entry,
|
|
1353
|
-
char *name, char *value)
|
|
1763
|
+
const char *name, const char *value)
|
|
1354
1764
|
{
|
|
1355
1765
|
char *name_decoded;
|
|
1356
1766
|
void *value_decoded;
|
|
1357
1767
|
size_t value_len;
|
|
1358
1768
|
|
|
1359
|
-
if (strlen(name) < 18 || (
|
|
1769
|
+
if (strlen(name) < 18 || (memcmp(name, "LIBARCHIVE.xattr.", 17)) != 0)
|
|
1360
1770
|
return 3;
|
|
1361
1771
|
|
|
1362
1772
|
name += 17;
|
|
@@ -1381,6 +1791,76 @@ pax_attribute_xattr(struct archive_entry *entry,
|
|
|
1381
1791
|
return 0;
|
|
1382
1792
|
}
|
|
1383
1793
|
|
|
1794
|
+
static int
|
|
1795
|
+
pax_attribute_schily_xattr(struct archive_entry *entry,
|
|
1796
|
+
const char *name, const char *value, size_t value_length)
|
|
1797
|
+
{
|
|
1798
|
+
if (strlen(name) < 14 || (memcmp(name, "SCHILY.xattr.", 13)) != 0)
|
|
1799
|
+
return 1;
|
|
1800
|
+
|
|
1801
|
+
name += 13;
|
|
1802
|
+
|
|
1803
|
+
archive_entry_xattr_add_entry(entry, name, value, value_length);
|
|
1804
|
+
|
|
1805
|
+
return 0;
|
|
1806
|
+
}
|
|
1807
|
+
|
|
1808
|
+
static int
|
|
1809
|
+
pax_attribute_rht_security_selinux(struct archive_entry *entry,
|
|
1810
|
+
const char *value, size_t value_length)
|
|
1811
|
+
{
|
|
1812
|
+
archive_entry_xattr_add_entry(entry, "security.selinux",
|
|
1813
|
+
value, value_length);
|
|
1814
|
+
|
|
1815
|
+
return 0;
|
|
1816
|
+
}
|
|
1817
|
+
|
|
1818
|
+
static int
|
|
1819
|
+
pax_attribute_acl(struct archive_read *a, struct tar *tar,
|
|
1820
|
+
struct archive_entry *entry, const char *value, int type)
|
|
1821
|
+
{
|
|
1822
|
+
int r;
|
|
1823
|
+
const char* errstr;
|
|
1824
|
+
|
|
1825
|
+
switch (type) {
|
|
1826
|
+
case ARCHIVE_ENTRY_ACL_TYPE_ACCESS:
|
|
1827
|
+
errstr = "SCHILY.acl.access";
|
|
1828
|
+
break;
|
|
1829
|
+
case ARCHIVE_ENTRY_ACL_TYPE_DEFAULT:
|
|
1830
|
+
errstr = "SCHILY.acl.default";
|
|
1831
|
+
break;
|
|
1832
|
+
case ARCHIVE_ENTRY_ACL_TYPE_NFS4:
|
|
1833
|
+
errstr = "SCHILY.acl.ace";
|
|
1834
|
+
break;
|
|
1835
|
+
default:
|
|
1836
|
+
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
|
1837
|
+
"Unknown ACL type: %d", type);
|
|
1838
|
+
return(ARCHIVE_FATAL);
|
|
1839
|
+
}
|
|
1840
|
+
|
|
1841
|
+
if (tar->sconv_acl == NULL) {
|
|
1842
|
+
tar->sconv_acl =
|
|
1843
|
+
archive_string_conversion_from_charset(
|
|
1844
|
+
&(a->archive), "UTF-8", 1);
|
|
1845
|
+
if (tar->sconv_acl == NULL)
|
|
1846
|
+
return (ARCHIVE_FATAL);
|
|
1847
|
+
}
|
|
1848
|
+
|
|
1849
|
+
r = archive_acl_from_text_l(archive_entry_acl(entry), value, type,
|
|
1850
|
+
tar->sconv_acl);
|
|
1851
|
+
if (r != ARCHIVE_OK) {
|
|
1852
|
+
if (r == ARCHIVE_FATAL) {
|
|
1853
|
+
archive_set_error(&a->archive, ENOMEM,
|
|
1854
|
+
"%s %s", "Can't allocate memory for ",
|
|
1855
|
+
errstr);
|
|
1856
|
+
return (r);
|
|
1857
|
+
}
|
|
1858
|
+
archive_set_error(&a->archive,
|
|
1859
|
+
ARCHIVE_ERRNO_MISC, "%s %s", "Parse error: ", errstr);
|
|
1860
|
+
}
|
|
1861
|
+
return (r);
|
|
1862
|
+
}
|
|
1863
|
+
|
|
1384
1864
|
/*
|
|
1385
1865
|
* Parse a single key=value attribute. key/value pointers are
|
|
1386
1866
|
* assumed to point into reasonably long-lived storage.
|
|
@@ -1395,15 +1875,26 @@ pax_attribute_xattr(struct archive_entry *entry,
|
|
|
1395
1875
|
* any of them look useful.
|
|
1396
1876
|
*/
|
|
1397
1877
|
static int
|
|
1398
|
-
pax_attribute(struct
|
|
1399
|
-
char *key, char *value)
|
|
1878
|
+
pax_attribute(struct archive_read *a, struct tar *tar,
|
|
1879
|
+
struct archive_entry *entry, const char *key, const char *value, size_t value_length)
|
|
1400
1880
|
{
|
|
1401
1881
|
int64_t s;
|
|
1402
1882
|
long n;
|
|
1403
|
-
|
|
1883
|
+
int err = ARCHIVE_OK, r;
|
|
1404
1884
|
|
|
1885
|
+
if (value == NULL)
|
|
1886
|
+
value = ""; /* Disable compiler warning; do not pass
|
|
1887
|
+
* NULL pointer to strlen(). */
|
|
1405
1888
|
switch (key[0]) {
|
|
1406
1889
|
case 'G':
|
|
1890
|
+
/* Reject GNU.sparse.* headers on non-regular files. */
|
|
1891
|
+
if (strncmp(key, "GNU.sparse", 10) == 0 &&
|
|
1892
|
+
!tar->sparse_allowed) {
|
|
1893
|
+
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
|
1894
|
+
"Non-regular file cannot be sparse");
|
|
1895
|
+
return (ARCHIVE_FATAL);
|
|
1896
|
+
}
|
|
1897
|
+
|
|
1407
1898
|
/* GNU "0.0" sparse pax format. */
|
|
1408
1899
|
if (strcmp(key, "GNU.sparse.numblocks") == 0) {
|
|
1409
1900
|
tar->sparse_offset = -1;
|
|
@@ -1414,17 +1905,21 @@ pax_attribute(struct tar *tar, struct archive_entry *entry,
|
|
|
1414
1905
|
if (strcmp(key, "GNU.sparse.offset") == 0) {
|
|
1415
1906
|
tar->sparse_offset = tar_atol10(value, strlen(value));
|
|
1416
1907
|
if (tar->sparse_numbytes != -1) {
|
|
1417
|
-
gnu_add_sparse_entry(tar,
|
|
1418
|
-
tar->sparse_offset, tar->sparse_numbytes)
|
|
1908
|
+
if (gnu_add_sparse_entry(a, tar,
|
|
1909
|
+
tar->sparse_offset, tar->sparse_numbytes)
|
|
1910
|
+
!= ARCHIVE_OK)
|
|
1911
|
+
return (ARCHIVE_FATAL);
|
|
1419
1912
|
tar->sparse_offset = -1;
|
|
1420
1913
|
tar->sparse_numbytes = -1;
|
|
1421
1914
|
}
|
|
1422
1915
|
}
|
|
1423
1916
|
if (strcmp(key, "GNU.sparse.numbytes") == 0) {
|
|
1424
1917
|
tar->sparse_numbytes = tar_atol10(value, strlen(value));
|
|
1425
|
-
if (tar->
|
|
1426
|
-
gnu_add_sparse_entry(tar,
|
|
1427
|
-
tar->sparse_offset, tar->sparse_numbytes)
|
|
1918
|
+
if (tar->sparse_offset != -1) {
|
|
1919
|
+
if (gnu_add_sparse_entry(a, tar,
|
|
1920
|
+
tar->sparse_offset, tar->sparse_numbytes)
|
|
1921
|
+
!= ARCHIVE_OK)
|
|
1922
|
+
return (ARCHIVE_FATAL);
|
|
1428
1923
|
tar->sparse_offset = -1;
|
|
1429
1924
|
tar->sparse_numbytes = -1;
|
|
1430
1925
|
}
|
|
@@ -1432,23 +1927,24 @@ pax_attribute(struct tar *tar, struct archive_entry *entry,
|
|
|
1432
1927
|
if (strcmp(key, "GNU.sparse.size") == 0) {
|
|
1433
1928
|
tar->realsize = tar_atol10(value, strlen(value));
|
|
1434
1929
|
archive_entry_set_size(entry, tar->realsize);
|
|
1930
|
+
tar->realsize_override = 1;
|
|
1435
1931
|
}
|
|
1436
1932
|
|
|
1437
1933
|
/* GNU "0.1" sparse pax format. */
|
|
1438
1934
|
if (strcmp(key, "GNU.sparse.map") == 0) {
|
|
1439
1935
|
tar->sparse_gnu_major = 0;
|
|
1440
1936
|
tar->sparse_gnu_minor = 1;
|
|
1441
|
-
if (gnu_sparse_01_parse(tar, value) != ARCHIVE_OK)
|
|
1937
|
+
if (gnu_sparse_01_parse(a, tar, value) != ARCHIVE_OK)
|
|
1442
1938
|
return (ARCHIVE_WARN);
|
|
1443
1939
|
}
|
|
1444
1940
|
|
|
1445
1941
|
/* GNU "1.0" sparse pax format */
|
|
1446
1942
|
if (strcmp(key, "GNU.sparse.major") == 0) {
|
|
1447
|
-
tar->sparse_gnu_major = tar_atol10(value, strlen(value));
|
|
1943
|
+
tar->sparse_gnu_major = (int)tar_atol10(value, strlen(value));
|
|
1448
1944
|
tar->sparse_gnu_pending = 1;
|
|
1449
1945
|
}
|
|
1450
1946
|
if (strcmp(key, "GNU.sparse.minor") == 0) {
|
|
1451
|
-
tar->sparse_gnu_minor = tar_atol10(value, strlen(value));
|
|
1947
|
+
tar->sparse_gnu_minor = (int)tar_atol10(value, strlen(value));
|
|
1452
1948
|
tar->sparse_gnu_pending = 1;
|
|
1453
1949
|
}
|
|
1454
1950
|
if (strcmp(key, "GNU.sparse.name") == 0) {
|
|
@@ -1463,105 +1959,141 @@ pax_attribute(struct tar *tar, struct archive_entry *entry,
|
|
|
1463
1959
|
if (strcmp(key, "GNU.sparse.realsize") == 0) {
|
|
1464
1960
|
tar->realsize = tar_atol10(value, strlen(value));
|
|
1465
1961
|
archive_entry_set_size(entry, tar->realsize);
|
|
1962
|
+
tar->realsize_override = 1;
|
|
1466
1963
|
}
|
|
1467
1964
|
break;
|
|
1468
1965
|
case 'L':
|
|
1469
1966
|
/* Our extensions */
|
|
1470
1967
|
/* TODO: Handle arbitrary extended attributes... */
|
|
1471
1968
|
/*
|
|
1472
|
-
if (strcmp(key, "LIBARCHIVE.xxxxxxx")==0)
|
|
1969
|
+
if (strcmp(key, "LIBARCHIVE.xxxxxxx") == 0)
|
|
1473
1970
|
archive_entry_set_xxxxxx(entry, value);
|
|
1474
1971
|
*/
|
|
1475
|
-
if (strcmp(key, "LIBARCHIVE.creationtime")==0) {
|
|
1972
|
+
if (strcmp(key, "LIBARCHIVE.creationtime") == 0) {
|
|
1476
1973
|
pax_time(value, &s, &n);
|
|
1477
1974
|
archive_entry_set_birthtime(entry, s, n);
|
|
1478
1975
|
}
|
|
1479
|
-
if (
|
|
1976
|
+
if (strcmp(key, "LIBARCHIVE.symlinktype") == 0) {
|
|
1977
|
+
if (strcmp(value, "file") == 0) {
|
|
1978
|
+
archive_entry_set_symlink_type(entry,
|
|
1979
|
+
AE_SYMLINK_TYPE_FILE);
|
|
1980
|
+
} else if (strcmp(value, "dir") == 0) {
|
|
1981
|
+
archive_entry_set_symlink_type(entry,
|
|
1982
|
+
AE_SYMLINK_TYPE_DIRECTORY);
|
|
1983
|
+
}
|
|
1984
|
+
}
|
|
1985
|
+
if (memcmp(key, "LIBARCHIVE.xattr.", 17) == 0)
|
|
1480
1986
|
pax_attribute_xattr(entry, key, value);
|
|
1481
1987
|
break;
|
|
1988
|
+
case 'R':
|
|
1989
|
+
/* GNU tar uses RHT.security header to store SELinux xattrs
|
|
1990
|
+
* SCHILY.xattr.security.selinux == RHT.security.selinux */
|
|
1991
|
+
if (strcmp(key, "RHT.security.selinux") == 0) {
|
|
1992
|
+
pax_attribute_rht_security_selinux(entry, value,
|
|
1993
|
+
value_length);
|
|
1994
|
+
}
|
|
1995
|
+
break;
|
|
1482
1996
|
case 'S':
|
|
1483
1997
|
/* We support some keys used by the "star" archiver */
|
|
1484
|
-
if (strcmp(key, "SCHILY.acl.access")==0) {
|
|
1485
|
-
|
|
1486
|
-
/* TODO: if (wp == NULL) */
|
|
1487
|
-
__archive_entry_acl_parse_w(entry, wp,
|
|
1998
|
+
if (strcmp(key, "SCHILY.acl.access") == 0) {
|
|
1999
|
+
r = pax_attribute_acl(a, tar, entry, value,
|
|
1488
2000
|
ARCHIVE_ENTRY_ACL_TYPE_ACCESS);
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
2001
|
+
if (r == ARCHIVE_FATAL)
|
|
2002
|
+
return (r);
|
|
2003
|
+
} else if (strcmp(key, "SCHILY.acl.default") == 0) {
|
|
2004
|
+
r = pax_attribute_acl(a, tar, entry, value,
|
|
1493
2005
|
ARCHIVE_ENTRY_ACL_TYPE_DEFAULT);
|
|
1494
|
-
|
|
2006
|
+
if (r == ARCHIVE_FATAL)
|
|
2007
|
+
return (r);
|
|
2008
|
+
} else if (strcmp(key, "SCHILY.acl.ace") == 0) {
|
|
2009
|
+
r = pax_attribute_acl(a, tar, entry, value,
|
|
2010
|
+
ARCHIVE_ENTRY_ACL_TYPE_NFS4);
|
|
2011
|
+
if (r == ARCHIVE_FATAL)
|
|
2012
|
+
return (r);
|
|
2013
|
+
} else if (strcmp(key, "SCHILY.devmajor") == 0) {
|
|
1495
2014
|
archive_entry_set_rdevmajor(entry,
|
|
1496
|
-
tar_atol10(value, strlen(value)));
|
|
1497
|
-
} else if (strcmp(key, "SCHILY.devminor")==0) {
|
|
2015
|
+
(dev_t)tar_atol10(value, strlen(value)));
|
|
2016
|
+
} else if (strcmp(key, "SCHILY.devminor") == 0) {
|
|
1498
2017
|
archive_entry_set_rdevminor(entry,
|
|
1499
|
-
tar_atol10(value, strlen(value)));
|
|
1500
|
-
} else if (strcmp(key, "SCHILY.fflags")==0) {
|
|
2018
|
+
(dev_t)tar_atol10(value, strlen(value)));
|
|
2019
|
+
} else if (strcmp(key, "SCHILY.fflags") == 0) {
|
|
1501
2020
|
archive_entry_copy_fflags_text(entry, value);
|
|
1502
|
-
} else if (strcmp(key, "SCHILY.dev")==0) {
|
|
2021
|
+
} else if (strcmp(key, "SCHILY.dev") == 0) {
|
|
1503
2022
|
archive_entry_set_dev(entry,
|
|
1504
|
-
tar_atol10(value, strlen(value)));
|
|
1505
|
-
} else if (strcmp(key, "SCHILY.ino")==0) {
|
|
2023
|
+
(dev_t)tar_atol10(value, strlen(value)));
|
|
2024
|
+
} else if (strcmp(key, "SCHILY.ino") == 0) {
|
|
1506
2025
|
archive_entry_set_ino(entry,
|
|
1507
2026
|
tar_atol10(value, strlen(value)));
|
|
1508
|
-
} else if (strcmp(key, "SCHILY.nlink")==0) {
|
|
1509
|
-
archive_entry_set_nlink(entry,
|
|
2027
|
+
} else if (strcmp(key, "SCHILY.nlink") == 0) {
|
|
2028
|
+
archive_entry_set_nlink(entry, (unsigned)
|
|
1510
2029
|
tar_atol10(value, strlen(value)));
|
|
1511
|
-
} else if (strcmp(key, "SCHILY.realsize")==0) {
|
|
2030
|
+
} else if (strcmp(key, "SCHILY.realsize") == 0) {
|
|
1512
2031
|
tar->realsize = tar_atol10(value, strlen(value));
|
|
2032
|
+
tar->realsize_override = 1;
|
|
1513
2033
|
archive_entry_set_size(entry, tar->realsize);
|
|
2034
|
+
} else if (strncmp(key, "SCHILY.xattr.", 13) == 0) {
|
|
2035
|
+
pax_attribute_schily_xattr(entry, key, value,
|
|
2036
|
+
value_length);
|
|
2037
|
+
} else if (strcmp(key, "SUN.holesdata") == 0) {
|
|
2038
|
+
/* A Solaris extension for sparse. */
|
|
2039
|
+
r = solaris_sparse_parse(a, tar, entry, value);
|
|
2040
|
+
if (r < err) {
|
|
2041
|
+
if (r == ARCHIVE_FATAL)
|
|
2042
|
+
return (r);
|
|
2043
|
+
err = r;
|
|
2044
|
+
archive_set_error(&a->archive,
|
|
2045
|
+
ARCHIVE_ERRNO_MISC,
|
|
2046
|
+
"Parse error: SUN.holesdata");
|
|
2047
|
+
}
|
|
1514
2048
|
}
|
|
1515
2049
|
break;
|
|
1516
2050
|
case 'a':
|
|
1517
|
-
if (strcmp(key, "atime")==0) {
|
|
2051
|
+
if (strcmp(key, "atime") == 0) {
|
|
1518
2052
|
pax_time(value, &s, &n);
|
|
1519
2053
|
archive_entry_set_atime(entry, s, n);
|
|
1520
2054
|
}
|
|
1521
2055
|
break;
|
|
1522
2056
|
case 'c':
|
|
1523
|
-
if (strcmp(key, "ctime")==0) {
|
|
2057
|
+
if (strcmp(key, "ctime") == 0) {
|
|
1524
2058
|
pax_time(value, &s, &n);
|
|
1525
2059
|
archive_entry_set_ctime(entry, s, n);
|
|
1526
|
-
} else if (strcmp(key, "charset")==0) {
|
|
2060
|
+
} else if (strcmp(key, "charset") == 0) {
|
|
1527
2061
|
/* TODO: Publish charset information in entry. */
|
|
1528
|
-
} else if (strcmp(key, "comment")==0) {
|
|
2062
|
+
} else if (strcmp(key, "comment") == 0) {
|
|
1529
2063
|
/* TODO: Publish comment in entry. */
|
|
1530
2064
|
}
|
|
1531
2065
|
break;
|
|
1532
2066
|
case 'g':
|
|
1533
|
-
if (strcmp(key, "gid")==0) {
|
|
2067
|
+
if (strcmp(key, "gid") == 0) {
|
|
1534
2068
|
archive_entry_set_gid(entry,
|
|
1535
2069
|
tar_atol10(value, strlen(value)));
|
|
1536
|
-
} else if (strcmp(key, "gname")==0) {
|
|
2070
|
+
} else if (strcmp(key, "gname") == 0) {
|
|
1537
2071
|
archive_strcpy(&(tar->entry_gname), value);
|
|
1538
2072
|
}
|
|
1539
2073
|
break;
|
|
1540
2074
|
case 'h':
|
|
1541
2075
|
if (strcmp(key, "hdrcharset") == 0) {
|
|
1542
2076
|
if (strcmp(value, "BINARY") == 0)
|
|
2077
|
+
/* Binary mode. */
|
|
1543
2078
|
tar->pax_hdrcharset_binary = 1;
|
|
1544
2079
|
else if (strcmp(value, "ISO-IR 10646 2000 UTF-8") == 0)
|
|
1545
2080
|
tar->pax_hdrcharset_binary = 0;
|
|
1546
|
-
else {
|
|
1547
|
-
/* TODO: Warn about unsupported hdrcharset */
|
|
1548
|
-
}
|
|
1549
2081
|
}
|
|
1550
2082
|
break;
|
|
1551
2083
|
case 'l':
|
|
1552
2084
|
/* pax interchange doesn't distinguish hardlink vs. symlink. */
|
|
1553
|
-
if (strcmp(key, "linkpath")==0) {
|
|
2085
|
+
if (strcmp(key, "linkpath") == 0) {
|
|
1554
2086
|
archive_strcpy(&(tar->entry_linkpath), value);
|
|
1555
2087
|
}
|
|
1556
2088
|
break;
|
|
1557
2089
|
case 'm':
|
|
1558
|
-
if (strcmp(key, "mtime")==0) {
|
|
2090
|
+
if (strcmp(key, "mtime") == 0) {
|
|
1559
2091
|
pax_time(value, &s, &n);
|
|
1560
2092
|
archive_entry_set_mtime(entry, s, n);
|
|
1561
2093
|
}
|
|
1562
2094
|
break;
|
|
1563
2095
|
case 'p':
|
|
1564
|
-
if (strcmp(key, "path")==0) {
|
|
2096
|
+
if (strcmp(key, "path") == 0) {
|
|
1565
2097
|
archive_strcpy(&(tar->entry_pathname), value);
|
|
1566
2098
|
}
|
|
1567
2099
|
break;
|
|
@@ -1570,20 +2102,33 @@ pax_attribute(struct tar *tar, struct archive_entry *entry,
|
|
|
1570
2102
|
break;
|
|
1571
2103
|
case 's':
|
|
1572
2104
|
/* POSIX has reserved 'security.*' */
|
|
1573
|
-
/* Someday: if (strcmp(key, "security.acl")==0) { ... } */
|
|
1574
|
-
if (strcmp(key, "size")==0) {
|
|
2105
|
+
/* Someday: if (strcmp(key, "security.acl") == 0) { ... } */
|
|
2106
|
+
if (strcmp(key, "size") == 0) {
|
|
1575
2107
|
/* "size" is the size of the data in the entry. */
|
|
1576
2108
|
tar->entry_bytes_remaining
|
|
1577
2109
|
= tar_atol10(value, strlen(value));
|
|
2110
|
+
if (tar->entry_bytes_remaining < 0) {
|
|
2111
|
+
tar->entry_bytes_remaining = 0;
|
|
2112
|
+
archive_set_error(&a->archive,
|
|
2113
|
+
ARCHIVE_ERRNO_MISC,
|
|
2114
|
+
"Tar size attribute is negative");
|
|
2115
|
+
return (ARCHIVE_FATAL);
|
|
2116
|
+
}
|
|
2117
|
+
if (tar->entry_bytes_remaining == INT64_MAX) {
|
|
2118
|
+
/* Note: tar_atol returns INT64_MAX on overflow */
|
|
2119
|
+
tar->entry_bytes_remaining = 0;
|
|
2120
|
+
archive_set_error(&a->archive,
|
|
2121
|
+
ARCHIVE_ERRNO_MISC,
|
|
2122
|
+
"Tar size attribute overflow");
|
|
2123
|
+
return (ARCHIVE_FATAL);
|
|
2124
|
+
}
|
|
1578
2125
|
/*
|
|
1579
|
-
*
|
|
1580
|
-
*
|
|
1581
|
-
*
|
|
1582
|
-
*
|
|
1583
|
-
* an old GNU header field or SCHILY.realsize
|
|
1584
|
-
* or ....
|
|
2126
|
+
* The "size" pax header keyword always overrides the
|
|
2127
|
+
* "size" field in the tar header.
|
|
2128
|
+
* GNU.sparse.realsize, GNU.sparse.size and
|
|
2129
|
+
* SCHILY.realsize override this value.
|
|
1585
2130
|
*/
|
|
1586
|
-
if (tar->
|
|
2131
|
+
if (!tar->realsize_override) {
|
|
1587
2132
|
archive_entry_set_size(entry,
|
|
1588
2133
|
tar->entry_bytes_remaining);
|
|
1589
2134
|
tar->realsize
|
|
@@ -1592,15 +2137,15 @@ pax_attribute(struct tar *tar, struct archive_entry *entry,
|
|
|
1592
2137
|
}
|
|
1593
2138
|
break;
|
|
1594
2139
|
case 'u':
|
|
1595
|
-
if (strcmp(key, "uid")==0) {
|
|
2140
|
+
if (strcmp(key, "uid") == 0) {
|
|
1596
2141
|
archive_entry_set_uid(entry,
|
|
1597
2142
|
tar_atol10(value, strlen(value)));
|
|
1598
|
-
} else if (strcmp(key, "uname")==0) {
|
|
2143
|
+
} else if (strcmp(key, "uname") == 0) {
|
|
1599
2144
|
archive_strcpy(&(tar->entry_uname), value);
|
|
1600
2145
|
}
|
|
1601
2146
|
break;
|
|
1602
2147
|
}
|
|
1603
|
-
return (
|
|
2148
|
+
return (err);
|
|
1604
2149
|
}
|
|
1605
2150
|
|
|
1606
2151
|
|
|
@@ -1660,11 +2205,11 @@ pax_time(const char *p, int64_t *ps, long *pn)
|
|
|
1660
2205
|
*/
|
|
1661
2206
|
static int
|
|
1662
2207
|
header_gnutar(struct archive_read *a, struct tar *tar,
|
|
1663
|
-
struct archive_entry *entry, const void *h)
|
|
2208
|
+
struct archive_entry *entry, const void *h, size_t *unconsumed)
|
|
1664
2209
|
{
|
|
1665
2210
|
const struct archive_entry_header_gnutar *header;
|
|
1666
|
-
|
|
1667
|
-
|
|
2211
|
+
int64_t t;
|
|
2212
|
+
int err = ARCHIVE_OK;
|
|
1668
2213
|
|
|
1669
2214
|
/*
|
|
1670
2215
|
* GNU header is like POSIX ustar, except 'prefix' is
|
|
@@ -1673,31 +2218,42 @@ header_gnutar(struct archive_read *a, struct tar *tar,
|
|
|
1673
2218
|
*/
|
|
1674
2219
|
|
|
1675
2220
|
/* Grab fields common to all tar variants. */
|
|
1676
|
-
header_common(a, tar, entry, h);
|
|
2221
|
+
err = header_common(a, tar, entry, h);
|
|
2222
|
+
if (err == ARCHIVE_FATAL)
|
|
2223
|
+
return (err);
|
|
1677
2224
|
|
|
1678
2225
|
/* Copy filename over (to ensure null termination). */
|
|
1679
2226
|
header = (const struct archive_entry_header_gnutar *)h;
|
|
1680
|
-
|
|
1681
|
-
sizeof(header->name))
|
|
1682
|
-
|
|
2227
|
+
if (archive_entry_copy_pathname_l(entry,
|
|
2228
|
+
header->name, sizeof(header->name), tar->sconv) != 0) {
|
|
2229
|
+
err = set_conversion_failed_error(a, tar->sconv, "Pathname");
|
|
2230
|
+
if (err == ARCHIVE_FATAL)
|
|
2231
|
+
return (err);
|
|
2232
|
+
}
|
|
1683
2233
|
|
|
1684
2234
|
/* Fields common to ustar and GNU */
|
|
1685
2235
|
/* XXX Can the following be factored out since it's common
|
|
1686
2236
|
* to ustar and gnu tar? Is it okay to move it down into
|
|
1687
2237
|
* header_common, perhaps? */
|
|
1688
|
-
|
|
1689
|
-
header->uname, sizeof(header->uname))
|
|
1690
|
-
|
|
2238
|
+
if (archive_entry_copy_uname_l(entry,
|
|
2239
|
+
header->uname, sizeof(header->uname), tar->sconv) != 0) {
|
|
2240
|
+
err = set_conversion_failed_error(a, tar->sconv, "Uname");
|
|
2241
|
+
if (err == ARCHIVE_FATAL)
|
|
2242
|
+
return (err);
|
|
2243
|
+
}
|
|
1691
2244
|
|
|
1692
|
-
|
|
1693
|
-
header->gname, sizeof(header->gname))
|
|
1694
|
-
|
|
2245
|
+
if (archive_entry_copy_gname_l(entry,
|
|
2246
|
+
header->gname, sizeof(header->gname), tar->sconv) != 0) {
|
|
2247
|
+
err = set_conversion_failed_error(a, tar->sconv, "Gname");
|
|
2248
|
+
if (err == ARCHIVE_FATAL)
|
|
2249
|
+
return (err);
|
|
2250
|
+
}
|
|
1695
2251
|
|
|
1696
2252
|
/* Parse out device numbers only for char and block specials */
|
|
1697
2253
|
if (header->typeflag[0] == '3' || header->typeflag[0] == '4') {
|
|
1698
|
-
archive_entry_set_rdevmajor(entry,
|
|
2254
|
+
archive_entry_set_rdevmajor(entry, (dev_t)
|
|
1699
2255
|
tar_atol(header->rdevmajor, sizeof(header->rdevmajor)));
|
|
1700
|
-
archive_entry_set_rdevminor(entry,
|
|
2256
|
+
archive_entry_set_rdevminor(entry, (dev_t)
|
|
1701
2257
|
tar_atol(header->rdevminor, sizeof(header->rdevminor)));
|
|
1702
2258
|
} else
|
|
1703
2259
|
archive_entry_set_rdev(entry, 0);
|
|
@@ -1705,43 +2261,56 @@ header_gnutar(struct archive_read *a, struct tar *tar,
|
|
|
1705
2261
|
tar->entry_padding = 0x1ff & (-tar->entry_bytes_remaining);
|
|
1706
2262
|
|
|
1707
2263
|
/* Grab GNU-specific fields. */
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
|
|
2264
|
+
t = tar_atol(header->atime, sizeof(header->atime));
|
|
2265
|
+
if (t > 0)
|
|
2266
|
+
archive_entry_set_atime(entry, t, 0);
|
|
2267
|
+
t = tar_atol(header->ctime, sizeof(header->ctime));
|
|
2268
|
+
if (t > 0)
|
|
2269
|
+
archive_entry_set_ctime(entry, t, 0);
|
|
2270
|
+
|
|
1712
2271
|
if (header->realsize[0] != 0) {
|
|
1713
2272
|
tar->realsize
|
|
1714
2273
|
= tar_atol(header->realsize, sizeof(header->realsize));
|
|
1715
2274
|
archive_entry_set_size(entry, tar->realsize);
|
|
2275
|
+
tar->realsize_override = 1;
|
|
1716
2276
|
}
|
|
1717
2277
|
|
|
1718
2278
|
if (header->sparse[0].offset[0] != 0) {
|
|
1719
|
-
gnu_sparse_old_read(a, tar, header)
|
|
2279
|
+
if (gnu_sparse_old_read(a, tar, header, unconsumed)
|
|
2280
|
+
!= ARCHIVE_OK)
|
|
2281
|
+
return (ARCHIVE_FATAL);
|
|
1720
2282
|
} else {
|
|
1721
2283
|
if (header->isextended[0] != 0) {
|
|
1722
2284
|
/* XXX WTF? XXX */
|
|
1723
2285
|
}
|
|
1724
2286
|
}
|
|
1725
2287
|
|
|
1726
|
-
return (
|
|
2288
|
+
return (err);
|
|
1727
2289
|
}
|
|
1728
2290
|
|
|
1729
|
-
static
|
|
1730
|
-
gnu_add_sparse_entry(struct
|
|
2291
|
+
static int
|
|
2292
|
+
gnu_add_sparse_entry(struct archive_read *a, struct tar *tar,
|
|
2293
|
+
int64_t offset, int64_t remaining)
|
|
1731
2294
|
{
|
|
1732
2295
|
struct sparse_block *p;
|
|
1733
2296
|
|
|
1734
|
-
p = (struct sparse_block *)
|
|
1735
|
-
if (p == NULL)
|
|
1736
|
-
|
|
1737
|
-
|
|
2297
|
+
p = (struct sparse_block *)calloc(1, sizeof(*p));
|
|
2298
|
+
if (p == NULL) {
|
|
2299
|
+
archive_set_error(&a->archive, ENOMEM, "Out of memory");
|
|
2300
|
+
return (ARCHIVE_FATAL);
|
|
2301
|
+
}
|
|
1738
2302
|
if (tar->sparse_last != NULL)
|
|
1739
2303
|
tar->sparse_last->next = p;
|
|
1740
2304
|
else
|
|
1741
2305
|
tar->sparse_list = p;
|
|
1742
2306
|
tar->sparse_last = p;
|
|
2307
|
+
if (remaining < 0 || offset < 0 || offset > INT64_MAX - remaining) {
|
|
2308
|
+
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, "Malformed sparse map data");
|
|
2309
|
+
return (ARCHIVE_FATAL);
|
|
2310
|
+
}
|
|
1743
2311
|
p->offset = offset;
|
|
1744
2312
|
p->remaining = remaining;
|
|
2313
|
+
return (ARCHIVE_OK);
|
|
1745
2314
|
}
|
|
1746
2315
|
|
|
1747
2316
|
static void
|
|
@@ -1771,7 +2340,7 @@ gnu_clear_sparse_list(struct tar *tar)
|
|
|
1771
2340
|
|
|
1772
2341
|
static int
|
|
1773
2342
|
gnu_sparse_old_read(struct archive_read *a, struct tar *tar,
|
|
1774
|
-
const struct archive_entry_header_gnutar *header)
|
|
2343
|
+
const struct archive_entry_header_gnutar *header, size_t *unconsumed)
|
|
1775
2344
|
{
|
|
1776
2345
|
ssize_t bytes_read;
|
|
1777
2346
|
const void *data;
|
|
@@ -1782,11 +2351,13 @@ gnu_sparse_old_read(struct archive_read *a, struct tar *tar,
|
|
|
1782
2351
|
};
|
|
1783
2352
|
const struct extended *ext;
|
|
1784
2353
|
|
|
1785
|
-
gnu_sparse_old_parse(tar, header->sparse, 4)
|
|
2354
|
+
if (gnu_sparse_old_parse(a, tar, header->sparse, 4) != ARCHIVE_OK)
|
|
2355
|
+
return (ARCHIVE_FATAL);
|
|
1786
2356
|
if (header->isextended[0] == 0)
|
|
1787
2357
|
return (ARCHIVE_OK);
|
|
1788
2358
|
|
|
1789
2359
|
do {
|
|
2360
|
+
tar_flush_unconsumed(a, unconsumed);
|
|
1790
2361
|
data = __archive_read_ahead(a, 512, &bytes_read);
|
|
1791
2362
|
if (bytes_read < 0)
|
|
1792
2363
|
return (ARCHIVE_FATAL);
|
|
@@ -1796,26 +2367,30 @@ gnu_sparse_old_read(struct archive_read *a, struct tar *tar,
|
|
|
1796
2367
|
"detected while reading sparse file data");
|
|
1797
2368
|
return (ARCHIVE_FATAL);
|
|
1798
2369
|
}
|
|
1799
|
-
|
|
2370
|
+
*unconsumed = 512;
|
|
1800
2371
|
ext = (const struct extended *)data;
|
|
1801
|
-
gnu_sparse_old_parse(tar, ext->sparse, 21)
|
|
2372
|
+
if (gnu_sparse_old_parse(a, tar, ext->sparse, 21) != ARCHIVE_OK)
|
|
2373
|
+
return (ARCHIVE_FATAL);
|
|
1802
2374
|
} while (ext->isextended[0] != 0);
|
|
1803
2375
|
if (tar->sparse_list != NULL)
|
|
1804
2376
|
tar->entry_offset = tar->sparse_list->offset;
|
|
1805
2377
|
return (ARCHIVE_OK);
|
|
1806
2378
|
}
|
|
1807
2379
|
|
|
1808
|
-
static
|
|
1809
|
-
gnu_sparse_old_parse(struct tar *tar,
|
|
2380
|
+
static int
|
|
2381
|
+
gnu_sparse_old_parse(struct archive_read *a, struct tar *tar,
|
|
1810
2382
|
const struct gnu_sparse *sparse, int length)
|
|
1811
2383
|
{
|
|
1812
2384
|
while (length > 0 && sparse->offset[0] != 0) {
|
|
1813
|
-
gnu_add_sparse_entry(tar,
|
|
2385
|
+
if (gnu_add_sparse_entry(a, tar,
|
|
1814
2386
|
tar_atol(sparse->offset, sizeof(sparse->offset)),
|
|
1815
|
-
tar_atol(sparse->numbytes, sizeof(sparse->numbytes)))
|
|
2387
|
+
tar_atol(sparse->numbytes, sizeof(sparse->numbytes)))
|
|
2388
|
+
!= ARCHIVE_OK)
|
|
2389
|
+
return (ARCHIVE_FATAL);
|
|
1816
2390
|
sparse++;
|
|
1817
2391
|
length--;
|
|
1818
2392
|
}
|
|
2393
|
+
return (ARCHIVE_OK);
|
|
1819
2394
|
}
|
|
1820
2395
|
|
|
1821
2396
|
/*
|
|
@@ -1824,7 +2399,7 @@ gnu_sparse_old_parse(struct tar *tar,
|
|
|
1824
2399
|
* Beginning with GNU tar 1.15, sparse files are stored using
|
|
1825
2400
|
* information in the pax extended header. The GNU tar maintainers
|
|
1826
2401
|
* have gone through a number of variations in the process of working
|
|
1827
|
-
* out this scheme;
|
|
2402
|
+
* out this scheme; fortunately, they're all numbered.
|
|
1828
2403
|
*
|
|
1829
2404
|
* Sparse format 0.0 uses attribute GNU.sparse.numblocks to store the
|
|
1830
2405
|
* number of blocks, and GNU.sparse.offset/GNU.sparse.numbytes to
|
|
@@ -1845,10 +2420,10 @@ gnu_sparse_old_parse(struct tar *tar,
|
|
|
1845
2420
|
*/
|
|
1846
2421
|
|
|
1847
2422
|
static int
|
|
1848
|
-
gnu_sparse_01_parse(struct tar *tar, const char *p)
|
|
2423
|
+
gnu_sparse_01_parse(struct archive_read *a, struct tar *tar, const char *p)
|
|
1849
2424
|
{
|
|
1850
2425
|
const char *e;
|
|
1851
|
-
|
|
2426
|
+
int64_t offset = -1, size = -1;
|
|
1852
2427
|
|
|
1853
2428
|
for (;;) {
|
|
1854
2429
|
e = p;
|
|
@@ -1865,7 +2440,9 @@ gnu_sparse_01_parse(struct tar *tar, const char *p)
|
|
|
1865
2440
|
size = tar_atol10(p, e - p);
|
|
1866
2441
|
if (size < 0)
|
|
1867
2442
|
return (ARCHIVE_WARN);
|
|
1868
|
-
gnu_add_sparse_entry(tar, offset, size)
|
|
2443
|
+
if (gnu_add_sparse_entry(a, tar, offset, size)
|
|
2444
|
+
!= ARCHIVE_OK)
|
|
2445
|
+
return (ARCHIVE_FATAL);
|
|
1869
2446
|
offset = -1;
|
|
1870
2447
|
}
|
|
1871
2448
|
if (*e == '\0')
|
|
@@ -1899,7 +2476,7 @@ gnu_sparse_01_parse(struct tar *tar, const char *p)
|
|
|
1899
2476
|
*/
|
|
1900
2477
|
static int64_t
|
|
1901
2478
|
gnu_sparse_10_atol(struct archive_read *a, struct tar *tar,
|
|
1902
|
-
|
|
2479
|
+
int64_t *remaining, size_t *unconsumed)
|
|
1903
2480
|
{
|
|
1904
2481
|
int64_t l, limit, last_digit_limit;
|
|
1905
2482
|
const char *p;
|
|
@@ -1915,7 +2492,8 @@ gnu_sparse_10_atol(struct archive_read *a, struct tar *tar,
|
|
|
1915
2492
|
* don't require this, but they should.
|
|
1916
2493
|
*/
|
|
1917
2494
|
do {
|
|
1918
|
-
bytes_read = readline(a, tar, &p,
|
|
2495
|
+
bytes_read = readline(a, tar, &p,
|
|
2496
|
+
(ssize_t)tar_min(*remaining, 100), unconsumed);
|
|
1919
2497
|
if (bytes_read <= 0)
|
|
1920
2498
|
return (ARCHIVE_FATAL);
|
|
1921
2499
|
*remaining -= bytes_read;
|
|
@@ -1944,11 +2522,11 @@ gnu_sparse_10_atol(struct archive_read *a, struct tar *tar,
|
|
|
1944
2522
|
* that was read.
|
|
1945
2523
|
*/
|
|
1946
2524
|
static ssize_t
|
|
1947
|
-
gnu_sparse_10_read(struct archive_read *a, struct tar *tar)
|
|
2525
|
+
gnu_sparse_10_read(struct archive_read *a, struct tar *tar, size_t *unconsumed)
|
|
1948
2526
|
{
|
|
1949
|
-
ssize_t
|
|
2527
|
+
ssize_t bytes_read;
|
|
1950
2528
|
int entries;
|
|
1951
|
-
|
|
2529
|
+
int64_t offset, size, to_skip, remaining;
|
|
1952
2530
|
|
|
1953
2531
|
/* Clear out the existing sparse list. */
|
|
1954
2532
|
gnu_clear_sparse_list(tar);
|
|
@@ -1956,27 +2534,77 @@ gnu_sparse_10_read(struct archive_read *a, struct tar *tar)
|
|
|
1956
2534
|
remaining = tar->entry_bytes_remaining;
|
|
1957
2535
|
|
|
1958
2536
|
/* Parse entries. */
|
|
1959
|
-
entries = gnu_sparse_10_atol(a, tar, &remaining);
|
|
2537
|
+
entries = (int)gnu_sparse_10_atol(a, tar, &remaining, unconsumed);
|
|
1960
2538
|
if (entries < 0)
|
|
1961
2539
|
return (ARCHIVE_FATAL);
|
|
1962
2540
|
/* Parse the individual entries. */
|
|
1963
2541
|
while (entries-- > 0) {
|
|
1964
2542
|
/* Parse offset/size */
|
|
1965
|
-
offset = gnu_sparse_10_atol(a, tar, &remaining);
|
|
2543
|
+
offset = gnu_sparse_10_atol(a, tar, &remaining, unconsumed);
|
|
1966
2544
|
if (offset < 0)
|
|
1967
2545
|
return (ARCHIVE_FATAL);
|
|
1968
|
-
size = gnu_sparse_10_atol(a, tar, &remaining);
|
|
2546
|
+
size = gnu_sparse_10_atol(a, tar, &remaining, unconsumed);
|
|
1969
2547
|
if (size < 0)
|
|
1970
2548
|
return (ARCHIVE_FATAL);
|
|
1971
2549
|
/* Add a new sparse entry. */
|
|
1972
|
-
gnu_add_sparse_entry(tar, offset, size)
|
|
2550
|
+
if (gnu_add_sparse_entry(a, tar, offset, size) != ARCHIVE_OK)
|
|
2551
|
+
return (ARCHIVE_FATAL);
|
|
1973
2552
|
}
|
|
1974
2553
|
/* Skip rest of block... */
|
|
1975
|
-
|
|
2554
|
+
tar_flush_unconsumed(a, unconsumed);
|
|
2555
|
+
bytes_read = (ssize_t)(tar->entry_bytes_remaining - remaining);
|
|
1976
2556
|
to_skip = 0x1ff & -bytes_read;
|
|
1977
|
-
if
|
|
2557
|
+
/* Fail if tar->entry_bytes_remaing would get negative */
|
|
2558
|
+
if (to_skip > remaining)
|
|
1978
2559
|
return (ARCHIVE_FATAL);
|
|
1979
|
-
|
|
2560
|
+
if (to_skip != __archive_read_consume(a, to_skip))
|
|
2561
|
+
return (ARCHIVE_FATAL);
|
|
2562
|
+
return ((ssize_t)(bytes_read + to_skip));
|
|
2563
|
+
}
|
|
2564
|
+
|
|
2565
|
+
/*
|
|
2566
|
+
* Solaris pax extension for a sparse file. This is recorded with the
|
|
2567
|
+
* data and hole pairs. The way recording sparse information by Solaris'
|
|
2568
|
+
* pax simply indicates where data and sparse are, so the stored contents
|
|
2569
|
+
* consist of both data and hole.
|
|
2570
|
+
*/
|
|
2571
|
+
static int
|
|
2572
|
+
solaris_sparse_parse(struct archive_read *a, struct tar *tar,
|
|
2573
|
+
struct archive_entry *entry, const char *p)
|
|
2574
|
+
{
|
|
2575
|
+
const char *e;
|
|
2576
|
+
int64_t start, end;
|
|
2577
|
+
int hole = 1;
|
|
2578
|
+
|
|
2579
|
+
(void)entry; /* UNUSED */
|
|
2580
|
+
|
|
2581
|
+
end = 0;
|
|
2582
|
+
if (*p == ' ')
|
|
2583
|
+
p++;
|
|
2584
|
+
else
|
|
2585
|
+
return (ARCHIVE_WARN);
|
|
2586
|
+
for (;;) {
|
|
2587
|
+
e = p;
|
|
2588
|
+
while (*e != '\0' && *e != ' ') {
|
|
2589
|
+
if (*e < '0' || *e > '9')
|
|
2590
|
+
return (ARCHIVE_WARN);
|
|
2591
|
+
e++;
|
|
2592
|
+
}
|
|
2593
|
+
start = end;
|
|
2594
|
+
end = tar_atol10(p, e - p);
|
|
2595
|
+
if (end < 0)
|
|
2596
|
+
return (ARCHIVE_WARN);
|
|
2597
|
+
if (start < end) {
|
|
2598
|
+
if (gnu_add_sparse_entry(a, tar, start,
|
|
2599
|
+
end - start) != ARCHIVE_OK)
|
|
2600
|
+
return (ARCHIVE_FATAL);
|
|
2601
|
+
tar->sparse_last->hole = hole;
|
|
2602
|
+
}
|
|
2603
|
+
if (*e == '\0')
|
|
2604
|
+
return (ARCHIVE_OK);
|
|
2605
|
+
p = e + 1;
|
|
2606
|
+
hole = hole == 0;
|
|
2607
|
+
}
|
|
1980
2608
|
}
|
|
1981
2609
|
|
|
1982
2610
|
/*-
|
|
@@ -1997,7 +2625,7 @@ gnu_sparse_10_read(struct archive_read *a, struct tar *tar)
|
|
|
1997
2625
|
* On read, this implementation supports both extensions.
|
|
1998
2626
|
*/
|
|
1999
2627
|
static int64_t
|
|
2000
|
-
tar_atol(const char *p,
|
|
2628
|
+
tar_atol(const char *p, size_t char_cnt)
|
|
2001
2629
|
{
|
|
2002
2630
|
/*
|
|
2003
2631
|
* Technically, GNU tar considers a field to be in base-256
|
|
@@ -2014,103 +2642,112 @@ tar_atol(const char *p, unsigned char_cnt)
|
|
|
2014
2642
|
* it does obey locale.
|
|
2015
2643
|
*/
|
|
2016
2644
|
static int64_t
|
|
2017
|
-
|
|
2645
|
+
tar_atol_base_n(const char *p, size_t char_cnt, int base)
|
|
2018
2646
|
{
|
|
2019
|
-
int64_t l, limit, last_digit_limit;
|
|
2020
|
-
int digit, sign
|
|
2647
|
+
int64_t l, maxval, limit, last_digit_limit;
|
|
2648
|
+
int digit, sign;
|
|
2021
2649
|
|
|
2022
|
-
|
|
2650
|
+
maxval = INT64_MAX;
|
|
2023
2651
|
limit = INT64_MAX / base;
|
|
2024
2652
|
last_digit_limit = INT64_MAX % base;
|
|
2025
2653
|
|
|
2026
|
-
|
|
2654
|
+
/* the pointer will not be dereferenced if char_cnt is zero
|
|
2655
|
+
* due to the way the && operator is evaluated.
|
|
2656
|
+
*/
|
|
2657
|
+
while (char_cnt != 0 && (*p == ' ' || *p == '\t')) {
|
|
2027
2658
|
p++;
|
|
2028
|
-
|
|
2659
|
+
char_cnt--;
|
|
2660
|
+
}
|
|
2661
|
+
|
|
2662
|
+
sign = 1;
|
|
2663
|
+
if (char_cnt != 0 && *p == '-') {
|
|
2029
2664
|
sign = -1;
|
|
2030
2665
|
p++;
|
|
2031
|
-
|
|
2032
|
-
|
|
2666
|
+
char_cnt--;
|
|
2667
|
+
|
|
2668
|
+
maxval = INT64_MIN;
|
|
2669
|
+
limit = -(INT64_MIN / base);
|
|
2670
|
+
last_digit_limit = -(INT64_MIN % base);
|
|
2671
|
+
}
|
|
2033
2672
|
|
|
2034
2673
|
l = 0;
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
l
|
|
2039
|
-
|
|
2674
|
+
if (char_cnt != 0) {
|
|
2675
|
+
digit = *p - '0';
|
|
2676
|
+
while (digit >= 0 && digit < base && char_cnt != 0) {
|
|
2677
|
+
if (l>limit || (l == limit && digit >= last_digit_limit)) {
|
|
2678
|
+
return maxval; /* Truncate on overflow. */
|
|
2679
|
+
}
|
|
2680
|
+
l = (l * base) + digit;
|
|
2681
|
+
digit = *++p - '0';
|
|
2682
|
+
char_cnt--;
|
|
2040
2683
|
}
|
|
2041
|
-
l = (l * base) + digit;
|
|
2042
|
-
digit = *++p - '0';
|
|
2043
2684
|
}
|
|
2044
2685
|
return (sign < 0) ? -l : l;
|
|
2045
2686
|
}
|
|
2046
2687
|
|
|
2047
|
-
/*
|
|
2048
|
-
* Note that this implementation does not (and should not!) obey
|
|
2049
|
-
* locale settings; you cannot simply substitute strtol here, since
|
|
2050
|
-
* it does obey locale.
|
|
2051
|
-
*/
|
|
2052
2688
|
static int64_t
|
|
2053
|
-
|
|
2689
|
+
tar_atol8(const char *p, size_t char_cnt)
|
|
2054
2690
|
{
|
|
2055
|
-
|
|
2056
|
-
|
|
2057
|
-
|
|
2058
|
-
base = 10;
|
|
2059
|
-
limit = INT64_MAX / base;
|
|
2060
|
-
last_digit_limit = INT64_MAX % base;
|
|
2061
|
-
|
|
2062
|
-
while (*p == ' ' || *p == '\t')
|
|
2063
|
-
p++;
|
|
2064
|
-
if (*p == '-') {
|
|
2065
|
-
sign = -1;
|
|
2066
|
-
p++;
|
|
2067
|
-
} else
|
|
2068
|
-
sign = 1;
|
|
2691
|
+
return tar_atol_base_n(p, char_cnt, 8);
|
|
2692
|
+
}
|
|
2069
2693
|
|
|
2070
|
-
|
|
2071
|
-
|
|
2072
|
-
|
|
2073
|
-
|
|
2074
|
-
l = INT64_MAX; /* Truncate on overflow. */
|
|
2075
|
-
break;
|
|
2076
|
-
}
|
|
2077
|
-
l = (l * base) + digit;
|
|
2078
|
-
digit = *++p - '0';
|
|
2079
|
-
}
|
|
2080
|
-
return (sign < 0) ? -l : l;
|
|
2694
|
+
static int64_t
|
|
2695
|
+
tar_atol10(const char *p, size_t char_cnt)
|
|
2696
|
+
{
|
|
2697
|
+
return tar_atol_base_n(p, char_cnt, 10);
|
|
2081
2698
|
}
|
|
2082
2699
|
|
|
2083
2700
|
/*
|
|
2084
|
-
* Parse a base-256 integer. This is just a
|
|
2085
|
-
* value in big-endian order, except
|
|
2086
|
-
* ignored.
|
|
2701
|
+
* Parse a base-256 integer. This is just a variable-length
|
|
2702
|
+
* twos-complement signed binary value in big-endian order, except
|
|
2703
|
+
* that the high-order bit is ignored. The values here can be up to
|
|
2704
|
+
* 12 bytes, so we need to be careful about overflowing 64-bit
|
|
2705
|
+
* (8-byte) integers.
|
|
2706
|
+
*
|
|
2707
|
+
* This code unashamedly assumes that the local machine uses 8-bit
|
|
2708
|
+
* bytes and twos-complement arithmetic.
|
|
2087
2709
|
*/
|
|
2088
2710
|
static int64_t
|
|
2089
|
-
tar_atol256(const char *_p,
|
|
2711
|
+
tar_atol256(const char *_p, size_t char_cnt)
|
|
2090
2712
|
{
|
|
2091
|
-
|
|
2713
|
+
uint64_t l;
|
|
2092
2714
|
const unsigned char *p = (const unsigned char *)_p;
|
|
2715
|
+
unsigned char c, neg;
|
|
2716
|
+
|
|
2717
|
+
/* Extend 7-bit 2s-comp to 8-bit 2s-comp, decide sign. */
|
|
2718
|
+
c = *p;
|
|
2719
|
+
if (c & 0x40) {
|
|
2720
|
+
neg = 0xff;
|
|
2721
|
+
c |= 0x80;
|
|
2722
|
+
l = ~ARCHIVE_LITERAL_ULL(0);
|
|
2723
|
+
} else {
|
|
2724
|
+
neg = 0;
|
|
2725
|
+
c &= 0x7f;
|
|
2726
|
+
l = 0;
|
|
2727
|
+
}
|
|
2093
2728
|
|
|
2094
|
-
|
|
2095
|
-
|
|
2729
|
+
/* If more than 8 bytes, check that we can ignore
|
|
2730
|
+
* high-order bits without overflow. */
|
|
2731
|
+
while (char_cnt > sizeof(int64_t)) {
|
|
2732
|
+
--char_cnt;
|
|
2733
|
+
if (c != neg)
|
|
2734
|
+
return neg ? INT64_MIN : INT64_MAX;
|
|
2735
|
+
c = *++p;
|
|
2736
|
+
}
|
|
2096
2737
|
|
|
2097
|
-
/*
|
|
2098
|
-
if ((
|
|
2099
|
-
|
|
2100
|
-
|
|
2101
|
-
|
|
2102
|
-
|
|
2738
|
+
/* c is first byte that fits; if sign mismatch, return overflow */
|
|
2739
|
+
if ((c ^ neg) & 0x80) {
|
|
2740
|
+
return neg ? INT64_MIN : INT64_MAX;
|
|
2741
|
+
}
|
|
2742
|
+
|
|
2743
|
+
/* Accumulate remaining bytes. */
|
|
2103
2744
|
while (--char_cnt > 0) {
|
|
2104
|
-
|
|
2105
|
-
|
|
2106
|
-
break;
|
|
2107
|
-
} else if (l < lower_limit) {
|
|
2108
|
-
l = INT64_MIN;
|
|
2109
|
-
break;
|
|
2110
|
-
}
|
|
2111
|
-
l = (l << 8) | (0xff & (int64_t)*p++);
|
|
2745
|
+
l = (l << 8) | c;
|
|
2746
|
+
c = *++p;
|
|
2112
2747
|
}
|
|
2113
|
-
|
|
2748
|
+
l = (l << 8) | c;
|
|
2749
|
+
/* Return signed twos-complement value. */
|
|
2750
|
+
return (int64_t)(l);
|
|
2114
2751
|
}
|
|
2115
2752
|
|
|
2116
2753
|
/*
|
|
@@ -2121,7 +2758,7 @@ tar_atol256(const char *_p, unsigned char_cnt)
|
|
|
2121
2758
|
*/
|
|
2122
2759
|
static ssize_t
|
|
2123
2760
|
readline(struct archive_read *a, struct tar *tar, const char **start,
|
|
2124
|
-
ssize_t limit)
|
|
2761
|
+
ssize_t limit, size_t *unconsumed)
|
|
2125
2762
|
{
|
|
2126
2763
|
ssize_t bytes_read;
|
|
2127
2764
|
ssize_t total_size = 0;
|
|
@@ -2129,6 +2766,8 @@ readline(struct archive_read *a, struct tar *tar, const char **start,
|
|
|
2129
2766
|
const char *s;
|
|
2130
2767
|
void *p;
|
|
2131
2768
|
|
|
2769
|
+
tar_flush_unconsumed(a, unconsumed);
|
|
2770
|
+
|
|
2132
2771
|
t = __archive_read_ahead(a, 1, &bytes_read);
|
|
2133
2772
|
if (bytes_read <= 0)
|
|
2134
2773
|
return (ARCHIVE_FATAL);
|
|
@@ -2143,10 +2782,11 @@ readline(struct archive_read *a, struct tar *tar, const char **start,
|
|
|
2143
2782
|
"Line too long");
|
|
2144
2783
|
return (ARCHIVE_FATAL);
|
|
2145
2784
|
}
|
|
2146
|
-
|
|
2785
|
+
*unconsumed = bytes_read;
|
|
2147
2786
|
*start = s;
|
|
2148
2787
|
return (bytes_read);
|
|
2149
2788
|
}
|
|
2789
|
+
*unconsumed = bytes_read;
|
|
2150
2790
|
/* Otherwise, we need to accumulate in a line buffer. */
|
|
2151
2791
|
for (;;) {
|
|
2152
2792
|
if (total_size + bytes_read > limit) {
|
|
@@ -2161,7 +2801,7 @@ readline(struct archive_read *a, struct tar *tar, const char **start,
|
|
|
2161
2801
|
return (ARCHIVE_FATAL);
|
|
2162
2802
|
}
|
|
2163
2803
|
memcpy(tar->line.s + total_size, t, bytes_read);
|
|
2164
|
-
|
|
2804
|
+
tar_flush_unconsumed(a, unconsumed);
|
|
2165
2805
|
total_size += bytes_read;
|
|
2166
2806
|
/* If we found '\n', clean up and return. */
|
|
2167
2807
|
if (p != NULL) {
|
|
@@ -2178,122 +2818,10 @@ readline(struct archive_read *a, struct tar *tar, const char **start,
|
|
|
2178
2818
|
if (p != NULL) {
|
|
2179
2819
|
bytes_read = 1 + ((const char *)p) - s;
|
|
2180
2820
|
}
|
|
2821
|
+
*unconsumed = bytes_read;
|
|
2181
2822
|
}
|
|
2182
2823
|
}
|
|
2183
2824
|
|
|
2184
|
-
static wchar_t *
|
|
2185
|
-
utf8_decode(struct tar *tar, const char *src, size_t length)
|
|
2186
|
-
{
|
|
2187
|
-
wchar_t *dest;
|
|
2188
|
-
ssize_t n;
|
|
2189
|
-
|
|
2190
|
-
/* Ensure pax_entry buffer is big enough. */
|
|
2191
|
-
if (tar->pax_entry_length <= length) {
|
|
2192
|
-
wchar_t *old_entry;
|
|
2193
|
-
|
|
2194
|
-
if (tar->pax_entry_length <= 0)
|
|
2195
|
-
tar->pax_entry_length = 1024;
|
|
2196
|
-
while (tar->pax_entry_length <= length + 1)
|
|
2197
|
-
tar->pax_entry_length *= 2;
|
|
2198
|
-
|
|
2199
|
-
old_entry = tar->pax_entry;
|
|
2200
|
-
tar->pax_entry = (wchar_t *)realloc(tar->pax_entry,
|
|
2201
|
-
tar->pax_entry_length * sizeof(wchar_t));
|
|
2202
|
-
if (tar->pax_entry == NULL) {
|
|
2203
|
-
free(old_entry);
|
|
2204
|
-
/* TODO: Handle this error. */
|
|
2205
|
-
return (NULL);
|
|
2206
|
-
}
|
|
2207
|
-
}
|
|
2208
|
-
|
|
2209
|
-
dest = tar->pax_entry;
|
|
2210
|
-
while (length > 0) {
|
|
2211
|
-
n = UTF8_mbrtowc(dest, src, length);
|
|
2212
|
-
if (n < 0)
|
|
2213
|
-
return (NULL);
|
|
2214
|
-
if (n == 0)
|
|
2215
|
-
break;
|
|
2216
|
-
dest++;
|
|
2217
|
-
src += n;
|
|
2218
|
-
length -= n;
|
|
2219
|
-
}
|
|
2220
|
-
*dest = L'\0';
|
|
2221
|
-
return (tar->pax_entry);
|
|
2222
|
-
}
|
|
2223
|
-
|
|
2224
|
-
/*
|
|
2225
|
-
* Copied and simplified from FreeBSD libc/locale.
|
|
2226
|
-
*/
|
|
2227
|
-
static ssize_t
|
|
2228
|
-
UTF8_mbrtowc(wchar_t *pwc, const char *s, size_t n)
|
|
2229
|
-
{
|
|
2230
|
-
int ch, i, len, mask;
|
|
2231
|
-
unsigned long wch;
|
|
2232
|
-
|
|
2233
|
-
if (s == NULL || n == 0 || pwc == NULL)
|
|
2234
|
-
return (0);
|
|
2235
|
-
|
|
2236
|
-
/*
|
|
2237
|
-
* Determine the number of octets that make up this character from
|
|
2238
|
-
* the first octet, and a mask that extracts the interesting bits of
|
|
2239
|
-
* the first octet.
|
|
2240
|
-
*/
|
|
2241
|
-
ch = (unsigned char)*s;
|
|
2242
|
-
if ((ch & 0x80) == 0) {
|
|
2243
|
-
mask = 0x7f;
|
|
2244
|
-
len = 1;
|
|
2245
|
-
} else if ((ch & 0xe0) == 0xc0) {
|
|
2246
|
-
mask = 0x1f;
|
|
2247
|
-
len = 2;
|
|
2248
|
-
} else if ((ch & 0xf0) == 0xe0) {
|
|
2249
|
-
mask = 0x0f;
|
|
2250
|
-
len = 3;
|
|
2251
|
-
} else if ((ch & 0xf8) == 0xf0) {
|
|
2252
|
-
mask = 0x07;
|
|
2253
|
-
len = 4;
|
|
2254
|
-
} else {
|
|
2255
|
-
/* Invalid first byte. */
|
|
2256
|
-
return (-1);
|
|
2257
|
-
}
|
|
2258
|
-
|
|
2259
|
-
if (n < (size_t)len) {
|
|
2260
|
-
/* Valid first byte but truncated. */
|
|
2261
|
-
return (-2);
|
|
2262
|
-
}
|
|
2263
|
-
|
|
2264
|
-
/*
|
|
2265
|
-
* Decode the octet sequence representing the character in chunks
|
|
2266
|
-
* of 6 bits, most significant first.
|
|
2267
|
-
*/
|
|
2268
|
-
wch = (unsigned char)*s++ & mask;
|
|
2269
|
-
i = len;
|
|
2270
|
-
while (--i != 0) {
|
|
2271
|
-
if ((*s & 0xc0) != 0x80) {
|
|
2272
|
-
/* Invalid intermediate byte; consume one byte and
|
|
2273
|
-
* emit '?' */
|
|
2274
|
-
*pwc = '?';
|
|
2275
|
-
return (1);
|
|
2276
|
-
}
|
|
2277
|
-
wch <<= 6;
|
|
2278
|
-
wch |= *s++ & 0x3f;
|
|
2279
|
-
}
|
|
2280
|
-
|
|
2281
|
-
/* Assign the value to the output; out-of-range values
|
|
2282
|
-
* just get truncated. */
|
|
2283
|
-
*pwc = (wchar_t)wch;
|
|
2284
|
-
#ifdef WCHAR_MAX
|
|
2285
|
-
/*
|
|
2286
|
-
* If platform has WCHAR_MAX, we can do something
|
|
2287
|
-
* more sensible with out-of-range values.
|
|
2288
|
-
*/
|
|
2289
|
-
if (wch >= WCHAR_MAX)
|
|
2290
|
-
*pwc = '?';
|
|
2291
|
-
#endif
|
|
2292
|
-
/* Return number of bytes input consumed: 0 for end-of-string. */
|
|
2293
|
-
return (wch == L'\0' ? 0 : len);
|
|
2294
|
-
}
|
|
2295
|
-
|
|
2296
|
-
|
|
2297
2825
|
/*
|
|
2298
2826
|
* base64_decode - Base64 decode
|
|
2299
2827
|
*
|