Skip to content

Commit 3360eb3

Browse files
committed
add parsing for spdx license expression make affected version range optional
Signed-off-by: Tushar Goel <tushar.goel.dav@gmail.com>
1 parent e8db544 commit 3360eb3

2 files changed

Lines changed: 50 additions & 7 deletions

File tree

vulnerabilities/importer.py

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
from packageurl import PackageURL
4242
from univers.version_range import VersionRange
4343
from univers.versions import Version
44+
from license_expression import Licensing
4445

4546
from vulnerabilities.helpers import classproperty
4647
from vulnerabilities.helpers import nearest_patched_package
@@ -117,22 +118,24 @@ class AffectedPackage:
117118
"""
118119
Contains a range of affected versions and a fixed version of a given package
119120
The PackageURL supplied must *not* have a version
121+
It must contain either `affected_version_range` or `fixed_version`
120122
"""
121123

122124
package: PackageURL
123-
affected_version_range: VersionRange
125+
affected_version_range: Optional[VersionRange]
124126
fixed_version: Optional[Version] = None
125127

126128
def __post_init__(self):
127-
if self.package.version:
129+
if self.package.version or not (self.affected_version_range or self.fixed_version):
128130
raise ValueError
129131

130132
def get_fixed_purl(self):
131133
"""
132134
Return PackageURL corresponding to object's fixed_version
133135
"""
134-
fixed_version = self.fixed_version
135-
fixed_purl = self.package._replace(version=str(fixed_version))
136+
if not self.fixed_version:
137+
raise ValueError
138+
fixed_purl = self.package._replace(version=str(self.fixed_version))
136139
return fixed_purl
137140

138141
@classmethod
@@ -228,6 +231,13 @@ class Importer:
228231
def __init__(self):
229232
if not self.spdx_license_expression:
230233
raise Exception(f"Cannot run importer {self!r} without a license")
234+
licensing = Licensing()
235+
try:
236+
licensing.parse(self.spdx_license_expression)
237+
except:
238+
raise Exception(
239+
f"{self.spdx_license_expression} is not a valid spdx license expression"
240+
)
231241

232242
@classproperty
233243
def qualified_name(cls):

vulnerabilities/importers/alpine_linux.py

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,18 +28,24 @@
2828

2929
import requests
3030
from bs4 import BeautifulSoup
31+
from packageurl import PackageURL
32+
from univers.versions import AlpineLinuxVersion
3133

3234
from vulnerabilities.helpers import is_cve
3335
from vulnerabilities.importer import AdvisoryData
36+
from vulnerabilities.importer import AffectedPackage
3437
from vulnerabilities.importer import Importer
3538
from vulnerabilities.importer import Reference
3639

3740

3841
class AlpineImporter(Importer):
42+
spdx_license_expression = "CC-BY-SA-4.0"
43+
3944
def advisory_data(self) -> Iterable[AdvisoryData]:
45+
advisories = []
4046
advisory_links = fetch_advisory_links()
4147
for link in advisory_links:
42-
yield (process_link(link))
48+
advisories.extend(process_link(link))
4349

4450

4551
def fetch_advisory_links():
@@ -74,26 +80,39 @@ def process_link(link) -> List[AdvisoryData]:
7480
return advisories
7581

7682
for package in record["packages"]:
83+
assert isinstance(record["archs"], Iterable[str])
84+
assert isinstance(record["reponame"], str)
85+
assert isinstance(record["distroversion"], str)
7786
advisories.extend(
7887
load_advisories(
7988
package["pkg"],
89+
record["distroversion"],
90+
record["reponame"],
91+
record["archs"],
8092
)
8193
)
8294
return advisories
8395

8496

8597
def load_advisories(
8698
pkg_infos: Mapping[str, Any],
99+
distroversion: str,
100+
reponame: str,
101+
archs: Iterable[str],
87102
) -> Iterable[AdvisoryData]:
88103

104+
if not (pkg_infos.get("name") and isinstance(pkg_infos["name"], str)):
105+
return []
106+
89107
assert isinstance(pkg_infos["secfixes"], Mapping[str, List])
90108

91-
for fixed_vulns in pkg_infos["secfixes"].values():
109+
for version, fixed_vulns in pkg_infos["secfixes"].items():
92110

93111
if fixed_vulns is None:
94112
continue
95113

96114
for vuln_ids in fixed_vulns:
115+
assert isinstance(vuln_ids, str)
97116
vuln_ids = vuln_ids.split()
98117
references = []
99118
for reference_id in vuln_ids[1:]:
@@ -127,6 +146,20 @@ def load_advisories(
127146
yield AdvisoryData(
128147
summary="",
129148
references=references,
130-
affected_packages=[],
149+
affected_packages=[
150+
AffectedPackage(
151+
package=PackageURL(
152+
type="alpine",
153+
name=pkg_infos["name"],
154+
qualifiers={
155+
"arch": arch,
156+
"distroversion": distroversion,
157+
"reponame": reponame,
158+
},
159+
),
160+
fixed_version=AlpineLinuxVersion(version),
161+
)
162+
for arch in archs
163+
],
131164
aliases=[vuln_ids[0] if is_cve(vuln_ids[0]) else ""],
132165
)

0 commit comments

Comments
 (0)