aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDelan Azabani <delan@azabani.com>2024-06-22 23:00:59 +0800
committerDelan Azabani <delan@azabani.com>2024-06-29 05:11:31 +0000
commitb2944d93a6d95810f0aef09e9ac44b95e2712554 (patch)
tree90a3c92b959aa27b742c7b6423c0337dd8a5f869 /src
parent5dc85e8b72d1ba433f69200537146275ff1c4a03 (diff)
Reject fully-qualified URLs in 'from' argument of `nix registry add`
We previously allowed you to map any flake URL to any other flake URL, including shorthand flakerefs, indirect flake URLs like `flake:nixpkgs`, direct flake URLs like `github:NixOS/nixpkgs`, or local paths. But flake registry entries mapping from direct flake URLs often come from swapping the 'from' and 'to' arguments by accident, and even when created intentionally, they may not actually work correctly. This patch rejects those URLs (and fully-qualified flake: URLs), making it harder to swap the arguments by accident. Fixes #181. Change-Id: I24713643a534166c052719b8770a4edfcfdb8cf3
Diffstat (limited to 'src')
-rw-r--r--src/libexpr/flake/flakeref.cc6
-rw-r--r--src/libutil/url-parts.hh3
-rw-r--r--src/libutil/url.cc1
-rw-r--r--src/nix/registry-add.md5
-rw-r--r--src/nix/registry.cc8
5 files changed, 18 insertions, 5 deletions
diff --git a/src/libexpr/flake/flakeref.cc b/src/libexpr/flake/flakeref.cc
index 1c90bfc43..a95df04ba 100644
--- a/src/libexpr/flake/flakeref.cc
+++ b/src/libexpr/flake/flakeref.cc
@@ -85,8 +85,8 @@ std::pair<FlakeRef, std::string> parseFlakeRefWithFragment(
+ "(?:#(" + queryRegex + "))?",
std::regex::ECMAScript);
- static std::regex flakeRegex(
- "((" + flakeIdRegexS + ")(?:/(?:" + refAndOrRevRegex + "))?)"
+ static std::regex flakeShorthandRegex(
+ flakeShorthandRegexS
+ "(?:#(" + queryRegex + "))?",
std::regex::ECMAScript);
@@ -95,7 +95,7 @@ std::pair<FlakeRef, std::string> parseFlakeRefWithFragment(
/* Check if 'url' is a flake ID. This is an abbreviated syntax for
'flake:<flake-id>?ref=<ref>&rev=<rev>'. */
- if (std::regex_match(url, match, flakeRegex)) {
+ if (std::regex_match(url, match, flakeShorthandRegex)) {
auto parsedURL = ParsedURL{
.url = url,
.base = "flake:" + match.str(1),
diff --git a/src/libutil/url-parts.hh b/src/libutil/url-parts.hh
index 6efcc7e50..1f570567c 100644
--- a/src/libutil/url-parts.hh
+++ b/src/libutil/url-parts.hh
@@ -46,4 +46,7 @@ const static std::string refAndOrRevRegex = "(?:(" + revRegexS + ")|(?:(" + refR
const static std::string flakeIdRegexS = "[a-zA-Z][a-zA-Z0-9_-]*";
extern std::regex flakeIdRegex;
+const static std::string flakeShorthandRegexS = "((" + flakeIdRegexS + ")(?:/(?:" + refAndOrRevRegex + "))?)";
+extern std::regex flakeShorthandRegex;
+
}
diff --git a/src/libutil/url.cc b/src/libutil/url.cc
index 46688cef5..87146ca56 100644
--- a/src/libutil/url.cc
+++ b/src/libutil/url.cc
@@ -9,6 +9,7 @@ std::regex refRegex(refRegexS, std::regex::ECMAScript);
std::regex badGitRefRegex(badGitRefRegexS, std::regex::ECMAScript);
std::regex revRegex(revRegexS, std::regex::ECMAScript);
std::regex flakeIdRegex(flakeIdRegexS, std::regex::ECMAScript);
+std::regex flakeShorthandRegex(flakeShorthandRegexS, std::regex::ECMAScript);
ParsedURL parseURL(const std::string & url)
{
diff --git a/src/nix/registry-add.md b/src/nix/registry-add.md
index a947fa0b3..90b54a596 100644
--- a/src/nix/registry-add.md
+++ b/src/nix/registry-add.md
@@ -31,8 +31,9 @@ R""(
# Description
This command adds an entry to the user registry that maps flake
-reference *from-url* to flake reference *to-url*. If an entry for
-*from-url* already exists, it is overwritten.
+reference *from-url* to flake reference *to-url*, where *from-url*
+must be a shorthand like 'nixpkgs' or 'nixpkgs/nixos-20.03'. If an
+entry for *from-url* already exists, it is overwritten.
Entries can be removed using [`nix registry
remove`](./nix3-registry-remove.md).
diff --git a/src/nix/registry.cc b/src/nix/registry.cc
index f509ccae8..9619b85d4 100644
--- a/src/nix/registry.cc
+++ b/src/nix/registry.cc
@@ -5,6 +5,7 @@
#include "flake/flake.hh"
#include "store-api.hh"
#include "fetchers.hh"
+#include "url-parts.hh"
#include "registry.hh"
using namespace nix;
@@ -109,7 +110,14 @@ struct CmdRegistryAdd : MixEvalArgs, Command, RegistryCommand
void run() override
{
+ std::smatch match;
+ if (!std::regex_match(fromUrl, match, flakeShorthandRegex)) {
+ throw UsageError("'from-url' argument must be a shorthand like 'nixpkgs' or 'nixpkgs/nixos-20.03'");
+ }
auto fromRef = parseFlakeRef(fromUrl);
+ if (fromRef.input.direct) {
+ throw UsageError("'from-url' argument must be an indirect flakeref like 'nixpkgs' or 'flake:nixpkgs'");
+ }
auto toRef = parseFlakeRef(toUrl);
auto registry = getRegistry();
fetchers::Attrs extraAttrs;