. "$BST_LIB" # libzip 1.10.1 -- the first ZIP *library* on this image. Info-ZIP zip (BRINTOS-152) # and unzip (BRINTOS-151) already ship here, but they are programs; libzip is the API # a consumer links, and it is also the only ZIP implementation here that modifies an # archive incrementally instead of rewriting it. # # The port ships three things and this suite has one leg for each: # # /usr/bin/{zipcmp,zipmerge,ziptool} the CLI tools (libzip) # /usr/lib/libzip.a the archive a consumer links (-staticdev) # /usr/include/{zip.h,zipconf.h} the API (-dev) # # --------------------------------------------------------------------------- # WHY THERE IS A PROBE AS WELL AS A CLI # # The CLI is real evidence -- unlike jansson or oniguruma, this port ships consumers # that run on the image -- but it reaches only part of the library. ziptool never # constructs a zip_source_function, never builds an archive in memory, and cannot # report a zip_error_t code; and libzip's central abstraction is precisely the # caller-supplied callback that libzip calls back into (OPEN/READ/CLOSE/STAT/ # SUPPORTS/FREE, plus the progress and cancel callbacks fired from inside # zip_close()). Those are indirect calls across a TU boundary -- the surface the # hwjs-cc coroutinize pass has to get right, and the class that made BRINTOS-217 # (oniguruma) compile and package perfectly and then return silently wrong offsets # to every caller. So data/libzip-probe is cross-linked with wasmcc-glibc against # THE VERY ARCHIVE THAT SHIPS and run below; its source is src/libzip_probe.c, and # it scores 158/158 against an x86_64 build of the identical release. # # THE ARCHIVE-MODIFY CASES ARE ALSO A LIVE PLATFORM PROBE. libzip commits a change # by writing a sibling temp file (mkstemp + fchmod) and rename(2)-ing it over the # original, so every add/replace/delete on an on-disk archive exercises that trio. # The probe's in-memory group never touches the filesystem at all, so "file cases # red, probe's mem-* cases green" reads as mkstemp/rename and not as libzip. # # ABSENCES ARE ASSERTED, NOT ASSUMED. This build has bzip2 and xz compiled in and # zstd and WinZip AES deliberately out (no zstd in the recipe's PACKAGECONFIG; # openssl is blocked on hwjs-cc#4, so HAVE_CRYPTO is unset). Both halves are # checked, three independent ways -- ziptool's own -h capability list, the symbols # in the shipped archive, and the library's zip_*_method_supported() answers -- so # the day openssl or zstd lands here the suite notices instead of quietly widening. # # FORK BUDGET: the runner bounds each suite by wall clock and on this runtime the # forking is the cost rather than the work (the cjson suite was killed at 156 # check_out cases). So the payload leg uses shell builtins with two `cat`s, the # capability matrix is read from ONE `ziptool -h`, the symbol list from ONE # `strings`, and the probe runs ONCE with its exit status taken from that same run. # --------------------------------------------------------------------------- require ziptool libzip/present bin=/usr/bin incd=/usr/include # BRINTOS-1619 allow-listed libzip, and libzip is cmake -- so at # BRINTOS_PACKAGE_SHARED = "1" the flip takes the static half away and no # libzip-staticdev is generated at all. The symbol assertions below read names out # of this file with strings/grep, which works the same on either artifact # (measured: zip_open, zip_close, zip_discard, zip_file_add and # zip_algorithm_deflate all appear in libzip.so.5.5), so the suite points at # whichever shape shipped rather than asserting one of them. if [ -e /usr/lib/libzip.a ]; then lib=/usr/lib/libzip.a zipshared=0 else lib=$(ls /usr/lib/libzip.so.*.* 2>/dev/null | head -1) zipshared=1 fi pc=/usr/lib/pkgconfig/libzip.pc cm=/usr/lib/cmake/libzip nl=' ' # hasfile -- ok iff is a non-empty regular file. # hasexe -- ok iff is executable. # has -- ok iff contains the literal . # hasnot -- ok iff it does NOT (an asserted absence). # hasline -- ok iff carries as a WHOLE line, so # zip_close cannot satisfy a lookup for zip_clos # and zip_source_buffer_create cannot satisfy one # for zip_source_buffer. # noline -- the whole-line counterpart of hasnot. hasfile() { if [ -s "$2" ]; then bst_ok "$1"; else bst_notok "$1" "absent or empty: $2"; fi; } hasexe() { if [ -x "$2" ]; then bst_ok "$1"; else bst_notok "$1" "not executable: $2"; fi; } has() { case "$3" in *"$2"*) bst_ok "$1" ;; *) bst_notok "$1" "not found: $2" ;; esac; } hasnot() { case "$3" in *"$2"*) bst_notok "$1" "unexpectedly present: $2" ;; *) bst_ok "$1" ;; esac; } hasline() { case "$nl$3$nl" in *"$nl$2$nl"*) bst_ok "$1" ;; *) bst_notok "$1" "not in archive: $2" ;; esac; } noline() { case "$nl$3$nl" in *"$nl$2$nl"*) bst_notok "$1" "unexpectedly in archive: $2" ;; *) bst_ok "$1" ;; esac; } # out_rc -- ok iff exits AND says # . bst.sh has check_out (needle, but rc MUST be 0) and check_rc (rc, but no # output), and every diagnostic below is a DELIBERATE non-zero exit whose message is # the thing being checked -- so neither helper fits and check_out would report a # correct tool as broken. BRINTOS-280 and BRINTOS-281 each hit this trap and worked # around it inline; this is the third occurrence, so promoting out_rc into # lib/bst.sh is the durable fix. out_rc() { _id=$1; _want=$2; _needle=$3; shift 3 _o=$("$@" 2>&1); _r=$? case "$_o" in *"$_needle"*) _h=1 ;; *) _h=0 ;; esac if [ "$_r" -eq "$_want" ] && [ "$_h" -eq 1 ]; then bst_ok "$_id" else bst_notok "$_id" "rc=$_r want=$_want needle:'$_needle' got:'$(_bst_1line "$_o")'"; fi } # --- the shipped payload ------------------------------------------------------ hasexe libzip/bin-zipcmp "$bin/zipcmp" hasexe libzip/bin-zipmerge "$bin/zipmerge" hasexe libzip/bin-ziptool "$bin/ziptool" hasfile libzip/header-zip "$incd/zip.h" hasfile libzip/header-zipconf "$incd/zipconf.h" hasfile libzip/archive "$lib" hasfile libzip/pkgconfig "$pc" hasfile libzip/cmake-config "$cm/libzip-config.cmake" hasfile libzip/cmake-version "$cm/libzip-config-version.cmake" hasfile libzip/cmake-targets "$cm/libzip-targets.cmake" hasfile libzip/cmake-mod-zstd "$cm/modules/Findzstd.cmake" hasfile libzip/cmake-mod-nettle "$cm/modules/FindNettle.cmake" hasfile libzip/cmake-mod-mbedtls "$cm/modules/FindMbedTLS.cmake" # The .pc's Libs.private IS the compiled-in codec list -- cmake builds it from the # zip target's LINK_LIBRARIES -- so these four lines are a configuration assertion # and not decoration. A build that lost bzip2 or xz support would still ship a # perfectly valid archive and fail here. pctext=$(cat "$pc" 2>/dev/null) has libzip/pc-name "Name: libzip" "$pctext" has libzip/pc-version "Version: 1.10.1" "$pctext" has libzip/pc-libs "-lzip" "$pctext" has libzip/pc-cflags "-I\${includedir}" "$pctext" has libzip/pc-priv-z "-lz" "$pctext" has libzip/pc-priv-bz2 "-lbz2" "$pctext" # xz IS in the stock feature set and is now compiled in on BOTH arms. It was not: # BRINTOS-2264 measured the converted arm at "-lbz2 -lz" against the static arm's # "-lbz2 -llzma -lz", because find_package(LibLZMA 5.2) puts three # CHECK_LIBRARY_EXISTS results in its REQUIRED_VARS and a configure-time link # probe cannot link against a converted `.so` on this arm. BRINTOS-2321 seeds # those three answers in the recipe, so HAVE_LIBLZMA is defined either way and # this line is once again one assertion rather than two shapes of one. has libzip/pc-priv-lzma "-llzma" "$pctext" hasnot libzip/pc-no-zstd "-lzstd" "$pctext" hasnot libzip/pc-no-crypto "-lcrypto" "$pctext" # zipconf.h is GENERATED by cmake from cmake-zipconf.h.in, so it is the one header # whose content proves the configure step ran on this arm rather than being copied. hdrtext=$(cat "$incd/zipconf.h" 2>/dev/null) has libzip/hdr-version "LIBZIP_VERSION \"1.10.1\"" "$hdrtext" has libzip/hdr-major "LIBZIP_VERSION_MAJOR 1" "$hdrtext" has libzip/hdr-minor "LIBZIP_VERSION_MINOR 10" "$hdrtext" has libzip/hdr-micro "LIBZIP_VERSION_MICRO 1" "$hdrtext" # ZIP_STATIC is what makes ZIP_EXTERN a plain extern. cmake writes it from the # build it actually ran, so it follows the shape: measured `#define ZIP_STATIC` # on the static arm and `/* #undef ZIP_STATIC */` on the converted one. Asserting # the spelling that matches the library that shipped is what keeps this case # meaningful -- a -dev package whose header disagrees with its library is the # thing that breaks a consumer link, in either direction. if [ -e /usr/lib/libzip.a ]; then has libzip/hdr-static "define ZIP_STATIC" "$hdrtext" else has libzip/hdr-notstatic "#undef ZIP_STATIC" "$hdrtext" fi has libzip/hdr-int64 "zip_int64_t" "$hdrtext" # --- symbol completeness, read out of the INSTALLED archive ------------------- # Matched as whole lines. The codec block below is the compiled-in feature set # stated a second, independent way from the .pc above. arcsyms=$(strings -a "$lib" 2>/dev/null | grep -o 'zip_[a-z0-9_]*' | sort -u) [ -n "$arcsyms" ] || arcsyms=$(grep -ao 'zip_[a-z0-9_]*' "$lib" 2>/dev/null | sort -u) hasline libzip/sym-open zip_open "$arcsyms" hasline libzip/sym-open-from-source zip_open_from_source "$arcsyms" hasline libzip/sym-close zip_close "$arcsyms" hasline libzip/sym-discard zip_discard "$arcsyms" hasline libzip/sym-file-add zip_file_add "$arcsyms" hasline libzip/sym-file-replace zip_file_replace "$arcsyms" hasline libzip/sym-file-rename zip_file_rename "$arcsyms" hasline libzip/sym-dir-add zip_dir_add "$arcsyms" hasline libzip/sym-delete zip_delete "$arcsyms" hasline libzip/sym-fopen zip_fopen "$arcsyms" hasline libzip/sym-fread zip_fread "$arcsyms" hasline libzip/sym-fseek zip_fseek "$arcsyms" hasline libzip/sym-ftell zip_ftell "$arcsyms" hasline libzip/sym-stat zip_stat "$arcsyms" hasline libzip/sym-stat-index zip_stat_index "$arcsyms" hasline libzip/sym-name-locate zip_name_locate "$arcsyms" hasline libzip/sym-num-entries zip_get_num_entries "$arcsyms" hasline libzip/sym-source-buffer zip_source_buffer "$arcsyms" hasline libzip/sym-source-function zip_source_function "$arcsyms" hasline libzip/sym-source-file zip_source_file "$arcsyms" hasline libzip/sym-source-zip-file zip_source_zip_file "$arcsyms" hasline libzip/sym-source-keep zip_source_keep "$arcsyms" hasline libzip/sym-progress-cb zip_register_progress_callback_with_state "$arcsyms" hasline libzip/sym-cancel-cb zip_register_cancel_callback_with_state "$arcsyms" hasline libzip/sym-error-strerror zip_error_strerror "$arcsyms" hasline libzip/sym-cm-supported zip_compression_method_supported "$arcsyms" hasline libzip/sym-em-supported zip_encryption_method_supported "$arcsyms" hasline libzip/sym-libzip-version zip_libzip_version "$arcsyms" hasline libzip/sym-set-compression zip_set_file_compression "$arcsyms" hasline libzip/sym-unchange-all zip_unchange_all "$arcsyms" # The codecs, by the backend entry each one calls. zip_algorithm_* are data # objects, named only in DWARF, so a stripped .so has none of them; a backend # entry is named in the import section (converted) or the name section (merged). allsyms=$(strings -a "$lib" 2>/dev/null | grep -o '[A-Za-z_][A-Za-z0-9_]*' | sort -u) hasline libzip/sym-algorithm-deflate deflateInit2_ "$allsyms" hasline libzip/sym-algorithm-bzip2 BZ2_bzCompressInit "$allsyms" hasline libzip/sym-algorithm-xz lzma_stream_encoder "$allsyms" # PKWARE needs no crypto library, so it survives HAVE_CRYPTO being unset hasline libzip/sym-pkware-decode zip_source_pkware_decode "$arcsyms" # ...and these are the ones that must NOT be here noline libzip/sym-no-algorithm-zstd ZSTD_createCCtx "$allsyms" noline libzip/sym-no-winzip-aes _zip_winzip_aes_new "$allsyms" noline libzip/sym-no-crypto-openssl EVP_CIPHER_CTX_new "$allsyms" # --- the needed entry the three tools live or die by (BRINTOS-2264) ----------- # On the converted arm libzip.so.5.5 imports the six BZ2_* symbols and records NO # needed entry of its own -- no side module on this image does (0 of 85, measured # by BRINTOS-2191 section 4), because the coroutinize pass wants every side-module # TU as bitcode and a finished .so never is. So the ONLY thing that can satisfy # them is the MAIN's own needed set, and cmake stops handing BZip2 to the three # tools the moment `zip` goes shared: while it is an archive they get it as # $, and a shared ELF would carry it in DT_NEEDED instead. # Without the entry all three ship DEAD -- not slow, not degraded, refused at exec # by the loader -- which is how BRINTOS-2191's whole-image census found them. # # THIS IS CHECKED SEPARATELY FROM THE CLI CASES BELOW ON PURPOSE. Every one of # those would also go red, but each reports only that its command could not be # exec'd; none of them names the missing entry, which is why the defect needed a # census to diagnose rather than a suite. This case names it directly. # # The needed list is a JSON array in the main's own `wasm.linux.needed` record, # so the match is scoped to that record rather than to the file at large -- the # name appearing anywhere else in the image would not be a needed entry. The # entry is the on-target file name, digest-qualified, so the assertion stops at # the "libbz2.so." prefix: the digest changes with every bzip2 rebuild and # pinning it would make this case fail on a rebuild that is entirely correct. # # liblzma IS CHECKED THE SAME WAY, AND ONLY BECOMES REACHABLE WITH BRINTOS-2321. # The recipe's patch attaches LibLZMA::LibLZMA to the three tools under # `if(HAVE_LIBLZMA)`, so while that stayed undefined on the converted arm the arm # never fired and there was no entry to look for -- the xz codec was not compiled # into libzip.so either, so nothing wanted one. With HAVE_LIBLZMA defined, # zip_algorithm_xz.c is in the library, its lzma_* imports are as dangling as the # BZ2_* ones, and the tools need the entry for exactly the same reason. if [ "$zipshared" = "1" ]; then for _t in zipcmp zipmerge ziptool; do for _l in bz2:BZ2_:BRINTOS-2264 lzma:lzma_:BRINTOS-2321; do _so=${_l%%:*}; _rest=${_l#*:}; _pfx=${_rest%%:*}; _tkt=${_rest##*:} # strings first, then grep -a on the binary itself -- the same hedge the # archive-symbol leg above uses, so a busybox strings that declines a wasm # object cannot turn a present entry into a red. _n=$(strings -a "$bin/$_t" 2>/dev/null | grep -c "wasm\.linux\.needed.*\"lib$_so\.so\.") || _n=0 [ "${_n:-0}" -eq 0 ] && _n=$(grep -ac "wasm\.linux\.needed.*\"lib$_so\.so\." "$bin/$_t" 2>/dev/null) if [ "${_n:-0}" -ge 1 ]; then bst_ok "libzip/needed-$_so-$_t" else bst_notok "libzip/needed-$_so-$_t" \ "$_t records no lib$_so needed entry, so libzip.so's $_pfx* imports cannot bind and it will not exec ($_tkt)" fi done done fi # --- the CLI ------------------------------------------------------------------ w=${TMPDIR:-/tmp}/bst-libzip.$$ mkdir -p "$w" 2>/dev/null cd "$w" 2>/dev/null || { bst_notok libzip/workdir "cannot create $w"; exit 0; } check_out libzip/cli-zipcmp-version "zipcmp (libzip 1.10.1)" zipcmp -V check_out libzip/cli-zipmerge-version "zipmerge (libzip 1.10.1)" zipmerge -V # ziptool -h prints its method lists by CALLING zip_compression_method_supported() # and zip_encryption_method_supported(), so this one fork is the whole capability # matrix as the shipped binary sees it -- a third independent statement of it. zh=$(ziptool -h 2>&1) has libzip/cli-cap-deflate "${nl} deflate" "$zh" has libzip/cli-cap-store "${nl} store" "$zh" has libzip/cli-cap-bzip2 "${nl} bzip2" "$zh" has libzip/cli-cap-xz "${nl} xz" "$zh" has libzip/cli-cap-pkware "${nl} PKWARE" "$zh" hasnot libzip/cli-cap-no-zstd "${nl} zstd" "$zh" hasnot libzip/cli-cap-no-aes "AES-" "$zh" # Build one archive and drive it. `ziptool -n` creates; each invocation opens, # applies its commands and commits, so every one of these is also a pass through the # mkstemp+rename commit path. printf 'payload-alpha\n' > a.txt printf 'payload-beta\n' > b.txt # 8 KiB of compressible text, by string concatenation rather than a loop of appends line='the quick brown fox jumps over the lazy dog 0123456789' blk="$line$line$line$line$line$line$line$line" s="$blk$blk$blk$blk$blk$blk$blk$blk" s="$s$s" printf '%s' "$s" > big.txt : > empty.txt check libzip/cli-create ziptool -n t.zip add e1.txt content-one check_out libzip/cli-count-1 "1 entry in archive" ziptool t.zip get_num_entries 0 check libzip/cli-add-second ziptool t.zip add e2.txt content-two check_out libzip/cli-count-2 "2 entries in archive" ziptool t.zip get_num_entries 0 check_out libzip/cli-cat "content-two" ziptool t.zip cat 1 check_out libzip/cli-name-locate "found at index 1" ziptool t.zip name_locate e2.txt 0 check_out libzip/cli-stat-name "name: 'e1.txt'" ziptool t.zip stat 0 check_out libzip/cli-stat-size "size: '11'" ziptool t.zip stat 0 # The CRC-32 of the 11 bytes "content-one" is 0x0eb1b813 -- a property of the # format, not a self-comparison, and ziptool prints it with %x so the leading zero # is absent. This is the one CLI case where a mis-lowered CRC table surfaces as a # wrong number rather than as a failure. check_out libzip/cli-stat-crc "crc: 'eb1b813'" ziptool t.zip stat 0 check_out libzip/cli-checkcons "2 entries in archive" ziptool -c t.zip get_num_entries 0 # add a real file, then each codec in turn. `stat` after each is what proves the # codec ran rather than that the flag was accepted. check libzip/cli-add-file ziptool t.zip add_file big.txt big.txt 0 0 check_out libzip/cli-added-file "3 entries in archive" ziptool t.zip get_num_entries 0 check libzip/cli-cm-deflate ziptool t.zip set_file_compression 2 deflate 0 check_out libzip/cli-cm-deflate-set "compression method: '8'" ziptool t.zip stat 2 check libzip/cli-cm-bzip2 ziptool t.zip set_file_compression 2 bzip2 0 check_out libzip/cli-cm-bzip2-set "compression method: '12'" ziptool t.zip stat 2 # 95 is ZIP_CM_XZ. Were HAVE_LIBLZMA undefined -- which is what BRINTOS-2321 # fixed on the converted arm -- ziptool's parser would not know "xz" and would # fall through to `return 0` (= store), exactly as it does for zstd below, and # this would read 0 rather than failing to set. So the number is the assertion # and the set itself is not. check libzip/cli-cm-xz ziptool t.zip set_file_compression 2 xz 0 check_out libzip/cli-cm-xz-set "compression method: '95'" ziptool t.zip stat 2 check libzip/cli-cm-store ziptool t.zip set_file_compression 2 store 0 check_out libzip/cli-cm-store-set "compression method: '0'" ziptool t.zip stat 2 # the big entry must still come back byte-identical after that round of recodings ziptool t.zip cat 2 > out-big.txt 2>/dev/null check libzip/cli-recode-roundtrip cmp -s out-big.txt big.txt # ziptool's compression-method parser is #if'd on the compiled-in codecs and falls # through to `return 0` (= store) for a name it does not know -- upstream's own # "TODO: error handling". So asking for zstd here does not fail, it silently means # STORE, and that is the legible assertion of the absence: method 0, not 93. check libzip/cli-cm-zstd-noop ziptool t.zip set_file_compression 2 zstd 0 check_out libzip/cli-cm-zstd-is-store "compression method: '0'" ziptool t.zip stat 2 # AES *is* refused properly, because the refusal comes from the library rather than # from ziptool's parser: zip_file_set_encryption returns the error. out_rc libzip/cli-aes-refused 1 "Encryption method not supported" \ ziptool t.zip set_file_encryption 0 AES256 pw # comments, rename, delete -- each its own commit check libzip/cli-set-archive-comment ziptool t.zip set_archive_comment brintos-libzip check_out libzip/cli-get-archive-comment "brintos-libzip" ziptool t.zip get_archive_comment check libzip/cli-set-file-comment ziptool t.zip set_file_comment 0 first-entry check_out libzip/cli-get-file-comment "first-entry" ziptool t.zip get_file_comment 0 check libzip/cli-rename ziptool t.zip rename 0 renamed.txt check_out libzip/cli-renamed "name: 'renamed.txt'" ziptool t.zip stat 0 check libzip/cli-add-dir ziptool t.zip add_dir sub check libzip/cli-delete ziptool t.zip delete 1 check_out libzip/cli-count-after-delete "3 entries in archive" ziptool t.zip get_num_entries 0 check libzip/cli-replace ziptool t.zip replace_file_contents 0 brand-new-bytes check_out libzip/cli-replaced "brand-new-bytes" ziptool t.zip cat 0 # and the archive is still consistent after all of that rewriting check libzip/cli-still-consistent ziptool -c t.zip get_num_entries 0 # A zero-length member is its own case in every ZIP writer. It gets a FRESH archive # so its index is 0 whatever the chain above renumbered t.zip to on its # delete-commit -- an index that shifts under a rewrite is a fragile assertion, not # a finding. check libzip/cli-add-empty ziptool -n e.zip add_file empty.txt empty.txt 0 0 check_out libzip/cli-empty-size "size: '0'" ziptool e.zip stat 0 check_out libzip/cli-empty-cons "1 entry in archive" ziptool -c e.zip get_num_entries 0 # error paths, by exit code AND message printf 'this is definitely not a zip archive\n' > nz.bin out_rc libzip/cli-not-zip 1 "Not a zip archive" ziptool nz.bin get_num_entries 0 out_rc libzip/cli-stat-oob 1 "Invalid argument" ziptool t.zip stat 99 out_rc libzip/cli-bad-option 1 "invalid option" ziptool -Z t.zip get_num_entries 0 # --- zipcmp / zipmerge -------------------------------------------------------- cp t.zip u.zip check libzip/zipcmp-identical zipcmp t.zip u.zip check libzip/zipcmp-contents zipcmp -t t.zip u.zip ziptool -n v.zip add only.txt only-in-v >/dev/null 2>&1 check_rc libzip/zipcmp-differs 1 zipcmp -q t.zip v.zip # -v prints the difference as a diff; both sides must be named out_rc libzip/zipcmp-diff-output 1 "+ file 'only.txt'" zipcmp t.zip v.zip # zipmerge gets a FRESH pair, for the same reason the empty-entry case does: the # merged entry's index has to be a fixed number, and t.zip's numbering depends on # how its delete-commit above renumbered it. ziptool -n m1.zip add m-a.txt merge-alpha >/dev/null 2>&1 ziptool -n m2.zip add m-b.txt merge-beta >/dev/null 2>&1 check libzip/zipmerge-run zipmerge -s m1.zip m2.zip check_out libzip/zipmerge-count "2 entries in archive" ziptool m1.zip get_num_entries 0 check_out libzip/zipmerge-kept "merge-alpha" ziptool m1.zip cat 0 check_out libzip/zipmerge-merged "merge-beta" ziptool m1.zip cat 1 check libzip/zipmerge-consistent zipcmp -t m1.zip m1.zip # --- interoperability with Info-ZIP ------------------------------------------ # The strongest single statement this suite makes: the central directory this arm # writes is really PKZIP and not merely self-consistent. A wrong offset field or a # mis-sized local header round-trips fine through libzip's own reader and fails # here. Both directions. if command -v unzip >/dev/null 2>&1; then ziptool -n io.zip add i1.txt interop-one >/dev/null 2>&1 ziptool io.zip add_file big.txt big.txt 0 0 >/dev/null 2>&1 ziptool io.zip set_file_compression 1 deflate 0 >/dev/null 2>&1 check libzip/interop-unzip-test unzip -t io.zip check_out libzip/interop-unzip-list "i1.txt" unzip -l io.zip check_out libzip/interop-unzip-cat "interop-one" unzip -p io.zip i1.txt unzip -p io.zip big.txt > u-big.txt 2>/dev/null check libzip/interop-unzip-deflate cmp -s u-big.txt big.txt else bst_skip libzip/interop-unzip-test "unzip not installed on this image" bst_skip libzip/interop-unzip-list "unzip not installed on this image" bst_skip libzip/interop-unzip-cat "unzip not installed on this image" bst_skip libzip/interop-unzip-deflate "unzip not installed on this image" fi if command -v zip >/dev/null 2>&1; then # Info-ZIP writes it, libzip reads it -- including the stream Info-ZIP deflated zip -q -9 gz.zip a.txt b.txt big.txt 2>/dev/null check_out libzip/interop-reads-zip-count "3 entries in archive" ziptool gz.zip get_num_entries 0 check_out libzip/interop-reads-zip-cat "payload-alpha" ziptool gz.zip cat 0 ziptool gz.zip cat 2 > z-big.txt 2>/dev/null check libzip/interop-reads-zip-deflate cmp -s z-big.txt big.txt check libzip/interop-reads-zip-cons ziptool -c gz.zip get_num_entries 0 # zipcmp across implementations: same three members, written by two writers ziptool -n mine.zip add_file a.txt a.txt 0 0 >/dev/null 2>&1 ziptool mine.zip add_file b.txt b.txt 0 0 >/dev/null 2>&1 ziptool mine.zip add_file big.txt big.txt 0 0 >/dev/null 2>&1 check libzip/interop-zipcmp-cross zipcmp -t gz.zip mine.zip else bst_skip libzip/interop-reads-zip-count "zip not installed on this image" bst_skip libzip/interop-reads-zip-cat "zip not installed on this image" bst_skip libzip/interop-reads-zip-deflate "zip not installed on this image" bst_skip libzip/interop-reads-zip-cons "zip not installed on this image" bst_skip libzip/interop-zipcmp-cross "zip not installed on this image" fi # --- the library RUNNING, via the cross-linked probe -------------------------- probe=$w/libzip-probe if cp "$BST_DATA/libzip-probe" "$probe" 2>/dev/null && chmod +x "$probe" 2>/dev/null; then out=$(LZ_WORKDIR="$w" "$probe" 2>&1); prc=$? # identity, straight out of the archive's own header has libzip/run-version-string "LZ-version-string OK" "$out" has libzip/run-version-macros "LZ-version-macros OK" "$out" has libzip/run-zipconf-static "LZ-zipconf-static OK" "$out" # the capability matrix as the LIBRARY answers it (the third statement of it) has libzip/run-cm-store "LZ-cm-store-compress OK" "$out" has libzip/run-cm-deflate "LZ-cm-deflate-compress OK" "$out" has libzip/run-cm-bzip2 "LZ-cm-bzip2-compress OK" "$out" has libzip/run-cm-xz "LZ-cm-xz-compress OK" "$out" has libzip/run-cm-zstd-absent "LZ-cm-zstd-absent OK" "$out" has libzip/run-em-none "LZ-em-none OK" "$out" has libzip/run-em-pkware "LZ-em-pkware-decode OK" "$out" has libzip/run-em-aes256-absent "LZ-em-aes256-absent OK" "$out" # an archive built and read back entirely in memory -- no filesystem at all, so # these staying green while the disk groups go red isolates mkstemp/rename has libzip/run-mem-open "LZ-mem-open OK" "$out" has libzip/run-mem-close "LZ-mem-close OK" "$out" has libzip/run-mem-local-sig "LZ-mem-local-sig OK" "$out" has libzip/run-mem-count "LZ-mem-count OK" "$out" has libzip/run-mem-crc-digits "LZ-mem-crc-digits OK" "$out" has libzip/run-mem-crc-fox "LZ-mem-crc-fox OK" "$out" has libzip/run-mem-content-fox "LZ-mem-content-fox OK" "$out" has libzip/run-mem-content-big "LZ-mem-content-big OK" "$out" # the on-disk archive: the container's own signatures, then a member per codec has libzip/run-disk-sig-local "LZ-disk-sig-local OK" "$out" has libzip/run-disk-sig-central "LZ-disk-sig-central OK" "$out" has libzip/run-disk-sig-eocd "LZ-disk-sig-eocd OK" "$out" has libzip/run-disk-crc-store "LZ-disk-crc-store OK" "$out" has libzip/run-disk-crc-deflate "LZ-disk-crc-deflate OK" "$out" has libzip/run-disk-ratio-bzip2 "LZ-disk-ratio-bzip2 OK" "$out" has libzip/run-disk-ratio-xz "LZ-disk-ratio-xz OK" "$out" has libzip/run-disk-read-store "LZ-disk-read-store OK" "$out" has libzip/run-disk-read-deflate "LZ-disk-read-deflate OK" "$out" has libzip/run-disk-read-bzip2 "LZ-disk-read-bzip2 OK" "$out" has libzip/run-disk-read-xz "LZ-disk-read-xz OK" "$out" has libzip/run-disk-read-empty "LZ-disk-read-empty OK" "$out" has libzip/run-disk-read-raw "LZ-disk-read-raw-deflate OK" "$out" has libzip/run-disk-fseek "LZ-disk-fseek-read OK" "$out" has libzip/run-disk-checkcons "LZ-disk-checkcons OK" "$out" # the commit path: temp file + rename, then rolled back without one has libzip/run-mod-commit "LZ-mod-commit OK" "$out" has libzip/run-mod-renamed "LZ-mod-renamed-content OK" "$out" has libzip/run-mod-replaced "LZ-mod-replaced-content OK" "$out" has libzip/run-mod-deleted "LZ-mod-deleted-gone OK" "$out" has libzip/run-mod-discard "LZ-mod-discard-no-write OK" "$out" has libzip/run-mod-unchange "LZ-mod-unchange-no-ghost OK" "$out" # the error contract, by CODE and not only by message has libzip/run-err-noent "LZ-err-noent-code OK" "$out" has libzip/run-err-nozip "LZ-err-nozip-code OK" "$out" has libzip/run-err-excl "LZ-err-excl-code OK" "$out" has libzip/run-err-strerror "LZ-err-strerror-noent OK" "$out" has libzip/run-err-locate "LZ-err-locate-code OK" "$out" has libzip/run-err-fopen-oob "LZ-err-fopen-oob-code OK" "$out" has libzip/run-err-rdonly "LZ-err-delete-rdonly-code OK" "$out" has libzip/run-err-crc "LZ-err-crc-detected OK" "$out" # callbacks: indirect calls the library makes back into the consumer, which is # the coroutinize-pass surface this probe exists for has libzip/run-cb-source-add "LZ-cb-source-add OK" "$out" has libzip/run-cb-open-called "LZ-cb-open-called OK" "$out" has libzip/run-cb-read-called "LZ-cb-read-called OK" "$out" has libzip/run-cb-stat-called "LZ-cb-stat-called OK" "$out" has libzip/run-cb-close-called "LZ-cb-close-called OK" "$out" has libzip/run-cb-content "LZ-cb-content OK" "$out" has libzip/run-cb-crc "LZ-cb-crc OK" "$out" has libzip/run-cb-progress "LZ-cb-progress-called OK" "$out" has libzip/run-cb-progress-final "LZ-cb-progress-final OK" "$out" has libzip/run-cancel-aborts "LZ-cancel-close-fails OK" "$out" has libzip/run-cancel-code "LZ-cancel-code OK" "$out" # an entry copied from one archive into another has libzip/run-copy-content "LZ-copy-content OK" "$out" has libzip/run-copy-crc "LZ-copy-crc OK" "$out" # The probe's own tally and its exit status, both from the SAME run: 158/158 is # what this source scores against a host build of the identical release. has libzip/run-summary "LZ-SUMMARY 158/158" "$out" check_eq libzip/run-exit0 0 "$prc" else bst_notok libzip/run-stage "cannot stage $BST_DATA/libzip-probe" fi cd / rm -rf "$w"