Wrong values for the version or update URL will cause very confusing build-time or runtime errors. Provide a better user experience by validating them up-front. Signed-off-by: Demi Marie Obenour <demiobenour@gmail.com> --- lib/config.nix | 41 +++++++++++++++++++++++++++++++++++------ 1 file changed, 35 insertions(+), 6 deletions(-) diff --git a/lib/config.nix b/lib/config.nix index 5b6b95013734202b7e2e01d5ffce313080658006..660a2427447fd9851e60e955da6bd1a5d71cfdac 100644 --- a/lib/config.nix +++ b/lib/config.nix @@ -19,10 +19,39 @@ let inherit default; } else config; finalConfig = default // callConfig config; + + # Only allow unreserved characters, : (for port numbers), /, and %-encoding. + # The rest of the code is allowed to assume that these are the only characters + # in the update URL. + # Do not use [:alnum:] or [:hexdigit:] as they depend on the locale in POSIX. + # Query strings and fragment identifiers break appending + # /SHA256SUMS and /SHA256SUMS.gpg to a URL. + # [, ], {, and } would cause globbing in curl. + url-regex = "^https?://([ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789:./~-]|%[ABCDEFabcdef0123456789]{2})+$"; + update-url = finalConfig.update-url; + + # Only allow a numeric version for now. + number_re = "(0|[1-9][0-9]{0,2})"; + version_re = "^(${number_re}\\.){2}${number_re}$"; in - finalConfig // { - update-signing-key = builtins.path { - name = "signing-key"; - path = finalConfig.update-signing-key; - }; - } + if !builtins.isString update-url then + builtins.abort "Update URL must be a string, not ${builtins.typeOf update-url}" + else if builtins.match "^https?://.*" update-url == null then + builtins.abort "Update URL ${builtins.toJSON update-url} has unsupported scheme (not https:// or http://) or is invalid" + else if builtins.match url-regex update-url == null then + builtins.abort "Update URL ${builtins.toJSON update-url} has forbidden characters" + else if builtins.substring (builtins.stringLength update-url - 1) 1 update-url == "/" then + builtins.abort "Update URL ${builtins.toJSON update-url} must not end with /" + else if !builtins.isString finalConfig.version then + builtins.abort "Version must be a string, not ${builtins.typeOf finalConfig.version}" + else if builtins.match version_re finalConfig.version == null then + builtins.abort "Version ${builtins.toJSON finalConfig.version} is invalid" + else if !builtins.isPath finalConfig.update-signing-key then + builtins.abort "Update verification key file is of type ${builtins.typeOf finalConfig.update-signing-key}, not path" + else + finalConfig // { + update-signing-key = builtins.path { + name = "signing-key"; + path = finalConfig.update-signing-key; + }; + } -- 2.51.2