tar.test 11 KB

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