Skip to content

Commit b505021

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 c1d1f21 commit b505021

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
@@ -84,8 +85,8 @@ def parse_advisory_data(
8485
)
8586

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

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

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

@@ -195,32 +195,23 @@ def parse_advisory_data_v2(
195195
)
196196

197197

198-
def extract_fixed_versions(fixed_range) -> Iterable[str]:
198+
def extract_introduced_and_fixed(ranges) -> Tuple[List[str], List[str]]:
199199
"""
200-
Return a list of fixed version strings given a ``fixed_range`` mapping of
201-
OSV data.
200+
Return pairs of introduced and fixed versions or commit hashes given a ``ranges``
201+
mapping of OSV data.
202202
203-
>>> list(extract_fixed_versions(
204-
... {"type": "SEMVER", "events": [{"introduced": "0"},{"fixed": "1.6.0"}]}))
205-
['1.6.0']
206-
207-
>>> list(extract_fixed_versions(
208-
... {"type": "ECOSYSTEM","events":[{"introduced": "0"},
209-
... {"fixed": "1.0.0"},{"fixed": "9.0.0"}]}))
210-
['1.0.0', '9.0.0']
211-
"""
212-
for event in fixed_range.get("events") or []:
213-
fixed = event.get("fixed")
214-
if fixed:
215-
yield fixed
203+
Both introduced and fixed fields may represent semantic versions or commit hashes.
216204
205+
>>> list(extract_introduced_and_fixed(
206+
... {"type": "SEMVER", "events": [{"introduced": "0"}, {"fixed": "1.6.0"}]}))
207+
[('0', None), (None, '1.6.0')]
217208
218-
def extract_commits(introduced_range) -> Iterable[str]:
209+
>>> list(extract_introduced_and_fixed(
210+
... {"type": "GIT", "events": [{"introduced": "abc123"},
211+
... {"fixed": "def456"}]}))
212+
[('abc123', None), (None, 'def456')]
219213
"""
220-
Return a list of fixed version strings given a ``fixed_range`` mapping of
221-
OSV data.
222-
"""
223-
for event in introduced_range.get("events") or []:
214+
for event in ranges.get("events") or []:
224215
introduced = event.get("introduced")
225216
fixed = event.get("fixed")
226217
yield introduced, fixed
@@ -369,91 +360,81 @@ def get_fixed_version_range(versions, ecosystem):
369360
logger.error(f"Failed to create VersionRange from: {versions}: error:{e!r}")
370361

371362

372-
def get_fixed_versions(fixed_range, raw_id, supported_ecosystem) -> List[Version]:
363+
def get_fixed_versions_and_commits(
364+
ranges, raw_id, supported_ecosystem=None
365+
) -> Tuple[List[Version], Tuple]:
373366
"""
374-
Return a list of unique fixed univers Versions given a ``fixed_range``
375-
univers VersionRange and a ``raw_id``.
367+
Extract and return all unique fixed versions and related commit data
368+
from a given OSV vulnerability range.
369+
376370
For example::
377-
>>> get_fixed_versions(fixed_range={}, raw_id="GHSA-j3f7-7rmc-6wqj", supported_ecosystem="pypi",)
378-
[]
379-
>>> get_fixed_versions(
380-
... fixed_range={"type": "ECOSYSTEM", "events": [{"fixed": "1.7.0"}], },
371+
>>> get_fixed_versions_and_commits(ranges={}, raw_id="GHSA-j3f7-7rmc-6wqj", supported_ecosystem="pypi",)
372+
([], ([], []))
373+
>>> get_fixed_versions_and_commits(
374+
... ranges={"type": "ECOSYSTEM", "events": [{"fixed": "1.7.0"}], },
381375
... raw_id="GHSA-j3f7-7rmc-6wqj",
382376
... supported_ecosystem="pypi",
383377
... )
384-
[PypiVersion(string='1.7.0')]
378+
([PypiVersion(string='1.7.0')], ([], []))
385379
"""
386380
fixed_versions = []
387-
if "type" not in fixed_range:
388-
logger.error(f"Invalid fixed_range type for: {fixed_range} for OSV id: {raw_id!r}")
389-
return []
381+
introduced_commits = []
382+
fixed_commits = []
390383

391-
fixed_range_type = fixed_range["type"]
384+
if "type" not in ranges:
385+
logger.error(f"Invalid range type for: {ranges} for OSV id: {raw_id!r}")
386+
return [], ([], [])
387+
388+
fixed_range_type = ranges["type"]
392389

393390
version_range_class = RANGE_CLASS_BY_SCHEMES.get(supported_ecosystem)
394391
version_class = version_range_class.version_class if version_range_class else None
395392

396-
for version in extract_fixed_versions(fixed_range):
397-
if fixed_range_type == "ECOSYSTEM":
393+
for introduced, fixed in extract_introduced_and_fixed(ranges):
394+
if fixed_range_type == "ECOSYSTEM" and fixed:
398395
try:
399396
if not version_class:
400397
raise InvalidVersion(
401398
f"Unsupported version for ecosystem: {supported_ecosystem}"
402399
)
403-
fixed_versions.append(version_class(version))
400+
fixed_versions.append(version_class(fixed))
404401
except InvalidVersion:
405402
logger.error(
406-
f"Invalid version class: {version_class} - {version!r} for OSV id: {raw_id!r}"
403+
f"Invalid version class: {version_class} - {fixed!r} for OSV id: {raw_id!r}"
407404
)
408405

409-
elif fixed_range_type == "SEMVER":
406+
elif fixed_range_type == "SEMVER" and fixed:
410407
try:
411-
fixed_versions.append(SemverVersion(version))
408+
fixed_versions.append(SemverVersion(fixed))
412409
except InvalidVersion:
413-
logger.error(f"Invalid SemverVersion: {version!r} for OSV id: {raw_id!r}")
414-
415-
if fixed_range_type == "GIT":
416-
# We process this in the get_code_commit function.
417-
continue
418-
else:
419-
logger.error(f"Unsupported fixed version type: {version!r} for OSV id: {raw_id!r}")
410+
logger.error(f"Invalid SemverVersion: {fixed!r} for OSV id: {raw_id!r}")
420411

421-
return dedupe(fixed_versions)
412+
elif fixed_range_type == "GIT" and (fixed or introduced):
413+
repo = ranges.get("repo")
414+
if not repo:
415+
logger.error(f"Missing 'repo' field in ranges: {ranges} (OSV id: {raw_id!r})")
416+
continue
422417

418+
# Git uses this magic hash for the empty tree
419+
if introduced == "0":
420+
introduced = "4b825dc642cb6eb9a060e54bf8d69288fbee4904"
423421

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

452-
try:
453429
if fixed:
454-
fixed_commit = CodeCommitData(commit_hash=fixed, vcs_url=repo)
455-
fixed_commits.append(fixed_commit)
456-
except ValueError as e:
457-
logger.error(f"Failed to extract fixed commits: {e!r}")
430+
try:
431+
fixed_commit = CodeCommitData(commit_hash=fixed, vcs_url=repo)
432+
fixed_commits.append(fixed_commit)
433+
except ValueError as e:
434+
logger.error(f"Failed to extract fixed commits: {e!r}")
435+
436+
else:
437+
if fixed:
438+
logger.error(f"Unsupported fixed version type: {ranges!r} for OSV id: {raw_id!r}")
458439

459-
return introduced_commits, fixed_commits
440+
return dedupe(fixed_versions), (introduced_commits, fixed_commits)

0 commit comments

Comments
 (0)