fsck: detect trailing garbage in all object types
authorJeff King <peff@peff.net>
Fri, 13 Jan 2017 18:00:25 +0000 (13:00 -0500)
committerJunio C Hamano <gitster@pobox.com>
Sun, 15 Jan 2017 23:59:03 +0000 (15:59 -0800)
When a loose tree or commit is read by fsck (or any git
program), unpack_sha1_rest() checks whether there is extra
cruft at the end of the object file, after the zlib data.
Blobs that are streamed, however, do not have this check.

For normal git operations, it's not a big deal. We know the
sha1 and size checked out, so we have the object bytes we
wanted. The trailing garbage doesn't affect what we're
trying to do.

But since the point of fsck is to find corruption or other
problems, it should be more thorough. This patch teaches its
loose-sha1 reader to detect extra bytes after the zlib
stream and complain.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
sha1_file.c
t/t1450-fsck.sh
index ca1c90e5d33785d980f8e053089cf98970bb1b44..b2c66480852c458f79f794a47de7d76c854097a0 100644 (file)
@@ -3847,6 +3847,11 @@ static int check_stream_sha1(git_zstream *stream,
                error("corrupt loose object '%s'", sha1_to_hex(expected_sha1));
                return -1;
        }
                error("corrupt loose object '%s'", sha1_to_hex(expected_sha1));
                return -1;
        }
+       if (stream->avail_in) {
+               error("garbage at end of loose object '%s'",
+                     sha1_to_hex(expected_sha1));
+               return -1;
+       }
 
        git_SHA1_Final(real_sha1, &c);
        if (hashcmp(expected_sha1, real_sha1)) {
 
        git_SHA1_Final(real_sha1, &c);
        if (hashcmp(expected_sha1, real_sha1)) {
index 455c186fe27d66fba76682d90cfdd9881ceb2a3f..8975b4d1bcc4675be4d1869783ee4b7cc17c750f 100755 (executable)
@@ -597,4 +597,26 @@ test_expect_success 'fsck finds problems in duplicate loose objects' '
        )
 '
 
        )
 '
 
+test_expect_success 'fsck detects trailing loose garbage (commit)' '
+       git cat-file commit HEAD >basis &&
+       echo bump-commit-sha1 >>basis &&
+       commit=$(git hash-object -w -t commit basis) &&
+       file=$(sha1_file $commit) &&
+       test_when_finished "remove_object $commit" &&
+       chmod +w "$file" &&
+       echo garbage >>"$file" &&
+       test_must_fail git fsck 2>out &&
+       test_i18ngrep "garbage.*$commit" out
+'
+
+test_expect_success 'fsck detects trailing loose garbage (blob)' '
+       blob=$(echo trailing | git hash-object -w --stdin) &&
+       file=$(sha1_file $blob) &&
+       test_when_finished "remove_object $blob" &&
+       chmod +w "$file" &&
+       echo garbage >>"$file" &&
+       test_must_fail git fsck 2>out &&
+       test_i18ngrep "garbage.*$blob" out
+'
+
 test_done
 test_done