@@ -402,18 +402,25 @@ class AffectedPackageV2:
402402 """
403403 Relate a Package URL with a range of affected versions and fixed versions.
404404 The Package URL must *not* have a version.
405- AffectedPackage must contain either ``affected_version_range`` or ``fixed_version_range``.
405+ AffectedPackage must contain either ``affected_version_range`` or ``fixed_version_range`` or ``affected_by_commits`` or ``fixed_by_commits`` .
406406 """
407407
408408 package : PackageURL
409409 affected_version_range : Optional [VersionRange ] = None
410410 fixed_version_range : Optional [VersionRange ] = None
411+ fixed_by_commits : List [CodeCommitData ] = dataclasses .field (default_factory = list )
412+ affected_by_commits : List [CodeCommitData ] = dataclasses .field (default_factory = list )
411413
412414 def __post_init__ (self ):
413415 if self .package .version :
414416 raise ValueError (f"Affected Package URL { self .package !r} cannot have a version." )
415417
416- if not (self .affected_version_range or self .fixed_version_range ):
418+ if not (
419+ self .affected_version_range
420+ or self .fixed_version_range
421+ or self .affected_by_commits
422+ or self .fixed_by_commits
423+ ):
417424 raise ValueError (
418425 f"Affected Package { self .package !r} should have either fixed version range or an "
419426 "affected version range."
@@ -430,6 +437,8 @@ def _cmp_key(self):
430437 str (self .package ),
431438 str (self .affected_version_range or "" ),
432439 str (self .fixed_version_range or "" ),
440+ str (self .affected_by_commits or []),
441+ str (self .fixed_by_commits or []),
433442 )
434443
435444 def to_dict (self ):
@@ -443,6 +452,12 @@ def to_dict(self):
443452 "package" : purl_to_dict (self .package ),
444453 "affected_version_range" : affected_version_range ,
445454 "fixed_version_range" : fixed_version_range ,
455+ "affected_by_commits" : [
456+ affected_by_commit .to_dict () for affected_by_commit in self .affected_by_commits
457+ ],
458+ "fixed_by_commits" : [
459+ fixed_by_commit .to_dict () for fixed_by_commit in self .fixed_by_commits
460+ ],
446461 }
447462
448463 @classmethod
@@ -454,6 +469,8 @@ def from_dict(cls, affected_pkg: dict):
454469 fixed_version_range = None
455470 affected_range = affected_pkg ["affected_version_range" ]
456471 fixed_range = affected_pkg ["fixed_version_range" ]
472+ affected_by_commits = affected_pkg .get ("affected_by_commits" ) or []
473+ fixed_by_commits = affected_pkg .get ("fixed_by_commits" ) or []
457474
458475 try :
459476 affected_version_range = VersionRange .from_string (affected_range )
@@ -475,6 +492,13 @@ def from_dict(cls, affected_pkg: dict):
475492 package = package ,
476493 affected_version_range = affected_version_range ,
477494 fixed_version_range = fixed_version_range ,
495+ affected_by_commits = [
496+ CodeCommitData .from_dict (affected_by_commit )
497+ for affected_by_commit in affected_by_commits
498+ ],
499+ fixed_by_commits = [
500+ CodeCommitData .from_dict (fixed_by_commit ) for fixed_by_commit in fixed_by_commits
501+ ],
478502 )
479503
480504
@@ -502,8 +526,6 @@ class AdvisoryData:
502526 date_published : Optional [datetime .datetime ] = None
503527 weaknesses : List [int ] = dataclasses .field (default_factory = list )
504528 severities : List [VulnerabilitySeverity ] = dataclasses .field (default_factory = list )
505- fixed_by_commits : List [CodeCommitData ] = dataclasses .field (default_factory = list )
506- affected_by_commits : List [CodeCommitData ] = dataclasses .field (default_factory = list )
507529 url : Optional [str ] = None
508530 original_advisory_text : Optional [str ] = None
509531
@@ -536,12 +558,6 @@ def to_dict(self):
536558 "severities" : [sev .to_dict () for sev in self .severities ],
537559 "date_published" : self .date_published .isoformat () if self .date_published else None ,
538560 "weaknesses" : self .weaknesses ,
539- "affected_by_commits" : [
540- affected_by_commit .to_dict () for affected_by_commit in self .affected_by_commits
541- ],
542- "fixed_by_commits" : [
543- fixed_by_commit .to_dict () for fixed_by_commit in self .fixed_by_commits
544- ],
545561 "url" : self .url if self .url else "" ,
546562 }
547563 return {
@@ -602,8 +618,6 @@ class AdvisoryDataV2:
602618 date_published : Optional [datetime .datetime ] = None
603619 weaknesses : List [int ] = dataclasses .field (default_factory = list )
604620 url : Optional [str ] = None
605- fixed_by_commits : List [CodeCommitData ] = dataclasses .field (default_factory = list )
606- affected_by_commits : List [CodeCommitData ] = dataclasses .field (default_factory = list )
607621
608622 def __post_init__ (self ):
609623 if self .date_published and not self .date_published .tzinfo :
@@ -627,12 +641,6 @@ def to_dict(self):
627641 "references" : [ref .to_dict () for ref in self .references ],
628642 "date_published" : self .date_published .isoformat () if self .date_published else None ,
629643 "weaknesses" : self .weaknesses ,
630- "affected_by_commits" : [
631- affected_by_commit .to_dict () for affected_by_commit in self .affected_by_commits
632- ],
633- "fixed_by_commits" : [
634- fixed_by_commit .to_dict () for fixed_by_commit in self .fixed_by_commits
635- ],
636644 "url" : self .url if self .url else "" ,
637645 }
638646
@@ -652,14 +660,6 @@ def from_dict(cls, advisory_data):
652660 if date_published
653661 else None ,
654662 "weaknesses" : advisory_data ["weaknesses" ],
655- "affected_by_commits" : [
656- CodeCommitData .from_dict (affected_by_commit )
657- for affected_by_commit in advisory_data ["affected_by_commits" ]
658- ],
659- "fixed_by_commits" : [
660- CodeCommitData .from_dict (fixed_by_commit )
661- for fixed_by_commit in advisory_data ["fixed_by_commits" ]
662- ],
663663 "url" : advisory_data .get ("url" ) or None ,
664664 }
665665 return cls (** transformed )
0 commit comments