forked from lix-project/lix
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
This commit is contained in:
parent
5dc85e8b72
commit
b2944d93a6
|
@ -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
|
||||||
|
|
10
doc/manual/rl-next/registry-add-shorthand-only.md
Normal file
10
doc/manual/rl-next/registry-add-shorthand-only.md
Normal 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.
|
|
@ -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),
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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).
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue