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

Side by Side Diff: Lib/tarfile.py

Issue 19974: tarfile doesn't overwrite symlink by directory
Patch Set: Created 5 years, 9 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 1978 matching lines...) Expand 10 before | Expand all | Expand 10 after
1989 if isinstance(member, str): 1989 if isinstance(member, str):
1990 tarinfo = self.getmember(member) 1990 tarinfo = self.getmember(member)
1991 else: 1991 else:
1992 tarinfo = member 1992 tarinfo = member
1993 1993
1994 # Prepare the link target for makelink(). 1994 # Prepare the link target for makelink().
1995 if tarinfo.islnk(): 1995 if tarinfo.islnk():
1996 tarinfo._link_target = os.path.join(path, tarinfo.linkname) 1996 tarinfo._link_target = os.path.join(path, tarinfo.linkname)
1997 1997
1998 try: 1998 try:
1999 self._extract_member(tarinfo, os.path.join(path, tarinfo.name), 1999 drv, normalized_path = os.path.splitdrive(path)
storchaka 2013/12/15 21:38:11 Why these changes are needed? They are not look re
vajrasky 2014/01/16 08:21:52 There is an underlying bug on Windows. Without the
storchaka 2014/01/16 08:31:23 Yes, please open a separate ticket.
2000 set_attrs=set_attrs) 2000 normalized_path = normalized_path.replace(os.sep, '/')
2001 joined_path = '/' + tarinfo.name
2002 # We don't want to join '/home/user' and 'home/user/file' to avoid
storchaka 2013/12/15 21:38:11 Why not?
vajrasky 2014/01/16 08:21:52 I'll explain it later when I get back to my Window
2003 # '/home/user/home/user/file'.
2004 native_tarinfo_name = tarinfo.name.replace('/', os.sep)
2005 if normalized_path != joined_path[:len(normalized_path)]:
2006 joined_path = os.path.join(path, native_tarinfo_name)
2007 else:
2008 # tarinfo.name is an absolute path
2009 if os.name == 'nt':
2010 joined_path = drv + os.sep + native_tarinfo_name
2011 else:
2012 joined_path = os.sep + native_tarinfo_name
2013 self._extract_member(tarinfo, joined_path, set_attrs=set_attrs)
2001 except OSError as e: 2014 except OSError as e:
2002 if self.errorlevel > 0: 2015 if self.errorlevel > 0:
2003 raise 2016 raise
2004 else: 2017 else:
2005 if e.filename is None: 2018 if e.filename is None:
2006 self._dbg(1, "tarfile: %s" % e.strerror) 2019 self._dbg(1, "tarfile: %s" % e.strerror)
2007 else: 2020 else:
2008 self._dbg(1, "tarfile: %s %r" % (e.strerror, e.filename)) 2021 self._dbg(1, "tarfile: %s %r" % (e.strerror, e.filename))
2009 except ExtractError as e: 2022 except ExtractError as e:
2010 if self.errorlevel > 1: 2023 if self.errorlevel > 1:
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after
2148 os.makedev(tarinfo.devmajor, tarinfo.devminor)) 2161 os.makedev(tarinfo.devmajor, tarinfo.devminor))
2149 2162
2150 def makelink(self, tarinfo, targetpath): 2163 def makelink(self, tarinfo, targetpath):
2151 """Make a (symbolic) link called targetpath. If it cannot be created 2164 """Make a (symbolic) link called targetpath. If it cannot be created
2152 (platform limitation), we try to make a copy of the referenced file 2165 (platform limitation), we try to make a copy of the referenced file
2153 instead of a link. 2166 instead of a link.
2154 """ 2167 """
2155 try: 2168 try:
2156 # For systems that support symbolic and hard links. 2169 # For systems that support symbolic and hard links.
2157 if tarinfo.issym(): 2170 if tarinfo.issym():
2158 os.symlink(tarinfo.linkname, targetpath) 2171 if os.path.exists(targetpath):
storchaka 2013/12/15 21:38:11 I think we should remove targetpath in all cases.
2172 os.unlink(targetpath)
2173 if os.name == 'nt' and os.path.isdir(tarinfo.linkname):
2174 os.symlink(tarinfo.linkname, targetpath, target_is_directory =True)
2175 else:
2176 os.symlink(tarinfo.linkname, targetpath)
2159 else: 2177 else:
2160 # See extract(). 2178 # See extract().
2161 if os.path.exists(tarinfo._link_target): 2179 if os.path.exists(tarinfo._link_target):
2162 os.link(tarinfo._link_target, targetpath) 2180 os.link(tarinfo._link_target, targetpath)
2163 else: 2181 else:
2164 self._extract_member(self._find_link_target(tarinfo), 2182 self._extract_member(self._find_link_target(tarinfo),
2165 targetpath) 2183 targetpath)
2166 except symlink_exception: 2184 except symlink_exception:
2167 try: 2185 try:
2168 self._extract_member(self._find_link_target(tarinfo), 2186 self._extract_member(self._find_link_target(tarinfo),
(...skipping 322 matching lines...) Expand 10 before | Expand all | Expand 10 after
2491 tf.add(file_name) 2509 tf.add(file_name)
2492 2510
2493 if args.verbose: 2511 if args.verbose:
2494 print('{!r} file created.'.format(tar_name)) 2512 print('{!r} file created.'.format(tar_name))
2495 2513
2496 else: 2514 else:
2497 parser.exit(1, parser.format_help()) 2515 parser.exit(1, parser.format_help())
2498 2516
2499 if __name__ == '__main__': 2517 if __name__ == '__main__':
2500 main() 2518 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+