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 <hanwen@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Han-Wen Nienhuys committed
Dec 7, 2021 at 13:38 UTC
3c966c7b4e97a5399662f85ab73af08a6419a303
4 files changed
+45
-32
refs.c
+4
-3
@@ -1083,9 +1083,10 @@ int ref_transaction_update(struct ref_transaction *transaction,
1083
{
1084
assert(err);
1085
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))) {
1090
strbuf_addf(err, _("refusing to update ref with bad name '%s'"),
1091
refname);
1092
return -1;
refs.h
+8
-2
@@ -621,12 +621,18 @@ struct ref_transaction *ref_transaction_begin(struct strbuf *err);
621
*/
622
#define REF_SKIP_OID_VERIFICATION (1 << 10)
623
624
+/*
625
+ * Skip verifying refname. This is useful for testing data corruption scenarios.
626
+ */
627
+#define REF_SKIP_REFNAME_VERIFICATION (1 << 11)
628
+
629
/*
630
* Bitmask of all of the flags that are allowed to be passed in to
631
* ref_transaction_update() and friends:
632
*/
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)
636
637
/*
638
* Add a reference update to transaction. `new_oid` is the value that
t/helper/test-ref-store.c
+1
@@ -131,6 +131,7 @@ static struct flag_definition transaction_flags[] = {
131
FLAG_DEF(REF_NO_DEREF),
132
FLAG_DEF(REF_FORCE_CREATE_REFLOG),
133
FLAG_DEF(REF_SKIP_OID_VERIFICATION),
134
+ FLAG_DEF(REF_SKIP_REFNAME_VERIFICATION),
135
{ NULL, 0 }
136
};
137
t/t1430-bad-ref-name.sh
+32
-27
@@ -9,7 +9,8 @@ TEST_PASSES_SANITIZE_LEAK=true
9
10
test_expect_success setup '
11
test_commit one &&
12
- test_commit two
12
+ test_commit two &&
13
+ main_sha1=$(git rev-parse refs/heads/main)
14
'
15
16
test_expect_success 'fast-import: fail on invalid branch name ".badbranchname"' '
@@ -43,16 +44,16 @@ test_expect_success 'fast-import: fail on invalid branch name "bad[branch]name"'
44
'
45
46
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" &&
49
git branch >output 2>error &&
50
test_i18ngrep -e "ignoring ref with broken name refs/heads/broken\.\.\.ref" error &&
51
! grep -e "broken\.\.\.ref" output
52
'
53
54
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" &&
57
git branch -d broken...ref &&
58
git branch >output 2>error &&
59
! grep -e "broken\.\.\.ref" error &&
@@ -60,8 +61,8 @@ test_expect_success 'branch -d can delete badly named ref' '
61
'
62
63
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" &&
66
git branch -D broken...ref &&
67
git branch >output 2>error &&
68
! grep -e "broken\.\.\.ref" error &&
@@ -90,7 +91,7 @@ test_expect_success 'branch -D cannot delete absolute path' '
91
'
92
93
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" &&
95
test_must_fail git branch broken...ref &&
96
git branch >output 2>error &&
97
! grep -e "broken\.\.\.ref" error &&
@@ -98,7 +99,7 @@ test_expect_success 'git branch cannot create a badly named ref' '
99
'
100
101
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" &&
103
test_might_fail git branch -D goodref &&
104
git branch goodref &&
105
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' '
110
'
111
112
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" &&
116
git branch -m broken...ref renamed &&
117
test_cmp_rev main renamed &&
118
git branch >output 2>error &&
@@ -119,7 +121,7 @@ test_expect_failure 'branch -m can rename from a bad ref name' '
121
'
122
123
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" &&
125
test_must_fail git push "file://$(pwd)" HEAD:refs/heads/broken...ref &&
126
git branch >output 2>error &&
127
! grep -e "broken\.\.\.ref" error &&
@@ -139,7 +141,7 @@ test_expect_failure 'push --mirror can delete badly named ref' '
141
cd dest &&
142
test_commit two &&
143
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
145
) &&
146
git -C src push --mirror "file://$top/dest" &&
147
git -C dest branch >output 2>error &&
@@ -148,9 +150,9 @@ test_expect_failure 'push --mirror can delete badly named ref' '
150
'
151
152
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" &&
154
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 &&
156
printf "ref: refs/heads/broken...ref\n" >.git/refs/tags/shadow &&
157
test_when_finished "rm -f .git/refs/tags/shadow" &&
158
git rev-parse --verify one >expect &&
@@ -160,8 +162,8 @@ test_expect_success 'rev-parse skips symref pointing to broken name' '
162
'
163
164
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" &&
167
printf "ref: refs/heads/broken...ref\n" >.git/refs/heads/badname &&
168
test_when_finished "rm -f .git/refs/heads/badname" &&
169
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' '
178
'
179
180
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" &&
183
git update-ref -d refs/heads/broken...ref >output 2>error &&
184
test_must_be_empty output &&
185
test_must_be_empty error &&
@@ -187,8 +189,8 @@ test_expect_success 'update-ref -d can delete broken name' '
189
'
190
191
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" &&
194
git branch -d broken...ref >output 2>error &&
195
test_i18ngrep "Deleted branch broken...ref (was broken)" output &&
196
test_must_be_empty error &&
@@ -198,8 +200,9 @@ test_expect_success 'branch -d can delete broken name' '
200
'
201
202
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" &&
206
printf "ref: refs/heads/broken...ref\n" >.git/refs/heads/badname &&
207
test_when_finished "rm -f .git/refs/heads/badname" &&
208
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'
212
'
213
214
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" &&
218
printf "ref: refs/heads/broken...ref\n" >.git/refs/heads/badname &&
219
test_when_finished "rm -f .git/refs/heads/badname" &&
220
git branch -d badname >output 2>error &&
@@ -238,8 +242,9 @@ test_expect_success 'branch -d can delete dangling symref to broken name' '
242
'
243
244
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" &&
248
printf "ref: refs/heads/broken...ref\n" >.git/refs/heads/badname &&
249
test_when_finished "rm -f .git/refs/heads/badname" &&
250
git update-ref -d refs/heads/badname >output 2>error &&