diff --git a/cpe_version.py b/cpe_version.py index 978fc0e..ac14d69 100644 --- a/cpe_version.py +++ b/cpe_version.py @@ -1,6 +1,7 @@ +import re import string -from requests.models import iter_slices +VERSION_PART_SEP_RE = re.compile(r'[^\da-zA-Z]') class CPEVersion: @@ -8,40 +9,8 @@ def __init__(self, ver_str): self.version_str = ver_str def get_version_parts(self): - parts = [] - cur_part = '' - cur_char_class = string.digits - is_leading_zeroes = False - for char in self.version_str: - if char not in cur_char_class: - if cur_part: - parts.append(cur_part) - elif cur_char_class == string.digits and is_leading_zeroes: - parts.append("0") - - cur_part = '' - is_leading_zeroes = False - if char in string.digits: - cur_char_class = string.digits - if char == '0': - is_leading_zeroes = True - elif char in string.ascii_letters: - cur_char_class = string.ascii_letters - else: - cur_char_class = string.punctuation - - if char not in string.punctuation: - if is_leading_zeroes and char == '0': - continue - is_leading_zeroes = False - cur_part += char - - if cur_part: - parts.append(cur_part) - elif cur_char_class == string.digits and is_leading_zeroes: - parts.append("0") - - return parts + re_version_parts = VERSION_PART_SEP_RE.split(self.version_str) + return [part.lstrip('0') for part in re_version_parts] # strip leading '0' from every part def __eq__(self, other): parts, other_parts = self.get_version_parts(), other.get_version_parts() @@ -75,64 +44,38 @@ def __lt__(self, other): min_part_count = min(len(parts), len(other_parts)) for part_idx in range(min_part_count): part, other_part = parts[part_idx], other_parts[part_idx] - if part_idx < len(parts)-1 and part_idx < len(other_parts)-1: - if part.lower() == other_part.lower(): - continue - val_part, val_part_other = 0, 0 + # right-pad with '0' to make both parts the same length + if len(part) < len(other_part): + part = part.rjust(len(other_part), '0') + if len(other_part) < len(part): + other_part = other_part.rjust(len(part), '0') - # Variant 1: full "value" of version part matters - # for i, char in enumerate(part): - # if char in string.digits: - # val_part += int(char) * 10**(len(part)-i) - # else: - # val_part += (string.ascii_lowercase.find(char.lower())+1) * 36**(len(part)-i) + # if both parts are empty / were zeroes + if (not part) and (not other_part): + # continue if not in last step and return False otherwise + if part_idx < len(parts)-1 and part_idx < len(other_parts)-1: + continue + return False - # for i, char in enumerate(other_part): - # if char in string.digits: - # val_part_other += int(char) * 10**(len(other_part)-i) - # else: - # val_part_other += (string.ascii_lowercase.find(char.lower())+1) * 36**(len(other_part)-i) + # if the comparison is not in the last step and the current parts are equal + if part_idx < len(parts)-1 and part_idx < len(other_parts)-1: + if part.lower() == other_part.lower(): + continue - # if val_part >= val_part_other: - # return False - # return True # if version part in front is smaller, the entire version is already smaller + # compare parts char by char + for i in range(len(part)): + if ord(part[i].lower()) < ord(other_part[i].lower()): + return True + if ord(part[i].lower()) > ord(other_part[i].lower()): + return False - # Variant 2: with version numbers made up of letters, the letters are compared step by step - if part[0].lower() in string.ascii_lowercase and other_part[0] in string.digits: - return False - elif part[0].lower() in string.digits and other_part[0] in string.ascii_lowercase: - return True - elif part[0] in string.ascii_letters: - iter_max = min(len(part), len(other_part)) - for i in range(iter_max): - if ord(part[i].lower()) > ord(other_part[i].lower()): - return False - if (i == iter_max - 1 and len(parts) == len(other_parts) and - len(part) == len(other_part) and - ord(part[i].lower()) == ord(other_part[i].lower())): - return False - else: - for i, char in enumerate(part): - val_part += int(char) * 10**(len(part)-i-1) - - for i, char in enumerate(other_part): - val_part_other += int(char) * 10**(len(other_part)-i-1) - - if val_part > val_part_other: + # very last part of the comparison and both parts are equal + if (i == len(part) - 1 and part_idx == min_part_count - 1 and + len(parts) == len(other_parts) and + len(part) == len(other_part) and + ord(part[i].lower()) == ord(other_part[i].lower())): return False - if val_part == val_part_other: - # check for equality and return False in that case - if len(parts) > len(other_parts) and all(x == "0" for x in parts[part_idx+1:]): - return False - if len(other_parts) > len(parts) and all(x == "0" for x in other_parts[part_idx+1:]): - return False - - # check for greater number of version parts on last iteration and return False in that case - if part_idx > min_part_count-2 and len(parts) >= len(other_parts): - return False - - return True # if version part in front is smaller, the entire version is already smaller if len(parts) > len(other_parts): return False