22from compatibility_helper
import byte_str_decode
24SCRIPT_DIR = os.path.dirname(sys.argv[0])
25CHECKOUT_ROOT = os.path.realpath(os.path.join(SCRIPT_DIR,
'..'))
26CHROMIUM_README_FILE =
'third_party/accessibility/README.md'
27CHROMIUM_README_COMMIT_LINE = 4
28CHROMIUM =
'https://chromium.googlesource.com/chromium/src'
29DEP_CLONE_DIR = CHECKOUT_ROOT +
'/clone-test'
30DEPS = os.path.join(CHECKOUT_ROOT,
'DEPS')
31UPSTREAM_PREFIX =
'upstream_'
45 """Implements the Var syntax."""
51 raise Exception(
'Var is not defined: %s' % var_name)
62 with open(deps_file,
'r')
as file:
63 deps_content = file.read()
66 exec(deps_content, global_scope, local_scope)
68 if not os.path.exists(DEP_CLONE_DIR):
69 os.mkdir(DEP_CLONE_DIR)
72 deps = local_scope.get(
'deps', {})
73 deps_list = local_scope.get(
'vars')
74 filtered_osv_deps = []
75 for _, dep
in deps.items():
78 if not isinstance(dep, str):
81 dep_split = dep.rsplit(
'@', 1)
84 filtered_osv_deps.append({
85 'package': {
'name': ancestor_result[1],
'commit': ancestor_result[0]}
90 shutil.rmtree(DEP_CLONE_DIR)
91 except OSError
as clone_dir_error:
92 print(
'Error cleaning up clone directory: %s : %s' % (DEP_CLONE_DIR, clone_dir_error.strerror))
95 'packageSource': {
'path': deps_file,
'type':
'lockfile'},
'packages': filtered_osv_deps
102 Opens the Flutter Accessibility Library README and uses the commit hash
103 found
in the README to check
for viulnerabilities.
104 The commit hash
in this README will always be
in the same format
106 file_path = os.path.join(CHECKOUT_ROOT, CHROMIUM_README_FILE)
107 with open(file_path)
as file:
109 content = file.readlines()
110 commit_line = content[CHROMIUM_README_COMMIT_LINE]
111 commit = re.search(
r'(?<=\[).*(?=\])', commit_line)
114 'packageSource': {
'path': file_path,
'type':
'lockfile'},
115 'packages': [{
'package': {
'name': CHROMIUM,
'commit': commit.group()}}]
123 Given an input of a mirrored dep,
124 compare to the mapping of deps to their upstream
125 in DEPS
and find a common ancestor
128 This
is done by first cloning the mirrored dep,
129 then a branch which tracks the upstream.
130 From there, git merge-base operates using the HEAD
131 commit SHA of the upstream branch
and the pinned
132 SHA value of the mirrored branch
137 dep_name = dep[0].split(
'/')[-1].split(
'.')[0]
138 if UPSTREAM_PREFIX + dep_name
not in deps_list:
139 print(
'did not find dep: ' + dep_name)
143 upstream = deps_list.get(UPSTREAM_PREFIX + dep_name)
144 temp_dep_dir = DEP_CLONE_DIR +
'/' + dep_name
146 subprocess.check_output([
'git',
'clone',
'--quiet',
'--', dep[0], dep_name], cwd=DEP_CLONE_DIR)
149 print(
'attempting to add upstream remote from: {upstream}'.
format(upstream=upstream))
150 subprocess.check_output([
'git',
'remote',
'add',
'upstream', upstream], cwd=temp_dep_dir)
151 subprocess.check_output([
'git',
'fetch',
'--quiet',
'upstream'], cwd=temp_dep_dir)
153 default_branch = subprocess.check_output(
154 'git remote show upstream ' +
"| sed -n \'/HEAD branch/s/.*: //p\'",
159 default_branch = default_branch.strip()
162 subprocess.check_output([
163 'git',
'checkout',
'--force',
'-b',
'upstream',
'--track',
'upstream/' + default_branch
167 commit = subprocess.check_output(
168 'git for-each-ref ' +
"--format=\'%(objectname:short)\' refs/heads/upstream",
173 commit = commit.strip()
176 ancestor_commit = subprocess.check_output(
177 'git merge-base {commit} {depUrl}'.
format(commit=commit, depUrl=dep[1]),
182 ancestor_commit = ancestor_commit.strip()
183 print(
'Ancestor commit: ' + ancestor_commit)
184 return ancestor_commit, upstream
185 except subprocess.CalledProcessError
as error:
187 "Subprocess command '{0}' failed with exit code: {1}.".
format(
188 error.cmd, str(error.returncode)
192 print(
"Subprocess error output: '{0}'".
format(error.output))
198 parser = argparse.ArgumentParser(description=
'A script to find common ancestor commit SHAs')
204 help=
'Input DEPS file to extract.',
205 default=os.path.join(CHECKOUT_ROOT,
'DEPS')
211 help=
'Output osv-scanner compatible deps file.',
212 default=os.path.join(CHECKOUT_ROOT,
'osv-lockfile.json')
215 return parser.parse_args(args)
219 output = {
'results': deps}
220 print(json.dumps(output, indent=2))
221 with open(manifest_file,
'w')
as manifest:
222 json.dump(output, manifest, indent=2)
233if __name__ ==
'__main__':
234 sys.exit(
main(sys.argv))
def lookup(self, var_name)
def __init__(self, local_scope)
uint32_t uint32_t * format
def byte_str_decode(str_or_bytes)
const myers::Point & get(const myers::Segment &)
def print(*args, **kwargs)
def get_common_ancestor(dep, deps_list)
def extract_deps(deps_file)
def write_manifest(deps, manifest_file)