def _get_version_rules(self, vuln_versions):
        """Version rules for all eco."""
        rules = []
        regex_op = "[0-9a-zA-Z\\_\\.\\-]+"
        regex_vr = "[<>=*]+"
        """For all the vulnerable versions information that we get, we need to create
        comparable version object so that we can apply these rules on top of all the available
        versions of a pkg in the market."""
        for version in vuln_versions:
            version = version.replace(" ", "")
            sub_vers = version.split('||')
            for sub_ver in sub_vers:
                tmp = []
                vr_relations = re.split(regex_vr, sub_ver)
                op_relations = re.split(regex_op, sub_ver)
                # Single affected version.
                if len(vr_relations) == 1:
                    tmp.append({
                        'key': "=",
                        'val': ComparableVersion(vr_relations[0])
                    })
                # All versions affected.
                elif len(op_relations) == 1 and op_relations[0] == '*':
                    tmp.append({'key': "*", 'val': ""})
                else:
                    for i in range(len(op_relations) - 1):
                        tmp.append({
                            'key':
                            op_relations[i],
                            'val':
                            ComparableVersion(vr_relations[i + 1])
                        })
                rules.append(tmp)

        return rules
def test_ge_operator():
    """Test the >= operator."""
    c1 = ComparableVersion('2.0.0')
    c2 = ComparableVersion('1.0.0')
    assert c1 >= c2

    # ComparableVersion >= None
    assert c1 >= None
    assert c2 >= None

    c3 = ComparableVersion('1.0.0')
    assert c3 >= c2
def test_le_operator():
    """Test the <= operator."""
    c1 = ComparableVersion('1.0.0')
    c2 = ComparableVersion('2.0.0')
    assert c1 <= c2

    # ComparableVersion <= None
    assert not c1 <= None
    assert not c2 <= None

    c3 = ComparableVersion('2.0.0')
    assert c2 <= c3
def test_init():
    """Test ComparableVersion objects `__init__` method."""
    # should work
    version = '1.0.0'
    v = ComparableVersion(version)
    # actually should not happen for proper constructor
    assert v is not None

    # both should raise
    with pytest.raises(TypeError):
        _ = ComparableVersion(None)
        assert _ is not None
        _ = ComparableVersion(1.0)
        assert _ is not None
Beispiel #5
0
def test_is_relation_applicable():
    """Test is_relation_applicable."""
    # Test lt operator
    res = scs._is_relation_applicable('<', '1.2', ComparableVersion('1.4'))
    assert res is True
    res = scs._is_relation_applicable('<', '1.4', ComparableVersion('1.4'))
    assert res is False

    # Test gt operator
    res = scs._is_relation_applicable('>', '1.4', ComparableVersion('1.4'))
    assert res is False
    res = scs._is_relation_applicable('>', '1.5', ComparableVersion('1.4'))
    assert res is True

    # Test gte operator
    res = scs._is_relation_applicable('>=', '1.4', ComparableVersion('1.4'))
    assert res is True
    # Test lte operator
    res = scs._is_relation_applicable('<=', '1.4', ComparableVersion('1.4'))
    assert res is True

    # Test eq operator
    res = scs._is_relation_applicable('=', '1.4', ComparableVersion('1.4'))
    assert res is True
    # Test universal operator
    res = scs._is_relation_applicable('*', '1.9', ComparableVersion(''))
    assert res is True
 def _is_relation_applicable(self, key, version, rule):
     """Check if the version satisfies the relation."""
     if key == '<':
         return ComparableVersion(version) < rule
     elif key == '>':
         return ComparableVersion(version) > rule
     elif key == '=':
         return ComparableVersion(version) == rule
     elif key == '<=':
         return ComparableVersion(version) <= rule
     elif key == '>=':
         return ComparableVersion(version) >= rule
     elif key == '*':
         return True
     return False
def select_latest_version(versions=[]):
    """Select latest version from list."""
    version_arr = []
    for x in versions:
        version_arr.append(ComparableVersion(x))
    version_arr.sort()
    return version_arr[-1]
def test_repr():
    """Test ComparableVersion objects `__repr__` method."""
    version = '1.0.0'
    expected_repr = "ComparableVersion(version={!r})".format(version)

    assert repr(
        ComparableVersion(version)) == expected_repr, "Invalid representation."
Beispiel #9
0
def classify_versions(upstream_versions, version_ranges):
    """Classify versions as affected and unaffected.

    :param upstream_versions: list[str], list of upstream versions
    :param version_ranges: list[[VersionRange]], list of CVE version ranges

    :return: list[ClassifiedVersion] sorted list of classified upstream versions
    """
    sorted_upstream_versions = [
        ComparableVersion(x) for x in upstream_versions
    ]
    sorted_upstream_versions.sort()

    # list of sorted upstream versions represented as "classified versions",
    # all versions are unaffected by default
    classified_versions = [
        ClassifiedVersion(x.version, False) for x in sorted_upstream_versions
    ]

    for classified_version in classified_versions:
        benev_upstream_version = BenevolentVersion(classified_version.version)

        for version_range in version_ranges:
            if version_range.contains(benev_upstream_version.exact,
                                      cmp_class=BenevolentVersion):
                # the version is within the range so it is affected, mark it as such
                classified_version.is_affected = True
                break

    return classified_versions
def check_version_different_order(v1, v2):
    """Check order of versions, the first version must be greater that the second."""
    c = ComparableVersion(v1)
    c1 = ComparableVersion(v2)

    # check using `compare_to` method
    res = c.compare_to(c1)
    assert res is not None
    assert res == 1, "{} is less than {}".format(v1, v2)

    # check using `compare_to` method and version string
    res = c.compare_to(v2)
    assert res is not None
    assert res == 1, "{} is less than {}".format(v1, v2)

    # check using rich comparison
    assert c > c1, "rich comparison: {} is not greater than {}".format(v1, v2)
def check_version_equal(v1, v2):
    """Check if versions are equal."""
    c = ComparableVersion(v1)
    c1 = ComparableVersion(v2)

    # check using `compare_to` method
    res = c.compare_to(c1)
    assert res is not None
    assert res == 0, "{} is not equal to {}".format(v1, v2)

    # check using `compare_to` method and version string
    res = c.compare_to(v2)
    assert res is not None
    assert res == 0, "{} is not equal to {}".format(v1, v2)

    # check using rich comparison
    assert c == c1, "rich comparison: {} is not equal to {}".format(v1, v2)
def check_version_order(v1, v2):
    """Check order of versions."""
    c = ComparableVersion(v1)
    c1 = ComparableVersion(v2)

    # check using `compare_to` method
    res = c.compare_to(c1)
    assert res is not None
    assert res == -1, "{} is greater than {}".format(v1, v2)

    # check using `compare_to` method and version string
    res = c.compare_to(v2)
    assert res is not None
    assert res == -1, "{} is greater than {}".format(v1, v2)

    # check using rich comparison
    assert c < c1, "rich comparison: {} is not lower than {}".format(v1, v2)
def test_eq_operator():
    """Test the == operator."""
    version = '1.0.0'
    c1 = ComparableVersion(version)
    c2 = ComparableVersion(version)
    assert c1 == c2

    # ComparableVersion == None
    assert not c1 == None  # noqa - because we really want to use == here

    version = '2.5.3-alpha'
    c3 = ComparableVersion(version)
    c4 = ComparableVersion(version)
    assert c3 == c4

    # ComparableVersion == None
    assert not c3 == None  # noqa - because we really want to use == here
Beispiel #14
0
 def __select_latest_version(self, versions=[]):
     """Select latest version from list."""
     if len(versions) == 0:
         return ""
     version_arr = []
     for x in versions:
         version_arr.append(ComparableVersion(x))
     version_arr.sort()
     return str(version_arr[-1])
def test_ne_operator():
    """Test the != operator."""
    version1 = '1.0.0'
    version2 = '2.0.0'
    c1 = ComparableVersion(version1)
    c2 = ComparableVersion(version2)
    assert c1 != c2

    # ComparableVersion != None
    assert c1 != None  # noqa - because we really want to use != here

    version1 = '2.5.3-alpha'
    version2 = '1.5.3-alpha'
    c3 = ComparableVersion(version1)
    c4 = ComparableVersion(version2)
    assert c3 != c4

    # ComparableVersion != None
    assert c3 != None  # noqa - because we really want to use != here
    def get_version_without_cves(self, latest_non_cve_versions):
        """Return higher version which doesn't have any CVEs. None if there is no such version.

        :return: Highest Version out of all latest_non_cve_versions.
        """
        highest_version = ''
        try:
            input_version_comparable = ComparableVersion(self.version)

            # latest non-cve is list with only one entry.
            latest_non_cve_version_comparable = ComparableVersion(latest_non_cve_versions[0])
        except TypeError:
            logger.error("Package %s@%s raised a TypeError", self.package, self.version)
        else:
            if latest_non_cve_version_comparable > input_version_comparable:
                highest_version = latest_non_cve_versions[0]

        logger.info("Highest non-cve version for %s@%s is %s", self.package, self.version,
                    highest_version)
        return highest_version
def test_lt_operator():
    """Test the < operator."""
    version = '1.0.0'
    c1 = ComparableVersion(version)
    version = '2.0.0'
    c2 = ComparableVersion(version)
    assert c1 < c2

    # ComparableVersion < None
    assert not c1 < None
    assert not c2 < None

    version = '2.1.1'
    c3 = ComparableVersion(version)
    assert c2 < c3
    # transitivity check
    assert c1 < c3

    # ComparableVersion < None
    assert not c3 < None
Beispiel #18
0
    def __init__(self, version_str):
        self._version_str = version_str.strip()

        # https://github.com/victims/victims-cve-db#version-string-common
        result = re.fullmatch(r'^[><=]{1}=[^, ]+(,[^, ]+)?$',
                              version_str.strip())
        if result is None:
            raise ParseError(
                'Invalid version string: {vs}'.format(vs=version_str))

        self._operator = self._version_str[:2]

        if ',' in self._version_str:
            self._version = ComparableVersion(
                self._version_str[2:].split(',')[0])
            self._explicit_boundary = ComparableVersion(
                self._version_str.split(',')[1])
        else:
            self._version = ComparableVersion(self._version_str[2:])
            self._explicit_boundary = None
def test_gt_operator():
    """Test the > operator."""
    version = '2.0.0'
    c1 = ComparableVersion(version)
    version = '1.0.0'
    c2 = ComparableVersion(version)
    assert c1 > c2

    # ComparableVersion < None
    assert c1 > None
    assert c2 > None

    version = '2.1.1'
    c3 = ComparableVersion(version)
    assert c3 > c2
    # transitivity check
    assert c3 > c1

    # ComparableVersion > None
    assert c3 > None
def test_parse_version():
    """Test the method to parse version."""
    c = ComparableVersion("1")
    itemlist = c.items.get_list()
    assert len(itemlist) == 1
    assert str(itemlist[0]) == "1"

    c = ComparableVersion("1.2")
    itemlist = c.items.get_list()
    assert len(itemlist) == 2
    assert str(itemlist[0]) == "1"
    assert str(itemlist[1]) == "2"

    c = ComparableVersion("1-2")
    itemlist = c.items.get_list()
    assert len(itemlist) == 2

    c = ComparableVersion(".2")
    itemlist = c.items.get_list()
    assert len(itemlist) == 2

    c = ComparableVersion("-2")
    itemlist = c.items.get_list()
    assert len(itemlist) == 1
def test_comparisons_wrong_type():
    """Test function compare_to."""
    v1 = "1.0.0"
    c = ComparableVersion(v1)

    # check the TypeError
    with pytest.raises(TypeError):
        c.compare_to(None)
        c.compare_to(True)
        c.compare_to(False)
        c.compare_to([])
        c.compare_to({})
        c.compare_to(42)
        c.compare_to(3.14)
        c.compare_to(1 + 2j)
Beispiel #22
0
    def __contains__(self, version):
        """Return True if `checked_version` is among `affected_versions`."""
        checked_version = ComparableVersion(version)

        # TODO: we are probably missing '>=' here; but do we need it?
        if self._operator == '==':
            if checked_version == self._version:
                return True
        elif self._operator == '<=':
            if self._explicit_boundary:
                if self._explicit_boundary <= checked_version <= self._version:
                    return True
            else:
                if checked_version <= self._version:
                    return True

        return False
def test_parse_item():
    """Test the method to parse item."""
    c = ComparableVersion("2")

    p1 = c.parse_item(False, "StringItem")
    assert p1 is not None
    assert str(p1) == "StringItem"

    p2 = c.parse_item(True, "0")
    assert p2 is not None
    assert str(p2) == "0"

    # try to parse empty string (which is definitely not a number)
    with pytest.raises(ValueError) as e:
        p3 = c.parse_item(True, "")

    # try to parse string that does not contain a number
    with pytest.raises(ValueError) as e:
        p3 = c.parse_item(True, "foobar")
def test_str():
    """Test ComparableVersion objects `__str__` method."""
    version = '1.0.0'
    assert str(
        ComparableVersion(version)) == version, "Invalid string conversion."
def test_gt_operator():
    """Test the > operator."""
    version = '2.0.0'
    c1 = ComparableVersion(version)
    version = '1.0.0'
    c2 = ComparableVersion(version)
    assert c1 > c2

    # ComparableVersion < None
    assert c1 > None
    assert c2 > None

    version = '2.1.1'
    c3 = ComparableVersion(version)
    assert c3 > c2
    # transitivity check
    assert c3 > c1

    # ComparableVersion > None
    assert c3 > None

    gt_data = [
        {
            'v1': '1.1.1',
            'v2': '1.1',
        },
        {
            'v1': '1.1',
            'v2': '1.0.9',
        },
        {
            'v1': '1.5.0.2',
            'v2': '1.5.0.1',
        },
        {
            'v1': '2.0.rc1',
            'v2': '2.0.rc0',
        },
        {
            'v1': '11.5.4.0',
            'v2': '10.4.5',
        },
        {
            'v1': '11.5.4.3',
            'v2': '11.5.4.2',
        },
        {
            'v1': '1.5-2.RELEASE',
            'v2': '1.5-1',
        },
        {
            'v1': '1.5-2.RELEASE',
            'v2': '1.5-1.RELEASE',
        },
        {
            'v1': '1.5.2.RELEASE',
            'v2': '1.5.1',
        },
        {
            'v1': '1.5.2.RELEASE',
            'v2': '1.5.1.RELEASE',
        },
        {
            'v1': '0.0.0-20201203092726-db298ee30ce6',
            'v2': '0.0.0-20201203092725-db298ee30ce6',
        },
        {
            'v1': '1.0.0-20201203092720-db298ee30ce6',
            'v2': '0.0.0-20201203092725-db298ee30ce6',
        },
        {
            'v1': '1.4.1',
            'v2': 'upstream/1.0.1',
        },
        {
            'v1': '1.40.1',
            'v2': 'kubernetes-1.14.0-beta.1',
        },
    ]
    invalid_c = ComparableVersion('-1')
    for d in gt_data:
        c1 = ComparableVersion(d['v1'])
        c2 = ComparableVersion(d['v2'])
        assert c1 > c2

        # Version must be greated than invalid
        assert c1 > invalid_c
def test_parse_version():
    """Test the method to parse version."""
    c = ComparableVersion("1")
    itemlist = c.items.get_list()
    assert len(itemlist) == 1
    assert str(itemlist[0]) == "1"

    c = ComparableVersion("1.2")
    itemlist = c.items.get_list()
    assert len(itemlist) == 2
    assert str(itemlist[0]) == "1"
    assert str(itemlist[1]) == "2"

    c = ComparableVersion("1-2")
    itemlist = c.items.get_list()
    assert len(itemlist) == 2

    c = ComparableVersion(".2")
    itemlist = c.items.get_list()
    assert len(itemlist) == 2

    c = ComparableVersion("-2")
    itemlist = c.items.get_list()
    assert len(itemlist) == 1

    c = ComparableVersion("-1")
    itemlist = c.items.get_list()
    assert len(itemlist) == 1
    assert len(itemlist[0].get_list()) == 1
    assert str(itemlist[0].get_list()[0]) == "1"

    c = ComparableVersion("INVALID_VERSION")
    itemlist = c.items.get_list()
    assert len(itemlist) == 1
    assert itemlist[0].to_string() == "invalid_version"

    c = ComparableVersion("upstream/1.0.3")
    itemlist = c.items.get_list()
    assert len(itemlist) == 2
    assert itemlist[0].to_string() == "upstream/"
    assert len(itemlist[1].get_list()) == 3
    assert itemlist[1].get_list()[0].to_string() == "1"
    assert itemlist[1].get_list()[1].to_string() == "0"
    assert itemlist[1].get_list()[2].to_string() == "3"

    c = ComparableVersion("kubernetes-1.14.0-beta.1")
    itemlist = c.items.get_list()
    assert len(itemlist) == 2
    assert itemlist[0].to_string() == "kubernetes"
    assert len(itemlist[1].get_list()) == 3
    assert itemlist[1].get_list()[0].to_string() == "1"
    assert itemlist[1].get_list()[1].to_string() == "14"
    assert len(itemlist[1].get_list()[2].get_list()) == 2
    assert itemlist[1].get_list()[2].get_list()[0].to_string() == "beta"
    assert itemlist[1].get_list()[2].get_list()[1].to_string() == "1"

    c = ComparableVersion("1.5.2.RELEASE")
    itemlist = c.items.get_list()
    assert len(itemlist) == 4
    assert itemlist[0].to_string() == "1"
    assert itemlist[1].to_string() == "5"
    assert itemlist[2].to_string() == "2"
    assert itemlist[3].to_string() == "release"

    c = ComparableVersion("1.5-2.RELEASE")
    itemlist = c.items.get_list()
    assert len(itemlist) == 3
    assert itemlist[0].to_string() == "1"
    assert itemlist[1].to_string() == "5"
    assert len(itemlist[2].get_list()) == 2
    assert itemlist[2].get_list()[0].to_string() == "2"
    assert itemlist[2].get_list()[1].to_string() == "release"

    c = ComparableVersion("2.0.rc1")
    itemlist = c.items.get_list()
    assert len(itemlist) == 4
    assert itemlist[0].to_string() == "2"
    assert itemlist[1].to_string() == "0"
    assert itemlist[2].to_string() == "rc"
    assert len(itemlist[3].get_list()) == 1
    assert itemlist[3].get_list()[0].to_string() == "1"

    c = ComparableVersion("11.5.4.0")
    itemlist = c.items.get_list()
    assert len(itemlist) == 3
    assert itemlist[0].to_string() == "11"
    assert itemlist[1].to_string() == "5"
    assert itemlist[2].to_string() == "4"

    c = ComparableVersion("1.6.8-20201203092725-db298ee30ce6")
    itemlist = c.items.get_list()
    assert len(itemlist) == 4
    assert itemlist[0].to_string() == "1"
    assert itemlist[1].to_string() == "6"
    assert itemlist[2].to_string() == "8"
    assert len(itemlist[3].get_list()) == 2
    assert itemlist[3].get_list()[0].to_string() == "20201203092725"
    assert itemlist[3].get_list()[1].get_list()[0].to_string() == "db"
    assert itemlist[3].get_list()[1].get_list()[1].get_list()[0].to_string(
    ) == "298"
    assert itemlist[3].get_list()[1].get_list()[1].get_list()[1].get_list(
    )[0].to_string() == "ee"

    sub_list = itemlist[3].get_list()[1].get_list()[1].get_list()[1].get_list(
    )[1]
    assert sub_list.get_list()[0].to_string() == "30"
    assert sub_list.get_list()[1].get_list()[0].to_string() == "ce"
    assert sub_list.get_list()[1].get_list()[1].get_list()[0].to_string(
    ) == "6"

    c = ComparableVersion("1.6.0-20201203092725-db1234567890")
    itemlist = c.items.get_list()
    assert len(itemlist) == 3
    assert itemlist[0].to_string() == "1"
    assert itemlist[1].to_string() == "6"
    assert len(itemlist[2].get_list()) == 2
    assert itemlist[2].get_list()[0].to_string() == "20201203092725"
    assert itemlist[2].get_list()[1].get_list()[0].to_string() == "db"
    assert itemlist[2].get_list()[1].get_list()[1].get_list()[0].to_string(
    ) == "1234567890"

    c = ComparableVersion("0.0.0-20201203092725-db1234567890")
    itemlist = c.items.get_list()
    assert len(itemlist) == 1
    assert len(itemlist[0].get_list()) == 2
    assert itemlist[0].get_list()[0].to_string() == "20201203092725"
    assert itemlist[0].get_list()[1].get_list()[0].to_string() == "db"
    assert itemlist[0].get_list()[1].get_list()[1].get_list()[0].to_string(
    ) == "1234567890"
def check_version_order(v1, v2):
    """Check order of versions."""
    c = ComparableVersion(v1)
    c1 = ComparableVersion(v2)
    res = c.compare_to(c1)
    assert res == -1, "{} is greater than {}".format(v1, v2)
def check_version_different_order(v1, v2):
    """Check order of versions, the first version must be greater that the second."""
    c = ComparableVersion(v1)
    c1 = ComparableVersion(v2)
    res = c.compare_to(c1)
    assert res == 1, "{} is less than {}".format(v1, v2)
def check_version_equal(v1, v2):
    """Check if versions are equal."""
    c = ComparableVersion(v1)
    c1 = ComparableVersion(v2)
    res = c.compare_to(c1)
    assert res == 0, "{} is not equal to  {}".format(v1, v2)