Skip to content

Commit 5237f51

Browse files
committed
refs: check refnames as fully qualified when writing
When a ref update is queued via ref_transaction_update(), we call check_refname_format() to make sure the name is acceptable. We pass REFNAME_ALLOW_ONELEVEL, which allows pseudorefs like MERGE_HEAD. But that's not enough to forbid names outside of refs/ like "foo/bar" or even scary stuff like "config" (though fortunately I think that should never work because we cannot resolve "config" to read the old value). Let's instead pass REFNAME_FULLY_QUALIFIED, which tells the checking function that we really do have a full refname, and it can enforce it as such. This means that "git update-ref foo/bar HEAD" will now be rejected. Note that _deleting_ such a ref is already forbidden (and there is a test in t1430 for that already), due to some confusing differences between check_refname_format() and refname_is_safe(). See the previous commit for more details. And that case is already tested via t1430's "update-ref -d cannot delete non-ref in .git dir" test, so we only need to add tests for our newly-changed behavior. Signed-off-by: Jeff King <peff@peff.net>
1 parent 4e15bbe commit 5237f51

File tree

2 files changed

+11
-1
lines changed

2 files changed

+11
-1
lines changed

refs.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1348,7 +1348,7 @@ static int transaction_refname_valid(const char *refname,
13481348
strbuf_addf(err, refusal_msg, refname);
13491349
return 0;
13501350
} else if ((new_oid && !is_null_oid(new_oid)) ?
1351-
check_refname_format(refname, REFNAME_ALLOW_ONELEVEL) :
1351+
check_refname_format(refname, REFNAME_FULLY_QUALIFIED) :
13521352
!refname_is_safe(refname)) {
13531353
const char *refusal_msg;
13541354
if (flags & REF_LOG_ONLY)

t/t1430-bad-ref-name.sh

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -389,4 +389,14 @@ test_expect_success 'branch -m can rename refs/heads/-dash' '
389389
git show-ref refs/heads/dash
390390
'
391391

392+
test_expect_success 'update-ref refuses lowercase outside of refs/' '
393+
test_must_fail git update-ref lowercase HEAD 2>err &&
394+
test_grep "refusing to update ref with bad name" err
395+
'
396+
397+
test_expect_success 'update-ref refuses non-underscore punctuation outside of refs/' '
398+
test_must_fail git update-ref FOO/HEAD HEAD 2>err &&
399+
test_grep "refusing to update ref with bad name" err
400+
'
401+
392402
test_done

0 commit comments

Comments
 (0)