Skip to content

Commit bcc74d8

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 8efe3d6 commit bcc74d8

2 files changed

Lines changed: 11 additions & 1 deletion

File tree

refs.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1381,7 +1381,7 @@ static int transaction_refname_valid(const char *refname,
13811381
strbuf_addf(err, refusal_msg, refname);
13821382
return 0;
13831383
} else if ((new_oid && !is_null_oid(new_oid)) ?
1384-
check_refname_format(refname, REFNAME_ALLOW_ONELEVEL) :
1384+
check_refname_format(refname, REFNAME_FULLY_QUALIFIED) :
13851385
!refname_is_safe(refname)) {
13861386
const char *refusal_msg;
13871387
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)