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

Side by Side Diff: Lib/test/test_tarfile.py

Issue 19974: tarfile doesn't overwrite symlink by directory
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:
View unified diff | Download patch
« Lib/tarfile.py ('K') | « Lib/tarfile.py ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 1140 matching lines...) Expand 10 before | Expand all | Expand 10 after
1155 finally: 1156 finally:
1156 tar.close() 1157 tar.close()
1157 1158
1158 if not dir: 1159 if not dir:
1159 os.remove(foo) 1160 os.remove(foo)
1160 else: 1161 else:
1161 os.rmdir(foo) 1162 os.rmdir(foo)
1162 1163
1163 self.assertEqual(t.name, cmp_path or path.replace(os.sep, "/")) 1164 self.assertEqual(t.name, cmp_path or path.replace(os.sep, "/"))
1164 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)
1165 1278
1166 @support.skip_unless_symlink 1279 @support.skip_unless_symlink
1167 def test_extractall_symlinks(self): 1280 def test_extractall_symlinks(self):
1168 # Test if extractall works properly when tarfile contains symlinks 1281 # Test if extractall works properly when tarfile contains symlinks
1169 tempdir = os.path.join(TEMPDIR, "testsymlinks") 1282 tempdir = os.path.join(TEMPDIR, "testsymlinks")
1170 temparchive = os.path.join(TEMPDIR, "testsymlinks.tar") 1283 temparchive = os.path.join(TEMPDIR, "testsymlinks.tar")
1171 os.mkdir(tempdir) 1284 os.mkdir(tempdir)
1172 try: 1285 try:
1173 source_file = os.path.join(tempdir,'source') 1286 # File symlink
1174 target_file = os.path.join(tempdir,'symlink') 1287 source_file = os.path.join(tempdir, 'source')
1288 other_source_file = os.path.join(tempdir, 'other_source')
1289 target_file = os.path.join(tempdir, 'symlink')
1175 with open(source_file,'w') as f: 1290 with open(source_file,'w') as f:
1176 f.write('something\n') 1291 f.write('source file content\n')
1292 with open(other_source_file,'w') as f:
1293 f.write('other source file content\n')
1177 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)
1178 tar = tarfile.open(temparchive,'w') 1302 tar = tarfile.open(temparchive,'w')
1179 tar.add(source_file) 1303 # We don't want to add absolute path to tar file because
1180 tar.add(target_file) 1304 # we don't want nested directory after extracting the file:
1305 # /home/user/python/symlink/home/user/python/symlink/file
1306 with support.change_cwd(tempdir):
1307 tar.add('source')
1308 tar.add('symlink')
1309 tar.add('source_dir')
1310 tar.add('symlink_dir')
1181 tar.close() 1311 tar.close()
1182 # Let's extract it to the location which contains the symlink 1312 # Point target_file to other_source_file and target_dir to
1313 # other_source_dir to exercise overwriting behavior.
1314 os.unlink(target_file)
1315 os.symlink(other_source_file, target_file)
1316 os.unlink(target_dir)
1317 os.symlink(other_source_dir, target_dir)
1183 tar = tarfile.open(temparchive,'r') 1318 tar = tarfile.open(temparchive,'r')
1184 # this should not raise OSError: [Errno 17] File exists
1185 try: 1319 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
1186 tar.extractall(path=tempdir) 1324 tar.extractall(path=tempdir)
1325 # target_file that symlinked to other_source_file now symlinks
1326 # back to source_file, and target_dir that symlinked to
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
1187 except OSError: 1332 except OSError:
1188 self.fail("extractall failed with symlinked files") 1333 self.fail("extractall failed with symlinked files")
1189 finally: 1334 finally:
1190 tar.close() 1335 tar.close()
1191 finally: 1336 finally:
1192 os.unlink(temparchive) 1337 os.unlink(temparchive)
1193 shutil.rmtree(tempdir) 1338 shutil.rmtree(tempdir)
1194 1339
1195 def test_pathnames(self): 1340 def test_pathnames(self):
1196 self._test_pathname("foo") 1341 self._test_pathname("foo")
(...skipping 951 matching lines...) Expand 10 before | Expand all | Expand 10 after
2148 testtarnames.append(c.tarname) 2293 testtarnames.append(c.tarname)
2149 with c.open(c.tarname, "wb") as tar: 2294 with c.open(c.tarname, "wb") as tar:
2150 tar.write(data) 2295 tar.write(data)
2151 2296
2152 def tearDownModule(): 2297 def tearDownModule():
2153 if os.path.exists(TEMPDIR): 2298 if os.path.exists(TEMPDIR):
2154 shutil.rmtree(TEMPDIR) 2299 shutil.rmtree(TEMPDIR)
2155 2300
2156 if __name__ == "__main__": 2301 if __name__ == "__main__":
2157 unittest.main() 2302 unittest.main()
OLDNEW
« Lib/tarfile.py ('K') | « Lib/tarfile.py ('k') | no next file » | no next file with comments »

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