Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(25130)

Delta Between Two Patch Sets: Lib/test/test_tarfile.py

Issue 19974: tarfile doesn't overwrite symlink by directory
Left Patch Set: Created 5 years, 9 months ago
Right Patch Set: Created 5 years, 7 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
« Lib/tarfile.py ('K') | « Lib/tarfile.py ('k') | no next file » | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
1 import sys 1 import sys
2 import os 2 import os
3 import io 3 import io
4 import shutil 4 import shutil
5 import errno
5 from hashlib import md5 6 from hashlib import md5
6 7
7 import unittest 8 import unittest
8 import tarfile 9 import tarfile
9 10
10 from test import support, script_helper 11 from test import support, script_helper
11 12
12 # Check for our compression modules. 13 # Check for our compression modules.
13 try: 14 try:
14 import gzip 15 import gzip
(...skipping 21 matching lines...) Expand all
36 dotlessname = os.path.join(TEMPDIR, "testtar") 37 dotlessname = os.path.join(TEMPDIR, "testtar")
37 38
38 md5_regtype = "65f477c818ad9e15f7feab0c6d37742f" 39 md5_regtype = "65f477c818ad9e15f7feab0c6d37742f"
39 md5_sparse = "a54fbc4ca4f4399a90e1b27164012fc6" 40 md5_sparse = "a54fbc4ca4f4399a90e1b27164012fc6"
40 41
41 42
42 class TarTest: 43 class TarTest:
43 tarname = tarname 44 tarname = tarname
44 suffix = '' 45 suffix = ''
45 open = io.FileIO 46 open = io.FileIO
47 taropen = tarfile.TarFile.taropen
46 48
47 @property 49 @property
48 def mode(self): 50 def mode(self):
49 return self.prefix + self.suffix 51 return self.prefix + self.suffix
50 52
51 @support.requires_gzip 53 @support.requires_gzip
52 class GzipTest: 54 class GzipTest:
53 tarname = gzipname 55 tarname = gzipname
54 suffix = 'gz' 56 suffix = 'gz'
55 open = gzip.GzipFile if gzip else None 57 open = gzip.GzipFile if gzip else None
58 taropen = tarfile.TarFile.gzopen
56 59
57 @support.requires_bz2 60 @support.requires_bz2
58 class Bz2Test: 61 class Bz2Test:
59 tarname = bz2name 62 tarname = bz2name
60 suffix = 'bz2' 63 suffix = 'bz2'
61 open = bz2.BZ2File if bz2 else None 64 open = bz2.BZ2File if bz2 else None
65 taropen = tarfile.TarFile.bz2open
62 66
63 @support.requires_lzma 67 @support.requires_lzma
64 class LzmaTest: 68 class LzmaTest:
65 tarname = xzname 69 tarname = xzname
66 suffix = 'xz' 70 suffix = 'xz'
67 open = lzma.LZMAFile if lzma else None 71 open = lzma.LZMAFile if lzma else None
72 taropen = tarfile.TarFile.xzopen
68 73
69 74
70 class ReadTest(TarTest): 75 class ReadTest(TarTest):
71 76
72 prefix = "r:" 77 prefix = "r:"
73 78
74 def setUp(self): 79 def setUp(self):
75 self.tar = tarfile.open(self.tarname, mode=self.mode, 80 self.tar = tarfile.open(self.tarname, mode=self.mode,
76 encoding="iso8859-1") 81 encoding="iso8859-1")
77 82
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
208 class GzipUstarReadTest(GzipTest, UstarReadTest): 213 class GzipUstarReadTest(GzipTest, UstarReadTest):
209 pass 214 pass
210 215
211 class Bz2UstarReadTest(Bz2Test, UstarReadTest): 216 class Bz2UstarReadTest(Bz2Test, UstarReadTest):
212 pass 217 pass
213 218
214 class LzmaUstarReadTest(LzmaTest, UstarReadTest): 219 class LzmaUstarReadTest(LzmaTest, UstarReadTest):
215 pass 220 pass
216 221
217 222
223 class ListTest(ReadTest, unittest.TestCase):
224
225 # Override setUp to use default encoding (UTF-8)
226 def setUp(self):
227 self.tar = tarfile.open(self.tarname, mode=self.mode)
228
229 def test_list(self):
230 tio = io.TextIOWrapper(io.BytesIO(), 'ascii', newline='\n')
231 with support.swap_attr(sys, 'stdout', tio):
232 self.tar.list(verbose=False)
233 out = tio.detach().getvalue()
234 self.assertIn(b'ustar/conttype', out)
235 self.assertIn(b'ustar/regtype', out)
236 self.assertIn(b'ustar/lnktype', out)
237 self.assertIn(b'ustar' + (b'/12345' * 40) + b'67/longname', out)
238 self.assertIn(b'./ustar/linktest2/symtype', out)
239 self.assertIn(b'./ustar/linktest2/lnktype', out)
240 # Make sure it puts trailing slash for directory
241 self.assertIn(b'ustar/dirtype/', out)
242 self.assertIn(b'ustar/dirtype-with-size/', out)
243 # Make sure it is able to print unencodable characters
244 def conv(b):
245 s = b.decode(self.tar.encoding, 'surrogateescape')
246 return s.encode('ascii', 'backslashreplace')
247 self.assertIn(conv(b'ustar/umlauts-\xc4\xd6\xdc\xe4\xf6\xfc\xdf'), out)
248 self.assertIn(conv(b'misc/regtype-hpux-signed-chksum-'
249 b'\xc4\xd6\xdc\xe4\xf6\xfc\xdf'), out)
250 self.assertIn(conv(b'misc/regtype-old-v7-signed-chksum-'
251 b'\xc4\xd6\xdc\xe4\xf6\xfc\xdf'), out)
252 self.assertIn(conv(b'pax/bad-pax-\xe4\xf6\xfc'), out)
253 self.assertIn(conv(b'pax/hdrcharset-\xe4\xf6\xfc'), out)
254 # Make sure it prints files separated by one newline without any
255 # 'ls -l'-like accessories if verbose flag is not being used
256 # ...
257 # ustar/conttype
258 # ustar/regtype
259 # ...
260 self.assertRegex(out, br'ustar/conttype ?\r?\n'
261 br'ustar/regtype ?\r?\n')
262 # Make sure it does not print the source of link without verbose flag
263 self.assertNotIn(b'link to', out)
264 self.assertNotIn(b'->', out)
265
266 def test_list_verbose(self):
267 tio = io.TextIOWrapper(io.BytesIO(), 'ascii', newline='\n')
268 with support.swap_attr(sys, 'stdout', tio):
269 self.tar.list(verbose=True)
270 out = tio.detach().getvalue()
271 # Make sure it prints files separated by one newline with 'ls -l'-like
272 # accessories if verbose flag is being used
273 # ...
274 # ?rw-r--r-- tarfile/tarfile 7011 2003-01-06 07:19:43 ustar/conttype
275 # ?rw-r--r-- tarfile/tarfile 7011 2003-01-06 07:19:43 ustar/regtype
276 # ...
277 self.assertRegex(out, (br'\?rw-r--r-- tarfile/tarfile\s+7011 '
278 br'\d{4}-\d\d-\d\d\s+\d\d:\d\d:\d\d '
279 br'ustar/\w+type ?\r?\n') * 2)
280 # Make sure it prints the source of link with verbose flag
281 self.assertIn(b'ustar/symtype -> regtype', out)
282 self.assertIn(b'./ustar/linktest2/symtype -> ../linktest1/regtype', out)
283 self.assertIn(b'./ustar/linktest2/lnktype link to '
284 b'./ustar/linktest1/regtype', out)
285 self.assertIn(b'gnu' + (b'/123' * 125) + b'/longlink link to gnu' +
286 (b'/123' * 125) + b'/longname', out)
287 self.assertIn(b'pax' + (b'/123' * 125) + b'/longlink link to pax' +
288 (b'/123' * 125) + b'/longname', out)
289
290
291 class GzipListTest(GzipTest, ListTest):
292 pass
293
294
295 class Bz2ListTest(Bz2Test, ListTest):
296 pass
297
298
299 class LzmaListTest(LzmaTest, ListTest):
300 pass
301
302
218 class CommonReadTest(ReadTest): 303 class CommonReadTest(ReadTest):
219 304
220 def test_empty_tarfile(self): 305 def test_empty_tarfile(self):
221 # Test for issue6123: Allow opening empty archives. 306 # Test for issue6123: Allow opening empty archives.
222 # This test checks if tarfile.open() is able to open an empty tar 307 # This test checks if tarfile.open() is able to open an empty tar
223 # archive successfully. Note that an empty tar archive is not the 308 # archive successfully. Note that an empty tar archive is not the
224 # same as an empty file! 309 # same as an empty file!
225 with tarfile.open(tmpname, self.mode.replace("r", "w")): 310 with tarfile.open(tmpname, self.mode.replace("r", "w")):
226 pass 311 pass
227 try: 312 try:
228 tar = tarfile.open(tmpname, self.mode) 313 tar = tarfile.open(tmpname, self.mode)
229 tar.getnames() 314 tar.getnames()
230 except tarfile.ReadError: 315 except tarfile.ReadError:
231 self.fail("tarfile.open() failed on empty archive") 316 self.fail("tarfile.open() failed on empty archive")
232 else: 317 else:
233 self.assertListEqual(tar.getmembers(), []) 318 self.assertListEqual(tar.getmembers(), [])
234 finally: 319 finally:
235 tar.close() 320 tar.close()
321
322 def test_non_existent_tarfile(self):
323 # Test for issue11513: prevent non-existent gzipped tarfiles raising
324 # multiple exceptions.
325 with self.assertRaisesRegex(FileNotFoundError, "xxx"):
326 tarfile.open("xxx", self.mode)
236 327
237 def test_null_tarfile(self): 328 def test_null_tarfile(self):
238 # Test for issue6123: Allow opening empty archives. 329 # Test for issue6123: Allow opening empty archives.
239 # This test guarantees that tarfile.open() does not treat an empty 330 # This test guarantees that tarfile.open() does not treat an empty
240 # file as an empty tar archive. 331 # file as an empty tar archive.
241 with open(tmpname, "wb"): 332 with open(tmpname, "wb"):
242 pass 333 pass
243 self.assertRaises(tarfile.ReadError, tarfile.open, tmpname, self.mode) 334 self.assertRaises(tarfile.ReadError, tarfile.open, tmpname, self.mode)
244 self.assertRaises(tarfile.ReadError, tarfile.open, tmpname) 335 self.assertRaises(tarfile.ReadError, tarfile.open, tmpname)
245 336
(...skipping 29 matching lines...) Expand all
275 tar = tarfile.open(fileobj=fobj, mode=self.mode) 366 tar = tarfile.open(fileobj=fobj, mode=self.mode)
276 self.assertEqual(tar.name, None) 367 self.assertEqual(tar.name, None)
277 368
278 def test_empty_name_attribute(self): 369 def test_empty_name_attribute(self):
279 with open(self.tarname, "rb") as fobj: 370 with open(self.tarname, "rb") as fobj:
280 data = fobj.read() 371 data = fobj.read()
281 fobj = io.BytesIO(data) 372 fobj = io.BytesIO(data)
282 fobj.name = "" 373 fobj.name = ""
283 with tarfile.open(fileobj=fobj, mode=self.mode) as tar: 374 with tarfile.open(fileobj=fobj, mode=self.mode) as tar:
284 self.assertEqual(tar.name, None) 375 self.assertEqual(tar.name, None)
376
377 def test_illegal_mode_arg(self):
378 with open(tmpname, 'wb'):
379 pass
380 with self.assertRaisesRegex(ValueError, 'mode must be '):
381 tar = self.taropen(tmpname, 'q')
382 with self.assertRaisesRegex(ValueError, 'mode must be '):
383 tar = self.taropen(tmpname, 'rw')
384 with self.assertRaisesRegex(ValueError, 'mode must be '):
385 tar = self.taropen(tmpname, '')
285 386
286 def test_fileobj_with_offset(self): 387 def test_fileobj_with_offset(self):
287 # Skip the first member and store values from the second member 388 # Skip the first member and store values from the second member
288 # of the testtar. 389 # of the testtar.
289 tar = tarfile.open(self.tarname, mode=self.mode) 390 tar = tarfile.open(self.tarname, mode=self.mode)
290 try: 391 try:
291 tar.next() 392 tar.next()
292 t = tar.next() 393 t = tar.next()
293 name = t.name 394 name = t.name
294 offset = t.offset 395 offset = t.offset
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
439 # from where it left off. 540 # from where it left off.
440 with tarfile.open(self.tarname) as tar: 541 with tarfile.open(self.tarname) as tar:
441 for m1, m2 in zip(tar, tar): 542 for m1, m2 in zip(tar, tar):
442 self.assertEqual(m1.offset, m2.offset) 543 self.assertEqual(m1.offset, m2.offset)
443 self.assertEqual(m1.get_info(), m2.get_info()) 544 self.assertEqual(m1.get_info(), m2.get_info())
444 545
445 class MiscReadTest(MiscReadTestBase, unittest.TestCase): 546 class MiscReadTest(MiscReadTestBase, unittest.TestCase):
446 test_fail_comp = None 547 test_fail_comp = None
447 548
448 class GzipMiscReadTest(GzipTest, MiscReadTestBase, unittest.TestCase): 549 class GzipMiscReadTest(GzipTest, MiscReadTestBase, unittest.TestCase):
449 def test_non_existent_targz_file(self): 550 pass
450 # Test for issue11513: prevent non-existent gzipped tarfiles raising
451 # multiple exceptions.
452 with self.assertRaisesRegex(FileNotFoundError, "xxx"):
453 tarfile.open("xxx", self.mode)
454 551
455 class Bz2MiscReadTest(Bz2Test, MiscReadTestBase, unittest.TestCase): 552 class Bz2MiscReadTest(Bz2Test, MiscReadTestBase, unittest.TestCase):
456 def test_no_name_argument(self): 553 def test_no_name_argument(self):
457 self.skipTest("BZ2File have no name attribute") 554 self.skipTest("BZ2File have no name attribute")
458 555
459 class LzmaMiscReadTest(LzmaTest, MiscReadTestBase, unittest.TestCase): 556 class LzmaMiscReadTest(LzmaTest, MiscReadTestBase, unittest.TestCase):
460 def test_no_name_argument(self): 557 def test_no_name_argument(self):
461 self.skipTest("LZMAFile have no name attribute") 558 self.skipTest("LZMAFile have no name attribute")
462 559
463 560
(...skipping 370 matching lines...) Expand 10 before | Expand all | Expand 10 after
834 class WriteTestBase(TarTest): 931 class WriteTestBase(TarTest):
835 # Put all write tests in here that are supposed to be tested 932 # Put all write tests in here that are supposed to be tested
836 # in all possible mode combinations. 933 # in all possible mode combinations.
837 934
838 def test_fileobj_no_close(self): 935 def test_fileobj_no_close(self):
839 fobj = io.BytesIO() 936 fobj = io.BytesIO()
840 tar = tarfile.open(fileobj=fobj, mode=self.mode) 937 tar = tarfile.open(fileobj=fobj, mode=self.mode)
841 tar.addfile(tarfile.TarInfo("foo")) 938 tar.addfile(tarfile.TarInfo("foo"))
842 tar.close() 939 tar.close()
843 self.assertFalse(fobj.closed, "external fileobjs must never closed") 940 self.assertFalse(fobj.closed, "external fileobjs must never closed")
941 # Issue #20238: Incomplete gzip output with mode="w:gz"
942 data = fobj.getvalue()
943 del tar
944 support.gc_collect()
945 self.assertFalse(fobj.closed)
946 self.assertEqual(data, fobj.getvalue())
844 947
845 948
846 class WriteTest(WriteTestBase, unittest.TestCase): 949 class WriteTest(WriteTestBase, unittest.TestCase):
847 950
848 prefix = "w:" 951 prefix = "w:"
849 952
850 def test_100_char_name(self): 953 def test_100_char_name(self):
851 # The name field in a tar header stores strings of at most 100 chars. 954 # The name field in a tar header stores strings of at most 100 chars.
852 # If a string is shorter than 100 chars it has to be padded with '\0', 955 # If a string is shorter than 100 chars it has to be padded with '\0',
853 # which implies that a string of exactly 100 chars is stored without 956 # which implies that a string of exactly 100 chars is stored without
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after
1053 finally: 1156 finally:
1054 tar.close() 1157 tar.close()
1055 1158
1056 if not dir: 1159 if not dir:
1057 os.remove(foo) 1160 os.remove(foo)
1058 else: 1161 else:
1059 os.rmdir(foo) 1162 os.rmdir(foo)
1060 1163
1061 self.assertEqual(t.name, cmp_path or path.replace(os.sep, "/")) 1164 self.assertEqual(t.name, cmp_path or path.replace(os.sep, "/"))
1062 1165
1166 def test_extractall_current_directory(self):
1167 tempdir = os.path.join(TEMPDIR, "testcurdir")
1168 temparchive = os.path.join(TEMPDIR, "testcurdir.tar")
1169 os.mkdir(tempdir)
1170 try:
1171 source_file = os.path.join(tempdir, 'source')
1172 with open(source_file,'w') as f:
1173 f.write('source file content\n')
1174 tar = tarfile.open(temparchive,'w')
1175 try:
1176 # We don't want to add absolute path to tar file because
1177 # we don't want nested directory after extracting the file.
1178 with support.change_cwd(tempdir):
1179 tar.add('./')
1180 finally:
1181 tar.close()
1182 os.remove(source_file)
1183 tar = tarfile.open(temparchive,'r')
1184 try:
1185 tar.extractall(path=tempdir)
1186 with open(source_file) as f:
1187 self.assertEqual(f.read(), 'source file content\n')
1188 except OSError:
1189 self.fail("extractall failed with ./ file")
1190 finally:
1191 tar.close()
1192 finally:
1193 os.unlink(temparchive)
1194 shutil.rmtree(tempdir)
1195
1196 def test_extractall_non_directory_overwrites_directory(self):
1197 tempdir = os.path.join(TEMPDIR, "testnotdiroverwritesdir")
1198 temparchive = os.path.join(TEMPDIR, "testnotdiroverwritesdir.tar")
1199 os.mkdir(tempdir)
1200 try:
1201 source_file = os.path.join(tempdir, 'source')
1202 with open(source_file,'w') as f:
1203 f.write('source file content\n')
1204 tar = tarfile.open(temparchive,'w')
Claudiu.Popa 2014/03/19 19:14:17 I guess the code could be simpler if you use conte
1205 try:
1206 # We don't want to add absolute path to tar file because
1207 # we don't want nested directory after extracting the file.
1208 with support.change_cwd(tempdir):
1209 tar.add('source')
1210 finally:
1211 tar.close()
1212 os.remove(source_file)
1213 os.mkdir(source_file)
1214 tar = tarfile.open(temparchive,'r')
1215 try:
1216 tar.extractall(path=tempdir)
1217 # Non-directory file should be able to overwrites empty
1218 # directory
1219 with open(source_file) as f:
1220 self.assertEqual(f.read(), 'source file content\n')
1221 except OSError:
1222 self.fail("extractall failed with non-directory files")
1223 finally:
1224 tar.close()
1225 os.remove(source_file)
1226 os.mkdir(source_file)
1227 os.mkdir(os.path.join(source_file, 'inner_source'))
1228 tar = tarfile.open(temparchive,'r')
1229 try:
1230 tar.extractall(path=tempdir)
1231 # Non-directory file should not be able to overwrites non-empty
1232 # directory
1233 self.fail("extractall failed with file overwriting non-empty "
1234 "directory")
1235 # This should raise OSError: [Errno 21] Is a directory
1236 except OSError as e:
1237 self.assertEqual(e.errno, errno.EISDIR)
1238 finally:
1239 tar.close()
1240 finally:
1241 os.unlink(temparchive)
1242 shutil.rmtree(tempdir)
1243
1244 def test_extractall_not_empty_directory(self):
1245 tempdir = os.path.join(TEMPDIR, "testnotemptydir")
1246 temparchive = os.path.join(TEMPDIR, "testnotemptydir.tar")
1247 os.mkdir(tempdir)
1248 try:
1249 dir_A = os.path.join(tempdir, 'A')
1250 dir_B = os.path.join(tempdir, 'B')
1251 dir_C = os.path.join(dir_A, 'C')
1252 os.mkdir(dir_A)
1253 os.mkdir(dir_B)
1254 os.mkdir(dir_C)
1255 tar = tarfile.open(temparchive,'w')
1256 try:
1257 # We don't want to add absolute path to tar file because
1258 # we don't want nested directory after extracting the file.
1259 with support.change_cwd(tempdir):
1260 tar.add('A')
1261 tar.add('B')
1262 finally:
1263 tar.close()
1264 os.rmdir(dir_C)
1265 dir_D = os.path.join(dir_A, 'D')
1266 os.mkdir(dir_D)
1267 tar = tarfile.open(temparchive,'r')
1268 try:
1269 tar.extractall(path=tempdir)
1270 self.assertEqual(sorted(os.listdir(dir_A)), ['C', 'D'])
1271 except OSError:
1272 self.fail("extractall failed with not empty directory")
1273 finally:
1274 tar.close()
1275 finally:
1276 os.unlink(temparchive)
1277 shutil.rmtree(tempdir)
1063 1278
1064 @support.skip_unless_symlink 1279 @support.skip_unless_symlink
1065 def test_extractall_symlinks(self): 1280 def test_extractall_symlinks(self):
1066 # Test if extractall works properly when tarfile contains symlinks 1281 # Test if extractall works properly when tarfile contains symlinks
1067 tempdir = os.path.join(TEMPDIR, "testsymlinks") 1282 tempdir = os.path.join(TEMPDIR, "testsymlinks")
1068 temparchive = os.path.join(TEMPDIR, "testsymlinks.tar") 1283 temparchive = os.path.join(TEMPDIR, "testsymlinks.tar")
1069 os.mkdir(tempdir) 1284 os.mkdir(tempdir)
1070 try: 1285 try:
1286 # File symlink
1071 source_file = os.path.join(tempdir, 'source') 1287 source_file = os.path.join(tempdir, 'source')
1072 other_source_file = os.path.join(tempdir, 'other_source') 1288 other_source_file = os.path.join(tempdir, 'other_source')
1073 target_file = os.path.join(tempdir,'symlink') 1289 target_file = os.path.join(tempdir, 'symlink')
1074 open(source_file, 'w').close() 1290 with open(source_file,'w') as f:
1075 open(other_source_file, 'w').close() 1291 f.write('source file content\n')
1292 with open(other_source_file,'w') as f:
1293 f.write('other source file content\n')
1076 os.symlink(source_file, target_file) 1294 os.symlink(source_file, target_file)
1295 # Directory symlink
1296 source_dir = os.path.join(tempdir, 'source_dir')
1297 other_source_dir = os.path.join(tempdir, 'other_source_dir')
1298 target_dir = os.path.join(tempdir, 'symlink_dir')
1299 os.mkdir(source_dir)
1300 os.mkdir(other_source_dir)
1301 os.symlink(source_dir, target_dir)
1077 tar = tarfile.open(temparchive,'w') 1302 tar = tarfile.open(temparchive,'w')
1078 tar.add(source_file) 1303 # We don't want to add absolute path to tar file because
1079 tar.add(target_file) 1304 # we don't want nested directory after extracting the file:
1080 tar.close() 1305 # /home/user/python/symlink/home/user/python/symlink/file
1081 # Point target_file to other_source_file to exersice overwriting 1306 with support.change_cwd(tempdir):
1082 # behavior. 1307 tar.add('source')
1308 tar.add('symlink')
1309 tar.add('source_dir')
1310 tar.add('symlink_dir')
1311 tar.close()
1312 # Point target_file to other_source_file and target_dir to
1313 # other_source_dir to exercise overwriting behavior.
1083 os.unlink(target_file) 1314 os.unlink(target_file)
1084 os.symlink(other_source_file, target_file) 1315 os.symlink(other_source_file, target_file)
1085 # Let's extract it to the location which contains the symlink 1316 os.unlink(target_dir)
1317 os.symlink(other_source_dir, target_dir)
1086 tar = tarfile.open(temparchive,'r') 1318 tar = tarfile.open(temparchive,'r')
1087 # This should not raise OSError: [Errno 17] File exists 1319 try:
1088 try: 1320 with open(target_file) as f:
1321 self.assertEqual(f.read(), 'other source file content\n')
1322 self.assertEqual(os.readlink(target_dir), other_source_dir)
1323 # Let's extract it to the location which contains the symlink
1089 tar.extractall(path=tempdir) 1324 tar.extractall(path=tempdir)
1090 # target_file that symlinked to other_source_file now symlinks 1325 # target_file that symlinked to other_source_file now symlinks
1091 # back to source_file. 1326 # back to source_file, and target_dir that symlinked to
1092 self.assertEqual(os.readlink(target_file), source_file) 1327 # other_source_dir now symlinks back to source_dir.
1328 with open(target_file) as f:
1329 self.assertEqual(f.read(), 'source file content\n')
1330 self.assertEqual(os.readlink(target_dir), source_dir)
1331 # This should not raise OSError: [Errno 17] File exists
1093 except OSError: 1332 except OSError:
1094 self.fail("extractall failed with symlinked files") 1333 self.fail("extractall failed with symlinked files")
1095 finally: 1334 finally:
1096 tar.close() 1335 tar.close()
1097 finally: 1336 finally:
1098 os.unlink(temparchive) 1337 os.unlink(temparchive)
1099 shutil.rmtree(tempdir) 1338 shutil.rmtree(tempdir)
1100 1339
1101 def test_pathnames(self): 1340 def test_pathnames(self):
1102 self._test_pathname("foo") 1341 self._test_pathname("foo")
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
1135 1374
1136 tar = tarfile.open(tmpname, "r") 1375 tar = tarfile.open(tmpname, "r")
1137 try: 1376 try:
1138 for t in tar: 1377 for t in tar:
1139 if t.name != ".": 1378 if t.name != ".":
1140 self.assertTrue(t.name.startswith("./"), t.name) 1379 self.assertTrue(t.name.startswith("./"), t.name)
1141 finally: 1380 finally:
1142 tar.close() 1381 tar.close()
1143 finally: 1382 finally:
1144 os.chdir(cwd) 1383 os.chdir(cwd)
1384
1385 def test_open_nonwritable_fileobj(self):
1386 for exctype in OSError, EOFError, RuntimeError:
1387 class BadFile(io.BytesIO):
1388 first = True
1389 def write(self, data):
1390 if self.first:
1391 self.first = False
1392 raise exctype
1393
1394 f = BadFile()
1395 with self.assertRaises(exctype):
1396 tar = tarfile.open(tmpname, self.mode, fileobj=f,
1397 format=tarfile.PAX_FORMAT,
1398 pax_headers={'non': 'empty'})
1399 self.assertFalse(f.closed)
1145 1400
1146 class GzipWriteTest(GzipTest, WriteTest): 1401 class GzipWriteTest(GzipTest, WriteTest):
1147 pass 1402 pass
1148 1403
1149 class Bz2WriteTest(Bz2Test, WriteTest): 1404 class Bz2WriteTest(Bz2Test, WriteTest):
1150 pass 1405 pass
1151 1406
1152 class LzmaWriteTest(LzmaTest, WriteTest): 1407 class LzmaWriteTest(LzmaTest, WriteTest):
1153 pass 1408 pass
1154 1409
(...skipping 574 matching lines...) Expand 10 before | Expand all | Expand 10 after
1729 with self.assertRaises(ValueError): 1984 with self.assertRaises(ValueError):
1730 tarfile.itn(0o10000000, 8, tarfile.USTAR_FORMAT) 1985 tarfile.itn(0o10000000, 8, tarfile.USTAR_FORMAT)
1731 with self.assertRaises(ValueError): 1986 with self.assertRaises(ValueError):
1732 tarfile.itn(-0x10000000001, 6, tarfile.GNU_FORMAT) 1987 tarfile.itn(-0x10000000001, 6, tarfile.GNU_FORMAT)
1733 with self.assertRaises(ValueError): 1988 with self.assertRaises(ValueError):
1734 tarfile.itn(0x10000000000, 6, tarfile.GNU_FORMAT) 1989 tarfile.itn(0x10000000000, 6, tarfile.GNU_FORMAT)
1735 1990
1736 1991
1737 class CommandLineTest(unittest.TestCase): 1992 class CommandLineTest(unittest.TestCase):
1738 1993
1739 def tarfilecmd(self, *args): 1994 def tarfilecmd(self, *args, **kwargs):
1740 rc, out, err = script_helper.assert_python_ok('-m', 'tarfile', *args) 1995 rc, out, err = script_helper.assert_python_ok('-m', 'tarfile', *args,
1996 **kwargs)
1741 return out.replace(os.linesep.encode(), b'\n') 1997 return out.replace(os.linesep.encode(), b'\n')
1742 1998
1743 def tarfilecmd_failure(self, *args): 1999 def tarfilecmd_failure(self, *args):
1744 return script_helper.assert_python_failure('-m', 'tarfile', *args) 2000 return script_helper.assert_python_failure('-m', 'tarfile', *args)
1745 2001
1746 def make_simple_tarfile(self, tar_name): 2002 def make_simple_tarfile(self, tar_name):
1747 files = [support.findfile('tokenize_tests.txt'), 2003 files = [support.findfile('tokenize_tests.txt'),
1748 support.findfile('tokenize_tests-no-coding-cookie-' 2004 support.findfile('tokenize_tests-no-coding-cookie-'
1749 'and-utf8-bom-sig-only.txt')] 2005 'and-utf8-bom-sig-only.txt')]
1750 self.addCleanup(support.unlink, tar_name) 2006 self.addCleanup(support.unlink, tar_name)
(...skipping 27 matching lines...) Expand all
1778 try: 2034 try:
1779 with open(tmpname, 'wb') as f: 2035 with open(tmpname, 'wb') as f:
1780 f.write(data[:511]) 2036 f.write(data[:511])
1781 rc, out, err = self.tarfilecmd_failure('-t', tmpname) 2037 rc, out, err = self.tarfilecmd_failure('-t', tmpname)
1782 self.assertEqual(out, b'') 2038 self.assertEqual(out, b'')
1783 self.assertEqual(rc, 1) 2039 self.assertEqual(rc, 1)
1784 finally: 2040 finally:
1785 support.unlink(tmpname) 2041 support.unlink(tmpname)
1786 2042
1787 def test_list_command(self): 2043 def test_list_command(self):
1788 self.make_simple_tarfile(tmpname) 2044 for tar_name in testtarnames:
1789 with support.captured_stdout() as t: 2045 with support.captured_stdout() as t:
1790 with tarfile.open(tmpname, 'r') as tf: 2046 with tarfile.open(tar_name, 'r') as tf:
1791 tf.list(verbose=False) 2047 tf.list(verbose=False)
1792 expected = t.getvalue().encode(sys.getfilesystemencoding()) 2048 expected = t.getvalue().encode('ascii', 'backslashreplace')
1793 for opt in '-l', '--list': 2049 for opt in '-l', '--list':
1794 out = self.tarfilecmd(opt, tmpname) 2050 out = self.tarfilecmd(opt, tar_name,
1795 self.assertEqual(out, expected) 2051 PYTHONIOENCODING='ascii')
2052 self.assertEqual(out, expected)
1796 2053
1797 def test_list_command_verbose(self): 2054 def test_list_command_verbose(self):
1798 self.make_simple_tarfile(tmpname) 2055 for tar_name in testtarnames:
1799 with support.captured_stdout() as t: 2056 with support.captured_stdout() as t:
1800 with tarfile.open(tmpname, 'r') as tf: 2057 with tarfile.open(tar_name, 'r') as tf:
1801 tf.list(verbose=True) 2058 tf.list(verbose=True)
1802 expected = t.getvalue().encode(sys.getfilesystemencoding()) 2059 expected = t.getvalue().encode('ascii', 'backslashreplace')
1803 for opt in '-v', '--verbose': 2060 for opt in '-v', '--verbose':
1804 out = self.tarfilecmd(opt, '-l', tmpname) 2061 out = self.tarfilecmd(opt, '-l', tar_name,
1805 self.assertEqual(out, expected) 2062 PYTHONIOENCODING='ascii')
2063 self.assertEqual(out, expected)
1806 2064
1807 def test_list_command_invalid_file(self): 2065 def test_list_command_invalid_file(self):
1808 zipname = support.findfile('zipdir.zip') 2066 zipname = support.findfile('zipdir.zip')
1809 rc, out, err = self.tarfilecmd_failure('-l', zipname) 2067 rc, out, err = self.tarfilecmd_failure('-l', zipname)
1810 self.assertIn(b' is not a tar archive.', err) 2068 self.assertIn(b' is not a tar archive.', err)
1811 self.assertEqual(out, b'') 2069 self.assertEqual(out, b'')
1812 self.assertEqual(rc, 1) 2070 self.assertEqual(rc, 1)
1813 2071
1814 def test_create_command(self): 2072 def test_create_command(self):
1815 files = [support.findfile('tokenize_tests.txt'), 2073 files = [support.findfile('tokenize_tests.txt'),
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after
2035 testtarnames.append(c.tarname) 2293 testtarnames.append(c.tarname)
2036 with c.open(c.tarname, "wb") as tar: 2294 with c.open(c.tarname, "wb") as tar:
2037 tar.write(data) 2295 tar.write(data)
2038 2296
2039 def tearDownModule(): 2297 def tearDownModule():
2040 if os.path.exists(TEMPDIR): 2298 if os.path.exists(TEMPDIR):
2041 shutil.rmtree(TEMPDIR) 2299 shutil.rmtree(TEMPDIR)
2042 2300
2043 if __name__ == "__main__": 2301 if __name__ == "__main__":
2044 unittest.main() 2302 unittest.main()
LEFTRIGHT

RSS Feeds Recent Issues | This issue
This is Rietveld 894c83f36cb7+