Skip to content

Commit 909fa08

Browse files
committed
Do not update related field of an immutable AdvisoryV2
Resolves: #2187 Signed-off-by: Keshav Priyadarshi <git@keshav.space>
1 parent 06d26a8 commit 909fa08

File tree

5 files changed

+80
-60
lines changed

5 files changed

+80
-60
lines changed

vulnerabilities/pipes/advisory.py

Lines changed: 60 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -291,21 +291,16 @@ def insert_advisory(advisory: AdvisoryData, pipeline_id: str, logger: Callable =
291291
def insert_advisory_v2(
292292
advisory: AdvisoryDataV2,
293293
pipeline_id: str,
294-
logger: Callable = None,
294+
logger: Callable,
295295
precedence: int = 0,
296296
):
297297
from vulnerabilities.models import ImpactedPackage
298298
from vulnerabilities.models import PackageV2
299299
from vulnerabilities.utils import compute_content_id_v2
300300

301301
advisory_obj = None
302-
aliases = get_or_create_advisory_aliases(aliases=advisory.aliases)
303-
references = get_or_create_advisory_references(references=advisory.references)
304-
severities = get_or_create_advisory_severities(severities=advisory.severities)
305-
patches = get_or_create_advisory_patches(patches=advisory.patches)
306-
weaknesses = get_or_create_advisory_weaknesses(weaknesses=advisory.weaknesses)
307-
content_id = compute_content_id_v2(advisory_data=advisory)
308302
created = False
303+
content_id = compute_content_id_v2(advisory_data=advisory)
309304
try:
310305
default_data = {
311306
"datasource_id": pipeline_id,
@@ -324,65 +319,73 @@ def insert_advisory_v2(
324319
unique_content_id=content_id,
325320
defaults=default_data,
326321
)
327-
related_fields = {
328-
"aliases": aliases,
329-
"references": references,
330-
"severities": severities,
331-
"weaknesses": weaknesses,
332-
"patches": patches,
333-
}
334-
335-
for field_name, values in related_fields.items():
336-
if values:
337-
getattr(advisory_obj, field_name).add(*values)
338-
339-
except Advisory.MultipleObjectsReturned:
322+
except AdvisoryV2.MultipleObjectsReturned:
340323
logger(
341324
f"Multiple Advisories returned: unique_content_id: {content_id}, url: {advisory.url}, advisory: {advisory!r}"
342325
)
343326
raise
344327
except Exception as e:
345-
if logger:
346-
logger(
347-
f"Error while processing {advisory!r} with aliases {advisory.aliases!r}: {e!r} \n {traceback_format_exc()}",
348-
level=logging.ERROR,
349-
)
328+
logger(
329+
f"Error while processing {advisory!r} with aliases {advisory.aliases!r}: {e!r} \n {traceback_format_exc()}",
330+
level=logging.ERROR,
331+
)
332+
raise
350333

351-
if created:
352-
for affected_pkg in advisory.affected_packages:
353-
impact = ImpactedPackage.objects.create(
354-
advisory=advisory_obj,
355-
base_purl=str(affected_pkg.package),
356-
affecting_vers=str(affected_pkg.affected_version_range)
357-
if affected_pkg.affected_version_range
358-
else None,
359-
fixed_vers=str(affected_pkg.fixed_version_range)
360-
if affected_pkg.fixed_version_range
361-
else None,
362-
)
363-
package_affected_purls, package_fixed_purls = get_exact_purls_v2(
364-
affected_package=affected_pkg,
365-
logger=logger,
366-
)
334+
if not created:
335+
return advisory_obj
367336

368-
affected_packages_v2 = PackageV2.objects.bulk_get_or_create_from_purls(
369-
purls=package_affected_purls
370-
)
371-
fixed_packages_v2 = PackageV2.objects.bulk_get_or_create_from_purls(
372-
purls=package_fixed_purls
373-
)
337+
aliases = get_or_create_advisory_aliases(aliases=advisory.aliases)
338+
references = get_or_create_advisory_references(references=advisory.references)
339+
severities = get_or_create_advisory_severities(severities=advisory.severities)
340+
patches = get_or_create_advisory_patches(patches=advisory.patches)
341+
weaknesses = get_or_create_advisory_weaknesses(weaknesses=advisory.weaknesses)
374342

375-
impact.affecting_packages.add(*affected_packages_v2)
376-
impact.fixed_by_packages.add(*fixed_packages_v2)
343+
related_fields = {
344+
"aliases": aliases,
345+
"references": references,
346+
"severities": severities,
347+
"weaknesses": weaknesses,
348+
"patches": patches,
349+
}
350+
351+
for field_name, values in related_fields.items():
352+
if values:
353+
getattr(advisory_obj, field_name).add(*values)
354+
355+
for affected_pkg in advisory.affected_packages:
356+
impact = ImpactedPackage.objects.create(
357+
advisory=advisory_obj,
358+
base_purl=str(affected_pkg.package),
359+
affecting_vers=str(affected_pkg.affected_version_range)
360+
if affected_pkg.affected_version_range
361+
else None,
362+
fixed_vers=str(affected_pkg.fixed_version_range)
363+
if affected_pkg.fixed_version_range
364+
else None,
365+
)
366+
package_affected_purls, package_fixed_purls = get_exact_purls_v2(
367+
affected_package=affected_pkg,
368+
logger=logger,
369+
)
377370

378-
introduced_commit_v2 = get_or_create_advisory_package_commit_patches(
379-
affected_pkg.introduced_by_commit_patches
380-
)
381-
fixed_commit_v2 = get_or_create_advisory_package_commit_patches(
382-
affected_pkg.fixed_by_commit_patches
383-
)
384-
impact.introduced_by_package_commit_patches.add(*introduced_commit_v2)
385-
impact.fixed_by_package_commit_patches.add(*fixed_commit_v2)
371+
affected_packages_v2 = PackageV2.objects.bulk_get_or_create_from_purls(
372+
purls=package_affected_purls
373+
)
374+
fixed_packages_v2 = PackageV2.objects.bulk_get_or_create_from_purls(
375+
purls=package_fixed_purls
376+
)
377+
378+
impact.affecting_packages.add(*affected_packages_v2)
379+
impact.fixed_by_packages.add(*fixed_packages_v2)
380+
381+
introduced_commit_v2 = get_or_create_advisory_package_commit_patches(
382+
affected_pkg.introduced_by_commit_patches
383+
)
384+
fixed_commit_v2 = get_or_create_advisory_package_commit_patches(
385+
affected_pkg.fixed_by_commit_patches
386+
)
387+
impact.introduced_by_package_commit_patches.add(*introduced_commit_v2)
388+
impact.fixed_by_package_commit_patches.add(*fixed_commit_v2)
386389
return advisory_obj
387390

388391

vulnerabilities/tests/pipelines/exporters/test_federate_vulnerabilities.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,10 +86,12 @@ def setUp(self):
8686
insert_advisory_v2(
8787
advisory=advisory1,
8888
pipeline_id="test_pipeline_v2",
89+
logger=self.logger.write,
8990
)
9091
insert_advisory_v2(
9192
advisory=advisory2,
9293
pipeline_id="test_pipeline_v2",
94+
logger=self.logger.write,
9395
)
9496

9597
@patch(

vulnerabilities/tests/pipelines/v2_improvers/test_unfurl_version_range.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,12 @@
2222
from vulnerabilities.models import PackageV2
2323
from vulnerabilities.pipelines.v2_improvers.unfurl_version_range import UnfurlVersionRangePipeline
2424
from vulnerabilities.pipes.advisory import insert_advisory_v2
25+
from vulnerabilities.tests.pipelines import TestLogger
2526

2627

2728
class TestUnfurlVersionRangePipeline(TestCase):
2829
def setUp(self):
30+
self.logger = TestLogger()
2931
advisory1 = AdvisoryDataV2(
3032
summary="Test advisory",
3133
aliases=["CVE-2025-0001"],
@@ -49,6 +51,7 @@ def setUp(self):
4951
insert_advisory_v2(
5052
advisory=advisory1,
5153
pipeline_id="test_pipeline_v2",
54+
logger=self.logger.write,
5255
)
5356

5457
@patch("vulnerabilities.pipelines.v2_improvers.unfurl_version_range.get_purl_versions")

vulnerabilities/tests/test_models.py

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
from vulnerabilities.severity_systems import CVSSV3
4040
from vulnerabilities.severity_systems import CVSSV4
4141
from vulnerabilities.severity_systems import ScoringSystem
42+
from vulnerabilities.tests.pipelines import TestLogger
4243
from vulnerabilities.utils import compute_content_id
4344

4445

@@ -747,6 +748,7 @@ def test_constraint_none(self):
747748

748749
class TestAdvisoryV2Model(DjangoTestCase):
749750
def setUp(self):
751+
self.logger = TestLogger()
750752
self.advisoryv2_data1 = AdvisoryDataV2(
751753
advisory_id="test_adv",
752754
aliases=[],
@@ -770,14 +772,17 @@ def setUp(self):
770772
def test_advisoryv2_to_advisory_data_patch_seralization(self):
771773
from vulnerabilities.pipes.advisory import insert_advisory_v2
772774

773-
insert_advisory_v2(advisory=self.advisoryv2_data1, pipeline_id="test_pipeline")
775+
insert_advisory_v2(
776+
advisory=self.advisoryv2_data1, pipeline_id="test_pipeline", logger=self.logger.write
777+
)
774778
result = models.AdvisoryV2.objects.first().to_advisory_data()
775779

776780
self.assertEqual(result, self.advisoryv2_data1)
777781

778782

779783
class TestAdvisoryV2ModelDuplication(DjangoTestCase):
780784
def setUp(self):
785+
self.logger = TestLogger()
781786
self.advisoryv2_data1 = AdvisoryDataV2(
782787
advisory_id="CVE-2023-0401",
783788
aliases=[],
@@ -813,8 +818,12 @@ def setUp(self):
813818
def test_advisoryv2_duplication_data(self):
814819
from vulnerabilities.pipes.advisory import insert_advisory_v2
815820

816-
insert_advisory_v2(advisory=self.advisoryv2_data1, pipeline_id="test_pipeline")
817-
insert_advisory_v2(advisory=self.advisoryv2_data2, pipeline_id="test_pipeline")
821+
insert_advisory_v2(
822+
advisory=self.advisoryv2_data1, pipeline_id="test_pipeline", logger=self.logger.write
823+
)
824+
insert_advisory_v2(
825+
advisory=self.advisoryv2_data2, pipeline_id="test_pipeline", logger=self.logger.write
826+
)
818827
result = models.AdvisoryV2.objects.count()
819828

820829
self.assertEqual(result, 2)

vulnerabilities/tests/test_utils.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
from vulnerabilities.pipelines import insert_advisory_v2
2929
from vulnerabilities.references import XsaReferenceV2
3030
from vulnerabilities.references import ZbxReferenceV2
31+
from vulnerabilities.tests.pipelines import TestLogger
3132
from vulnerabilities.utils import AffectedPackage
3233
from vulnerabilities.utils import get_item
3334
from vulnerabilities.utils import get_severity_range
@@ -170,6 +171,7 @@ def test_get_severity_range():
170171

171172
class TestComputeContentIdV2(TestCase):
172173
def setUp(self):
174+
self.logger = TestLogger()
173175
self.advisory1 = AdvisoryDataV2(
174176
summary="Test advisory",
175177
aliases=["CVE-2025-0001", "CVE-2024-0001"],
@@ -239,6 +241,7 @@ def setUp(self):
239241
insert_advisory_v2(
240242
advisory=self.advisory1,
241243
pipeline_id="test_pipeline_v2",
244+
logger=self.logger.write,
242245
)
243246

244247
def test_compute_content_id_v2(self):

0 commit comments

Comments
 (0)