fsck: detect and warn a commit with embedded NUL
Even though a Git commit object is designed to be capable of storing any binary data as its payload, in practice people use it to describe the changes in textual form, and tools like "git log" are designed to treat the payload as text. Detect and warn when we see any commit object with a NUL byte in it. Note that a NUL byte in the header part is already detected as a grave error. This change is purely about the message part. Signed-off-by: Junio C Hamano <gitster@pobox.com>
Junio C Hamano committed
Apr 14, 2016 at 10:58 UTC
6d2d780f6359df424a625a51f09da80ab6dc1ef8
2 files changed
+26
fsck.c
+8
@@ -59,6 +59,7 @@
59
FUNC(HAS_DOTGIT, WARN) \
60
FUNC(NULL_SHA1, WARN) \
61
FUNC(ZERO_PADDED_FILEMODE, WARN) \
62
+ FUNC(NUL_IN_COMMIT, WARN) \
63
/* infos (reported as warnings, but ignored by default) */ \
64
FUNC(BAD_TAG_NAME, INFO) \
65
FUNC(MISSING_TAGGER_ENTRY, INFO)
@@ -610,6 +611,7 @@ static int fsck_commit_buffer(struct commit *commit, const char *buffer,
611
struct commit_graft *graft;
612
unsigned parent_count, parent_line_count = 0, author_count;
613
int err;
614
+ const char *buffer_begin = buffer;
615
616
if (verify_headers(buffer, size, &commit->object, options))
617
return -1;
@@ -671,6 +673,12 @@ static int fsck_commit_buffer(struct commit *commit, const char *buffer,
673
if (err)
674
return err;
675
}
676
+ if (memchr(buffer_begin, '\0', size)) {
677
+ err = report(options, &commit->object, FSCK_MSG_NUL_IN_COMMIT,
678
+ "NUL byte in the commit object body");
679
+ if (err)
680
+ return err;
681
+ }
682
return 0;
683
}
684
t/t1450-fsck.sh
+18
@@ -427,6 +427,24 @@ test_expect_success 'fsck allows .Ňit' '
427
)
428
'
429
430
+test_expect_success 'NUL in commit' '
431
+ rm -fr nul-in-commit &&
432
+ git init nul-in-commit &&
433
+ (
434
+ cd nul-in-commit &&
435
+ git commit --allow-empty -m "initial commitQNUL after message" &&
436
+ git cat-file commit HEAD >original &&
437
+ q_to_nul <original >munged &&
438
+ git hash-object -w -t commit --stdin <munged >name &&
439
+ git branch bad $(cat name) &&
440
+
441
+ test_must_fail git -c fsck.nulInCommit=error fsck 2>warn.1 &&
442
+ grep nulInCommit warn.1 &&
443
+ git fsck 2>warn.2 &&
444
+ grep nulInCommit warn.2
445
+ )
446
+'
447
+
448
# create a static test repo which is broken by omitting
449
# one particular object ($1, which is looked up via rev-parse
450
# in the new repository).