Skip to content

Commit 981b9f9

Browse files
keshav-spacemichaelehab
authored andcommitted
Properly parse Snyk fixed versions
Signed-off-by: Keshav Priyadarshi <git@keshav.space> Signed-off-by: Michael Ehab Mikhail <michael.ehab@hotmail.com>
1 parent a307157 commit 981b9f9

2 files changed

Lines changed: 26 additions & 16 deletions

File tree

vulntotal/datasources/snyk.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#
99

1010
import logging
11+
import re
1112
from typing import Iterable
1213
from urllib.parse import quote
1314
from urllib.parse import unquote_plus
@@ -23,6 +24,8 @@
2324

2425
logger = logging.getLogger(__name__)
2526

27+
fixed_version_pattern = re.compile(r"\b\d[\w.-]*\b")
28+
2629

2730
class SnykDataSource(DataSource):
2831
spdx_license_expression = "TODO"
@@ -272,19 +275,16 @@ def parse_html_advisory(advisory_html, snyk_id, affected, purl) -> VendorData:
272275
advisory_soup = BeautifulSoup(advisory_html, "html.parser")
273276
cve_span = advisory_soup.find("span", class_="cve")
274277
if cve_span:
275-
cve_anchor = cve_span.find("a", class_="vue--anchor")
276-
if cve_anchor:
278+
if cve_anchor := cve_span.find("a", class_="vue--anchor"):
277279
aliases.append(cve_anchor.get("id"))
278280

279281
how_to_fix = advisory_soup.find(
280282
"div", class_="vue--block vuln-page__instruction-block vue--block--instruction"
281283
)
282-
if how_to_fix:
283-
fixed = how_to_fix.find("p").text.split(" ")
284-
if "Upgrade" in fixed:
285-
lower = fixed.index("version") if "version" in fixed else fixed.index("versions")
286-
upper = fixed.index("or")
287-
fixed_versions = "".join(fixed[lower + 1 : upper]).split(",")
284+
285+
if how_to_fix and (fixed := how_to_fix.find("p").text):
286+
fixed_versions = fixed_version_pattern.findall(fixed)
287+
288288
aliases.append(snyk_id)
289289
return VendorData(
290290
purl=PackageURL(purl.type, purl.namespace, purl.name),

vulntotal/vulntotal_utils.py

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,9 @@
1313

1414
class GenericVersion:
1515
def __init__(self, version):
16-
self.value = version.replace(" ", "").lstrip("v")
17-
16+
self.value = version
1817
self.decomposed = tuple(
19-
[int(com) if com.isnumeric() else com for com in self.value.split(".")]
18+
[com for com in self.value.replace(" ", "").lstrip("vV").split(".")]
2019
)
2120

2221
def __str__(self):
@@ -25,17 +24,28 @@ def __str__(self):
2524
def __eq__(self, other):
2625
if not isinstance(other, self.__class__):
2726
return NotImplemented
28-
return self.value.__eq__(other.value)
27+
for i, j in zip(self.decomposed, other.decomposed):
28+
if i.isnumeric() and j.isnumeric():
29+
i = int(i)
30+
j = int(j)
31+
if not i.__eq__(j):
32+
return False
33+
return True
2934

3035
def __lt__(self, other):
3136
if not isinstance(other, self.__class__):
3237
return NotImplemented
3338
for i, j in zip(self.decomposed, other.decomposed):
34-
if not isinstance(i, type(j)):
39+
if i.isnumeric() and j.isnumeric():
40+
i = int(i)
41+
j = int(j)
42+
if i.__eq__(j):
3543
continue
44+
if i.__lt__(j):
45+
return True
3646
if i.__gt__(j):
3747
return False
38-
return True
48+
return False
3949

4050
def __le__(self, other):
4151
if not isinstance(other, self.__class__):
@@ -57,8 +67,8 @@ def compare(version, package_comparator, package_version):
5767
"(": operator.gt,
5868
"[": operator.ge,
5969
}
60-
compare = operator_comparator[package_comparator]
61-
return compare(version, package_version)
70+
compare_v = operator_comparator[package_comparator]
71+
return compare_v(version, package_version)
6272

6373

6474
def parse_constraint(constraint):

0 commit comments

Comments
 (0)