diff options
author | Junio C Hamano <gitster@pobox.com> | 2014-12-22 12:28:02 -0800 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2014-12-22 12:28:02 -0800 |
commit | 8ada1d8e9c71eeebaf6af3adc664a17479f2c2e8 (patch) | |
tree | 3f0604c93636fdd6b2ac39bf24aa414a17f3c841 | |
parent | 3dadfc7e173e27db641291d8f049ab487b696704 (diff) | |
parent | 8e9faf27c11d515b2eef526f2a15c1c2a4ac8d4e (diff) | |
download | git-8ada1d8e9c71eeebaf6af3adc664a17479f2c2e8.tar.gz git-8ada1d8e9c71eeebaf6af3adc664a17479f2c2e8.tar.xz |
Merge branch 'jk/always-allow-large-packets'
"git push" and "git fetch" did not communicate an overlong refname
correctly.
* jk/always-allow-large-packets:
pkt-line: allow writing of LARGE_PACKET_MAX buffers
-rw-r--r-- | pkt-line.c | 37 | ||||
-rwxr-xr-x | t/t5527-fetch-odd-refs.sh | 33 |
2 files changed, 52 insertions, 18 deletions
diff --git a/pkt-line.c b/pkt-line.c index 8bc89b1e0..187a2293e 100644 --- a/pkt-line.c +++ b/pkt-line.c @@ -64,44 +64,45 @@ void packet_buf_flush(struct strbuf *buf) } #define hex(a) (hexchar[(a) & 15]) -static char buffer[1000]; -static unsigned format_packet(const char *fmt, va_list args) +static void format_packet(struct strbuf *out, const char *fmt, va_list args) { static char hexchar[] = "0123456789abcdef"; - unsigned n; + size_t orig_len, n; - n = vsnprintf(buffer + 4, sizeof(buffer) - 4, fmt, args); - if (n >= sizeof(buffer)-4) + orig_len = out->len; + strbuf_addstr(out, "0000"); + strbuf_vaddf(out, fmt, args); + n = out->len - orig_len; + + if (n > LARGE_PACKET_MAX) die("protocol error: impossibly long line"); - n += 4; - buffer[0] = hex(n >> 12); - buffer[1] = hex(n >> 8); - buffer[2] = hex(n >> 4); - buffer[3] = hex(n); - packet_trace(buffer+4, n-4, 1); - return n; + + out->buf[orig_len + 0] = hex(n >> 12); + out->buf[orig_len + 1] = hex(n >> 8); + out->buf[orig_len + 2] = hex(n >> 4); + out->buf[orig_len + 3] = hex(n); + packet_trace(out->buf + orig_len + 4, n - 4, 1); } void packet_write(int fd, const char *fmt, ...) { + static struct strbuf buf = STRBUF_INIT; va_list args; - unsigned n; + strbuf_reset(&buf); va_start(args, fmt); - n = format_packet(fmt, args); + format_packet(&buf, fmt, args); va_end(args); - write_or_die(fd, buffer, n); + write_or_die(fd, buf.buf, buf.len); } void packet_buf_write(struct strbuf *buf, const char *fmt, ...) { va_list args; - unsigned n; va_start(args, fmt); - n = format_packet(fmt, args); + format_packet(buf, fmt, args); va_end(args); - strbuf_add(buf, buffer, n); } static int get_packet_data(int fd, char **src_buf, size_t *src_size, diff --git a/t/t5527-fetch-odd-refs.sh b/t/t5527-fetch-odd-refs.sh index edea9f957..207899a99 100755 --- a/t/t5527-fetch-odd-refs.sh +++ b/t/t5527-fetch-odd-refs.sh @@ -26,4 +26,37 @@ test_expect_success 'suffix ref is ignored during fetch' ' test_cmp expect actual ' +test_expect_success 'try to create repo with absurdly long refname' ' + ref240=$_z40/$_z40/$_z40/$_z40/$_z40/$_z40 && + ref1440=$ref240/$ref240/$ref240/$ref240/$ref240/$ref240 && + git init long && + ( + cd long && + test_commit long && + test_commit master + ) && + if git -C long update-ref refs/heads/$ref1440 long; then + test_set_prereq LONG_REF + else + echo >&2 "long refs not supported" + fi +' + +test_expect_success LONG_REF 'fetch handles extremely long refname' ' + git fetch long refs/heads/*:refs/remotes/long/* && + cat >expect <<-\EOF && + long + master + EOF + git for-each-ref --format="%(subject)" refs/remotes/long >actual && + test_cmp expect actual +' + +test_expect_success LONG_REF 'push handles extremely long refname' ' + git push long :refs/heads/$ref1440 && + git -C long for-each-ref --format="%(subject)" refs/heads >actual && + echo master >expect && + test_cmp expect actual +' + test_done |