@@ -51,6 +51,7 @@ def compute_individual_advisory_todo(self):
5151 .exclude (advisory_todos__issue_type = "MISSING_SUMMARY" )
5252 .exclude (advisory_todos__issue_type = "MISSING_AFFECTED_PACKAGE" )
5353 .exclude (advisory_todos__issue_type = "MISSING_FIXED_BY_PACKAGE" )
54+ .exclude (advisory_todos__issue_type = "MISSING_AFFECTED_AND_FIXED_BY_PACKAGES" )
5455 .prefetch_related (
5556 "impacted_packages" ,
5657 )
@@ -126,8 +127,6 @@ def detect_conflicting_advisories(self):
126127 AdvisoryV2 .objects .exclude (
127128 advisory_todos__issue_type = "MISSING_AFFECTED_AND_FIXED_BY_PACKAGES"
128129 )
129- .exclude (advisory_todos__issue_type = "MISSING_AFFECTED_PACKAGE" )
130- .exclude (advisory_todos__issue_type = "MISSING_FIXED_BY_PACKAGE" )
131130 .todo_excluded ()
132131 .latest_per_avid ()
133132 .distinct ()
@@ -195,7 +194,7 @@ def detect_conflicting_advisories(self):
195194 advisory_map ["fixed" ].update (p .version for p in impact .fixed_by_packages .all ())
196195 advisory_map ["impact_count" ] += 1
197196
198- if not impact .last_successful_range_unfurl_at :
197+ if not impact .last_successful_range_unfurl_at and impact . affecting_vers :
199198 unfurled_base_purls .add (base_purl )
200199 advisories_with_unfurled_purls .add (advisory .avid )
201200
@@ -448,19 +447,21 @@ def check_conflicting_affected_and_fixed_by_packages_for_alias(
448447
449448 conflicting_advisories = list (conflicting_advisories )
450449 conflicting_avids = [avd .avid for avd in conflicting_advisories ]
451- non_conflicting_purl_avid_map = get_best_impact_for_non_conflicting_purls (
450+ best_purl_avid_impact_map = get_advisory_with_best_impact_for_purls (
452451 purl_adv_map ,
453- conflicting_package_details ,
454452 conflicting_avids ,
455453 )
456- partial_merged_advisory = merged_advisory (conflicting_advisories , non_conflicting_purl_avid_map )
454+
455+ partial_merged_advisory = merged_advisory (
456+ conflicting_advisories , best_purl_avid_impact_map , conflicting_package_details
457+ )
457458 conflict_checksum = sha256_digest (canonical_value (conflicting_package_details ))
458459
459460 issue_detail = {
460461 "alias" : alias .alias ,
461462 "conflict_checksum" : conflict_checksum ,
462463 "conflict_details" : conflicting_package_details ,
463- "partial_merged_advisory " : partial_merged_advisory ,
464+ "partial_curation_advisory " : partial_merged_advisory ,
464465 }
465466
466467 todo_id = advisories_checksum (conflicting_advisories )
@@ -494,18 +495,14 @@ def check_conflicting_affected_and_fixed_by_packages_for_alias(
494495 return conflicting_package_count , conflicting_advisories_count
495496
496497
497- def get_best_impact_for_non_conflicting_purls (
498- purl_adv_map , conflicting_package_details , conflicting_avids
499- ):
498+ def get_advisory_with_best_impact_for_purls (purl_adv_map , conflicting_avids ):
500499 """
501- Return PURL - AVID mapping for non-conflicting packages.
500+ Return PURL - AVID mapping for packages.
502501
503502 Select only one advisory per PURL based on maximum impact package count.
504503 """
505504 best_purl_avid_map = {}
506505 for purl , advs in purl_adv_map .items ():
507- if purl in conflicting_package_details :
508- continue
509506
510507 candidates = [
511508 (avid , values ["impact_count" ])
@@ -518,8 +515,8 @@ def get_best_impact_for_non_conflicting_purls(
518515 return best_purl_avid_map
519516
520517
521- def merged_advisory (advisories , non_conflicting_purl_avid_map ):
522- """Merge multiple advisory to one removing any duplicates or conflicting package ranges."""
518+ def merged_advisory (advisories , best_purl_avid_impact_map , conflicting_package_details ):
519+ """Merge multiple advisory to one removing any duplicates or conflicting portion of package ranges."""
523520 merged_adv = {
524521 "aliases" : set (),
525522 "summary" : "" ,
@@ -571,15 +568,31 @@ def merged_advisory(advisories, non_conflicting_purl_avid_map):
571568
572569 for affected in adv_dict .get ("affected_packages" , []):
573570 base_purl = PackageURL (** affected ["package" ]).to_string ()
574- if (
575- base_purl in non_conflicting_purl_avid_map
576- and non_conflicting_purl_avid_map [base_purl ][0 ] == adv .avid
577- ):
578- update_advisory_item (
579- item = affected ,
580- seen_item = seen_affected ,
581- updatable = merged_adv ["affected_packages" ],
582- )
571+
572+ if base_purl in best_purl_avid_impact_map :
573+ # if PURL is present in >1 advisory, then choose from best avid mapping.
574+ # if PURL is not present in best avid mapping, then it means
575+ # PURL is associated with only one advisory and can be merged as is.
576+ if best_purl_avid_impact_map [base_purl ][0 ] != adv .avid :
577+ continue
578+
579+ if base_purl in conflicting_package_details :
580+ conflict = conflicting_package_details [base_purl ]
581+
582+ if conflict ["affected_disagreement" ]:
583+ affected ["affected_version_range" ] = None
584+
585+ if conflict ["fixed_disagreement" ]:
586+ affected ["fixed_version_range" ] = None
587+
588+ if not (affected ["affected_version_range" ] or affected ["fixed_version_range" ]):
589+ continue
590+
591+ update_advisory_item (
592+ item = affected ,
593+ seen_item = seen_affected ,
594+ updatable = merged_adv ["affected_packages" ],
595+ )
583596
584597 for summary , avids in seen_summaries .values ():
585598 merged_summary .append (f"{ tuple (avids )} : { summary } " )
@@ -588,7 +601,7 @@ def merged_advisory(advisories, non_conflicting_purl_avid_map):
588601 merged_adv ["aliases" ] = list (merged_adv ["aliases" ])
589602 merged_adv ["weaknesses" ] = list (merged_adv ["weaknesses" ])
590603
591- merged_adv ["advisory_id" ] = "PLACEHOLDER_AVID "
604+ merged_adv ["advisory_id" ] = "PLACEHOLDER_PARTIAL_CURATION_AVID "
592605 merged_adv ["date_published" ] = ""
593606 merged_adv = AdvisoryDataV2 .from_dict (merged_adv ).to_dict ()
594607
0 commit comments