aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMaximilian Bosch <maximilian@mbosch.me>2020-10-06 20:08:51 +0200
committerMaximilian Bosch <maximilian@mbosch.me>2020-10-06 20:08:51 +0200
commit59f2dd8e8da1f82aa9e29e30ba1df643434a9254 (patch)
tree26de740eb4dfa01380cf7825870123c021eafe59
parentad143c5b3b7e713b89f0437ce17c20ac642ca530 (diff)
libfetchers/github: allow slashes in refs
Refs #4061
-rw-r--r--src/libfetchers/github.cc20
-rw-r--r--src/libutil/url-parts.hh2
2 files changed, 18 insertions, 4 deletions
diff --git a/src/libfetchers/github.cc b/src/libfetchers/github.cc
index 92ff224f7..3d1cc15e2 100644
--- a/src/libfetchers/github.cc
+++ b/src/libfetchers/github.cc
@@ -37,15 +37,29 @@ struct GitArchiveInputScheme : InputScheme
std::optional<std::string> ref;
std::optional<std::string> host_url;
- if (path.size() == 2) {
- } else if (path.size() == 3) {
+ auto size = path.size();
+ if (size == 3) {
if (std::regex_match(path[2], revRegex))
rev = Hash::parseAny(path[2], htSHA1);
else if (std::regex_match(path[2], refRegex))
ref = path[2];
else
throw BadURL("in URL '%s', '%s' is not a commit hash or branch/tag name", url.url, path[2]);
- } else
+ } else if (size > 3) {
+ std::string rs;
+ for (auto i = std::next(path.begin(), 2); i != path.end(); i++) {
+ rs += *i;
+ if (std::next(i) != path.end()) {
+ rs += "/";
+ }
+ }
+
+ if (std::regex_match(rs, refRegex)) {
+ ref = rs;
+ } else {
+ throw BadURL("in URL '%s', '%s' is not a branch/tag name", url.url, rs);
+ }
+ } else if (size < 2)
throw BadURL("URL '%s' is invalid", url.url);
for (auto &[name, value] : url.query) {
diff --git a/src/libutil/url-parts.hh b/src/libutil/url-parts.hh
index 68be15cb0..e0e2809fd 100644
--- a/src/libutil/url-parts.hh
+++ b/src/libutil/url-parts.hh
@@ -22,7 +22,7 @@ const static std::string absPathRegex = "(?:(?:/" + segmentRegex + ")*/?)";
const static std::string pathRegex = "(?:" + segmentRegex + "(?:/" + segmentRegex + ")*/?)";
// A Git ref (i.e. branch or tag name).
-const static std::string refRegexS = "[a-zA-Z0-9][a-zA-Z0-9_.-]*"; // FIXME: check
+const static std::string refRegexS = "[a-zA-Z0-9][a-zA-Z0-9_.\\/-]*"; // FIXME: check
extern std::regex refRegex;
// Instead of defining what a good Git Ref is, we define what a bad Git Ref is