Skip to content

Commit 32521d5

Browse files
shejialuogitster
authored andcommitted
files-backend: add object check for regular ref
Although we use "parse_loose_ref_content" to check whether the object id is correct, we never parse it into the "struct object" structure thus we ignore checking whether there is a real object existing in the repo and whether the object type is correct. Use "parse_object" to parse the oid for the regular ref content. If the object does not exist, report the error to the user by reusing the fsck message "BAD_REF_CONTENT". Then, we need to check the type of the object. Just like "git-fsck(1)", we only report "not a commit" error when the ref is a branch. Last, update the test to exercise the code. Mentored-by: Patrick Steinhardt <[email protected]> Mentored-by: Karthik Nayak <[email protected]> Signed-off-by: shejialuo <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent e63e621 commit 32521d5

File tree

2 files changed

+70
-10
lines changed

2 files changed

+70
-10
lines changed

refs/files-backend.c

Lines changed: 40 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "../lockfile.h"
2222
#include "../object.h"
2323
#include "../object-file.h"
24+
#include "../packfile.h"
2425
#include "../path.h"
2526
#include "../dir.h"
2627
#include "../chdir-notify.h"
@@ -3638,6 +3639,34 @@ static int files_fsck_symref_target(struct fsck_options *o,
36383639
return ret;
36393640
}
36403641

3642+
static int files_fsck_refs_oid(struct fsck_options *o,
3643+
struct ref_store *ref_store,
3644+
struct fsck_ref_report report,
3645+
const char *target_name,
3646+
struct object_id *oid)
3647+
{
3648+
struct object *obj;
3649+
int ret = 0;
3650+
3651+
if (is_promisor_object(ref_store->repo, oid))
3652+
return 0;
3653+
3654+
obj = parse_object(ref_store->repo, oid);
3655+
if (!obj) {
3656+
ret |= fsck_report_ref(o, &report,
3657+
FSCK_MSG_BAD_REF_CONTENT,
3658+
"points to non-existing object %s",
3659+
oid_to_hex(oid));
3660+
} else if (obj->type != OBJ_COMMIT && is_branch(target_name)) {
3661+
ret |= fsck_report_ref(o, &report,
3662+
FSCK_MSG_BAD_REF_CONTENT,
3663+
"points to non-commit object %s",
3664+
oid_to_hex(oid));
3665+
}
3666+
3667+
return ret;
3668+
}
3669+
36413670
static int files_fsck_refs_content(struct ref_store *ref_store,
36423671
struct fsck_options *o,
36433672
const char *target_name,
@@ -3703,18 +3732,19 @@ static int files_fsck_refs_content(struct ref_store *ref_store,
37033732
}
37043733

37053734
if (!(type & REF_ISSYMREF)) {
3735+
ret |= files_fsck_refs_oid(o, ref_store, report, target_name, &oid);
3736+
37063737
if (!*trailing) {
3707-
ret = fsck_report_ref(o, &report,
3708-
FSCK_MSG_REF_MISSING_NEWLINE,
3709-
"misses LF at the end");
3710-
goto cleanup;
3711-
}
3712-
if (*trailing != '\n' || *(trailing + 1)) {
3713-
ret = fsck_report_ref(o, &report,
3714-
FSCK_MSG_TRAILING_REF_CONTENT,
3715-
"has trailing garbage: '%s'", trailing);
3716-
goto cleanup;
3738+
ret |= fsck_report_ref(o, &report,
3739+
FSCK_MSG_REF_MISSING_NEWLINE,
3740+
"misses LF at the end");
3741+
} else if (*trailing != '\n' || *(trailing + 1)) {
3742+
ret |= fsck_report_ref(o, &report,
3743+
FSCK_MSG_TRAILING_REF_CONTENT,
3744+
"has trailing garbage: '%s'", trailing);
37173745
}
3746+
3747+
goto cleanup;
37183748
} else {
37193749
ret = files_fsck_symref_target(o, &report, &referent, 0);
37203750
goto cleanup;

t/t0602-reffiles-fsck.sh

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,8 +161,10 @@ test_expect_success 'regular ref content should be checked (individual)' '
161161
test_when_finished "rm -rf repo" &&
162162
git init repo &&
163163
branch_dir_prefix=.git/refs/heads &&
164+
tag_dir_prefix=.git/refs/tags &&
164165
cd repo &&
165166
test_commit default &&
167+
git branch branch-1 &&
166168
mkdir -p "$branch_dir_prefix/a/b" &&
167169
168170
git refs verify 2>err &&
@@ -198,6 +200,28 @@ test_expect_success 'regular ref content should be checked (individual)' '
198200
rm $branch_dir_prefix/branch-no-newline &&
199201
test_cmp expect err &&
200202
203+
for non_existing_oid in "$(test_oid 001)" "$(test_oid 002)"
204+
do
205+
printf "%s\n" $non_existing_oid >$branch_dir_prefix/invalid-commit &&
206+
test_must_fail git refs verify 2>err &&
207+
cat >expect <<-EOF &&
208+
error: refs/heads/invalid-commit: badRefContent: points to non-existing object $non_existing_oid
209+
EOF
210+
rm $branch_dir_prefix/invalid-commit &&
211+
test_cmp expect err || return 1
212+
done &&
213+
214+
for tree_oid in "$(git rev-parse main^{tree})" "$(git rev-parse branch-1^{tree})"
215+
do
216+
printf "%s\n" $tree_oid >$branch_dir_prefix/branch-tree &&
217+
test_must_fail git refs verify 2>err &&
218+
cat >expect <<-EOF &&
219+
error: refs/heads/branch-tree: badRefContent: points to non-commit object $tree_oid
220+
EOF
221+
rm $branch_dir_prefix/branch-tree &&
222+
test_cmp expect err || return 1
223+
done &&
224+
201225
for trailing_content in " garbage" " more garbage"
202226
do
203227
printf "%s" "$(git rev-parse main)$trailing_content" >$branch_dir_prefix/branch-garbage &&
@@ -244,15 +268,21 @@ test_expect_success 'regular ref content should be checked (aggregate)' '
244268
bad_content_1=$(git rev-parse main)x &&
245269
bad_content_2=xfsazqfxcadas &&
246270
bad_content_3=Xfsazqfxcadas &&
271+
non_existing_oid=$(test_oid 001) &&
272+
tree_oid=$(git rev-parse main^{tree}) &&
247273
printf "%s" $bad_content_1 >$tag_dir_prefix/tag-bad-1 &&
248274
printf "%s" $bad_content_2 >$tag_dir_prefix/tag-bad-2 &&
249275
printf "%s" $bad_content_3 >$branch_dir_prefix/a/b/branch-bad &&
250276
printf "%s" "$(git rev-parse main)" >$branch_dir_prefix/branch-no-newline &&
251277
printf "%s garbage" "$(git rev-parse main)" >$branch_dir_prefix/branch-garbage &&
278+
printf "%s\n" $non_existing_oid >$branch_dir_prefix/branch-non-existing-oid &&
279+
printf "%s\n" $tree_oid >$branch_dir_prefix/branch-tree &&
252280
253281
test_must_fail git refs verify 2>err &&
254282
cat >expect <<-EOF &&
255283
error: refs/heads/a/b/branch-bad: badRefContent: $bad_content_3
284+
error: refs/heads/branch-non-existing-oid: badRefContent: points to non-existing object $non_existing_oid
285+
error: refs/heads/branch-tree: badRefContent: points to non-commit object $tree_oid
256286
error: refs/tags/tag-bad-1: badRefContent: $bad_content_1
257287
error: refs/tags/tag-bad-2: badRefContent: $bad_content_2
258288
warning: refs/heads/branch-garbage: trailingRefContent: has trailing garbage: '\'' garbage'\''

0 commit comments

Comments
 (0)