From: Junio C Hamano <gitster@pobox.com>
To: Jeff King <peff@peff.net>
Cc: "Nguyễn Thái Ngọc Duy" <pclouds@gmail.com>, git@vger.kernel.org
Subject: Re: [BUG] serious inflate inconsistency on master
Date: Tue, 03 Jul 2012 15:40:07 -0700 [thread overview]
Message-ID: <7vipe4tqns.fsf@alter.siamese.dyndns.org> (raw)
In-Reply-To: <20120703221900.GA28897@sigill.intra.peff.net> (Jeff King's message of "Tue, 3 Jul 2012 18:19:01 -0400")
Jeff King <peff@peff.net> writes:
> The problem seems to be in index-pack.c:unpack_data, which does this:
>
>> git_inflate_init(&stream);
>> stream.next_out = data;
>> stream.avail_out = consume ? 64*1024 : obj->size;
>>
>> do {
>> unsigned char *last_out = stream.next_out;
>> ssize_t n = (len < 64*1024) ? len : 64*1024;
>> n = pread(pack_fd, inbuf, n, from);
>> if (n < 0)
>> die_errno(_("cannot pread pack file"));
>> if (!n)
>> die(Q_("premature end of pack file, %lu byte missing",
>> "premature end of pack file, %lu bytes missing",
>> len),
>> len);
>> from += n;
>> len -= n;
>> stream.next_in = inbuf;
>> stream.avail_in = n;
>> status = git_inflate(&stream, 0);
>> if (consume) {
>> if (consume(last_out, stream.next_out - last_out, cb_data)) {
>> free(inbuf);
>> free(data);
>> return NULL;
>> }
>> stream.next_out = data;
>> stream.avail_out = 64*1024;
>> }
>> } while (len && status == Z_OK && !stream.avail_in);
>>
>> /* This has been inflated OK when first encountered, so... */
>> if (status != Z_STREAM_END || stream.total_out != obj->size)
>> die(_("serious inflate inconsistency"));
Yeah, that "if (consume)" part is clearly bogus. It should feed
what it read in "inbuf" fully to git_inflate() in a (missing) inner
loop and keep feeding consume() with the inflated data, but instead
happily goes on to read more from the packfile once the initial part
of the inflated data is fed to consume, ignoring the remainder.
> So I don't really understand what this !stream.avail_in is doing there
> in the do-while loop. Don't we instead need to have an inner loop that
> keeps feeding the result of pread into git_inflate until we don't have
> any available data left?
Exactly. I do not think the avain_in check should be done at the
end of the outer loop at all. When we are buffering the entire
inflated data in core without using consume, we allocate enough
memory to "data" to hold the whole thing, so in that case, it may be
OK to expect that git_inflate() would never return without consuming
the input bytes (i.e. stream.avail_in would always be zero at the
site of the check), but with consume(), we give small piece of
memory as a temporary output area and call git_inflate(), and it is
entirely possible and normal for it to run out of output before
inflating all the input bytes.
next prev parent reply other threads:[~2012-07-03 22:40 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-07-03 22:19 [BUG] serious inflate inconsistency on master Jeff King
2012-07-03 22:40 ` Junio C Hamano [this message]
2012-07-04 5:35 ` Nguyen Thai Ngoc Duy
2012-07-04 6:31 ` Junio C Hamano
2012-07-04 7:01 ` Nguyen Thai Ngoc Duy
2012-07-04 7:24 ` Jeff King
2012-07-04 7:12 ` Jeff King
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=7vipe4tqns.fsf@alter.siamese.dyndns.org \
--to=gitster@pobox.com \
--cc=git@vger.kernel.org \
--cc=pclouds@gmail.com \
--cc=peff@peff.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).