diff options
-rw-r--r-- | sha1_file.c | 3 | ||||
-rwxr-xr-x | t/t1450-fsck.sh | 19 |
2 files changed, 21 insertions, 1 deletions
diff --git a/sha1_file.c b/sha1_file.c index d77b915db6..7d016184a3 100644 --- a/sha1_file.c +++ b/sha1_file.c @@ -3847,7 +3847,8 @@ static int check_stream_sha1(git_zstream *stream, * see the comment in unpack_sha1_rest for details. */ while (total_read <= size && - (status == Z_OK || status == Z_BUF_ERROR)) { + (status == Z_OK || + (status == Z_BUF_ERROR && !stream->avail_out))) { stream->next_out = buf; stream->avail_out = sizeof(buf); if (size - total_read < stream->avail_out) diff --git a/t/t1450-fsck.sh b/t/t1450-fsck.sh index 770d68e44e..1f245bbc5f 100755 --- a/t/t1450-fsck.sh +++ b/t/t1450-fsck.sh @@ -646,6 +646,25 @@ test_expect_success 'fsck detects trailing loose garbage (large blob)' ' test_i18ngrep "garbage.*$blob" out ' +test_expect_success 'fsck detects truncated loose object' ' + # make it big enough that we know we will truncate in the data + # portion, not the header + test-genrandom truncate 4096 >file && + blob=$(git hash-object -w file) && + file=$(sha1_file $blob) && + test_when_finished "remove_object $blob" && + test_copy_bytes 1024 <"$file" >tmp && + rm "$file" && + mv -f tmp "$file" && + + # check both regular and streaming code paths + test_must_fail git fsck 2>out && + test_i18ngrep corrupt.*$blob out && + + test_must_fail git -c core.bigfilethreshold=128 fsck 2>out && + test_i18ngrep corrupt.*$blob out +' + # for each of type, we have one version which is referenced by another object # (and so while unreachable, not dangling), and another variant which really is # dangling. |