Quote reference names while fetching with curl.

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>
This commit is contained in:
Junio C Hamano 2005-10-10 23:22:02 -07:00
parent d06b689a93
commit 94fa447ace

View File

@ -969,9 +969,54 @@ int fetch(unsigned char *sha1)
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;
@ -981,13 +1026,7 @@ int fetch_ref(char *ref, unsigned char *sha1)
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);