Skip to content

Commit 8c69661

Browse files
authored
Merge pull request #623 from TG1999/migration/alpine_linux
Migrate current alpine importer to alpine importer-improver model
2 parents f9f4bc0 + 104c760 commit 8c69661

File tree

19 files changed

+958
-203
lines changed

19 files changed

+958
-203
lines changed

AUTHORS.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,4 @@ The following organizations or individuals have contributed to this repo:
1313
- Navonil Das @NavonilDas
1414
- Tushar Upadhyay @tushar912
1515
- Hritik Vijay @hritik14
16+
- Tushar Goel @TG1999

requirements.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ django-widget-tweaks>=1.4.8
88
packageurl-python>=0.9.4
99
binaryornot>=0.4.4
1010
GitPython>=3.1.17
11-
univers>=30.0.0
11+
univers>=30.1.0
1212
saneyaml>=0.5.2
1313
beautifulsoup4>=4.9.3
1414
python-dateutil>=2.8.1
@@ -17,5 +17,6 @@ lxml>=4.6.4
1717
gunicorn>=20.1.0
1818
django-environ==0.4.5
1919
defusedxml==0.7.1
20+
license-expression>=21.6.14
2021

2122
Markdown==3.3.4

vulnerabilities/importer.py

Lines changed: 39 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
from binaryornot.helpers import is_binary_string
3939
from git import DiffIndex
4040
from git import Repo
41+
from license_expression import Licensing
4142
from packageurl import PackageURL
4243
from univers.version_range import VersionRange
4344
from univers.versions import Version
@@ -117,22 +118,28 @@ 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] = None
124126
fixed_version: Optional[Version] = None
125127

126128
def __post_init__(self):
127129
if self.package.version:
128-
raise ValueError
130+
raise ValueError("The PackageURL supplied must not have a version")
131+
if not (self.affected_version_range or self.fixed_version):
132+
raise ValueError(
133+
"Affected Package should at least have either a fixed version or affected version range"
134+
)
129135

130136
def get_fixed_purl(self):
131137
"""
132138
Return PackageURL corresponding to object's fixed_version
133139
"""
134-
fixed_version = self.fixed_version
135-
fixed_purl = self.package._replace(version=str(fixed_version))
140+
if not self.fixed_version:
141+
raise ValueError("Affected package should have a fixed version")
142+
fixed_purl = self.package._replace(version=str(self.fixed_version))
136143
return fixed_purl
137144

138145
@classmethod
@@ -152,7 +159,8 @@ def merge(cls, affected_packages: Iterable):
152159
fixed_versions = set()
153160
purls = set()
154161
for pkg in affected_packages:
155-
affected_version_ranges.add(pkg.affected_version_range)
162+
if pkg.affected_version_range:
163+
affected_version_ranges.add(pkg.affected_version_range)
156164
if pkg.fixed_version:
157165
fixed_versions.add(pkg.fixed_version)
158166
purls.add(pkg.package)
@@ -164,9 +172,12 @@ def to_dict(self):
164172
"""
165173
Return a serializable dict that can be converted back using self.from_dict
166174
"""
175+
affected_version_range = None
176+
if self.affected_version_range:
177+
affected_version_range = str(self.affected_version_range)
167178
return {
168179
"package": self.package.to_dict(),
169-
"affected_version_range": str(self.affected_version_range),
180+
"affected_version_range": affected_version_range,
170181
"fixed_version": str(self.fixed_version) if self.fixed_version else None,
171182
}
172183

@@ -176,9 +187,16 @@ def from_dict(cls, affected_pkg: dict):
176187
Return an AffectedPackage object from dict generated by self.to_dict
177188
"""
178189
package = PackageURL(**affected_pkg["package"])
179-
affected_version_range = VersionRange.from_string(affected_pkg["affected_version_range"])
190+
affected_version_range = None
191+
if (
192+
affected_pkg["affected_version_range"]
193+
and affected_pkg["affected_version_range"] != "None"
194+
):
195+
affected_version_range = VersionRange.from_string(
196+
affected_pkg["affected_version_range"]
197+
)
180198
fixed_version = affected_pkg["fixed_version"]
181-
if fixed_version:
199+
if fixed_version and affected_version_range:
182200
# TODO: revisit after https://github.com/nexB/univers/issues/10
183201
fixed_version = affected_version_range.version_class(fixed_version)
184202

@@ -203,7 +221,7 @@ class AdvisoryData:
203221
"""
204222

205223
aliases: List[str] = dataclasses.field(default_factory=list)
206-
summary: str = None
224+
summary: Optional[str] = None
207225
affected_packages: List[AffectedPackage] = dataclasses.field(default_factory=list)
208226
references: List[Reference] = dataclasses.field(default_factory=list)
209227
date_published: Optional[datetime.datetime] = None
@@ -217,17 +235,29 @@ class NoLicenseError(Exception):
217235
pass
218236

219237

238+
class InvalidSPDXLicense(Exception):
239+
pass
240+
241+
220242
class Importer:
221243
"""
222244
An Importer collects data from various upstreams and returns corresponding AdvisoryData objects
223245
in its advisory_data method. Subclass this class to implement an importer
224246
"""
225247

226248
spdx_license_expression = ""
249+
license_url = ""
227250

228251
def __init__(self):
229252
if not self.spdx_license_expression:
230253
raise Exception(f"Cannot run importer {self!r} without a license")
254+
licensing = Licensing()
255+
try:
256+
licensing.parse(self.spdx_license_expression)
257+
except InvalidSPDXLicense as e:
258+
raise ValueError(
259+
f"{self.spdx_license_expression!r} is not a valid SPDX license expression"
260+
) from e
231261

232262
@classproperty
233263
def qualified_name(cls):

vulnerabilities/importers/__init__.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,9 @@
1919
# for any legal advice.
2020
# VulnerableCode is a free software code scanning tool from nexB Inc. and others.
2121
# Visit https://github.com/nexB/vulnerablecode/ for support and download.
22+
from vulnerabilities.importers import alpine_linux
2223
from vulnerabilities.importers import nginx
2324

24-
IMPORTERS_REGISTRY = [nginx.NginxImporter]
25+
IMPORTERS_REGISTRY = [nginx.NginxImporter, alpine_linux.AlpineImporter]
2526

2627
IMPORTERS_REGISTRY = {x.qualified_name: x for x in IMPORTERS_REGISTRY}

0 commit comments

Comments
 (0)