The idea is good but this really needs a test suite. If the class is added to a new file meta/lib/oe/cvecheck.py or similar then you can add a test suite too.
Ross On Thu, 21 Jan 2021 at 02:26, Lee Chee Yang <[email protected]> wrote: > > From: Lee Chee Yang <[email protected]> > > The way distutils.version.LooseVersion compare version are tricky, it treat > all these ( "1.0-beta2", "1.0-rc1", "1.0A", "1.0p2" and "1.0pre1") as greater > version than "1.0". This might be right for "1.0A" and "1.0p1" but not for > the rest, also these version could be confusing, the "p" in "1.0p1" can be > "pre" or "patched" version or even other meaning. > > replace Looseversion with custom class, it uses regex to capture common > version format like "1.1.1" or tag format using date like "2020-12-12" as > release section, check for following known string/label (beta, rc, pre, dev, > alpha, preview) as pre-release section, any other trailing characters > are difficult to understand and define so dont consider these when > comparing. compare release section and pre-release section saperately. > > [YOCTO#14127] > > Signed-off-by: Lee Chee Yang <[email protected]> > --- > meta/classes/cve-check.bbclass | 55 ++++++++++++++++++++++++++++++---- > 1 file changed, 50 insertions(+), 5 deletions(-) > > diff --git a/meta/classes/cve-check.bbclass b/meta/classes/cve-check.bbclass > index d843e7c4ac..b119353781 100644 > --- a/meta/classes/cve-check.bbclass > +++ b/meta/classes/cve-check.bbclass > @@ -206,7 +206,52 @@ def check_cves(d, patched_cves): > """ > Connect to the NVD database and find unpatched cves. > """ > - from distutils.version import LooseVersion > + import collections, re, itertools > + > + _Version = collections.namedtuple( > + "_Version", ["release", "pre_l", "pre_v"] > + ) > + > + class Version(): > + _version_pattern = > r"""v?(?:(?P<release>[0-9]+(?:[-\.][0-9]+)*)(?P<pre>[-_\.]?(?P<pre_l>(rc|alpha|beta|pre|preview|dev))[-_\.]?(?P<pre_v>[0-9]+)?)?)(.*)?""" > + _regex = re.compile(r"^\s*" + _version_pattern + r"\s*$", re.VERBOSE > | re.IGNORECASE) > + def __init__(self, version): > + match = self._regex.search(version) > + if not match: > + raise Exception("Invalid version: '{0}'".format(version)) > + > + self._version = _Version( > + release=tuple(int(i) for i in > match.group("release").replace("-",".").split(".")), > + pre_l=match.group("pre_l"), > + pre_v=match.group("pre_v") > + ) > + > + self._key = _cmpkey( > + self._version.release, > + self._version.pre_l, > + self._version.pre_v > + ) > + > + def __ge__(self, other): > + if not isinstance(other, Version): > + return NotImplemented > + return self._key >= other._key > + > + def __gt__(self, other): > + if not isinstance(other, Version): > + return NotImplemented > + return self._key > other._key > + > + def _cmpkey(release, pre_l, pre_v): > + # remove leading 0 > + _release = tuple( > + reversed(list(itertools.dropwhile(lambda x: x == 0, > reversed(release)))) > + ) > + if pre_l is None and pre_v is None: > + _pre = float('inf') > + else: > + _pre = float(pre_v) if pre_v else float('-inf') > + return _release, _pre > > pn = d.getVar("PN") > real_pv = d.getVar("PV") > @@ -263,8 +308,8 @@ def check_cves(d, patched_cves): > else: > if operator_start: > try: > - vulnerable_start = (operator_start == '>=' and > LooseVersion(pv) >= LooseVersion(version_start)) > - vulnerable_start |= (operator_start == '>' and > LooseVersion(pv) > LooseVersion(version_start)) > + vulnerable_start = (operator_start == '>=' and > Version(pv) >= Version(version_start)) > + vulnerable_start |= (operator_start == '>' and > Version(pv) > Version(version_start)) > except: > bb.warn("%s: Failed to compare %s %s %s for %s" % > (product, pv, operator_start, > version_start, cve)) > @@ -274,8 +319,8 @@ def check_cves(d, patched_cves): > > if operator_end: > try: > - vulnerable_end = (operator_end == '<=' and > LooseVersion(pv) <= LooseVersion(version_end)) > - vulnerable_end |= (operator_end == '<' and > LooseVersion(pv) < LooseVersion(version_end)) > + vulnerable_end = (operator_end == '<=' and > Version(version_end) >= Version(pv)) > + vulnerable_end |= (operator_end == '<' and > Version(version_end) > Version(pv) ) > except: > bb.warn("%s: Failed to compare %s %s %s for %s" % > (product, pv, operator_end, version_end, > cve)) > -- > 2.17.1 > > > >
-=-=-=-=-=-=-=-=-=-=-=- Links: You receive all messages sent to this group. View/Reply Online (#147059): https://lists.openembedded.org/g/openembedded-core/message/147059 Mute This Topic: https://lists.openembedded.org/mt/79995299/21656 Group Owner: [email protected] Unsubscribe: https://lists.openembedded.org/g/openembedded-core/unsub [[email protected]] -=-=-=-=-=-=-=-=-=-=-=-
