fsck: complain when .gitmodules is a symlink
We've recently forbidden .gitmodules to be a symlink in verify_path(). And it's an easy way to circumvent our fsck checks for .gitmodules content. So let's complain when we see it. Signed-off-by: Jeff King <peff@peff.net>
Jeff King committed
May 4, 2018 at 20:03 UTC
b7b1fca175f1ed7933f361028c631b9ac86d868d
2 files changed
+38
-2
fsck.c
+9
-2
@@ -63,6 +63,7 @@ static struct oidset gitmodules_done = OIDSET_INIT;
63
FUNC(GITMODULES_BLOB, ERROR) \
64
FUNC(GITMODULES_PARSE, ERROR) \
65
FUNC(GITMODULES_NAME, ERROR) \
66
+ FUNC(GITMODULES_SYMLINK, ERROR) \
67
/* warnings */ \
68
FUNC(BAD_FILEMODE, WARN) \
69
FUNC(EMPTY_NAME, WARN) \
@@ -576,8 +577,14 @@ static int fsck_tree(struct tree *item, struct fsck_options *options)
577
has_dotgit |= is_hfs_dotgit(name) || is_ntfs_dotgit(name);
578
has_zero_pad |= *(char *)desc.buffer == '0';
579
579
- if (is_hfs_dotgitmodules(name) || is_ntfs_dotgitmodules(name))
580
- oidset_insert(&gitmodules_found, oid);
580
+ if (is_hfs_dotgitmodules(name) || is_ntfs_dotgitmodules(name)) {
581
+ if (!S_ISLNK(mode))
582
+ oidset_insert(&gitmodules_found, oid);
583
+ else
584
+ retval += report(options, &item->object,
585
+ FSCK_MSG_GITMODULES_SYMLINK,
586
+ ".gitmodules is a symbolic link");
587
+ }
588
589
if (update_tree_entry_gently(&desc)) {
590
retval += report(options, &item->object, FSCK_MSG_BAD_TREE, "cannot be parsed as a tree");
t/t7415-submodule-names.sh
+29
@@ -122,4 +122,33 @@ test_expect_success 'transfer.fsckObjects handles odd pack (index)' '
122
test_must_fail git -C dst.git index-pack --strict --stdin <odd.pack
123
'
124
125
+test_expect_success 'fsck detects symlinked .gitmodules file' '
126
+ git init symlink &&
127
+ (
128
+ cd symlink &&
129
+
130
+ # Make the tree directly to avoid index restrictions.
131
+ #
132
+ # Because symlinks store the target as a blob, choose
133
+ # a pathname that could be parsed as a .gitmodules file
134
+ # to trick naive non-symlink-aware checking.
135
+ tricky="[foo]bar=true" &&
136
+ content=$(git hash-object -w ../.gitmodules) &&
137
+ target=$(printf "$tricky" | git hash-object -w --stdin) &&
138
+ tree=$(
139
+ {
140
+ printf "100644 blob $content\t$tricky\n" &&
141
+ printf "120000 blob $target\t.gitmodules\n"
142
+ } | git mktree
143
+ ) &&
144
+ commit=$(git commit-tree $tree) &&
145
+
146
+ # Check not only that we fail, but that it is due to the
147
+ # symlink detector; this grep string comes from the config
148
+ # variable name and will not be translated.
149
+ test_must_fail git fsck 2>output &&
150
+ grep gitmodulesSymlink output
151
+ )
152
+'
153
+
154
test_done