diff options
author | Sergey Vlasov <vsu@altlinux.ru> | 2005-10-13 10:49:53 -0700 |
---|---|---|
committer | Junio C Hamano <junkio@cox.net> | 2005-10-14 17:15:46 -0700 |
commit | bc8f26527064e8bd9123c293741a0a3762b8a64e (patch) | |
tree | 172a73d9554dde5d350f3d9504250a0aba5933fb /http-fetch.c | |
parent | e70ec8632ca0968e4738a66235361937eb4162a9 (diff) | |
download | git-bc8f26527064e8bd9123c293741a0a3762b8a64e.tar.gz git-bc8f26527064e8bd9123c293741a0a3762b8a64e.tar.xz |
git-http-fetch: Remove size limit for objects/info/{packs,alternates}
git-http-fetch received objects/info/packs into a fixed-size buffer
and started to fail when this file became larger than the buffer.
Change it to grow the buffer dynamically, and do the same thing for
objects/info/alternates. Also add missing free() calls for these
buffers.
Signed-off-by: Sergey Vlasov <vsu@altlinux.ru>
Signed-off-by: Junio C Hamano <junkio@cox.net>
Diffstat (limited to 'http-fetch.c')
-rw-r--r-- | http-fetch.c | 43 |
1 files changed, 36 insertions, 7 deletions
diff --git a/http-fetch.c b/http-fetch.c index 0aba89175..c6daf6a01 100644 --- a/http-fetch.c +++ b/http-fetch.c @@ -110,6 +110,22 @@ static size_t fwrite_buffer(void *ptr, size_t eltsize, size_t nmemb, return size; } +static size_t fwrite_buffer_dynamic(const void *ptr, size_t eltsize, + size_t nmemb, struct buffer *buffer) +{ + size_t size = eltsize * nmemb; + if (size > buffer->size - buffer->posn) { + buffer->size = buffer->size * 3 / 2; + if (buffer->size < buffer->posn + size) + buffer->size = buffer->posn + size; + buffer->buffer = xrealloc(buffer->buffer, buffer->size); + } + memcpy(buffer->buffer + buffer->posn, ptr, size); + buffer->posn += size; + data_received++; + return size; +} + static size_t fwrite_sha1_file(void *ptr, size_t eltsize, size_t nmemb, void *data) { @@ -618,11 +634,12 @@ static int fetch_alternates(char *base) int i = 0; int http_specific = 1; struct alt_base *tail = alt; + static const char null_byte = '\0'; struct active_request_slot *slot; data = xmalloc(4096); - buffer.size = 4095; + buffer.size = 4096; buffer.posn = 0; buffer.buffer = data; @@ -634,7 +651,8 @@ static int fetch_alternates(char *base) slot = get_active_slot(); curl_easy_setopt(slot->curl, CURLOPT_FILE, &buffer); - curl_easy_setopt(slot->curl, CURLOPT_WRITEFUNCTION, fwrite_buffer); + curl_easy_setopt(slot->curl, CURLOPT_WRITEFUNCTION, + fwrite_buffer_dynamic); curl_easy_setopt(slot->curl, CURLOPT_URL, url); if (start_active_slot(slot)) { run_active_slot(slot); @@ -646,20 +664,24 @@ static int fetch_alternates(char *base) slot = get_active_slot(); curl_easy_setopt(slot->curl, CURLOPT_FILE, &buffer); curl_easy_setopt(slot->curl, CURLOPT_WRITEFUNCTION, - fwrite_buffer); + fwrite_buffer_dynamic); curl_easy_setopt(slot->curl, CURLOPT_URL, url); if (start_active_slot(slot)) { run_active_slot(slot); if (slot->curl_result != CURLE_OK) { + free(buffer.buffer); return 0; } } } } else { + free(buffer.buffer); return 0; } - data[buffer.posn] = '\0'; + fwrite_buffer_dynamic(&null_byte, 1, 1, &buffer); + buffer.posn--; + data = buffer.buffer; while (i < buffer.posn) { int posn = i; @@ -718,7 +740,8 @@ static int fetch_alternates(char *base) } i = posn + 1; } - + + free(buffer.buffer); return ret; } @@ -748,17 +771,22 @@ static int fetch_indices(struct alt_base *repo) slot = get_active_slot(); curl_easy_setopt(slot->curl, CURLOPT_FILE, &buffer); - curl_easy_setopt(slot->curl, CURLOPT_WRITEFUNCTION, fwrite_buffer); + curl_easy_setopt(slot->curl, CURLOPT_WRITEFUNCTION, + fwrite_buffer_dynamic); curl_easy_setopt(slot->curl, CURLOPT_URL, url); curl_easy_setopt(slot->curl, CURLOPT_HTTPHEADER, NULL); if (start_active_slot(slot)) { run_active_slot(slot); - if (slot->curl_result != CURLE_OK) + if (slot->curl_result != CURLE_OK) { + free(buffer.buffer); return error("%s", curl_errorstr); + } } else { + free(buffer.buffer); return error("Unable to start request"); } + data = buffer.buffer; while (i < buffer.posn) { switch (data[i]) { case 'P': @@ -778,6 +806,7 @@ static int fetch_indices(struct alt_base *repo) i++; } + free(buffer.buffer); repo->got_indices = 1; return 0; } |