1#!/bin/bash 2 3[ -f testing.sh ] && . testing.sh 4 5#testing "name" "command" "result" "infile" "stdin" 6 7# For reproducibility: UTC and umask 0002 8 9OLDTZ="$TZ" 10export TZ=utc 11OLDUMASK=$(umask) 12umask 0002 13 14# 255 bytes, longest VFS name 15LONG=0123456789abcdef0123456789abcdef 16LONG=$LONG$LONG$LONG$LONG$LONG$LONG$LONG$LONG 17LONG=${LONG:1:255} 18 19# Reproducible tarballs: override ownership and timestamp. 20TAR='tar c --owner root --group root --mtime @1234567890' 21 22# Also amount of trailing NUL padding varies (1024 bytes is minimum, 23# gnu/dammit does more) so look at first N 512-byte frames when 24# analyzing header content. 25function SUM() 26{ 27 if [ -n "$TARHD" ]; then 28 # (Android's shell doesn't support process substitution.) 29 mkfifo xxd-pipe 30 xxd <xxd-pipe & pid=$! 31 tee xxd-pipe | head -c $(($1*512)) | sha1sum | sed "s/ .*//" 32 rm xxd-pipe 33 wait $pid 34 else 35 head -c $(($1*512)) | sha1sum | sed "s/ .*//" 36 fi 37} 38 39function LST() 40{ 41 tar tv "$@" | sed 's/[ \t][ \t]*/ /g' 42} 43 44touch file 45testing "create file" "$TAR file | SUM 3" \ 46 "fecaecba936e604bb115627a6ef4db7c7a3a8f81\n" "" "" 47 48testing "pass file" "$TAR file | LST" \ 49 "-rw-rw-r-- root/root 0 2009-02-13 23:31 file\n" "" "" 50 51# The kernel has two hardwired meaningful UIDs: 0 (root) and 65534 (nobody). 52# (Technically changeable via /proc/sys/*/overflowuid but nobody ever does) 53skipnot id nobody >/dev/null 54testing "pass user" "tar -c --owner nobody --group root --mtime @0 file | LST" \ 55 "-rw-rw-r-- nobody/root 0 1970-01-01 00:00 file\n" "" "" 56# (We assume that if we have the nobody user, we also have the group, in the 57# absence of a good portable way to test for the existence of a named group.) 58skipnot id nobody >/dev/null 59testing "pass group" "tar c --owner root --group nobody --mtime @0 file | LST" \ 60 "-rw-rw-r-- root/nobody 0 1970-01-01 00:00 file\n" "" "" 61 62touch -t 198701231234.56 file 63testing "pass mtime" \ 64 "tar c --owner root --group root file | LST --full-time" \ 65 "-rw-rw-r-- root/root 0 1987-01-23 12:34:56 file\n" "" "" 66 67testing "adjust mode" \ 68 "tar c --owner root --group root --mode a+x file | LST --full-time" \ 69 "-rwxrwxr-x root/root 0 1987-01-23 12:34:56 file\n" "" "" 70 71mkdir dir 72testing "create dir" "$TAR dir | SUM 3" \ 73 "05739c423d7d4a7f12b3dbb7c94149acb2bb4f8d\n" "" "" 74 75testing "pass dir" "$TAR dir | LST" \ 76 "drwxrwxr-x root/root 0 2009-02-13 23:31 dir/\n" "" "" 77 78# note: does _not_ include dir entry in archive, just file 79touch dir/file 80testing "create file in dir" "$TAR dir/file | SUM 3" \ 81 "2d7b96c7025987215f5a41f10eaa84311160afdb\n" "" "" 82 83# Tests recursion without worrying about content order 84testing "create dir and dir/file" "$TAR dir | SUM 3" \ 85 "0bcc8005a3e07eb63c9b735267aecc5b774795d7\n" "" "" 86 87testing "pass dir/file" "$TAR dir | LST" \ 88 "drwxrwxr-x root/root 0 2009-02-13 23:31 dir/\n-rw-rw-r-- root/root 0 2009-02-13 23:31 dir/file\n" "" "" 89 90echo boing > dir/that 91testing "tar C" "$TAR -C dir that | SUM 3" \ 92 "f0deff71bf4858eb0c5f49d99d052f12f1831feb\n" "" "" 93 94# / and .. only stripped from name, not symlink target. 95ln -s ../name.././.. dir/link 96testing "create symlink" "$TAR dir/link | SUM 3" \ 97 "7324cafbd9aeec5036b6efc54d741f11528aeb10\n" "" "" 98 99# Also two explicit targets 100ln dir/file dir/hardlink 101testing "create hardlink" "$TAR dir/file dir/hardlink | SUM 3" \ 102 "c5383651f8c03ec0fe15e8a9e28a4e8e5273990d\n" "" "" 103 104ln dir/link dir/hlink 105testing "create hardlink to symlink" "$TAR dir/link dir/hlink | SUM 3" \ 106 "3bc16f8fb6fc8b05f691da8caf989a70ee99284a\n" "" "" 107 108skipnot mkfifo dir/fifo 109testing "create dir/fifo" "$TAR dir/fifo | SUM 3" \ 110 "bd1365db6e8ead4c813333f9666994c1899924d9\n" "" "" 111 112# test L and K records 113 114# 4+96=100 (biggest short name), 4+97=101 (shortest long name) 115touch dir/${LONG:1:96} dir/${LONG:1:97} 116testing "create long fname" "$TAR dir/${LONG:1:97} dir/${LONG:1:96} | SUM 3" \ 117 "99348686fe9c9bf80f5740f1fc0c6f32f2021e3d\n" "" "" 118 119ln -s dir/${LONG:1:96} dir/lshort 120ln -s dir/${LONG:1:97} dir/llong 121testing "create long symlnk" "$TAR dir/lshort dir/llong | SUM 3" \ 122 "8a5d652dc85f252a2e3b3f47d1ecd699e98a5f4b\n" "" "" 123 124ln -s $LONG dir/${LONG:5} 125testing "create long->long" "$TAR dir/${LONG:5} | SUM 7" \ 126 "543116b8e690a116a559ab5b673f9b6d6601c925\n" "" "" 127# absolute and relative link names, broken and not 128 129ln -s file dir/linkok 130testing "create symlink" "$TAR dir/linkok | SUM 3" \ 131 "55652846506cf0a9d43b3ef03ccf9e98123befaf\n" "" "" 132 133ln -s /dev/null dir/linknull 134testing "pass absolute symlink" "$TAR dir/linknull | LST" \ 135 "lrwxrwxrwx root/root 0 2009-02-13 23:31 dir/linknull -> /dev/null\n" "" "" 136 137ln -s rel/broken dir/relbrok 138testing "pass broken symlink" "$TAR dir/relbrok | LST" \ 139 "lrwxrwxrwx root/root 0 2009-02-13 23:31 dir/relbrok -> rel/broken\n" "" "" 140 141ln -s /does/not/exist dir/linkabsbrok 142testing "pass broken absolute symlink" "$TAR dir/linkabsbrok | LST" \ 143 "lrwxrwxrwx root/root 0 2009-02-13 23:31 dir/linkabsbrok -> /does/not/exist\n" \ 144 "" "" 145 146# this expects devtmpfs values 147 148testing "pass /dev/null" \ 149 "tar c --mtime @0 /dev/null 2>/dev/null | LST" \ 150 "crw-rw-rw- root/root 1,3 1970-01-01 00:00 dev/null\n" "" "" 151 152# compression types 153testing "autodetect gzip" 'LST -f "$FILES"/tar/tar.tgz' \ 154 "drwxr-x--- enh/eng 0 2017-05-13 01:05 dir/\n-rw-r----- enh/eng 12 2017-05-13 01:05 dir/file\n" \ 155 "" "" 156 157testing "manually specify bz2" 'LST -jf "$FILES"/tar/tar.tbz2' \ 158 "drwxr-x--- enh/eng 0 2017-05-13 01:05 dir/\n-rw-r----- enh/eng 12 2017-05-13 01:05 dir/file\n" \ 159 "" "" 160 161skipnot mknod dir/char c 12 34 162testing "character special" "tar --mtime @0 -cf test.tar dir/char && rm -f dir/char && tar xf test.tar && ls -l dir/char" \ 163 "crw-rw---- 1 root root 12, 34 1970-01-01 00:00 dir/char\n" "" "" 164 165skipnot mknod dir/block b 23 45 166testing "block special" "tar --mtime @0 -cf test.tar dir/block && rm -f dir/block && tar xf test.tar && ls -l dir/block" \ 167 "brw-rw---- 1 root root 23, 45 1970-01-01 00:00 dir/block\n" "" "" 168 169skipnot chown nobody dir/file 170testing "ownership" "$TAR dir/file | SUM 3" \ 171 "2d7b96c7025987215f5a41f10eaa84311160afdb\n" "" "" 172 173mkdir -p dd/sub/blah && 174tar cf test.tar dd/sub/blah && 175rm -rf dd/sub && 176ln -s ../.. dd/sub || SKIPNEXT=1 177toyonly testing "symlink out of cwd" \ 178 "tar xf test.tar 2> /dev/null || echo yes ; [ ! -e dd/sub/blah ] && echo yes" \ 179 "yes\nyes\n" "" "" 180 181# If not root can't preserve ownership, so don't try yet. 182 183testing "extract dir/file from tar" \ 184 "tar xvCf dd $FILES/tar/tar.tar && stat -c '%A %Y %n' dd/dir dd/dir/file" \ 185 "dir/\ndir/file\ndrwxr-x--- 1494637555 dd/dir\n-rw-r----- 1494637555 dd/dir/file\n" \ 186 "" "" 187 188testing "extract dir/file from tgz (autodetect)" \ 189 "tar xvCf dd $FILES/tar/tar.tgz && stat -c '%A %Y %n' dd/dir dd/dir/file" \ 190 "dir/\ndir/file\ndrwxr-x--- 1494637555 dd/dir\n-rw-r----- 1494637555 dd/dir/file\n" \ 191 "" "" 192 193toyonly testing "cat tgz | extract dir/file (autodetect)" \ 194 "cat $FILES/tar/tar.tgz | tar xvC dd && stat -c '%A %Y %n' dd/dir dd/dir/file" \ 195 "dir/\ndir/file\ndrwxr-x--- 1494637555 dd/dir\n-rw-r----- 1494637555 dd/dir/file\n" \ 196 "" "" 197 198testing "extract dir/file from tbz2 (autodetect)" \ 199 "tar xvCf dd $FILES/tar/tar.tbz2 && stat -c '%A %Y %n' dd/dir dd/dir/file" \ 200 "dir/\ndir/file\ndrwxr-x--- 1494637555 dd/dir\n-rw-r----- 1494637555 dd/dir/file\n" \ 201 "" "" 202 203toyonly testing "cat tbz | extract dir/file (autodetect)" \ 204 "cat $FILES/tar/tar.tbz2 | tar xvC dd && stat -c '%A %Y %n' dd/dir dd/dir/file" \ 205 "dir/\ndir/file\ndrwxr-x--- 1494637555 dd/dir\n-rw-r----- 1494637555 dd/dir/file\n" \ 206 "" "" 207 208yes | (dd bs=$((1<<16)) count=1; dd bs=8192 seek=14 count=1; dd bs=4096 seek=64 count=5) 2>/dev/null > fweep 209testing "sparse without overflow" "$TAR --sparse fweep | SUM 3" \ 210 "e1560110293247934493626d564c8f03c357cec5\n" "" "" 211 212rm fweep 213for i in 1 3 5 7 9 14 27 36 128 256 300 304 214do 215 dd if=/dev/zero of=fweep bs=65536 seek=$i count=1 2>/dev/null 216done 217 218testing "sparse single overflow" "$TAR --sparse fweep | SUM 6" \ 219 "063fc6519ea2607763bc591cc90dd15ac2b43eb8\n" "" "" 220 221rm fweep 222for i in $(seq 8 3 200) 223do 224 dd if=/dev/zero of=fweep bs=65536 seek=$i count=1 2>/dev/null 225 dd if=/dev/zero of=fweep2 bs=65536 seek=$i count=1 2>/dev/null 226done 227truncate -s 20m fweep2 228 229testing "sparse double overflow" "$TAR --sparse fweep | SUM 7" \ 230 "f1fe57f8313a9d682ec9013a80f3798910b6ff51\n" "" "" 231 232tar c --sparse fweep > fweep.tar 233rm fweep 234testing "sparse extract" "tar xf fweep.tar && $TAR --sparse fweep | SUM 4" \ 235 "38dc57b8b95632a287db843c214b5c96d1cfe415\n" "" "" 236testing "sparse tvf" "tar tvf fweep.tar | grep -wq 13172736 && echo right size"\ 237 "right size\n" "" "" 238rm fweep fweep.tar 239 240tar c --sparse fweep2 > fweep2.tar 241rm fweep2 242testing "sparse extract hole at end" \ 243 "tar xf fweep2.tar && $TAR --sparse fweep2 | SUM 4" \ 244 "791060574c569e5c059e2b90c1961a3575898f97\n" "" "" 245rm fweep2 fweep2.tar 246 247if false 248then 249 250chmod 700 dir 251tar cpf tar.tgz dir/file 252#chmod 700 dir 253#tar xpf file 254#ls -ld dir/file 255 256# restore ownership of file, dir, and symlink 257 258# merge add_to_tar and write_longname, 259# filter, incl or excl and anchored/wildcards 260 261# extract file not under cwd 262# exclusion defaults to --no-anchored and --wildcards-match-slash 263# both incl and excl 264 265# catch symlink overwrite 266# add dir with no trailing slash 267# don't allow hardlink target outside cwd 268# extract dir/file without dir in tarball 269# create with and without each flag 270# --owner --group --numeric-owner 271# extract with and without each flag 272# --owner 0 --group 0 273# set symlink owner 274# >256 hardlink inodes 275# // remove leading / and any .. entries from saved name 276# // exclusion defaults to --no-anchored and --wildcards-match-slash 277# //bork blah../thing blah/../thing blah/../and/../that blah/.. ../blah 278# tar tv --owner --group --mtime 279# extract file within dir date correct 280# name ending in /.. or just ".." as a name 281 282 283fi 284 285TZ="$OLDTZ" 286umask $OLDUMASK 287unset LONG TAR SUM OLDUMASK OLDTZ 288unset -f LST 289