git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: Bug in reflog of length 0x2BFF

From
Jeff King <peff@peff.net>
Date
Dec 4, 2014, 21:58 UTC
Message-ID
<20141204215805.GD19953@peff.net>
In-Reply-To
<5480C60E.3070903@cs.uni-saarland.de>
On Thu, Dec 04, 2014 at 09:37:34PM +0100, Christoph Mallon wrote:
Show 17 quoted lines
> Am 04.12.14 21:18, schrieb Junio C Hamano:
> > Jonathan Nieder <jrnieder@gmail.com> writes:
> >> Could you make a test script that illustrates and reproduces the
> >> problem?  I.e., a patch to a file like t/t1410-reflog.sh, such that
> >> if I run
> >>
> >> 	cd git
> >> 	make
> >> 	cd t
> >> 	./t1410-reflog.sh
> >>
> >> then I can reproduce the bug?
> > 
> > Amen to that.  I am getting the same thing.
> 
> I ran reproduce it reliably on multiple machines (OS X, FreeBSD, ia32,
> amd64), a friend of mine can, too.
Thanks, I was able to reproduce this easily on an OS X machine.
Does this patch fix your problem?
diff --git a/refs.c b/refs.c
index f1afec5..42e3a30 100644
--- a/refs.c
+++ b/refs.c
@@ -3052,7 +3052,7 @@ static int show_one_reflog_ent(struct strbuf *sb, each_reflog_ent_fn fn, void *c
 	int tz;
 
 	/* old SP new SP name <email> SP time TAB msg LF */
-	if (sb->len < 83 || sb->buf[sb->len - 1] != '\n' ||
+	if (sb->len < 83 ||
 	    get_sha1_hex(sb->buf, osha1) || sb->buf[40] != ' ' ||
 	    get_sha1_hex(sb->buf + 41, nsha1) || sb->buf[81] != ' ' ||
 	    !(email_end = strchr(sb->buf + 82, '>')) ||


I think the bug is in the reverse-reflog reader in
for_each_reflog_ent_reverse. It reads BUFSIZ chunks of the file in
reverse order, and then parses them individually. If the trailing
newline for a line falls directly on the block boundary, we may not have
it in our current block, and pass the line to show_one_reflog_ent
without a trailing newline. That function is picky about making sure it
got a full line.

So this is a long-standing bug in for_each_reflog_ent_reverse. It just
showed up recently because we started using that function for
read_ref_at_ent.

I haven't confirmed yet, but I suspect the problem shows up on OS X and
FreeBSD but not Linux because of the definition of BUFSIZ (so it is
really probably glibc versus BSD libc). The same bug exists on Linux,
but you would need different input to stimulate the newline at the right
spot.

The above is a workaround. I think the right solution is probably to
teach for_each_reflog_ent_reverse to makes sure the trailing newline is
included (either by tweaking the reverse code, or conditionally adding
it to the parsed buffer).

-Peff
Previous: Christoph MallonNext: Junio C Hamano
Message 10 of 15 in “Bug in reflog of length 0x2BFF”
  1. Christoph MallonDec 1, 2014
  2. Christoph MallonDec 1, 2014
  3. Stefan BellerDec 1, 2014
  4. Christoph MallonDec 1, 2014
  5. Jonathan NiederDec 1, 2014
  6. Stefan BellerDec 2, 2014
  7. Christoph MallonDec 2, 2014
  8. Junio C HamanoDec 4, 2014
  9. Christoph MallonDec 4, 2014
  10. Jeff KingDec 4, 2014
  11. Junio C HamanoDec 4, 2014
  12. for_each_reflog_ent_reverse: fix newlines on block boundariesJeff King, Dec 5, 2014
  13. for_each_reflog_ent_reverse: turn leftover check into assertionJeff King, Dec 5, 2014
  14. Junio C HamanoDec 5, 2014
  15. Junio C HamanoDec 4, 2014

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.