Merge "Reject fully-qualified URLs in 'from' argument of nix registry add" into main

This commit is contained in:
Delan Azabani 2024-07-02 07:20:01 +00:00 committed by Gerrit Code Review
commit 865a3732fa
8 changed files with 44 additions and 5 deletions

View file

@ -44,6 +44,11 @@ cole-h:
display_name: Cole Helbling display_name: Cole Helbling
github: cole-h github: cole-h
delan:
display_name: delan
forgejo: delan
github: delan
edolstra: edolstra:
display_name: Eelco Dolstra display_name: Eelco Dolstra
github: edolstra github: edolstra

View file

@ -0,0 +1,10 @@
---
synopsis: "`nix registry add` now requires a shorthand flakeref on the 'from' side"
cls: 1494
credits: delan
category: Improvements
---
The 'from' argument must now be a shorthand flakeref like `nixpkgs` or `nixpkgs/nixos-20.03`, making it harder to accidentally swap the 'from' and 'to' arguments.
Registry entries that map from other flake URLs can still be specified in registry.json, the `nix.registry` option in NixOS, or the `--override-flake` option in the CLI, but they are not guaranteed to work correctly.

View file

@ -85,8 +85,8 @@ std::pair<FlakeRef, std::string> parseFlakeRefWithFragment(
+ "(?:#(" + queryRegex + "))?", + "(?:#(" + queryRegex + "))?",
std::regex::ECMAScript); std::regex::ECMAScript);
static std::regex flakeRegex( static std::regex flakeShorthandRegex(
"((" + flakeIdRegexS + ")(?:/(?:" + refAndOrRevRegex + "))?)" flakeShorthandRegexS
+ "(?:#(" + queryRegex + "))?", + "(?:#(" + queryRegex + "))?",
std::regex::ECMAScript); 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 /* Check if 'url' is a flake ID. This is an abbreviated syntax for
'flake:<flake-id>?ref=<ref>&rev=<rev>'. */ 'flake:<flake-id>?ref=<ref>&rev=<rev>'. */
if (std::regex_match(url, match, flakeRegex)) { if (std::regex_match(url, match, flakeShorthandRegex)) {
auto parsedURL = ParsedURL{ auto parsedURL = ParsedURL{
.url = url, .url = url,
.base = "flake:" + match.str(1), .base = "flake:" + match.str(1),

View file

@ -46,4 +46,7 @@ const static std::string refAndOrRevRegex = "(?:(" + revRegexS + ")|(?:(" + refR
const static std::string flakeIdRegexS = "[a-zA-Z][a-zA-Z0-9_-]*"; const static std::string flakeIdRegexS = "[a-zA-Z][a-zA-Z0-9_-]*";
extern std::regex flakeIdRegex; extern std::regex flakeIdRegex;
const static std::string flakeShorthandRegexS = "((" + flakeIdRegexS + ")(?:/(?:" + refAndOrRevRegex + "))?)";
extern std::regex flakeShorthandRegex;
} }

View file

@ -9,6 +9,7 @@ std::regex refRegex(refRegexS, std::regex::ECMAScript);
std::regex badGitRefRegex(badGitRefRegexS, std::regex::ECMAScript); std::regex badGitRefRegex(badGitRefRegexS, std::regex::ECMAScript);
std::regex revRegex(revRegexS, std::regex::ECMAScript); std::regex revRegex(revRegexS, std::regex::ECMAScript);
std::regex flakeIdRegex(flakeIdRegexS, std::regex::ECMAScript); std::regex flakeIdRegex(flakeIdRegexS, std::regex::ECMAScript);
std::regex flakeShorthandRegex(flakeShorthandRegexS, std::regex::ECMAScript);
ParsedURL parseURL(const std::string & url) ParsedURL parseURL(const std::string & url)
{ {

View file

@ -31,8 +31,9 @@ R""(
# Description # Description
This command adds an entry to the user registry that maps flake This command adds an entry to the user registry that maps flake
reference *from-url* to flake reference *to-url*. If an entry for reference *from-url* to flake reference *to-url*, where *from-url*
*from-url* already exists, it is overwritten. 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 Entries can be removed using [`nix registry
remove`](./nix3-registry-remove.md). remove`](./nix3-registry-remove.md).

View file

@ -5,6 +5,7 @@
#include "flake/flake.hh" #include "flake/flake.hh"
#include "store-api.hh" #include "store-api.hh"
#include "fetchers.hh" #include "fetchers.hh"
#include "url-parts.hh"
#include "registry.hh" #include "registry.hh"
using namespace nix; using namespace nix;
@ -109,7 +110,14 @@ struct CmdRegistryAdd : MixEvalArgs, Command, RegistryCommand
void run() override 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); 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 toRef = parseFlakeRef(toUrl);
auto registry = getRegistry(); auto registry = getRegistry();
fetchers::Attrs extraAttrs; fetchers::Attrs extraAttrs;

View file

@ -366,6 +366,17 @@ nix registry pin flake1 flake3
nix registry remove flake1 nix registry remove flake1
[[ $(nix registry list | wc -l) == 5 ]] [[ $(nix registry list | wc -l) == 5 ]]
# 'nix registry add' should accept flake shorthands (with or without branch or rev)
# in the from argument, but reject fully-qualified from-urls (direct or indirect).
nix registry add nixpkgz github:NixOS/nixpkgz
nix registry remove nixpkgz
nix registry add nixpkgz/branch github:NixOS/nixpkgz
nix registry remove nixpkgz/branch
nix registry add nixpkgz/branch/1db42b7fe3878f3f5f7a4f2dc210772fd080e205 github:NixOS/nixpkgz
nix registry remove nixpkgz/branch/1db42b7fe3878f3f5f7a4f2dc210772fd080e205
! nix registry add flake:nixpkgz github:NixOS/nixpkgz
! nix registry add github:NixOS/nixpkgz github:NixOS/nixpkgz
# Test 'nix registry list' with a disabled global registry. # Test 'nix registry list' with a disabled global registry.
nix registry add user-flake1 git+file://$flake1Dir nix registry add user-flake1 git+file://$flake1Dir
nix registry add user-flake2 git+file://$flake2Dir nix registry add user-flake2 git+file://$flake2Dir