Skip to content

Commit d96e20f

Browse files
authored
Merge pull request #959 from TG1999/fix_gitlab_importer
Fix gitlab importer
2 parents 92eb01a + 0d1520f commit d96e20f

File tree

3 files changed

+37
-36
lines changed

3 files changed

+37
-36
lines changed

requirements.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,4 +113,4 @@ websocket-client==0.59.0
113113
yarl==1.7.2
114114
zipp==3.8.0
115115
dateparser==1.1.1
116-
fetchcode==0.1.0
116+
fetchcode==0.2.0

setup.cfg

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ install_requires =
8282
# networking
8383
GitPython>=3.1.17
8484
requests>=2.25.1
85-
fetchcode>=0.1.0
85+
fetchcode>=0.2.0
8686

8787
[options.extras_require]
8888
dev =

vulnerabilities/importers/gitlab.py

Lines changed: 35 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -64,60 +64,61 @@
6464
GITLAB_SCHEME_BY_PURL_TYPE = {v: k for k, v in PURL_TYPE_BY_GITLAB_SCHEME.items()}
6565

6666

67-
def fork_and_get_dir(url):
68-
"""
69-
Fetch a clone of the gitlab repository at url and return the directory destination
70-
"""
71-
return fetch_via_vcs(url).dest_dir
72-
73-
7467
class GitLabAPIImporter(GitImporter):
7568
spdx_license_expression = "MIT"
7669
license_url = "https://gitlab.com/gitlab-org/advisories-community/-/blob/main/LICENSE"
7770

7871
def __init__(self):
7972
super().__init__(repo_url="git+https://gitlab.com/gitlab-org/advisories-community/")
8073

81-
def advisory_data(self) -> Iterable[AdvisoryData]:
74+
def advisory_data(self, _keep_clone=True) -> Iterable[AdvisoryData]:
8275
try:
8376
self.clone()
84-
path = Path(self.vcs_response.dest_dir)
85-
86-
glob = "**/*.yml"
87-
files = (p for p in path.glob(glob) if p.is_file())
88-
for file in files:
89-
# split a path according to gitlab conventions where package type and name are a part of path
90-
# For example with this path:
91-
# /tmp/tmpi1klhpmd/pypi/gradio/CVE-2021-43831.yml
92-
# the package type is pypi and the package name is gradio
93-
# to ('/', 'tmp', 'tmpi1klhpmd', 'pypi', 'gradio', 'CVE-2021-43831.yml')
94-
purl_type = get_gitlab_package_type(path=file)
95-
if not purl_type:
96-
logger.error(f"Unknow gitlab directory structure {file!r}")
97-
continue
77+
base_path = Path(self.vcs_response.dest_dir)
78+
79+
for file_path in base_path.glob("**/*.yml"):
80+
gitlab_type, package_slug, vuln_id = parse_advisory_path(
81+
base_path=base_path,
82+
file_path=file_path,
83+
)
9884

99-
if purl_type in PURL_TYPE_BY_GITLAB_SCHEME:
100-
yield parse_gitlab_advisory(file)
85+
if gitlab_type in PURL_TYPE_BY_GITLAB_SCHEME:
86+
yield parse_gitlab_advisory(file_path)
10187

10288
else:
103-
logger.error(f"Unknow package type {purl_type!r}")
89+
logger.error(f"Unknow package type {gitlab_type!r} in {file_path!r}")
10490
continue
10591
finally:
106-
if self.vcs_response:
92+
if self.vcs_response and not _keep_clone:
10793
self.vcs_response.delete()
10894

10995

110-
def get_gitlab_package_type(path: Path):
96+
def parse_advisory_path(base_path: Path, file_path: Path) -> Optional[AdvisoryData]:
11197
"""
112-
Return a package type extracted from a gitlab advisory path or None
113-
"""
114-
parts = path.parts[-3:]
98+
Parse a gitlab advisory file and return a 3-tuple of:
99+
(gitlab_type, package_slug, vulnerability_id)
115100
116-
if len(parts) < 3:
117-
return
101+
For example::
102+
103+
>>> base_path = Path("/tmp/tmpi1klhpmd/checkout")
104+
>>> file_path=Path("/tmp/tmpi1klhpmd/checkout/pypi/gradio/CVE-2021-43831.yml")
105+
>>> parse_advisory_path(base_path=base_path, file_path=file_path)
106+
('pypi', 'gradio', 'CVE-2021-43831')
107+
108+
>>> file_path=Path("/tmp/tmpi1klhpmd/checkout/nuget/github.com/beego/beego/v2/nuget/CVE-2021-43831.yml")
109+
>>> parse_advisory_path(base_path=base_path, file_path=file_path)
110+
('nuget', 'github.com/beego/beego/v2/nuget', 'CVE-2021-43831')
111+
112+
>>> file_path = Path("/tmp/tmpi1klhpmd/checkout/npm/@express/beego/beego/v2/CVE-2021-43831.yml")
113+
>>> parse_advisory_path(base_path=base_path, file_path=file_path)
114+
('npm', '@express/beego/beego/v2', 'CVE-2021-43831')
115+
"""
116+
relative_path_segments = str(file_path.relative_to(base_path)).strip("/").split("/")
117+
gitlab_type = relative_path_segments[0]
118+
vuln_id = relative_path_segments[-1].replace(".yml", "")
119+
package_slug = "/".join(relative_path_segments[1:-1])
118120

119-
type, _name, _vid = parts
120-
return type
121+
return gitlab_type, package_slug, vuln_id
121122

122123

123124
def get_purl(package_slug):

0 commit comments

Comments
 (0)