diff options
author | Eelco Dolstra <edolstra@gmail.com> | 2019-05-01 20:43:16 +0200 |
---|---|---|
committer | Eelco Dolstra <edolstra@gmail.com> | 2019-05-01 20:44:30 +0200 |
commit | 5d6e8c008ba8716f16ddfad954663d9e732f8556 (patch) | |
tree | 932a2ebe009adfbbae8461c95b04e0a452f47e58 /src | |
parent | a37436d7929f37fb390837419d166a81559abb3e (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.cc | 19 |
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; } |