As a recovery tool, unpack-objects should go on unpacking as many objects as it can. Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@xxxxxxxxx> --- builtin/unpack-objects.c | 42 +++++++++++++++++++++++++++++++++++++++++- t/t1050-large.sh | 7 +++++++ 2 files changed, 48 insertions(+), 1 deletion(-) diff --git a/builtin/unpack-objects.c b/builtin/unpack-objects.c index 99cde45..8b5c67e 100644 --- a/builtin/unpack-objects.c +++ b/builtin/unpack-objects.c @@ -88,10 +88,50 @@ static void use(int bytes) consumed_bytes += bytes; } +static void inflate_and_throw_away(unsigned long size) +{ + git_zstream stream; + char buf[8192]; + + memset(&stream, 0, sizeof(stream)); + stream.next_out = (unsigned char *)buf; + stream.avail_out = sizeof(buf); + stream.next_in = fill(1); + stream.avail_in = len; + git_inflate_init(&stream); + + for (;;) { + int ret = git_inflate(&stream, 0); + use(len - stream.avail_in); + if (stream.total_out == size && ret == Z_STREAM_END) + break; + if (ret != Z_OK) { + error("inflate returned %d", ret); + if (!recover) + exit(1); + has_errors = 1; + break; + } + stream.next_out = (unsigned char *)buf; + stream.avail_out = sizeof(buf); + stream.next_in = fill(1); + stream.avail_in = len; + } + git_inflate_end(&stream); +} + static void *get_data(unsigned long size) { git_zstream stream; - void *buf = xmalloc(size); + void *buf = xmalloc_gentle(size); + + if (!buf) { + if (!recover) + exit(1); + has_errors = 1; + inflate_and_throw_away(size); + return NULL; + } memset(&stream, 0, sizeof(stream)); diff --git a/t/t1050-large.sh b/t/t1050-large.sh index 5642f84..eec2cca 100755 --- a/t/t1050-large.sh +++ b/t/t1050-large.sh @@ -169,4 +169,11 @@ test_expect_success 'fsck' ' test "$n" -gt 1 ' +test_expect_success 'unpack-objects' ' + P=`ls .git/objects/pack/*.pack` && + git unpack-objects -n -r <$P 2>err + test $? = 1 && + grep "error: attempting to allocate .* over limit" err +' + test_done -- 2.1.0.rc0.78.gc0d8480 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html