Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(221)

Side by Side Diff: tools/telemetry/catapult_base/dependency_manager/dependency_manager_util.py

Issue 1599413006: Remove catapult_base from telemetry. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@perf_cb_move
Patch Set: Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 # Copyright 2015 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file.
4
5 import os
6 import shutil
7 import stat
8 import sys
9 import zipfile
10
11 from . import exceptions
12
13
14 def _WinReadOnlyHandler(func, path, execinfo):
15 if not os.access(path, os.W_OK):
16 os.chmod(path, stat.S_IWRITE)
17 func(path)
18 else:
19 raise execinfo[0], execinfo[1], execinfo[2]
20
21
22 def RemoveDir(dir_path):
23 if os.path.isdir(dir_path):
24 shutil.rmtree(dir_path, onerror=_WinReadOnlyHandler)
25
26
27 def VerifySafeArchive(archive):
28 def ResolvePath(path_name):
29 return os.path.realpath(os.path.abspath(path_name))
30 # Must add pathsep to avoid false positives.
31 # Ex: /tmp/abc/bad_file.py starts with /tmp/a but not /tmp/a/
32 base_path = ResolvePath(os.getcwd()) + os.path.sep
33 for member in archive.namelist():
34 if not ResolvePath(os.path.join(base_path, member)).startswith(base_path):
35 raise exceptions.ArchiveError(
36 'Archive %s contains a bad member: %s.' % (archive.filename, member))
37
38
39 def GetModeFromPath(file_path):
40 return stat.S_IMODE(os.stat(file_path).st_mode)
41
42
43 def GetModeFromZipInfo(zip_info):
44 return zip_info.external_attr >> 16
45
46
47 def SetUnzippedDirPermissions(archive, unzipped_dir):
48 """Set the file permissions in an unzipped archive.
49
50 Designed to be called right after extractall() was called on |archive|.
51 Noop on Win. Otherwise sets the executable bit on files where needed.
52
53 Args:
54 archive: A zipfile.ZipFile object opened for reading.
55 unzipped_dir: A path to a directory containing the unzipped contents
56 of |archive|.
57 """
58 if sys.platform.startswith('win'):
59 # Windows doesn't have an executable bit, so don't mess with the ACLs.
60 return
61 for zip_info in archive.infolist():
62 archive_acls = GetModeFromZipInfo(zip_info)
63 if archive_acls & stat.S_IXUSR:
64 # Only preserve owner execurable permissions.
65 unzipped_path = os.path.abspath(
66 os.path.join(unzipped_dir, zip_info.filename))
67 mode = GetModeFromPath(unzipped_path)
68 os.chmod(unzipped_path, mode | stat.S_IXUSR)
69
70
71 def UnzipArchive(archive_path, unzip_path):
72 """Unzips a file if it is a zip file.
73
74 Args:
75 archive_path: The downloaded file to unzip.
76 unzip_path: The destination directory to unzip to.
77
78 Raises:
79 ValueError: If |archive_path| is not a zipfile.
80 """
81 # TODO(aiolos): Add tests once the refactor is completed. crbug.com/551158
82 if not (archive_path and zipfile.is_zipfile(archive_path)):
83 raise ValueError(
84 'Attempting to unzip a non-archive file at %s' % archive_path)
85 if not os.path.exists(unzip_path):
86 os.makedirs(unzip_path)
87 try:
88 with zipfile.ZipFile(archive_path, 'r') as archive:
89 VerifySafeArchive(archive)
90 archive.extractall(path=unzip_path)
91 SetUnzippedDirPermissions(archive, unzip_path)
92 except:
93 if unzip_path and os.path.isdir(unzip_path):
94 RemoveDir(unzip_path)
95 raise
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698