Re: Bug in reflog of length 0x2BFF

3 messages, 3 authors, 2016-06-15 · open the first message on its own page

Re: Bug in reflog of length 0x2BFF

From: Junio C Hamano <hidden>
Date: 2016-06-15 23:03:12

Jonathan Nieder [off-list ref] writes:
Christoph Mallon wrote:
quoted
% git rev-parse 'master@{52}'
warning: Log for ref refs/heads/master has gap after Thu, 1 Jan 1970 00:00:01 +0000.
0000000000000000000000000000000000000036
Can you say more?  What output did you expect and how does this differ
from it?

I tried, with git 2.2.0,

	git init gitbug &&
	cd gitbug &&
	git commit --allow-empty -m a &&
	wget http://tron.yamagi.org/zeug/reflog.bad &&
	mv reflog.bad .git/logs/refs/heads/master &&
	sha1sum .git/logs/refs/heads/master &&
	git rev-parse 'master@{52}'

The output:

 9ffe44715d0e542a60916255f144c74e6760ffd0  .git/logs/refs/heads/master
 0000000000000000000000000000000000000035

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.

Re: Bug in reflog of length 0x2BFF

From: Christoph Mallon <hidden>
Date: 2016-06-15 23:03:12

Am 04.12.14 21:18, schrieb Junio C Hamano:
Jonathan Nieder [off-list ref] writes:
quoted
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.
I already sent a test-patch, here it is again:
	http://tron.yamagi.org/zeug/0001-t1410-Test-erroneous-skipping-of-reflog-entries.patch
Using this test, bisect reliably gives
	4207ed285f31ad3e04f08254237c0c1a1609642b
as culprit.
It seems that Linux does not exhibit this particular behaviour.
Maybe there are differences in memory allocation, which mask the symptom.
Stefan Beller experienced some other sporadic bug regarding the reflog:
	http://marc.info/?l=git&m=141748434801505&w=2

Re: Bug in reflog of length 0x2BFF

From: Jeff King <hidden>
Date: 2016-06-15 23:03:12

On Thu, Dec 04, 2014 at 09:37:34PM +0100, Christoph Mallon wrote:
Am 04.12.14 21:18, schrieb Junio C Hamano:
quoted
Jonathan Nieder [off-list ref] writes:
quoted
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
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help