Skip to content

Commit

Permalink
fix: improve prerelease handling
Browse files Browse the repository at this point in the history
  • Loading branch information
terriko committed Jan 9, 2024
1 parent fc4f062 commit 34de349
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 10 deletions.
33 changes: 23 additions & 10 deletions cve_bin_tool/version_compare.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,8 @@ def parse_version(version_string: str):

# convert all non alpha-numeric characters to be treated like . below
# we could switch to a re split but it seems to leave blanks so this is less hassle
versionString = re.sub("[^0-9a-zA-Z]+", ".", versionString)

# Note: This expression may need improvement if we need to handle unicode
versionString = re.sub("[^0-9a-zA-Z]+", ".", versionString)

# if anything looks like a hash, we'll replace it with the word HASH and
# treat it like a pre-release in comparisons
Expand All @@ -53,7 +52,7 @@ def parse_version(version_string: str):
# otherwise, split up letters and numbers into separate units for compare
versionString = re.sub("([a-zA-Z]+)", r".\1.", versionString)

# Clean up some . and then split
# Clean up any duplicate . and then split
versionString = re.sub(r"\.+", ".", versionString)
split_version = versionString.strip(".").split(".")

Expand All @@ -66,8 +65,7 @@ def version_compare(v1: str, v2: str):
returns 0 if they're the same.
returns 1 if v1 > v2
returns -1 if v1 < v2findall
n
returns -1 if v1 < v2
"""
v1_array = parse_version(v1)
v2_array = parse_version(v2)
Expand All @@ -92,6 +90,19 @@ def version_compare(v1: str, v2: str):
# Converting to lower() so that 3.14a == 3.14A
# but this may not be ideal in all cases
elif v1_array[i].isalpha() and v2_array[i].isalpha():
# allow pre-releases to come before arbitrary letters.
if (
v1_array[i] in pre_release_words
and v2_array[i] not in pre_release_words
):
return -1
if (
v1_array[i] not in pre_release_words
and v2_array[i] in pre_release_words
):
return 1

# Note that if both are in the pre-release list we alpha compare
if v1_array[i].lower() > v2_array[i].lower():
return 1
if v1_array[i].lower() < v2_array[i].lower():
Expand Down Expand Up @@ -174,23 +185,25 @@ def __ge__(self, other):
def __eq__(self, other):
"""=="""
# Require exact match of hashes for equality
if self.is_hash() or other.is_hash():
if self.has_hash() or other.has_hash():
return str(self) == str(other)
return bool(version_compare(self, other) == 0)

def __ne__(self, other):
"""!="""
# Require exact match of hashes for equality
if self.is_hash() or other.is_hash():
# Require exact match of hashes for inequality
if self.has_hash() or other.has_hash():
return str(self) != str(other)
return bool(version_compare(self, other) != 0)

def __repr__(self):
"""print the version string"""
return f"Version: {self} aka {parse_version(self)}"

def is_hash(self):
"""Check to see if a version looks like it contains a hash"""
def has_hash(self):
"""Check to see if a version looks like it contains a hash
to avoid nonsense comparisons. This likely needs improvement."""

if re.match("[a-fA-F0-9]{8,}", self) is None:
return False
return True
4 changes: 4 additions & 0 deletions test/test_version_compare.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ def test_lt(self):
assert Version("1.1.0l.1~deb9u2") < Version("1.1.0m")
assert Version("8.9~deb7u9") < Version("8.9~deb9u6")
assert Version("8.9~deb7u9") < Version("8.9~deb9u6")
assert Version("3.9.pre1") < Version("3.9.u")
assert Version("3.9.rc1") < Version("3.9.g")

def test_gt(self):
"""Make sure > works between versions, including some with unusual version schemes"""
Expand All @@ -57,6 +59,8 @@ def test_gt(self):
)
assert Version("1.1.0m") > Version("1.1.0l.1~deb9u2")
assert Version("8.9~deb9u6") > Version("8.9~deb7u9")
assert Version("3.9.u") > Version("3.9.pre1")
assert Version("3.9.g") > Version("3.9.rc1")

def test_error(self):
"""Make sure 'unknown' and blank strings raise appropriate errors"""
Expand Down

0 comments on commit 34de349

Please sign in to comment.