# libarchive -- the four compression backends, driven in BOTH directions. # # 98-libarchive.test asserts from `bsdtar --version` that zlib, bz2lib, liblzma # and libzstd were linked. That is a claim about the link, not about the codec: # a backend can be present and still be wrong, and the whole reason libarchive # is worth having here is that a caller can hand it a .tar.gz, .tar.bz2, .tar.xz # or .tar.zst without knowing which. So each codec is exercised twice. # # THE SECOND DIRECTION IS THE ONE THAT CANNOT BE FAKED. Compressing and then # decompressing with the same library proves only that it is self-consistent -- # a codec that emitted its own private framing would round-trip perfectly and # still be unable to read anything real. This image also ships gzip, bzip2, xz # and zstd as standalone CLIs (BRINTOS-80 / -123 / -127 and the bzip2 pickup), # each a DIFFERENT implementation of the same format, so every codec here is # additionally asked to read a stream one of those wrote. That is the same # argument 96-erofs-utils.test makes with its shipped upstream-built fixture, # obtained here without shipping a fixture at all. # # Payload is deliberately ~18 KiB rather than the 37 KiB its sibling uses: this # file forks four compressors and four decompressors twice over, and process # count against the runner's 60 s cap -- not compression work -- is what put # 56-lz4.test and the first draft of 97-parted.test over budget. . "$BST_LIB" require bsdtar libarchive/bsdtar-present T=${TMPDIR:-/tmp}/bst-libarchive-c.$$ rm -rf "$T"; mkdir -p "$T/src" i=0 while [ $i -lt 256 ]; do printf 'the quick brown fox jumps over the lazy dog 0123456789 ABCDEFGHIJKLMNOP\n' i=$((i + 1)) done > "$T/src/compressible.txt" printf 'libarchive fixture\n' > "$T/src/top.txt" SRCSZ=$(wc -c < "$T/src/compressible.txt" | tr -d ' ') bsdtar -C "$T/src" -cf "$T/plain.tar" . 2> /dev/null TARSZ=$(wc -c < "$T/plain.tar" | tr -d ' ') # ours # create with libarchive, assert the result is materially smaller than the tar # it came from, extract with libarchive, compare byte-for-byte. # # The LOWER size bound is not decoration: a failed create leaves a zero-byte or # header-only file behind, and an upper-bound-only assertion passes on it -- the # exact way a write-side case reported green on a run where nothing was written. ours() { _id=$1; _flag=$2; _tag=$3; _a=$T/ours.$_tag; _o=$T/o.$_tag if bsdtar -C "$T/src" -c "$_flag" -f "$_a" . 2> /dev/null; then bst_ok "libarchive/$_id-create" else bst_notok "libarchive/$_id-create" "bsdtar -c $_flag failed" fi _sz=$(wc -c < "$_a" 2> /dev/null | tr -d ' ') if [ -n "$_sz" ] && [ "$_sz" -gt 64 ] && [ "$_sz" -lt "$TARSZ" ]; then bst_ok "libarchive/$_id-smaller" else bst_notok "libarchive/$_id-smaller" \ "archive is ${_sz:-absent} bytes; a real one holding a $TARSZ byte tar is >64 and <$TARSZ" fi rm -rf "$_o"; mkdir -p "$_o" # -x auto-detects the codec from the stream, so no flag is passed back in: # a decoder picked by sniffing is the one a real caller gets. if bsdtar -C "$_o" -xf "$_a" 2> /dev/null; then bst_ok "libarchive/$_id-extract" else bst_notok "libarchive/$_id-extract" "bsdtar -xf failed on our own $_tag archive" fi check "libarchive/$_id-roundtrip" cmp -s "$T/src/compressible.txt" "$_o/compressible.txt" } ours gzip -z gz ours bzip2 -j bz2 ours xz -J xz ours zstd --zstd zst # theirs # compress the SAME plain tar with the image's standalone CLI, then read it # back with libarchive. Nothing libarchive wrote is involved in the input. theirs() { _id=$1; _tag=$2; shift 2 _a=$T/theirs.$_tag; _o=$T/t.$_tag if ! command -v "$1" > /dev/null 2>&1; then bst_skip "libarchive/$_id-foreign" "$1 is not on this image" return fi "$@" < "$T/plain.tar" > "$_a" 2> /dev/null rm -rf "$_o"; mkdir -p "$_o" if [ -s "$_a" ] && bsdtar -C "$_o" -xf "$_a" 2> /dev/null; then bst_ok "libarchive/$_id-foreign" else bst_notok "libarchive/$_id-foreign" "bsdtar could not read a $_tag stream written by $1" fi check "libarchive/$_id-foreign-content" cmp -s "$T/src/compressible.txt" "$_o/compressible.txt" } theirs gzip gz gzip -c theirs bzip2 bz2 bzip2 -c theirs xz xz xz -c theirs zstd zst zstd -q -c # ------------------------------------------------------------------- control # A codec that "decompressed" anything handed to it would satisfy every foreign # case above without doing any of the work. # # Non-zero bytes, deliberately: a run of ZEROES is a valid empty tar (the # all-zero block is tar's end-of-archive marker), so a zeroes-based control goes # red against a correct bsdtar. See the longer note in 98-libarchive.test. i=0 while [ $i -lt 128 ]; do printf 'NOT-A-COMPRESSED-STREAM-%d-qwertyuiopasdfghjkl\n' "$i" i=$((i + 1)) done > "$T/junk.gz" if bsdtar -tf "$T/junk.gz" > /dev/null 2>&1; then bst_notok libarchive/reject-junk-stream "bsdtar decoded non-archive text named .gz as an archive" else bst_ok libarchive/reject-junk-stream fi rm -rf "$T"