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

Side by Side Diff: Lib/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
« no previous file with comments | « no previous file | Lib/test/test_tarfile.py » ('j') | Lib/test/test_tarfile.py » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 #!/usr/bin/env python3 1 #!/usr/bin/env python3
2 #------------------------------------------------------------------- 2 #-------------------------------------------------------------------
3 # tarfile.py 3 # tarfile.py
4 #------------------------------------------------------------------- 4 #-------------------------------------------------------------------
5 # Copyright (C) 2002 Lars Gustaebel <lars@gustaebel.de> 5 # Copyright (C) 2002 Lars Gustaebel <lars@gustaebel.de>
6 # All rights reserved. 6 # All rights reserved.
7 # 7 #
8 # Permission is hereby granted, free of charge, to any person 8 # Permission is hereby granted, free of charge, to any person
9 # obtaining a copy of this software and associated documentation 9 # obtaining a copy of this software and associated documentation
10 # files (the "Software"), to deal in the Software without 10 # files (the "Software"), to deal in the Software without
(...skipping 29 matching lines...) Expand all
40 #--------- 40 #---------
41 import sys 41 import sys
42 import os 42 import os
43 import io 43 import io
44 import shutil 44 import shutil
45 import stat 45 import stat
46 import time 46 import time
47 import struct 47 import struct
48 import copy 48 import copy
49 import re 49 import re
50 import errno
Martin Panter 2018/12/16 02:37:21 What is this needed for?
50 51
51 try: 52 try:
52 import grp, pwd 53 import grp, pwd
53 except ImportError: 54 except ImportError:
54 grp = pwd = None 55 grp = pwd = None
55 56
56 # os.symlink on Windows prior to 6.0 raises NotImplementedError 57 # os.symlink on Windows prior to 6.0 raises NotImplementedError
57 symlink_exception = (AttributeError, NotImplementedError) 58 symlink_exception = (AttributeError, NotImplementedError)
58 try: 59 try:
59 # OSError (winerror=1314) will be raised if the caller does not hold the 60 # OSError (winerror=1314) will be raised if the caller does not hold the
(...skipping 2017 matching lines...) Expand 10 before | Expand all | Expand 10 after
2077 upperdirs = os.path.dirname(targetpath) 2078 upperdirs = os.path.dirname(targetpath)
2078 if upperdirs and not os.path.exists(upperdirs): 2079 if upperdirs and not os.path.exists(upperdirs):
2079 # Create directories that are not part of the archive with 2080 # Create directories that are not part of the archive with
2080 # default permissions. 2081 # default permissions.
2081 os.makedirs(upperdirs) 2082 os.makedirs(upperdirs)
2082 2083
2083 if tarinfo.islnk() or tarinfo.issym(): 2084 if tarinfo.islnk() or tarinfo.issym():
2084 self._dbg(1, "%s -> %s" % (tarinfo.name, tarinfo.linkname)) 2085 self._dbg(1, "%s -> %s" % (tarinfo.name, tarinfo.linkname))
2085 else: 2086 else:
2086 self._dbg(1, tarinfo.name) 2087 self._dbg(1, tarinfo.name)
2088
2089 if os.path.exists(targetpath) and \
Martin Panter 2018/12/16 02:37:21 What about “lexists” for handling broken links? Se
2090 (not os.path.isdir(targetpath) or os.path.islink(targetpath)):
2091 os.remove(targetpath)
2092 else:
2093 # File should be able to overwrite empty directory
2094 try:
2095 os.rmdir(targetpath)
2096 except OSError:
2097 pass
2087 2098
2088 if tarinfo.isreg(): 2099 if tarinfo.isreg():
2089 self.makefile(tarinfo, targetpath) 2100 self.makefile(tarinfo, targetpath)
2090 elif tarinfo.isdir(): 2101 elif tarinfo.isdir():
2091 self.makedir(tarinfo, targetpath) 2102 self.makedir(tarinfo, targetpath)
2092 elif tarinfo.isfifo(): 2103 elif tarinfo.isfifo():
2093 self.makefifo(tarinfo, targetpath) 2104 self.makefifo(tarinfo, targetpath)
2094 elif tarinfo.ischr() or tarinfo.isblk(): 2105 elif tarinfo.ischr() or tarinfo.isblk():
2095 self.makedev(tarinfo, targetpath) 2106 self.makedev(tarinfo, targetpath)
2096 elif tarinfo.islnk() or tarinfo.issym(): 2107 elif tarinfo.islnk() or tarinfo.issym():
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
2168 os.makedev(tarinfo.devmajor, tarinfo.devminor)) 2179 os.makedev(tarinfo.devmajor, tarinfo.devminor))
2169 2180
2170 def makelink(self, tarinfo, targetpath): 2181 def makelink(self, tarinfo, targetpath):
2171 """Make a (symbolic) link called targetpath. If it cannot be created 2182 """Make a (symbolic) link called targetpath. If it cannot be created
2172 (platform limitation), we try to make a copy of the referenced file 2183 (platform limitation), we try to make a copy of the referenced file
2173 instead of a link. 2184 instead of a link.
2174 """ 2185 """
2175 try: 2186 try:
2176 # For systems that support symbolic and hard links. 2187 # For systems that support symbolic and hard links.
2177 if tarinfo.issym(): 2188 if tarinfo.issym():
2178 os.symlink(tarinfo.linkname, targetpath) 2189 if os.name == 'nt' and os.path.isdir(tarinfo.linkname):
2190 os.symlink(tarinfo.linkname, targetpath, target_is_directory =True)
2191 else:
2192 os.symlink(tarinfo.linkname, targetpath)
2179 else: 2193 else:
2180 # See extract(). 2194 # See extract().
2181 if os.path.exists(tarinfo._link_target): 2195 if os.path.exists(tarinfo._link_target):
2182 os.link(tarinfo._link_target, targetpath) 2196 os.link(tarinfo._link_target, targetpath)
2183 else: 2197 else:
2184 self._extract_member(self._find_link_target(tarinfo), 2198 self._extract_member(self._find_link_target(tarinfo),
2185 targetpath) 2199 targetpath)
2186 except symlink_exception: 2200 except symlink_exception:
2187 try: 2201 try:
2188 self._extract_member(self._find_link_target(tarinfo), 2202 self._extract_member(self._find_link_target(tarinfo),
(...skipping 322 matching lines...) Expand 10 before | Expand all | Expand 10 after
2511 tf.add(file_name) 2525 tf.add(file_name)
2512 2526
2513 if args.verbose: 2527 if args.verbose:
2514 print('{!r} file created.'.format(tar_name)) 2528 print('{!r} file created.'.format(tar_name))
2515 2529
2516 else: 2530 else:
2517 parser.exit(1, parser.format_help()) 2531 parser.exit(1, parser.format_help())
2518 2532
2519 if __name__ == '__main__': 2533 if __name__ == '__main__':
2520 main() 2534 main()
OLDNEW
« no previous file with comments | « no previous file | Lib/test/test_tarfile.py » ('j') | Lib/test/test_tarfile.py » ('J')

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