2 # Copyright 2009 by Denys Vlasenko
3 # Licensed under GPLv2, see file LICENSE in this source tree.
13 rm -rf tar.tempdir 2>/dev/null
14 mkdir tar.tempdir && cd tar.tempdir || exit 1
16 # testing "test name" "script" "expected result" "file input" "stdin"
18 testing "Empty file is not a tarball" '\
19 tar xvf - 2>&1; echo $?
27 optional FEATURE_SEAMLESS_GZ GUNZIP
28 # In NOMMU case, "invalid magic" message comes from gunzip child process.
29 # Otherwise, it comes from tar.
30 # Need to fix output up to avoid false positive.
31 testing "Empty file is not a tarball.tar.gz" '\
32 { tar xvzf - 2>&1; echo $?; } | grep -Fv "invalid magic"
40 testing "Two zeroed blocks is a ('truncated') empty tarball" '\
41 dd if=/dev/zero bs=512 count=2 2>/dev/null | tar xvf - 2>&1; echo $?
48 testing "Twenty zeroed blocks is an empty tarball" '\
49 dd if=/dev/zero bs=512 count=20 2>/dev/null | tar xvf - 2>&1; echo $?
56 # "tar cf test.tar input input_dir/ input_hard1 input_hard2 input_hard1 input_dir/ input":
57 # GNU tar 1.26 records as hardlinks:
58 # input_hard2 -> input_hard1
59 # input_hard1 -> input_hard1 (!!!)
60 # input_dir/file -> input_dir/file
62 # As of 1.24.0, we don't record last two: for them, nlink==1
63 # and we check for "hardlink"ness only files with nlink!=1
64 # We also don't use "hrw-r--r--" notation for hardlinks in "tar tv" listing.
65 optional FEATURE_TAR_CREATE FEATURE_LS_SORTFILES
66 testing "tar hardlinks and repeated files" '\
67 rm -rf input_* test.tar 2>/dev/null
69 ln input_hard1 input_hard2
74 tar cf test.tar input input_dir/ input_hard1 input_hard2 input_hard1 input_dir/ input
75 tar tvf test.tar | sed "s/.*[0-9] input/input/"
79 ls -l . input_dir/* | grep input_ | sed "s/\\(^[^ ]*\\) .* input/\\1 input/"
85 input_hard2 -> input_hard1
86 input_hard1 -> input_hard1
91 -rw-r--r-- input_dir/file
93 -rw-r--r-- input_hard1
94 -rw-r--r-- input_hard2
99 optional FEATURE_TAR_CREATE FEATURE_LS_SORTFILES
100 testing "tar hardlinks mode" '\
101 rm -rf input_* test.tar 2>/dev/null
103 chmod 741 input_hard1
104 ln input_hard1 input_hard2
106 ln input_hard1 input_dir
107 ln input_hard2 input_dir
109 # On some filesystems, input_dir/input_hard2 is returned by readdir
110 # BEFORE input_dir/input_hard1! Thats why we cant just "tar cf ... input_*":
111 tar cf test.tar input_dir/input_hard* input_hard*
112 tar tvf test.tar | sed "s/.*[0-9] input/input/"
117 ls -l . input_dir/* | grep "input.*hard" | sed "s/\\(^[^ ]*\\) .* input/\\1 input/"
119 input_dir/input_hard1
120 input_dir/input_hard2 -> input_dir/input_hard1
121 input_hard1 -> input_dir/input_hard1
122 input_hard2 -> input_dir/input_hard1
124 -rwxr----x input_dir/input_hard1
125 -rwxr----x input_dir/input_hard2
126 -rwxr----x input_hard1
127 -rwxr----x input_hard2
132 optional FEATURE_TAR_CREATE FEATURE_LS_SORTFILES
133 testing "tar symlinks mode" '\
134 rm -rf input_* test.tar 2>/dev/null
137 ln -s input_file input_soft
139 ln input_file input_dir
140 ln input_soft input_dir
142 tar cf test.tar input_dir/* input_[fs]*
143 tar tvf test.tar | sed "s/.*[0-9] input/input/" | sort
148 ls -l . input_dir/* | grep "input_[fs]" | sed "s/\\(^[^ ]*\\) .* input/\\1 input/"
151 input_dir/input_soft -> input_file
152 input_file -> input_dir/input_file
153 input_soft -> input_dir/input_soft
155 -rwxr----x input_dir/input_file
156 lrwxrwxrwx input_file
157 -rwxr----x input_file
158 lrwxrwxrwx input_file
163 optional FEATURE_TAR_CREATE FEATURE_TAR_LONG_OPTIONS
164 testing "tar --overwrite" "\
165 rm -rf input_* test.tar 2>/dev/null
167 tar cf test.tar input_hard
169 # --overwrite opens 'input_hard' without unlinking,
170 # thus 'input_hard' still linked to 'input' and we write 'Ok' into it
171 tar xf test.tar --overwrite 2>&1 && cat input
178 test x"$SKIP_KNOWN_BUGS" = x"" && {
179 # Needs to be run under non-root for meaningful test
180 optional FEATURE_TAR_CREATE
181 testing "tar writing into read-only dir" '\
182 rm -rf input_* test.tar 2>/dev/null
184 >input_dir/input_file
186 tar cf test.tar input_dir
187 tar tvf test.tar | sed "s/.*[0-9] input/input/"
192 ls -l input_dir/* . | grep input_ | sed "s/\\(^[^ ]*\\) .* input/\\1 input/"
198 -rw-r--r-- input_dir/input_file
205 # Had a bug where on extract autodetect first "switched off" -z
206 # and then failed to recognize .tgz extension
207 optional FEATURE_TAR_CREATE FEATURE_SEAMLESS_GZ GUNZIP
208 testing "tar extract tgz" "\
209 dd count=1 bs=1M if=/dev/zero of=F0 2>/dev/null
212 tar -xzvf F0.tgz && echo Ok
221 # Do we detect XZ-compressed data (even w/o .tar.xz or txz extension)?
222 # (the uuencoded hello_world.txz contains one empty file named "hello_world")
223 optional UUDECODE FEATURE_TAR_AUTODETECT FEATURE_SEAMLESS_XZ
224 testing "tar extract txz" "\
225 uudecode -o input && tar tf input && echo Ok
231 begin-base64 644 hello_world.txz
232 /Td6WFoAAATm1rRGAgAhARYAAAB0L+Wj4AX/AEldADQZSe6ODIZQ3rSQ8kAJ
233 SnMPTX+XWGKW3Yu/Rwqg4Ik5wqgQKgVH97J8yA8IvZ4ahaCQogUNHRkXibr2
234 Q615wcb2G7fJU49AhWAAAAAAUA8gu9DyXfAAAWWADAAAAB5FXGCxxGf7AgAA
240 # On extract, everything up to and including last ".." component is stripped
241 optional FEATURE_TAR_CREATE
242 testing "tar strips /../ on extract" "\
243 rm -rf input_* test.tar 2>/dev/null
245 echo Ok >input_dir/file
246 tar cf test.tar ./../tar.tempdir/input_dir/../input_dir 2>&1
247 rm -rf input_* 2>/dev/null
248 tar -vxf test.tar 2>&1
249 cat input_dir/file 2>&1
251 tar: removing leading './../tar.tempdir/input_dir/../' from member names
259 # attack.tar.bz2 has symlink pointing to a system file
260 # followed by a regular file with the same name
261 # containing "root::0:0::/root:/bin/sh":
262 # lrwxrwxrwx root/root passwd -> /tmp/passwd
263 # -rw-r--r-- root/root passwd
264 # naive tar implementation may end up creating the symlink
265 # and then writing into it.
266 # The correct implementation unlinks target before
267 # creating the second file.
268 # We test that /tmp/passwd remains empty:
269 optional UUDECODE FEATURE_TAR_AUTODETECT FEATURE_SEAMLESS_BZ2
270 testing "tar does not extract into symlinks" "\
271 >>/tmp/passwd && uudecode -o input && tar xf input 2>&1 && rm passwd; cat /tmp/passwd; echo \$?
276 begin-base64 644 attack.tar.bz2
277 QlpoOTFBWSZTWRVn/bIAAKt7hMqwAEBAAP2QAhB0Y96AAACACCAAlISgpqe0
278 po0DIaDynqAkpDRP1ANAhiYNSPR8VchKhAz0AK59+DA6FcMKBggOARIJdVHL
279 DGllrjs20ATUgR1HmccBX3EhoMnpMJaNyggmxgLDMz54lBnBTJO/1L1lbMS4
280 l4/V8LDoe90yiWJhOJvIypgEfxdyRThQkBVn/bI=
285 optional UUDECODE FEATURE_TAR_AUTODETECT FEATURE_SEAMLESS_BZ2
286 testing "tar -k does not extract into symlinks" "\
287 >>/tmp/passwd && uudecode -o input && tar xf input -k 2>&1 && rm passwd; cat /tmp/passwd; echo \$?
289 tar: can't open 'passwd': File exists
293 begin-base64 644 attack.tar.bz2
294 QlpoOTFBWSZTWRVn/bIAAKt7hMqwAEBAAP2QAhB0Y96AAACACCAAlISgpqe0
295 po0DIaDynqAkpDRP1ANAhiYNSPR8VchKhAz0AK59+DA6FcMKBggOARIJdVHL
296 DGllrjs20ATUgR1HmccBX3EhoMnpMJaNyggmxgLDMz54lBnBTJO/1L1lbMS4
297 l4/V8LDoe90yiWJhOJvIypgEfxdyRThQkBVn/bI=
302 optional UNICODE_SUPPORT FEATURE_TAR_GNU_EXTENSIONS FEATURE_SEAMLESS_BZ2 FEATURE_TAR_AUTODETECT
303 testing "Pax-encoded UTF8 names and symlinks" '\
304 tar xvf ../tar.utf8.tar.bz2 2>&1; echo $?
305 export LANG=en_US.UTF-8
306 ls -l etc/ssl/certs/* | sed "s:.*etc/:etc/:" | sort
310 etc/ssl/certs/3b2716e5.0
311 etc/ssl/certs/EBG_Elektronik_Sertifika_Hizmet_Sağlayıcısı.pem
312 etc/ssl/certs/f80cc7f6.0
313 usr/share/ca-certificates/mozilla/EBG_Elektronik_Sertifika_Hizmet_Sağlayıcısı.crt
315 etc/ssl/certs/3b2716e5.0 -> EBG_Elektronik_Sertifika_Hizmet_Sağlayıcısı.pem
316 etc/ssl/certs/EBG_Elektronik_Sertifika_Hizmet_Sağlayıcısı.pem -> /usr/share/ca-certificates/mozilla/EBG_Elektronik_Sertifika_Hizmet_Sağlayıcısı.crt
317 etc/ssl/certs/f80cc7f6.0 -> EBG_Elektronik_Sertifika_Hizmet_Sağlayıcısı.pem
323 cd .. && rm -rf tar.tempdir || exit 1