Skip to content

Commit

Permalink
Add: Allow parsing CPEs with parts containing a colon
Browse files Browse the repository at this point in the history
In the real world CPEs contain escaped colons in the vendor or product
parts exist. Therefore allow to parse these CPE strings. Currently
parsing a CPE string like `cpe:2.3:a:foo\\:bar:...` wouldn't work. But
as far as I can see this is neither a valid CPE nor a real world
scenario.
  • Loading branch information
bjoernricks committed Nov 3, 2023
1 parent 174c5fa commit d25fe2f
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 3 deletions.
19 changes: 18 additions & 1 deletion pontos/cpe/_cpe.py
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
24 changes: 22 additions & 2 deletions tests/cpe/test_cpe.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down

0 comments on commit d25fe2f

Please sign in to comment.