aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorEelco Dolstra <edolstra@gmail.com>2019-05-01 20:43:16 +0200
committerEelco Dolstra <edolstra@gmail.com>2019-05-01 20:44:30 +0200
commit5d6e8c008ba8716f16ddfad954663d9e732f8556 (patch)
tree932a2ebe009adfbbae8461c95b04e0a452f47e58 /src
parenta37436d7929f37fb390837419d166a81559abb3e (diff)
Allow 'dir' parameter in github: URIs
E.g. 'github:edolstra/dwarffs/flake?dir=foo/bar'.
Diffstat (limited to 'src')
-rw-r--r--src/libexpr/primops/flakeref.cc19
1 files changed, 17 insertions, 2 deletions
diff --git a/src/libexpr/primops/flakeref.cc b/src/libexpr/primops/flakeref.cc
index b7a20a170..141d61c0d 100644
--- a/src/libexpr/primops/flakeref.cc
+++ b/src/libexpr/primops/flakeref.cc
@@ -33,12 +33,14 @@ const static std::string pathRegex = "/?" + segmentRegex + "(?:/" + segmentRegex
// FIXME: support escaping in query string.
// Note: '/' is not a valid query parameter, but so what...
const static std::string paramRegex = "[a-z]+=[/a-zA-Z0-9._-]*";
+const static std::string paramsRegex = "(?:[?](" + paramRegex + "(?:&" + paramRegex + ")*))";
// 'dir' path elements cannot start with a '.'. We also reject
// potentially dangerous characters like ';'.
const static std::string subDirElemRegex = "(?:[a-zA-Z0-9_-]+[a-zA-Z0-9._-]*)";
const static std::string subDirRegex = subDirElemRegex + "(?:/" + subDirElemRegex + ")*";
+
FlakeRef::FlakeRef(const std::string & uri, bool allowRelative)
{
// FIXME: could combine this into one regex.
@@ -48,14 +50,15 @@ FlakeRef::FlakeRef(const std::string & uri, bool allowRelative)
std::regex::ECMAScript);
static std::regex githubRegex(
- "github:(" + ownerRegex + ")/(" + repoRegex + ")(?:/" + revOrRefRegex + ")?",
+ "github:(" + ownerRegex + ")/(" + repoRegex + ")(?:/" + revOrRefRegex + ")?"
+ + paramsRegex + "?",
std::regex::ECMAScript);
static std::regex uriRegex(
"((" + schemeRegex + "):" +
"(?://(" + authorityRegex + "))?" +
"(" + pathRegex + "))" +
- "(?:[?](" + paramRegex + "(?:&" + paramRegex + ")*))?",
+ paramsRegex + "?",
std::regex::ECMAScript);
static std::regex refRegex2(refRegex, std::regex::ECMAScript);
@@ -85,6 +88,18 @@ FlakeRef::FlakeRef(const std::string & uri, bool allowRelative)
else if (match[4].matched) {
ref = match[4];
}
+ for (auto & param : tokenizeString<Strings>(match[5], "&")) {
+ auto n = param.find('=');
+ assert(n != param.npos);
+ std::string name(param, 0, n);
+ std::string value(param, n + 1);
+ if (name == "dir") {
+ if (value != "" && !std::regex_match(value, subDirRegex2))
+ throw Error("flake '%s' has invalid subdirectory '%s'", uri, value);
+ subdir = value;
+ } else
+ throw Error("invalid Git flake reference parameter '%s', in '%s'", name, uri);
+ }
data = d;
}