@@ -511,7 +511,7 @@ LIBFOO_IGNORE_CVES += CVE-2020-12345
LIBFOO_IGNORE_CVES += CVE-2020-54321
----------------------
-* +LIBFOO_CPE_ID_*+ variables is a set of variables that allows the
+* [[cpe-id]] +LIBFOO_CPE_ID_*+ variables is a set of variables that allows the
package to define its https://nvd.nist.gov/products/cpe[CPE
identifier]. The available variables are:
+
@@ -366,3 +366,76 @@ class VariableWithBraces(_CheckFunction):
return ["{}:{}: use $() to delimit variables, not ${{}}"
.format(self.filename, lineno),
text]
+
+
+class CPEVariables(_CheckFunction):
+ """
+ Check that the values for the CPE variables are not the default.
+ - CPE_ID_* variables must not be set to their default
+ - CPE_ID_VALID must not be set if a non-default CPE_ID variable is set
+ """
+ def before(self):
+ pkg, _ = os.path.splitext(os.path.basename(self.filename))
+ self.CPE_fields_defaults = {
+ "VALID": "NO",
+ "PREFIX": "cpe:2.3:a",
+ "VENDOR": f"{pkg}_project",
+ "PRODUCT": pkg,
+ "VERSION": None,
+ "UPDATE": "*",
+ }
+ self.valid = None
+ self.non_defaults = 0
+ self.CPE_FIELDS_RE = re.compile(
+ r"^\s*(.+_CPE_ID_({}))\s*=\s*(.+)$"
+ .format("|".join(self.CPE_fields_defaults)),
+ )
+ self.VERSION_RE = re.compile(
+ rf"^(HOST_)?{pkg.upper().replace('-', '_')}_VERSION\s*=\s*(.+)$",
+ )
+ self.COMMENT_RE = re.compile(r"^\s*#.*")
+
+ def check_line(self, lineno, text):
+ text = self.COMMENT_RE.sub('', text.rstrip())
+
+ # WARNING! The VERSION_RE can _also_ match the same lines as CPE_FIELDS_RE,
+ # but not the other way around. So we must first check for CPE_FIELDS_RE,
+ # and if not matched, then and only then check for VERSION_RE.
+ match = self.CPE_FIELDS_RE.match(text)
+ if match:
+ var, field, val = match.groups()
+ return self._check_field(lineno, text, field, var, val)
+
+ match = self.VERSION_RE.match(text)
+ if match:
+ self.CPE_fields_defaults["VERSION"] = match.groups()[1]
+
+ def after(self):
+ # "VALID" counts in the non-defaults; so when "VALID" is present,
+ # 1 non-default means only "VALID" is present, so that's OK.
+ if self.valid and self.non_defaults > 1:
+ return ["{}:{}: 'YES' is implied when a non-default CPE_ID field is specified: {} ({}#cpe-id)".format(
+ self.filename,
+ self.valid["lineno"],
+ self.valid["text"],
+ self.url_to_manual,
+ )]
+
+ def _check_field(self, lineno, text, field, var, val):
+ if field == "VERSION" and self.CPE_fields_defaults[field] is None:
+ return ["{}:{}: expecting package version to be set before CPE_ID_VERSION".format(
+ self.filename,
+ lineno,
+ )]
+ if val == self.CPE_fields_defaults[field]:
+ return ["{}:{}: '{}' is the default value for {} ({}#cpe-id)".format(
+ self.filename,
+ lineno,
+ val,
+ var,
+ self.url_to_manual,
+ )]
+ else:
+ if field == "VALID":
+ self.valid = {"lineno": lineno, "text": text}
+ self.non_defaults += 1
Now that we can specify that the default values for the CPE_ID variables are valid, without having to actually set one (or more) to their default, add a check-package check that validates that the CPE_ID variables are indeed not set to their default. It also validates that CPE_ID_VALID is not set when another CPE_ID variable is set to a non-default value. Add an anchor in the manual so that we can easily point to it. Signed-off-by: Yann E. MORIN <yann.morin.1998@free.fr> Cc: Fabrice Fontaine <fontaine.fabrice@gmail.com> Cc: Ricardo Martincoski <ricardo.martincoski@gmail.com> --- docs/manual/adding-packages-generic.adoc | 2 +- utils/checkpackagelib/lib_mk.py | 73 ++++++++++++++++++++++++ 2 files changed, 74 insertions(+), 1 deletion(-)