summaryrefslogtreecommitdiffstats
path: root/meta/lib/oe/cve_check.py
diff options
context:
space:
mode:
authorLee Chee Yang <chee.yang.lee@intel.com>2021-01-22 18:07:19 +0800
committerSteve Sakoman <steve@sakoman.com>2021-02-04 04:57:53 -1000
commit294baea424472341d2ec880f13699076315d8274 (patch)
treef0cfe2f29cc6af8d9e3fa06a2abef49b099f9491 /meta/lib/oe/cve_check.py
parent2a558ee61a2452a209d39cd1528a309c549c0f4e (diff)
downloadopenembedded-core-contrib-294baea424472341d2ec880f13699076315d8274.tar.gz
cve-check: replace Looseversion with custom version class
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/tags ( beta, rc, pre, dev, alpha, preview) as pre-release section, any other trailing characters are difficult to understand/define so ignore them. Compare release section and pre-release section saperately. included selftest for the version class. [YOCTO#14127] Signed-off-by: Lee Chee Yang <chee.yang.lee@intel.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org> (cherry picked from commit 6ced85e9ddd3569240f1e8b82130d1ac0fffbc40) Signed-off-by: Steve Sakoman <steve@sakoman.com>
Diffstat (limited to 'meta/lib/oe/cve_check.py')
-rw-r--r--meta/lib/oe/cve_check.py58
1 files changed, 58 insertions, 0 deletions
diff --git a/meta/lib/oe/cve_check.py b/meta/lib/oe/cve_check.py
new file mode 100644
index 0000000000..ec48a3f829
--- /dev/null
+++ b/meta/lib/oe/cve_check.py
@@ -0,0 +1,58 @@
+import collections
+import re
+import 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 __le__(self, other):
+ if not isinstance(other, Version):
+ return NotImplemented
+ return self._key <= other._key
+
+ def __lt__(self, other):
+ if not isinstance(other, Version):
+ return NotImplemented
+ return self._key < other._key
+
+ 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