Skip to content

Commit 3c966c7

Browse files
hanwengitster
authored andcommitted
refs: introduce REF_SKIP_REFNAME_VERIFICATION flag
Use this flag with the test-helper in t1430, to avoid direct writes to the ref database. Signed-off-by: Han-Wen Nienhuys <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent e9706a1 commit 3c966c7

File tree

4 files changed

+45
-32
lines changed

4 files changed

+45
-32
lines changed

refs.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1083,9 +1083,10 @@ int ref_transaction_update(struct ref_transaction *transaction,
10831083
{
10841084
assert(err);
10851085

1086-
if ((new_oid && !is_null_oid(new_oid)) ?
1087-
check_refname_format(refname, REFNAME_ALLOW_ONELEVEL) :
1088-
!refname_is_safe(refname)) {
1086+
if (!(flags & REF_SKIP_REFNAME_VERIFICATION) &&
1087+
((new_oid && !is_null_oid(new_oid)) ?
1088+
check_refname_format(refname, REFNAME_ALLOW_ONELEVEL) :
1089+
!refname_is_safe(refname))) {
10891090
strbuf_addf(err, _("refusing to update ref with bad name '%s'"),
10901091
refname);
10911092
return -1;

refs.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -621,12 +621,18 @@ struct ref_transaction *ref_transaction_begin(struct strbuf *err);
621621
*/
622622
#define REF_SKIP_OID_VERIFICATION (1 << 10)
623623

624+
/*
625+
* Skip verifying refname. This is useful for testing data corruption scenarios.
626+
*/
627+
#define REF_SKIP_REFNAME_VERIFICATION (1 << 11)
628+
624629
/*
625630
* Bitmask of all of the flags that are allowed to be passed in to
626631
* ref_transaction_update() and friends:
627632
*/
628-
#define REF_TRANSACTION_UPDATE_ALLOWED_FLAGS \
629-
(REF_NO_DEREF | REF_FORCE_CREATE_REFLOG | REF_SKIP_OID_VERIFICATION)
633+
#define REF_TRANSACTION_UPDATE_ALLOWED_FLAGS \
634+
(REF_NO_DEREF | REF_FORCE_CREATE_REFLOG | REF_SKIP_OID_VERIFICATION | \
635+
REF_SKIP_REFNAME_VERIFICATION)
630636

631637
/*
632638
* Add a reference update to transaction. `new_oid` is the value that

t/helper/test-ref-store.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@ static struct flag_definition transaction_flags[] = {
131131
FLAG_DEF(REF_NO_DEREF),
132132
FLAG_DEF(REF_FORCE_CREATE_REFLOG),
133133
FLAG_DEF(REF_SKIP_OID_VERIFICATION),
134+
FLAG_DEF(REF_SKIP_REFNAME_VERIFICATION),
134135
{ NULL, 0 }
135136
};
136137

t/t1430-bad-ref-name.sh

Lines changed: 32 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ TEST_PASSES_SANITIZE_LEAK=true
99

1010
test_expect_success setup '
1111
test_commit one &&
12-
test_commit two
12+
test_commit two &&
13+
main_sha1=$(git rev-parse refs/heads/main)
1314
'
1415

1516
test_expect_success 'fast-import: fail on invalid branch name ".badbranchname"' '
@@ -43,25 +44,25 @@ test_expect_success 'fast-import: fail on invalid branch name "bad[branch]name"'
4344
'
4445

4546
test_expect_success 'git branch shows badly named ref as warning' '
46-
cp .git/refs/heads/main .git/refs/heads/broken...ref &&
47-
test_when_finished "rm -f .git/refs/heads/broken...ref" &&
47+
test-tool ref-store main update-ref msg "refs/heads/broken...ref" $main_sha1 $ZERO_OID REF_SKIP_REFNAME_VERIFICATION &&
48+
test_when_finished "test-tool ref-store main delete-refs REF_NO_DEREF msg refs/heads/broken...ref" &&
4849
git branch >output 2>error &&
4950
test_i18ngrep -e "ignoring ref with broken name refs/heads/broken\.\.\.ref" error &&
5051
! grep -e "broken\.\.\.ref" output
5152
'
5253

5354
test_expect_success 'branch -d can delete badly named ref' '
54-
cp .git/refs/heads/main .git/refs/heads/broken...ref &&
55-
test_when_finished "rm -f .git/refs/heads/broken...ref" &&
55+
test-tool ref-store main update-ref msg "refs/heads/broken...ref" $main_sha1 $ZERO_OID REF_SKIP_REFNAME_VERIFICATION &&
56+
test_when_finished "test-tool ref-store main delete-refs REF_NO_DEREF msg refs/heads/broken...ref" &&
5657
git branch -d broken...ref &&
5758
git branch >output 2>error &&
5859
! grep -e "broken\.\.\.ref" error &&
5960
! grep -e "broken\.\.\.ref" output
6061
'
6162

6263
test_expect_success 'branch -D can delete badly named ref' '
63-
cp .git/refs/heads/main .git/refs/heads/broken...ref &&
64-
test_when_finished "rm -f .git/refs/heads/broken...ref" &&
64+
test-tool ref-store main update-ref msg "refs/heads/broken...ref" $main_sha1 $ZERO_OID REF_SKIP_REFNAME_VERIFICATION &&
65+
test_when_finished "test-tool ref-store main delete-refs REF_NO_DEREF msg refs/heads/broken...ref" &&
6566
git branch -D broken...ref &&
6667
git branch >output 2>error &&
6768
! grep -e "broken\.\.\.ref" error &&
@@ -90,15 +91,15 @@ test_expect_success 'branch -D cannot delete absolute path' '
9091
'
9192

9293
test_expect_success 'git branch cannot create a badly named ref' '
93-
test_when_finished "rm -f .git/refs/heads/broken...ref" &&
94+
test_when_finished "test-tool ref-store main delete-refs REF_NO_DEREF msg refs/heads/broken...ref" &&
9495
test_must_fail git branch broken...ref &&
9596
git branch >output 2>error &&
9697
! grep -e "broken\.\.\.ref" error &&
9798
! grep -e "broken\.\.\.ref" output
9899
'
99100

100101
test_expect_success 'branch -m cannot rename to a bad ref name' '
101-
test_when_finished "rm -f .git/refs/heads/broken...ref" &&
102+
test_when_finished "test-tool ref-store main delete-refs REF_NO_DEREF msg refs/heads/broken...ref" &&
102103
test_might_fail git branch -D goodref &&
103104
git branch goodref &&
104105
test_must_fail git branch -m goodref broken...ref &&
@@ -109,8 +110,9 @@ test_expect_success 'branch -m cannot rename to a bad ref name' '
109110
'
110111

111112
test_expect_failure 'branch -m can rename from a bad ref name' '
112-
cp .git/refs/heads/main .git/refs/heads/broken...ref &&
113-
test_when_finished "rm -f .git/refs/heads/broken...ref" &&
113+
test-tool ref-store main update-ref msg "refs/heads/broken...ref" $main_sha1 $ZERO_OID REF_SKIP_REFNAME_VERIFICATION &&
114+
115+
test_when_finished "test-tool ref-store main delete-refs REF_NO_DEREF msg refs/heads/broken...ref" &&
114116
git branch -m broken...ref renamed &&
115117
test_cmp_rev main renamed &&
116118
git branch >output 2>error &&
@@ -119,7 +121,7 @@ test_expect_failure 'branch -m can rename from a bad ref name' '
119121
'
120122

121123
test_expect_success 'push cannot create a badly named ref' '
122-
test_when_finished "rm -f .git/refs/heads/broken...ref" &&
124+
test_when_finished "test-tool ref-store main delete-refs REF_NO_DEREF msg refs/heads/broken...ref" &&
123125
test_must_fail git push "file://$(pwd)" HEAD:refs/heads/broken...ref &&
124126
git branch >output 2>error &&
125127
! grep -e "broken\.\.\.ref" error &&
@@ -139,7 +141,7 @@ test_expect_failure 'push --mirror can delete badly named ref' '
139141
cd dest &&
140142
test_commit two &&
141143
git checkout --detach &&
142-
cp .git/refs/heads/main .git/refs/heads/broken...ref
144+
test-tool ref-store main update-ref msg "refs/heads/broken...ref" $main_sha1 $ZERO_OID REF_SKIP_REFNAME_VERIFICATION
143145
) &&
144146
git -C src push --mirror "file://$top/dest" &&
145147
git -C dest branch >output 2>error &&
@@ -148,9 +150,9 @@ test_expect_failure 'push --mirror can delete badly named ref' '
148150
'
149151

150152
test_expect_success 'rev-parse skips symref pointing to broken name' '
151-
test_when_finished "rm -f .git/refs/heads/broken...ref" &&
153+
test_when_finished "test-tool ref-store main delete-refs REF_NO_DEREF msg refs/heads/broken...ref" &&
152154
git branch shadow one &&
153-
cp .git/refs/heads/main .git/refs/heads/broken...ref &&
155+
test-tool ref-store main update-ref msg "refs/heads/broken...ref" $main_sha1 $ZERO_OID REF_SKIP_REFNAME_VERIFICATION &&
154156
printf "ref: refs/heads/broken...ref\n" >.git/refs/tags/shadow &&
155157
test_when_finished "rm -f .git/refs/tags/shadow" &&
156158
git rev-parse --verify one >expect &&
@@ -160,8 +162,8 @@ test_expect_success 'rev-parse skips symref pointing to broken name' '
160162
'
161163

162164
test_expect_success 'for-each-ref emits warnings for broken names' '
163-
cp .git/refs/heads/main .git/refs/heads/broken...ref &&
164-
test_when_finished "rm -f .git/refs/heads/broken...ref" &&
165+
test-tool ref-store main update-ref msg "refs/heads/broken...ref" $main_sha1 $ZERO_OID REF_SKIP_REFNAME_VERIFICATION &&
166+
test_when_finished "test-tool ref-store main delete-refs REF_NO_DEREF msg refs/heads/broken...ref" &&
165167
printf "ref: refs/heads/broken...ref\n" >.git/refs/heads/badname &&
166168
test_when_finished "rm -f .git/refs/heads/badname" &&
167169
printf "ref: refs/heads/main\n" >.git/refs/heads/broken...symref &&
@@ -176,8 +178,8 @@ test_expect_success 'for-each-ref emits warnings for broken names' '
176178
'
177179

178180
test_expect_success 'update-ref -d can delete broken name' '
179-
cp .git/refs/heads/main .git/refs/heads/broken...ref &&
180-
test_when_finished "rm -f .git/refs/heads/broken...ref" &&
181+
test-tool ref-store main update-ref msg "refs/heads/broken...ref" $main_sha1 $ZERO_OID REF_SKIP_REFNAME_VERIFICATION &&
182+
test_when_finished "test-tool ref-store main delete-refs REF_NO_DEREF msg refs/heads/broken...ref" &&
181183
git update-ref -d refs/heads/broken...ref >output 2>error &&
182184
test_must_be_empty output &&
183185
test_must_be_empty error &&
@@ -187,8 +189,8 @@ test_expect_success 'update-ref -d can delete broken name' '
187189
'
188190

189191
test_expect_success 'branch -d can delete broken name' '
190-
cp .git/refs/heads/main .git/refs/heads/broken...ref &&
191-
test_when_finished "rm -f .git/refs/heads/broken...ref" &&
192+
test-tool ref-store main update-ref msg "refs/heads/broken...ref" $main_sha1 $ZERO_OID REF_SKIP_REFNAME_VERIFICATION &&
193+
test_when_finished "test-tool ref-store main delete-refs REF_NO_DEREF msg refs/heads/broken...ref" &&
192194
git branch -d broken...ref >output 2>error &&
193195
test_i18ngrep "Deleted branch broken...ref (was broken)" output &&
194196
test_must_be_empty error &&
@@ -198,8 +200,9 @@ test_expect_success 'branch -d can delete broken name' '
198200
'
199201

200202
test_expect_success 'update-ref --no-deref -d can delete symref to broken name' '
201-
cp .git/refs/heads/main .git/refs/heads/broken...ref &&
202-
test_when_finished "rm -f .git/refs/heads/broken...ref" &&
203+
test-tool ref-store main update-ref msg "refs/heads/broken...ref" $main_sha1 $ZERO_OID REF_SKIP_REFNAME_VERIFICATION &&
204+
205+
test_when_finished "test-tool ref-store main delete-refs REF_NO_DEREF msg refs/heads/broken...ref" &&
203206
printf "ref: refs/heads/broken...ref\n" >.git/refs/heads/badname &&
204207
test_when_finished "rm -f .git/refs/heads/badname" &&
205208
git update-ref --no-deref -d refs/heads/badname >output 2>error &&
@@ -209,8 +212,9 @@ test_expect_success 'update-ref --no-deref -d can delete symref to broken name'
209212
'
210213

211214
test_expect_success 'branch -d can delete symref to broken name' '
212-
cp .git/refs/heads/main .git/refs/heads/broken...ref &&
213-
test_when_finished "rm -f .git/refs/heads/broken...ref" &&
215+
test-tool ref-store main update-ref msg "refs/heads/broken...ref" $main_sha1 $ZERO_OID REF_SKIP_REFNAME_VERIFICATION &&
216+
217+
test_when_finished "test-tool ref-store main delete-refs REF_NO_DEREF msg refs/heads/broken...ref" &&
214218
printf "ref: refs/heads/broken...ref\n" >.git/refs/heads/badname &&
215219
test_when_finished "rm -f .git/refs/heads/badname" &&
216220
git branch -d badname >output 2>error &&
@@ -238,8 +242,9 @@ test_expect_success 'branch -d can delete dangling symref to broken name' '
238242
'
239243

240244
test_expect_success 'update-ref -d can delete broken name through symref' '
241-
cp .git/refs/heads/main .git/refs/heads/broken...ref &&
242-
test_when_finished "rm -f .git/refs/heads/broken...ref" &&
245+
test-tool ref-store main update-ref msg "refs/heads/broken...ref" $main_sha1 $ZERO_OID REF_SKIP_REFNAME_VERIFICATION &&
246+
247+
test_when_finished "test-tool ref-store main delete-refs REF_NO_DEREF msg refs/heads/broken...ref" &&
243248
printf "ref: refs/heads/broken...ref\n" >.git/refs/heads/badname &&
244249
test_when_finished "rm -f .git/refs/heads/badname" &&
245250
git update-ref -d refs/heads/badname >output 2>error &&

0 commit comments

Comments
 (0)