diff options
| author | Ron Yorston <rmy@pobox.com> | 2026-03-24 12:15:33 +0000 |
|---|---|---|
| committer | Ron Yorston <rmy@pobox.com> | 2026-03-24 12:15:33 +0000 |
| commit | aaae1865727bcd53da581340456de34dfb182d5c (patch) | |
| tree | b0be881225fad8bcb14977854b248539b7d81ea2 | |
| parent | 052807cc3330b3c5c1fb60b93ad0d2039d6142df (diff) | |
| download | busybox-w32-zstd.tar.gz busybox-w32-zstd.tar.bz2 busybox-w32-zstd.zip | |
archival: support zstd in rpm and dpkgzstd
| -rw-r--r-- | archival/Config.src | 4 | ||||
| -rw-r--r-- | archival/dpkg.c | 6 | ||||
| -rw-r--r-- | archival/dpkg_deb.c | 4 | ||||
| -rw-r--r-- | archival/libarchive/Kbuild.src | 1 | ||||
| -rw-r--r-- | archival/libarchive/decompress_unzstd.c | 11 | ||||
| -rw-r--r-- | archival/libarchive/filter_accept_list_reassign.c | 6 | ||||
| -rw-r--r-- | archival/libarchive/get_header_tar_zstd.c | 20 | ||||
| -rw-r--r-- | archival/libarchive/open_transformer.c | 5 | ||||
| -rw-r--r-- | archival/tar.c | 18 | ||||
| -rw-r--r-- | include/bb_archive.h | 1 | ||||
| -rwxr-xr-x | testsuite/tar.tests | 22 |
11 files changed, 78 insertions, 20 deletions
diff --git a/archival/Config.src b/archival/Config.src index 1dbb0f3fa..bd75f0f65 100644 --- a/archival/Config.src +++ b/archival/Config.src | |||
| @@ -27,7 +27,9 @@ config FEATURE_SEAMLESS_Z | |||
| 27 | 27 | ||
| 28 | config FEATURE_SEAMLESS_ZSTD | 28 | config FEATURE_SEAMLESS_ZSTD |
| 29 | bool "Make tar, rpm, modprobe etc understand .zst data" | 29 | bool "Make tar, rpm, modprobe etc understand .zst data" |
| 30 | default y | 30 | default n |
| 31 | help | ||
| 32 | This requires external zstd and unzstd binaries. | ||
| 31 | 33 | ||
| 32 | INSERT | 34 | INSERT |
| 33 | 35 | ||
diff --git a/archival/dpkg.c b/archival/dpkg.c index a53da8df1..c007633dd 100644 --- a/archival/dpkg.c +++ b/archival/dpkg.c | |||
| @@ -1510,6 +1510,9 @@ static void init_archive_deb_control(archive_handle_t *ar_handle) | |||
| 1510 | #if ENABLE_FEATURE_SEAMLESS_XZ | 1510 | #if ENABLE_FEATURE_SEAMLESS_XZ |
| 1511 | llist_add_to(&(ar_handle->accept), (char*)"control.tar.xz"); | 1511 | llist_add_to(&(ar_handle->accept), (char*)"control.tar.xz"); |
| 1512 | #endif | 1512 | #endif |
| 1513 | #if ENABLE_FEATURE_SEAMLESS_ZSTD | ||
| 1514 | llist_add_to(&(ar_handle->accept), (char*)"control.tar.zst"); | ||
| 1515 | #endif | ||
| 1513 | 1516 | ||
| 1514 | /* Assign the tar handle as a subarchive of the ar handle */ | 1517 | /* Assign the tar handle as a subarchive of the ar handle */ |
| 1515 | ar_handle->dpkg__sub_archive = tar_handle; | 1518 | ar_handle->dpkg__sub_archive = tar_handle; |
| @@ -1537,6 +1540,9 @@ static void init_archive_deb_data(archive_handle_t *ar_handle) | |||
| 1537 | #if ENABLE_FEATURE_SEAMLESS_XZ | 1540 | #if ENABLE_FEATURE_SEAMLESS_XZ |
| 1538 | llist_add_to(&(ar_handle->accept), (char*)"data.tar.xz"); | 1541 | llist_add_to(&(ar_handle->accept), (char*)"data.tar.xz"); |
| 1539 | #endif | 1542 | #endif |
| 1543 | #if ENABLE_FEATURE_SEAMLESS_ZSTD | ||
| 1544 | llist_add_to(&(ar_handle->accept), (char*)"data.tar.zst"); | ||
| 1545 | #endif | ||
| 1540 | 1546 | ||
| 1541 | /* Assign the tar handle as a subarchive of the ar handle */ | 1547 | /* Assign the tar handle as a subarchive of the ar handle */ |
| 1542 | ar_handle->dpkg__sub_archive = tar_handle; | 1548 | ar_handle->dpkg__sub_archive = tar_handle; |
diff --git a/archival/dpkg_deb.c b/archival/dpkg_deb.c index dda931169..0c60ae41a 100644 --- a/archival/dpkg_deb.c +++ b/archival/dpkg_deb.c | |||
| @@ -77,6 +77,10 @@ int dpkg_deb_main(int argc UNUSED_PARAM, char **argv) | |||
| 77 | llist_add_to(&ar_archive->accept, (char*)"data.tar.xz"); | 77 | llist_add_to(&ar_archive->accept, (char*)"data.tar.xz"); |
| 78 | llist_add_to(&control_tar_llist, (char*)"control.tar.xz"); | 78 | llist_add_to(&control_tar_llist, (char*)"control.tar.xz"); |
| 79 | #endif | 79 | #endif |
| 80 | #if ENABLE_FEATURE_SEAMLESS_ZSTD | ||
| 81 | llist_add_to(&ar_archive->accept, (char*)"data.tar.zst"); | ||
| 82 | llist_add_to(&control_tar_llist, (char*)"control.tar.zst"); | ||
| 83 | #endif | ||
| 80 | 84 | ||
| 81 | /* Must have 1 or 2 args */ | 85 | /* Must have 1 or 2 args */ |
| 82 | opt = getopt32(argv, "^" "cefXx" | 86 | opt = getopt32(argv, "^" "cefXx" |
diff --git a/archival/libarchive/Kbuild.src b/archival/libarchive/Kbuild.src index 70c7fae5b..1af3cf61d 100644 --- a/archival/libarchive/Kbuild.src +++ b/archival/libarchive/Kbuild.src | |||
| @@ -39,6 +39,7 @@ DPKG_FILES:= \ | |||
| 39 | get_header_tar_bz2.o \ | 39 | get_header_tar_bz2.o \ |
| 40 | get_header_tar_lzma.o \ | 40 | get_header_tar_lzma.o \ |
| 41 | get_header_tar_xz.o \ | 41 | get_header_tar_xz.o \ |
| 42 | get_header_tar_zstd.o \ | ||
| 42 | 43 | ||
| 43 | INSERT | 44 | INSERT |
| 44 | 45 | ||
diff --git a/archival/libarchive/decompress_unzstd.c b/archival/libarchive/decompress_unzstd.c index 08930a3e5..c55ab8575 100644 --- a/archival/libarchive/decompress_unzstd.c +++ b/archival/libarchive/decompress_unzstd.c | |||
| @@ -4,16 +4,9 @@ | |||
| 4 | IF_DESKTOP(long long) int FAST_FUNC | 4 | IF_DESKTOP(long long) int FAST_FUNC |
| 5 | unpack_zstd_stream(transformer_state_t *xstate) | 5 | unpack_zstd_stream(transformer_state_t *xstate) |
| 6 | { | 6 | { |
| 7 | char *argv[] = {(char *)"unzstd", NULL}; | 7 | // FIXME Provide an internal implementation of zstd decompression. |
| 8 | char *argv[] = {(char *)"unzstd", (char *)"-cf", (char *)"-", NULL}; | ||
| 8 | 9 | ||
| 9 | /* Exec external unzstd. */ | ||
| 10 | #if BB_MMU | ||
| 11 | if (xstate->signature_skipped) { | ||
| 12 | /* If called from fork_transformer_with_no_sig() signature_skipped | ||
| 13 | * is just a flag, not the actual offset. But we know it's 4. */ | ||
| 14 | xlseek(xstate->src_fd, -4, SEEK_CUR); | ||
| 15 | } | ||
| 16 | #endif | ||
| 17 | xmove_fd(xstate->src_fd, STDIN_FILENO); | 10 | xmove_fd(xstate->src_fd, STDIN_FILENO); |
| 18 | xmove_fd(xstate->dst_fd, STDOUT_FILENO); | 11 | xmove_fd(xstate->dst_fd, STDOUT_FILENO); |
| 19 | BB_EXECVP_or_die(argv); | 12 | BB_EXECVP_or_die(argv); |
diff --git a/archival/libarchive/filter_accept_list_reassign.c b/archival/libarchive/filter_accept_list_reassign.c index 826c5c29d..a78186a6e 100644 --- a/archival/libarchive/filter_accept_list_reassign.c +++ b/archival/libarchive/filter_accept_list_reassign.c | |||
| @@ -55,6 +55,12 @@ char FAST_FUNC filter_accept_list_reassign(archive_handle_t *archive_handle) | |||
| 55 | archive_handle->dpkg__action_data_subarchive = get_header_tar_xz; | 55 | archive_handle->dpkg__action_data_subarchive = get_header_tar_xz; |
| 56 | return EXIT_SUCCESS; | 56 | return EXIT_SUCCESS; |
| 57 | } | 57 | } |
| 58 | if (ENABLE_FEATURE_SEAMLESS_ZSTD | ||
| 59 | && strcmp(name_ptr, "zst") == 0 | ||
| 60 | ) { | ||
| 61 | archive_handle->dpkg__action_data_subarchive = get_header_tar_zstd; | ||
| 62 | return EXIT_SUCCESS; | ||
| 63 | } | ||
| 58 | } | 64 | } |
| 59 | return EXIT_FAILURE; | 65 | return EXIT_FAILURE; |
| 60 | } | 66 | } |
diff --git a/archival/libarchive/get_header_tar_zstd.c b/archival/libarchive/get_header_tar_zstd.c new file mode 100644 index 000000000..6f1b4b977 --- /dev/null +++ b/archival/libarchive/get_header_tar_zstd.c | |||
| @@ -0,0 +1,20 @@ | |||
| 1 | /* vi: set sw=4 ts=4: */ | ||
| 2 | /* | ||
| 3 | * Licensed under GPLv2 or later, see file LICENSE in this source tree. | ||
| 4 | */ | ||
| 5 | #include "libbb.h" | ||
| 6 | #include "bb_archive.h" | ||
| 7 | |||
| 8 | char FAST_FUNC get_header_tar_zstd(archive_handle_t *archive_handle) | ||
| 9 | { | ||
| 10 | /* Can't lseek over pipes */ | ||
| 11 | archive_handle->seek = seek_by_read; | ||
| 12 | |||
| 13 | fork_transformer_with_sig(archive_handle->src_fd, unpack_zstd_stream, "unzstd"); | ||
| 14 | archive_handle->offset = 0; | ||
| 15 | while (get_header_tar(archive_handle) == EXIT_SUCCESS) | ||
| 16 | continue; | ||
| 17 | |||
| 18 | /* Can only do one file at a time */ | ||
| 19 | return EXIT_FAILURE; | ||
| 20 | } | ||
diff --git a/archival/libarchive/open_transformer.c b/archival/libarchive/open_transformer.c index 9f41c7b4f..375e7b249 100644 --- a/archival/libarchive/open_transformer.c +++ b/archival/libarchive/open_transformer.c | |||
| @@ -211,11 +211,14 @@ static transformer_state_t *setup_transformer_on_fd(int fd, int die_if_not_compr | |||
| 211 | } | 211 | } |
| 212 | 212 | ||
| 213 | if (ENABLE_FEATURE_SEAMLESS_ZSTD && xstate->magic.b16[0] == ZSTD_MAGIC1) { | 213 | if (ENABLE_FEATURE_SEAMLESS_ZSTD && xstate->magic.b16[0] == ZSTD_MAGIC1) { |
| 214 | xstate->signature_skipped = 4; | ||
| 215 | xread(fd, &xstate->magic.b16[1], 2); | 214 | xread(fd, &xstate->magic.b16[1], 2); |
| 216 | if (xstate->magic.b16[1] == ZSTD_MAGIC2) { | 215 | if (xstate->magic.b16[1] == ZSTD_MAGIC2) { |
| 217 | xstate->xformer = unpack_zstd_stream; | 216 | xstate->xformer = unpack_zstd_stream; |
| 218 | USE_FOR_NOMMU(xstate->xformer_prog = "unzstd";) | 217 | USE_FOR_NOMMU(xstate->xformer_prog = "unzstd";) |
| 218 | // FIXME We execute an external decompressor even on MMU. | ||
| 219 | // Force a seek back to the signature. | ||
| 220 | xstate->signature_skipped = 0; | ||
| 221 | xlseek(xstate->src_fd, -4, SEEK_CUR); | ||
| 219 | goto found_magic; | 222 | goto found_magic; |
| 220 | } | 223 | } |
| 221 | } | 224 | } |
diff --git a/archival/tar.c b/archival/tar.c index c3e9f0e0c..033e08105 100644 --- a/archival/tar.c +++ b/archival/tar.c | |||
| @@ -856,8 +856,8 @@ enum { | |||
| 856 | IF_FEATURE_TAR_NOPRESERVE_TIME(OPTBIT_NOPRESERVE_TIME,) | 856 | IF_FEATURE_TAR_NOPRESERVE_TIME(OPTBIT_NOPRESERVE_TIME,) |
| 857 | #if ENABLE_FEATURE_TAR_LONG_OPTIONS | 857 | #if ENABLE_FEATURE_TAR_LONG_OPTIONS |
| 858 | OPTBIT_STRIP_COMPONENTS, | 858 | OPTBIT_STRIP_COMPONENTS, |
| 859 | IF_FEATURE_SEAMLESS_LZMA(OPTBIT_LZMA ,) | ||
| 860 | IF_FEATURE_SEAMLESS_ZSTD(OPTBIT_ZSTD ,) | 859 | IF_FEATURE_SEAMLESS_ZSTD(OPTBIT_ZSTD ,) |
| 860 | IF_FEATURE_SEAMLESS_LZMA(OPTBIT_LZMA ,) | ||
| 861 | OPTBIT_NORECURSION, | 861 | OPTBIT_NORECURSION, |
| 862 | IF_FEATURE_TAR_TO_COMMAND(OPTBIT_2COMMAND ,) | 862 | IF_FEATURE_TAR_TO_COMMAND(OPTBIT_2COMMAND ,) |
| 863 | OPTBIT_NUMERIC_OWNER, | 863 | OPTBIT_NUMERIC_OWNER, |
| @@ -884,8 +884,8 @@ enum { | |||
| 884 | OPT_AUTOCOMPRESS_BY_EXT = 1 << OPTBIT_AUTOCOMPRESS_BY_EXT, // a | 884 | OPT_AUTOCOMPRESS_BY_EXT = 1 << OPTBIT_AUTOCOMPRESS_BY_EXT, // a |
| 885 | OPT_NOPRESERVE_TIME = IF_FEATURE_TAR_NOPRESERVE_TIME((1 << OPTBIT_NOPRESERVE_TIME)) + 0, // m | 885 | OPT_NOPRESERVE_TIME = IF_FEATURE_TAR_NOPRESERVE_TIME((1 << OPTBIT_NOPRESERVE_TIME)) + 0, // m |
| 886 | OPT_STRIP_COMPONENTS = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_STRIP_COMPONENTS)) + 0, // strip-components | 886 | OPT_STRIP_COMPONENTS = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_STRIP_COMPONENTS)) + 0, // strip-components |
| 887 | OPT_LZMA = IF_FEATURE_TAR_LONG_OPTIONS(IF_FEATURE_SEAMLESS_LZMA((1 << OPTBIT_LZMA))) + 0, // lzma | ||
| 888 | OPT_ZSTD = IF_FEATURE_TAR_LONG_OPTIONS(IF_FEATURE_SEAMLESS_ZSTD((1 << OPTBIT_ZSTD))) + 0, // zstd | 887 | OPT_ZSTD = IF_FEATURE_TAR_LONG_OPTIONS(IF_FEATURE_SEAMLESS_ZSTD((1 << OPTBIT_ZSTD))) + 0, // zstd |
| 888 | OPT_LZMA = IF_FEATURE_TAR_LONG_OPTIONS(IF_FEATURE_SEAMLESS_LZMA((1 << OPTBIT_LZMA))) + 0, // lzma | ||
| 889 | OPT_NORECURSION = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_NORECURSION )) + 0, // no-recursion | 889 | OPT_NORECURSION = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_NORECURSION )) + 0, // no-recursion |
| 890 | OPT_2COMMAND = IF_FEATURE_TAR_TO_COMMAND( (1 << OPTBIT_2COMMAND )) + 0, // to-command | 890 | OPT_2COMMAND = IF_FEATURE_TAR_TO_COMMAND( (1 << OPTBIT_2COMMAND )) + 0, // to-command |
| 891 | OPT_NUMERIC_OWNER = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_NUMERIC_OWNER )) + 0, // numeric-owner | 891 | OPT_NUMERIC_OWNER = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_NUMERIC_OWNER )) + 0, // numeric-owner |
| @@ -932,13 +932,13 @@ static const char tar_longopts[] ALIGN1 = | |||
| 932 | # if ENABLE_FEATURE_TAR_NOPRESERVE_TIME | 932 | # if ENABLE_FEATURE_TAR_NOPRESERVE_TIME |
| 933 | "touch\0" No_argument "m" | 933 | "touch\0" No_argument "m" |
| 934 | # endif | 934 | # endif |
| 935 | "strip-components\0" Required_argument "\xf8" | 935 | "strip-components\0" Required_argument "\xf7" |
| 936 | # if ENABLE_FEATURE_SEAMLESS_ZSTD | ||
| 937 | "zstd\0" No_argument "\xf8" | ||
| 938 | # endif | ||
| 936 | # if ENABLE_FEATURE_SEAMLESS_LZMA | 939 | # if ENABLE_FEATURE_SEAMLESS_LZMA |
| 937 | "lzma\0" No_argument "\xf9" | 940 | "lzma\0" No_argument "\xf9" |
| 938 | # endif | 941 | # endif |
| 939 | # if ENABLE_FEATURE_SEAMLESS_ZSTD | ||
| 940 | "zstd\0" No_argument "\xf7" | ||
| 941 | # endif | ||
| 942 | "no-recursion\0" No_argument "\xfa" | 942 | "no-recursion\0" No_argument "\xfa" |
| 943 | # if ENABLE_FEATURE_TAR_TO_COMMAND | 943 | # if ENABLE_FEATURE_TAR_TO_COMMAND |
| 944 | "to-command\0" Required_argument "\xfb" | 944 | "to-command\0" Required_argument "\xfb" |
| @@ -1033,7 +1033,7 @@ int tar_main(int argc UNUSED_PARAM, char **argv) | |||
| 1033 | IF_FEATURE_SEAMLESS_Z( "Z" ) | 1033 | IF_FEATURE_SEAMLESS_Z( "Z" ) |
| 1034 | "a" | 1034 | "a" |
| 1035 | IF_FEATURE_TAR_NOPRESERVE_TIME("m") | 1035 | IF_FEATURE_TAR_NOPRESERVE_TIME("m") |
| 1036 | IF_FEATURE_TAR_LONG_OPTIONS("\xf8:") // --strip-components | 1036 | IF_FEATURE_TAR_LONG_OPTIONS("\xf7:") // --strip-components |
| 1037 | "\0" | 1037 | "\0" |
| 1038 | "tt:vv:" // count -t,-v | 1038 | "tt:vv:" // count -t,-v |
| 1039 | #if ENABLE_FEATURE_TAR_LONG_OPTIONS && ENABLE_FEATURE_TAR_FROM | 1039 | #if ENABLE_FEATURE_TAR_LONG_OPTIONS && ENABLE_FEATURE_TAR_FROM |
| @@ -1043,7 +1043,7 @@ int tar_main(int argc UNUSED_PARAM, char **argv) | |||
| 1043 | IF_FEATURE_TAR_CREATE("c--tx:t--cx:x--ct") // mutually exclusive | 1043 | IF_FEATURE_TAR_CREATE("c--tx:t--cx:x--ct") // mutually exclusive |
| 1044 | IF_NOT_FEATURE_TAR_CREATE("t--x:x--t") // mutually exclusive | 1044 | IF_NOT_FEATURE_TAR_CREATE("t--x:x--t") // mutually exclusive |
| 1045 | #if ENABLE_FEATURE_TAR_LONG_OPTIONS | 1045 | #if ENABLE_FEATURE_TAR_LONG_OPTIONS |
| 1046 | ":\xf8+" // --strip-components=NUM | 1046 | ":\xf7+" // --strip-components=NUM |
| 1047 | #endif | 1047 | #endif |
| 1048 | LONGOPTS | 1048 | LONGOPTS |
| 1049 | , &base_dir // -C dir | 1049 | , &base_dir // -C dir |
| @@ -1083,8 +1083,8 @@ int tar_main(int argc UNUSED_PARAM, char **argv) | |||
| 1083 | showopt(OPT_AUTOCOMPRESS_BY_EXT); | 1083 | showopt(OPT_AUTOCOMPRESS_BY_EXT); |
| 1084 | showopt(OPT_NOPRESERVE_TIME ); | 1084 | showopt(OPT_NOPRESERVE_TIME ); |
| 1085 | showopt(OPT_STRIP_COMPONENTS); | 1085 | showopt(OPT_STRIP_COMPONENTS); |
| 1086 | showopt(OPT_LZMA ); | ||
| 1087 | showopt(OPT_ZSTD ); | 1086 | showopt(OPT_ZSTD ); |
| 1087 | showopt(OPT_LZMA ); | ||
| 1088 | showopt(OPT_NORECURSION ); | 1088 | showopt(OPT_NORECURSION ); |
| 1089 | showopt(OPT_2COMMAND ); | 1089 | showopt(OPT_2COMMAND ); |
| 1090 | showopt(OPT_NUMERIC_OWNER ); | 1090 | showopt(OPT_NUMERIC_OWNER ); |
diff --git a/include/bb_archive.h b/include/bb_archive.h index eb784d464..916c51bab 100644 --- a/include/bb_archive.h +++ b/include/bb_archive.h | |||
| @@ -213,6 +213,7 @@ char get_header_tar_gz(archive_handle_t *archive_handle) FAST_FUNC; | |||
| 213 | char get_header_tar_bz2(archive_handle_t *archive_handle) FAST_FUNC; | 213 | char get_header_tar_bz2(archive_handle_t *archive_handle) FAST_FUNC; |
| 214 | char get_header_tar_lzma(archive_handle_t *archive_handle) FAST_FUNC; | 214 | char get_header_tar_lzma(archive_handle_t *archive_handle) FAST_FUNC; |
| 215 | char get_header_tar_xz(archive_handle_t *archive_handle) FAST_FUNC; | 215 | char get_header_tar_xz(archive_handle_t *archive_handle) FAST_FUNC; |
| 216 | char get_header_tar_zstd(archive_handle_t *archive_handle) FAST_FUNC; | ||
| 216 | 217 | ||
| 217 | void seek_by_jump(int fd, off_t amount) FAST_FUNC; | 218 | void seek_by_jump(int fd, off_t amount) FAST_FUNC; |
| 218 | void seek_by_read(int fd, off_t amount) FAST_FUNC; | 219 | void seek_by_read(int fd, off_t amount) FAST_FUNC; |
diff --git a/testsuite/tar.tests b/testsuite/tar.tests index 0f2e89112..d2155add7 100755 --- a/testsuite/tar.tests +++ b/testsuite/tar.tests | |||
| @@ -245,6 +245,28 @@ SKIP= | |||
| 245 | cd .. || exit 1; rm -rf tar.tempdir 2>/dev/null | 245 | cd .. || exit 1; rm -rf tar.tempdir 2>/dev/null |
| 246 | 246 | ||
| 247 | mkdir tar.tempdir && cd tar.tempdir || exit 1 | 247 | mkdir tar.tempdir && cd tar.tempdir || exit 1 |
| 248 | # Do we detect ZSTD-compressed data (even w/o .tar.zst extension)? | ||
| 249 | # (uuencoded hello_world.tar.zst contains one empty file named "hello_world") | ||
| 250 | # Currently we require an external unzstd program to be available. | ||
| 251 | optional UUDECODE FEATURE_TAR_AUTODETECT FEATURE_SEAMLESS_ZSTD | ||
| 252 | command -v unzstd >/dev/null || SKIP=1 | ||
| 253 | testing "tar extract tar.zst" "\ | ||
| 254 | uudecode -o input && tar tf input && echo Ok | ||
| 255 | " "\ | ||
| 256 | hello_world | ||
| 257 | Ok | ||
| 258 | " \ | ||
| 259 | "" "\ | ||
| 260 | begin-base64 644 hello_world.tar.zst | ||
| 261 | KLUv/QRYpQIA5ANoZWxsb193b3JsZAAwMDAwNjQ0ADAwMDE3NTAAMTUxNjA0 | ||
| 262 | NTQwMzAAMDExNDc3ACAwAHVzdGFyICAAcm15AAcAtAbwMBQOAJMCkBq8wApX | ||
| 263 | awJ0ak0T/A== | ||
| 264 | ==== | ||
| 265 | " | ||
| 266 | SKIP= | ||
| 267 | cd .. || exit 1; rm -rf tar.tempdir 2>/dev/null | ||
| 268 | |||
| 269 | mkdir tar.tempdir && cd tar.tempdir || exit 1 | ||
| 248 | # On extract, everything up to and including last ".." component is stripped | 270 | # On extract, everything up to and including last ".." component is stripped |
| 249 | optional FEATURE_TAR_CREATE | 271 | optional FEATURE_TAR_CREATE |
| 250 | testing "tar strips /../ on extract" "\ | 272 | testing "tar strips /../ on extract" "\ |
