summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: d06b689)
raw | patch | inline | side by side (parent: d06b689)
author | Junio C Hamano <junkio@cox.net> | |
Tue, 11 Oct 2005 06:22:02 +0000 (23:22 -0700) | ||
committer | Junio C Hamano <junkio@cox.net> | |
Wed, 12 Oct 2005 05:05:09 +0000 (22:05 -0700) |
curl_escape ought to do this, but we should not let it quote
slashes (nobody said refs/tags cannot have subdirectories), so
we roll our own safer version. With this, the last part of
git-clone from Martin's moodle repository that used to fail now
works, which reads:
$ git-http-fetch -v -a -w 'tags/MOODLE_15_MERGED **INVALID**' \
'tags/MOODLE_15_MERGED **INVALID**' \
http://locke.catalyst.net.nz/git/moodle.git/
Signed-off-by: Junio C Hamano <junkio@cox.net>
slashes (nobody said refs/tags cannot have subdirectories), so
we roll our own safer version. With this, the last part of
git-clone from Martin's moodle repository that used to fail now
works, which reads:
$ git-http-fetch -v -a -w 'tags/MOODLE_15_MERGED **INVALID**' \
'tags/MOODLE_15_MERGED **INVALID**' \
http://locke.catalyst.net.nz/git/moodle.git/
Signed-off-by: Junio C Hamano <junkio@cox.net>
http-fetch.c | patch | blob | history |
diff --git a/http-fetch.c b/http-fetch.c
index e537591edb1853a62c4bc9d77c47bae5fce082e4..0aba8917548b3db9a43ce9802caa1c90176c70c1 100644 (file)
--- a/http-fetch.c
+++ b/http-fetch.c
alt->base);
}
+static inline int needs_quote(int ch)
+{
+ switch (ch) {
+ case '/': case '-': case '.':
+ case 'A'...'Z': case 'a'...'z': case '0'...'9':
+ return 0;
+ default:
+ return 1;
+ }
+}
+
+static inline int hex(int v)
+{
+ if (v < 10) return '0' + v;
+ else return 'A' + v - 10;
+}
+
+static char *quote_ref_url(const char *base, const char *ref)
+{
+ const char *cp;
+ char *dp, *qref;
+ int len, baselen, ch;
+
+ baselen = strlen(base);
+ len = baselen + 6; /* "refs/" + NUL */
+ for (cp = ref; (ch = *cp) != 0; cp++, len++)
+ if (needs_quote(ch))
+ len += 2; /* extra two hex plus replacement % */
+ qref = xmalloc(len);
+ memcpy(qref, base, baselen);
+ memcpy(qref + baselen, "refs/", 5);
+ for (cp = ref, dp = qref + baselen + 5; (ch = *cp) != 0; cp++) {
+ if (needs_quote(ch)) {
+ *dp++ = '%';
+ *dp++ = hex((ch >> 4) & 0xF);
+ *dp++ = hex(ch & 0xF);
+ }
+ else
+ *dp++ = ch;
+ }
+ *dp = 0;
+
+ return qref;
+}
+
int fetch_ref(char *ref, unsigned char *sha1)
{
- char *url, *posn;
+ char *url;
char hex[42];
struct buffer buffer;
char *base = alt->base;
buffer.buffer = hex;
hex[41] = '\0';
- url = xmalloc(strlen(base) + 6 + strlen(ref));
- strcpy(url, base);
- posn = url + strlen(base);
- strcpy(posn, "refs/");
- posn += 5;
- strcpy(posn, ref);
-
+ url = quote_ref_url(base, ref);
slot = get_active_slot();
curl_easy_setopt(slot->curl, CURLOPT_FILE, &buffer);
curl_easy_setopt(slot->curl, CURLOPT_WRITEFUNCTION, fwrite_buffer);