aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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 db1ced5d6..8352ef02d 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 5d21b8d1a..862d9fa6e 100644
--- a/src/libutil/url-parts.hh
+++ b/src/libutil/url-parts.hh
@@ -23,7 +23,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