[bitbake-devel] [PATCH v3 3/7] fetch2/npm.py: restrict version parameter

Jean-Marie LEMETAYER jean-marie.lemetayer at savoirfairelinux.com
Wed Nov 20 09:34:08 UTC 2019


The npm command allows version to be actual versions, tags or ranges.
The fetcher must be more restrictive and only allows fixed versions
(which are following the semver specification [1]).

The 'latest' tag which is automatically set to the latest published
version is also allowed to make the use of the 'devtool add' command
easier.

1: https://semver.org/spec/v2.0.0.html

Signed-off-by: Jean-Marie LEMETAYER <jean-marie.lemetayer at savoirfairelinux.com>
---
 lib/bb/fetch2/npm.py | 50 ++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 50 insertions(+)

diff --git a/lib/bb/fetch2/npm.py b/lib/bb/fetch2/npm.py
index e377d18a..e253cf3e 100644
--- a/lib/bb/fetch2/npm.py
+++ b/lib/bb/fetch2/npm.py
@@ -46,6 +46,33 @@ class Npm(FetchMethod):
         """
         return ud.type in ['npm']
 
+    @staticmethod
+    def _is_semver(version):
+        """
+            Is the version string following the semver semantic?
+
+            https://semver.org/spec/v2.0.0.html
+        """
+        regex = re.compile(
+        r"""
+        ^
+        (0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)
+        (?:-(
+            (?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)
+            (?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*
+        ))?
+        (?:\+(
+            [0-9a-zA-Z-]+
+            (?:\.[0-9a-zA-Z-]+)*
+        ))?
+        $
+        """, re.VERBOSE)
+
+        if regex.match(version) is None:
+            return False
+
+        return True
+
     def urldata_init(self, ud, d):
         """
             Init npm specific variables within url data
@@ -65,6 +92,9 @@ class Npm(FetchMethod):
         if not ud.version:
             raise MissingParameterError("Parameter 'version' required", ud.url)
 
+        if not self._is_semver(ud.version) and not ud.version == "latest":
+            raise ParameterError("Parameter 'version' is invalid", ud.url)
+
         # Get the 'registry' part of the url
         registry = re.sub(r"^npm://", "", ud.url.split(";")[0])
         ud.registry = "http://" + registry
@@ -96,6 +126,18 @@ class Npm(FetchMethod):
             ud.basecmd += " --passive-ftp"
             ud.basecmd += " --no-check-certificate"
 
+    def need_update(self, ud, d):
+        """
+            Force a fetch, even if localpath exists?
+        """
+        if ud.version == "latest":
+            return True
+
+        if os.path.exists(ud.localpath):
+            return False
+
+        return True
+
     @staticmethod
     def _run_npm_view(ud, d):
         """
@@ -158,6 +200,14 @@ class Npm(FetchMethod):
         integrity = view.get("dist", {}).get("integrity")
         shasum = view.get("dist", {}).get("shasum")
 
+        # Check if version is valid
+        if ud.version == "latest":
+            bb.warn("The npm package '{}' is using the latest version " \
+                    "available. This could lead to non-reproducible " \
+                    "builds.".format(ud.name))
+        elif ud.version != view.get("version"):
+            raise ParameterError("Parameter 'version' is invalid", ud.url)
+
         cmd = ud.basecmd
 
         bb.utils.mkdirhier(os.path.dirname(ud.localpath))
-- 
2.20.1



More information about the bitbake-devel mailing list