Skip to content

Commit 56bf9d0

Browse files
committed
Remove get_code_commit function
Add all the fields in keys for comparison CodeCommitData Signed-off-by: ziad hany <ziadhany2016@gmail.com>
1 parent 9a4580c commit 56bf9d0

File tree

3 files changed

+163
-170
lines changed

3 files changed

+163
-170
lines changed

vulnerabilities/importer.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,13 @@ def __lt__(self, other):
221221

222222
# TODO: Add cache
223223
def _cmp_key(self):
224-
return (self.commit_hash, self.vcs_url, self.commit_author, self.commit_message)
224+
return (
225+
self.commit_hash,
226+
self.vcs_url,
227+
self.commit_author,
228+
self.commit_message,
229+
self.commit_date,
230+
)
225231

226232
def to_dict(self) -> dict:
227233
"""Return a normalized dictionary representation of the commit."""

vulnerabilities/importers/osv.py

Lines changed: 65 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
from typing import Iterable
1313
from typing import List
1414
from typing import Optional
15+
from typing import Tuple
1516

1617
import dateparser
1718
from cvss.exceptions import CVSS3MalformedError
@@ -85,8 +86,8 @@ def parse_advisory_data(
8586
)
8687

8788
for fixed_range in affected_pkg.get("ranges") or []:
88-
fixed_version = get_fixed_versions(
89-
fixed_range=fixed_range, raw_id=raw_id, supported_ecosystem=purl.type
89+
fixed_version, _ = get_fixed_versions_and_commits(
90+
ranges=fixed_range, raw_id=raw_id, supported_ecosystem=purl.type
9091
)
9192

9293
for version in fixed_version:
@@ -151,12 +152,11 @@ def parse_advisory_data_v2(
151152
fixed_versions = []
152153
fixed_version_range = None
153154
for fixed_range in affected_pkg.get("ranges") or []:
154-
fixed_version = get_fixed_versions(
155-
fixed_range=fixed_range, raw_id=advisory_id, supported_ecosystem=purl.type
155+
fixed_version, (introduced_commits, fixed_commits) = get_fixed_versions_and_commits(
156+
ranges=fixed_range, raw_id=advisory_id, supported_ecosystem=purl.type
156157
)
157158
fixed_versions.extend([v.string for v in fixed_version])
158159

159-
introduced_commits, fixed_commits = get_code_commit(fixed_range, raw_id=advisory_id)
160160
fixed_by_commits.extend(fixed_commits)
161161
affected_by_commits.extend(introduced_commits)
162162

@@ -196,32 +196,23 @@ def parse_advisory_data_v2(
196196
)
197197

198198

199-
def extract_fixed_versions(fixed_range) -> Iterable[str]:
199+
def extract_introduced_and_fixed(ranges) -> Tuple[List[str], List[str]]:
200200
"""
201-
Return a list of fixed version strings given a ``fixed_range`` mapping of
202-
OSV data.
201+
Return pairs of introduced and fixed versions or commit hashes given a ``ranges``
202+
mapping of OSV data.
203203
204-
>>> list(extract_fixed_versions(
205-
... {"type": "SEMVER", "events": [{"introduced": "0"},{"fixed": "1.6.0"}]}))
206-
['1.6.0']
207-
208-
>>> list(extract_fixed_versions(
209-
... {"type": "ECOSYSTEM","events":[{"introduced": "0"},
210-
... {"fixed": "1.0.0"},{"fixed": "9.0.0"}]}))
211-
['1.0.0', '9.0.0']
212-
"""
213-
for event in fixed_range.get("events") or []:
214-
fixed = event.get("fixed")
215-
if fixed:
216-
yield fixed
204+
Both introduced and fixed fields may represent semantic versions or commit hashes.
217205
206+
>>> list(extract_introduced_and_fixed(
207+
... {"type": "SEMVER", "events": [{"introduced": "0"}, {"fixed": "1.6.0"}]}))
208+
[('0', None), (None, '1.6.0')]
218209
219-
def extract_commits(introduced_range) -> Iterable[str]:
210+
>>> list(extract_introduced_and_fixed(
211+
... {"type": "GIT", "events": [{"introduced": "abc123"},
212+
... {"fixed": "def456"}]}))
213+
[('abc123', None), (None, 'def456')]
220214
"""
221-
Return a list of fixed version strings given a ``fixed_range`` mapping of
222-
OSV data.
223-
"""
224-
for event in introduced_range.get("events") or []:
215+
for event in ranges.get("events") or []:
225216
introduced = event.get("introduced")
226217
fixed = event.get("fixed")
227218
yield introduced, fixed
@@ -375,91 +366,81 @@ def get_fixed_version_range(versions, ecosystem):
375366
logger.error(f"Failed to create VersionRange from: {versions}: error:{e!r}")
376367

377368

378-
def get_fixed_versions(fixed_range, raw_id, supported_ecosystem) -> List[Version]:
369+
def get_fixed_versions_and_commits(
370+
ranges, raw_id, supported_ecosystem=None
371+
) -> Tuple[List[Version], Tuple]:
379372
"""
380-
Return a list of unique fixed univers Versions given a ``fixed_range``
381-
univers VersionRange and a ``raw_id``.
373+
Extract and return all unique fixed versions and related commit data
374+
from a given OSV vulnerability range.
375+
382376
For example::
383-
>>> get_fixed_versions(fixed_range={}, raw_id="GHSA-j3f7-7rmc-6wqj", supported_ecosystem="pypi",)
384-
[]
385-
>>> get_fixed_versions(
386-
... fixed_range={"type": "ECOSYSTEM", "events": [{"fixed": "1.7.0"}], },
377+
>>> get_fixed_versions_and_commits(ranges={}, raw_id="GHSA-j3f7-7rmc-6wqj", supported_ecosystem="pypi",)
378+
([], ([], []))
379+
>>> get_fixed_versions_and_commits(
380+
... ranges={"type": "ECOSYSTEM", "events": [{"fixed": "1.7.0"}], },
387381
... raw_id="GHSA-j3f7-7rmc-6wqj",
388382
... supported_ecosystem="pypi",
389383
... )
390-
[PypiVersion(string='1.7.0')]
384+
([PypiVersion(string='1.7.0')], ([], []))
391385
"""
392386
fixed_versions = []
393-
if "type" not in fixed_range:
394-
logger.error(f"Invalid fixed_range type for: {fixed_range} for OSV id: {raw_id!r}")
395-
return []
387+
introduced_commits = []
388+
fixed_commits = []
396389

397-
fixed_range_type = fixed_range["type"]
390+
if "type" not in ranges:
391+
logger.error(f"Invalid range type for: {ranges} for OSV id: {raw_id!r}")
392+
return [], ([], [])
393+
394+
fixed_range_type = ranges["type"]
398395

399396
version_range_class = RANGE_CLASS_BY_SCHEMES.get(supported_ecosystem)
400397
version_class = version_range_class.version_class if version_range_class else None
401398

402-
for version in extract_fixed_versions(fixed_range):
403-
if fixed_range_type == "ECOSYSTEM":
399+
for introduced, fixed in extract_introduced_and_fixed(ranges):
400+
if fixed_range_type == "ECOSYSTEM" and fixed:
404401
try:
405402
if not version_class:
406403
raise InvalidVersion(
407404
f"Unsupported version for ecosystem: {supported_ecosystem}"
408405
)
409-
fixed_versions.append(version_class(version))
406+
fixed_versions.append(version_class(fixed))
410407
except InvalidVersion:
411408
logger.error(
412-
f"Invalid version class: {version_class} - {version!r} for OSV id: {raw_id!r}"
409+
f"Invalid version class: {version_class} - {fixed!r} for OSV id: {raw_id!r}"
413410
)
414411

415-
elif fixed_range_type == "SEMVER":
412+
elif fixed_range_type == "SEMVER" and fixed:
416413
try:
417-
fixed_versions.append(SemverVersion(version))
414+
fixed_versions.append(SemverVersion(fixed))
418415
except InvalidVersion:
419-
logger.error(f"Invalid SemverVersion: {version!r} for OSV id: {raw_id!r}")
420-
421-
if fixed_range_type == "GIT":
422-
# We process this in the get_code_commit function.
423-
continue
424-
else:
425-
logger.error(f"Unsupported fixed version type: {version!r} for OSV id: {raw_id!r}")
416+
logger.error(f"Invalid SemverVersion: {fixed!r} for OSV id: {raw_id!r}")
426417

427-
return dedupe(fixed_versions)
418+
elif fixed_range_type == "GIT" and (fixed or introduced):
419+
repo = ranges.get("repo")
420+
if not repo:
421+
logger.error(f"Missing 'repo' field in ranges: {ranges} (OSV id: {raw_id!r})")
422+
continue
428423

424+
# Git uses this magic hash for the empty tree
425+
if introduced == "0":
426+
introduced = "4b825dc642cb6eb9a060e54bf8d69288fbee4904"
429427

430-
def get_code_commit(ranges, raw_id):
431-
"""
432-
Return two lists of unique code commits (introduced and fixed) extracted from a
433-
given vulnerability `ranges` dictionary.
434-
"""
435-
if ranges.get("type") != "GIT":
436-
logger.debug(f"Skipping non-GIT range for OSV id: {raw_id!r}")
437-
return [], []
438-
439-
repo = ranges.get("repo")
440-
if not repo:
441-
logger.error(f"Missing 'repo' field in range: {ranges} (OSV id: {raw_id!r})")
442-
return [], []
443-
444-
repo = ranges.get("repo")
445-
introduced_commits, fixed_commits = [], []
446-
for introduced, fixed in extract_commits(ranges):
447-
# Git uses this magic hash for the empty tree
448-
if introduced == "0":
449-
introduced = "4b825dc642cb6eb9a060e54bf8d69288fbee4904"
450-
451-
try:
452428
if introduced:
453-
introduced_commit = CodeCommitData(commit_hash=introduced, vcs_url=repo)
454-
introduced_commits.append(introduced_commit)
455-
except ValueError as e:
456-
logger.error(f"Failed to extract introduced commits: {e!r}")
429+
try:
430+
introduced_commit = CodeCommitData(commit_hash=introduced, vcs_url=repo)
431+
introduced_commits.append(introduced_commit)
432+
except ValueError as e:
433+
logger.error(f"Failed to extract introduced commits: {e!r}")
457434

458-
try:
459435
if fixed:
460-
fixed_commit = CodeCommitData(commit_hash=fixed, vcs_url=repo)
461-
fixed_commits.append(fixed_commit)
462-
except ValueError as e:
463-
logger.error(f"Failed to extract fixed commits: {e!r}")
436+
try:
437+
fixed_commit = CodeCommitData(commit_hash=fixed, vcs_url=repo)
438+
fixed_commits.append(fixed_commit)
439+
except ValueError as e:
440+
logger.error(f"Failed to extract fixed commits: {e!r}")
441+
442+
else:
443+
if fixed:
444+
logger.error(f"Unsupported fixed version type: {ranges!r} for OSV id: {raw_id!r}")
464445

465-
return introduced_commits, fixed_commits
446+
return dedupe(fixed_versions), (introduced_commits, fixed_commits)

0 commit comments

Comments
 (0)