Skip to content

Commit b68f076

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 b68f076

2 files changed

Lines changed: 41 additions & 7 deletions

File tree

vulnerabilities/importer.py

Lines changed: 12 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,11 @@ 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(f"{self.spdx_license_expression} is not a valid spdx license expression")
231239

232240
@classproperty
233241
def qualified_name(cls):

vulnerabilities/importers/alpine_linux.py

Lines changed: 29 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,13 @@ def load_advisories(
127146
yield AdvisoryData(
128147
summary="",
129148
references=references,
130-
affected_packages=[],
149+
affected_packages=[
150+
AffectedPackage(
151+
package= PackageURL(type="alpine", name=pkg_infos['name'], qualifiers={"arch": arch, "distroversion": distroversion, "reponame": reponame}),
152+
fixed_version= AlpineLinuxVersion(version)
153+
)
154+
for arch in archs
155+
]
156+
,
131157
aliases=[vuln_ids[0] if is_cve(vuln_ids[0]) else ""],
132158
)

0 commit comments

Comments
 (0)