diff --git a/pontos/cpe/_cpe.py b/pontos/cpe/_cpe.py index f51828f3..eb1ce6cb 100644 --- a/pontos/cpe/_cpe.py +++ b/pontos/cpe/_cpe.py @@ -392,7 +392,24 @@ def from_string(cpe: str) -> "CPE": Create a new CPE from a string """ cleaned_cpe = cpe.strip().lower() - parts = cpe.split(":") + if "\\:" in cleaned_cpe: + # houston we have a problem + # the cpe string contains an escaped colon (:) + parts = [] + index = 0 + start_index = 0 + while index < len(cleaned_cpe): + if ( + index > 0 + and cleaned_cpe[index] == ":" + and cleaned_cpe[index - 1] != "\\" + ): + part = cleaned_cpe[start_index:index] + parts.append(part) + start_index = index + 1 + index += 1 + else: + parts = cpe.split(":") if is_uri_binding(cleaned_cpe): values: dict[str, Optional[str]] = dict( diff --git a/tests/cpe/test_cpe.py b/tests/cpe/test_cpe.py index ce23f28c..157b3d29 100644 --- a/tests/cpe/test_cpe.py +++ b/tests/cpe/test_cpe.py @@ -463,14 +463,34 @@ def test_formatted_unbind_examples(self): self.assertEqual(cpe.target_hw, "80gb") self.assertEqual(cpe.other, ANY) + cpe = CPE.from_string("cpe:2.3:a:foo:bar\:mumble:1.0:*:*:*:*:*:*:*") + self.assertFalse(cpe.is_uri_binding()) + self.assertTrue(cpe.is_formatted_string_binding()) + self.assertEqual(cpe.part, Part.APPLICATION) + self.assertEqual(cpe.vendor, "foo") + self.assertEqual(cpe.product, "bar\:mumble") + self.assertEqual(cpe.version, "1.0") + self.assertEqual(cpe.update, ANY) + self.assertEqual(cpe.edition, ANY) + self.assertEqual(cpe.language, ANY) + self.assertEqual(cpe.sw_edition, ANY) + self.assertEqual(cpe.target_sw, ANY) + self.assertEqual(cpe.target_hw, ANY) + self.assertEqual(cpe.other, ANY) + def test_as_uri_binding(self): - cpe_string = "cpe:2.3:a:microsoft:internet_explorer:8\\.*:sp?" - cpe = CPE.from_string(cpe_string) + cpe = CPE.from_string("cpe:2.3:a:microsoft:internet_explorer:8\\.*:sp?") self.assertEqual( cpe.as_uri_binding(), "cpe:/a:microsoft:internet_explorer:8.%02:sp%01", ) + cpe = CPE.from_string("cpe:2.3:a:cgiirc:cgi\:irc:0.5.7:*:*:*:*:*:*:*") + self.assertEqual( + cpe.as_uri_binding(), + "cpe:/a:cgiirc:cgi%3airc:0.5.7", + ) + def test_as_uri_binding_with_edition(self): cpe_string = "cpe:2.3:a:hp:insight_diagnostics:7.4.0.1570:-:*:*:online:win2003:x64" cpe = CPE.from_string(cpe_string)