Skip to content

Commit

Permalink
Add: Add CPE function for unquoting WNF attribute values
Browse files Browse the repository at this point in the history
Currently the CPE parsing model stores quoted well-formed CPE name (WNF)
attribute values. This is not ideal for using them in the application
logic. For example a version attribute will always return something like
`"1\.2\.3"` as it's value. Therefore add a new function that allows to
convert these values into their unquoted form.
  • Loading branch information
bjoernricks authored and greenbonebot committed Nov 8, 2023
1 parent be2b808 commit f3723d0
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 0 deletions.
30 changes: 30 additions & 0 deletions pontos/cpe/_cpe.py
Original file line number Diff line number Diff line change
Expand Up @@ -328,6 +328,36 @@ def unbind_value_uri(value: Optional[str]) -> Optional[str]:
return result


def unquote_attribute_value(value: Optional[str]) -> Optional[str]:
"""
Unquote a Well-Formed CPE Name Data Model (WFN) attribute value
"""
if not value or "\\" not in value:
# do nothing
return value

index = 0
result = ""
while index < len(value):
c = value[index]
if c == "\\":
next_c = value[index + 1]
if next_c in ["*", "?"]:
# keep escaped asterisks and question marks
result += f"{c}{next_c}"
else:
result += next_c

index += 2
continue
else:
result += c

index += 1

return result


def split_cpe(cpe: str) -> list[str]:
"""
Split a CPE into its parts
Expand Down
21 changes: 21 additions & 0 deletions tests/cpe/test_cpe.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
convert_double_backslash,
split_cpe,
unbind_value_from_formatted_string,
unquote_attribute_value,
)


Expand Down Expand Up @@ -163,6 +164,26 @@ def test_unchanged(self):
self.assertEqual(bind_value_for_formatted_string("foo\\*"), "foo\\*")


class UnquoteAttributeValueTestCase(unittest.TestCase):
def test_unchanged(self):
self.assertIsNone(unquote_attribute_value(None))
self.assertEqual(unquote_attribute_value(""), "")
self.assertEqual(unquote_attribute_value(ANY), ANY)
self.assertEqual(unquote_attribute_value("?"), "?")
self.assertEqual(unquote_attribute_value("foo-bar"), "foo-bar")
self.assertEqual(unquote_attribute_value("foo_bar"), "foo_bar")
self.assertEqual(unquote_attribute_value("1.2.3"), "1.2.3")

def test_special(self):
self.assertEqual(unquote_attribute_value("foo\\?bar"), "foo\\?bar")
self.assertEqual(unquote_attribute_value("foo\\*bar"), "foo\\*bar")

def test_unquote(self):
self.assertEqual(unquote_attribute_value("foo\\\\bar"), "foo\\bar")
self.assertEqual(unquote_attribute_value("foo\\:bar"), "foo:bar")
self.assertEqual(unquote_attribute_value("1\\.2\\.3"), "1.2.3")


class CPETestCase(unittest.TestCase):
def test_uri_binding(self):
cpe_string = "cpe:/o:microsoft:windows_xp:::pro"
Expand Down

0 comments on commit f3723d0

Please sign in to comment.