diff options
author | Jeff King <peff@peff.net> | 2014-12-04 20:28:54 -0500 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2014-12-05 11:11:35 -0800 |
commit | e5e73ff20b5a750b9622438fd877f4e4a4c3519b (patch) | |
tree | f64518215456c5ee2e0f2d02b92eec097668a5b5 /t/t1410-reflog.sh | |
parent | eeff891ac756fd97a05476446f15269b714ce4cc (diff) | |
download | git-e5e73ff20b5a750b9622438fd877f4e4a4c3519b.tar.gz |
for_each_reflog_ent_reverse: fix newlines on block boundaries
When we read a reflog file in reverse, we read whole chunks
of BUFSIZ bytes, then loop over the buffer, parsing any
lines we find. We find the beginning of each line by looking
for the newline from the previous line. If we don't find
one, we know that we are either at the beginning of
the file, or that we have to read another block.
In the latter case, we stuff away what we have into a
strbuf, read another block, and continue our parse. But we
missed one case here. If we did find a newline, and it is at
the beginning of the block, we must also stuff that newline
into the strbuf, as it belongs to the block we are about to
read.
The minimal fix here would be to add this special case to
the conditional that checks whether we found a newline.
But we can make the flow a little clearer by rearranging a
bit: we first handle lines that we are going to show, and
then at the end of each loop, stuff away any leftovers if
necessary. That lets us fold this special-case in with the
more common "we ended in the middle of a line" case.
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 't/t1410-reflog.sh')
-rwxr-xr-x | t/t1410-reflog.sh | 30 |
1 files changed, 30 insertions, 0 deletions
diff --git a/t/t1410-reflog.sh b/t/t1410-reflog.sh index 236b13a3ab..e582c0182b 100755 --- a/t/t1410-reflog.sh +++ b/t/t1410-reflog.sh @@ -245,4 +245,34 @@ test_expect_success 'gc.reflogexpire=false' ' ' +# Triggering the bug detected by this test requires a newline to fall +# exactly BUFSIZ-1 bytes from the end of the file. We don't know +# what that value is, since it's platform dependent. However, if +# we choose some value N, we also catch any D which divides N evenly +# (since we will read backwards in chunks of D). So we choose 8K, +# which catches glibc (with an 8K BUFSIZ) and *BSD (1K). +# +# Each line is 114 characters, so we need 75 to still have a few before the +# last 8K. The 89-character padding on the final entry lines up our +# newline exactly. +test_expect_success 'parsing reverse reflogs at BUFSIZ boundaries' ' + git checkout -b reflogskip && + z38=00000000000000000000000000000000000000 && + ident="abc <xyz> 0000000001 +0000" && + for i in $(test_seq 1 75); do + printf "$z38%02d $z38%02d %s\t" $i $(($i+1)) "$ident" && + if test $i = 75; then + for j in $(test_seq 1 89); do + printf X + done + else + printf X + fi && + printf "\n" + done >.git/logs/refs/heads/reflogskip && + git rev-parse reflogskip@{73} >actual && + echo ${z38}03 >expect && + test_cmp expect actual +' + test_done |