From c2abe517716544c5f69efc99f65da9d191aa3e29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Ricks?= Date: Fri, 3 Nov 2023 10:39:38 +0100 Subject: [PATCH] Add: Allow to clone and adjust a CPE Add a new CPE method to clone a CPE object and allow to adjust the parts of the CPE while cloning. This will become necessary when transforming a CPE for example having a CPE with a specific version put we want to address all versions of this product. --- pontos/cpe/_cpe.py | 34 ++++++++++++++++++++++++++++++++++ tests/cpe/test_cpe.py | 16 ++++++++++++++++ 2 files changed, 50 insertions(+) diff --git a/pontos/cpe/_cpe.py b/pontos/cpe/_cpe.py index f870d2d6..308e8d96 100644 --- a/pontos/cpe/_cpe.py +++ b/pontos/cpe/_cpe.py @@ -562,6 +562,40 @@ def as_formatted_string_binding(self) -> str: f"{edition}:{language}:{sw_edition}:{target_sw}:{target_hw}:{other}" ) + def clone( + self, + **kwargs, + ) -> "CPE": + """ + Clone a CPE and allow to override parts + + Example: + .. code-block:: python + + from pontos.cpe import CPE, ANY + + android_13 = CPE.from_string( + "cpe:2.3:o:google:android:13.0:*:*:*:*:*:*:*" + ) + all_android_versions = cpe.clone(version=ANY) + """ + args = { + "part": self.part, + "vendor": self.vendor, + "product": self.product, + "version": self.version, + "update": self.update, + "edition": self.edition, + "language": self.language, + "sw_edition": self.sw_edition, + "target_sw": self.target_sw, + "target_hw": self.target_hw, + "other": self.other, + "cpe_string": self.cpe_string, + } + args.update(**kwargs) + return CPE(**args) # type: ignore[arg-type] + def __str__(self) -> str: """ Returns the string representation (uri of formatted string) of the CPE diff --git a/tests/cpe/test_cpe.py b/tests/cpe/test_cpe.py index d2fca5e2..c60ad090 100644 --- a/tests/cpe/test_cpe.py +++ b/tests/cpe/test_cpe.py @@ -591,3 +591,19 @@ def test_has_extended_attribute(self): target_sw="ipsum", ) self.assertTrue(cpe.has_extended_attribute()) + + def test_clone(self): + cpe = CPE.from_string( + "cpe:2.3:a:hp:openview_network_manager:7.51:*:*:*:*:linux:*:*" + ) + + cpe2 = cpe.clone() + self.assertIsNot(cpe, cpe2) + + cpe = CPE.from_string( + "cpe:2.3:a:hp:openview_network_manager:7.51:*:*:*:*:linux:*:*" + ) + cpe2 = cpe.clone(version=ANY) + self.assertIsNot(cpe, cpe2) + self.assertEqual(cpe.version, "7\\.51") + self.assertEqual(cpe2.version, ANY)