From 80a0ff437c24fc8cbac5c5d73590096eb7d816a5 Mon Sep 17 00:00:00 2001 From: Terri Oda Date: Wed, 6 Dec 2023 13:12:32 -0800 Subject: [PATCH] fix: improve version_compare to drop hashes Currently version_compare rasies an error when it gets a hash, since we can't really compare those without more knowledge of the product. This changes the code to silently drop hashes and similar distro markers from the end of versions, which should make our code more robust to real-life cases. We may also want to put in an error handler to log the versions we can't handle without halting the program, but this doesn't do that yet. Signed-off-by: Terri Oda --- cve_bin_tool/version_compare.py | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/cve_bin_tool/version_compare.py b/cve_bin_tool/version_compare.py index 775abd1a72..3c67f79266 100644 --- a/cve_bin_tool/version_compare.py +++ b/cve_bin_tool/version_compare.py @@ -49,7 +49,8 @@ def parse_version(version_string: str): # future, but we'd like to look at those cases before adding them in case the version # logic is very different. - # Attempt a split + # remove any trailing . then split + versionString = versionString.strip(".") split_version = versionString.split(".") # if the whole string was numeric then we're done and you can move on @@ -58,10 +59,10 @@ def parse_version(version_string: str): return versionArray # Go through and split up anything like 6a in to 6 and a - number_letter = re.compile("([0-9]+)([a-zA-Z]+)") - letter_number = re.compile("([a-zA-Z]+)([0-9]+)") + number_letter = re.compile("^([0-9]+)([a-zA-Z]+)$") + letter_number = re.compile("^([a-zA-Z]+)([0-9]+)$") for section in split_version: - # if it's all letters or all nubmers, just add it to the array + # if it's all letters or all numbers, just add it to the array if section.isnumeric() or section.isalpha(): versionArray.append(section) @@ -84,9 +85,19 @@ def parse_version(version_string: str): elif re.match(letter_number, section): versionArray.append(section) - # If all else fails, complain + # It's not a "pure" alpha or number string, it's not something like rc12 or 44g + + # It could be a hash, which we can't string compare without knowledge of the product. + # It could also be a distro release string like deb8u5, which we could compare + # but the data may not be useful or usable in context. else: - if versionString != ".": + # If it's the last part of the version just drop it silently + # we could log these but I suspect it would be very noisy + if section == split_version[len(split_version) - 1]: + pass + + # if it's not, raise an exception because we should probably examine it + elif versionString != ".": raise CannotParseVersionException(f"version string = {versionString}") return versionArray