Skip to content

t1402: test forbidden characters in refnames - #2203

Open
nikolauspschuetz wants to merge 1 commit into
gitgitgadget:masterfrom
nikolauspschuetz:ns/t1402-forbidden-characters
Open

t1402: test forbidden characters in refnames#2203
nikolauspschuetz wants to merge 1 commit into
gitgitgadget:masterfrom
nikolauspschuetz:ns/t1402-forbidden-characters

Conversation

@nikolauspschuetz

@nikolauspschuetz nikolauspschuetz commented Aug 13, 2026

Copy link
Copy Markdown

git-check-ref-format(1) documents the characters that a refname may not contain (space, tilde, caret, colon, question-mark, asterisk, open-bracket) and the rule that it may not be the single character "@". t1402 only exercised a few of these directly.

This adds the remaining forbidden characters in embedded form, and checks that "@" alone is rejected even with --allow-onelevel, where "@" is otherwise a valid refname component (as "refs/@" confirms).

Test-only; documents existing behaviour, in the spirit of 919eb8a (t1402: check for refs ending with a dot).

cc: Patrick Steinhardt ps@pks.im

@nikolauspschuetz
nikolauspschuetz marked this pull request as ready for review August 13, 2026 20:03
@nikolauspschuetz

Copy link
Copy Markdown
Author

/preview

@gitgitgadget

gitgitgadget Bot commented Aug 13, 2026

Copy link
Copy Markdown

Preview email sent as pull.2203.git.1786651494406.gitgitgadget@gmail.com

@nikolauspschuetz

Copy link
Copy Markdown
Author

/submit

@gitgitgadget

gitgitgadget Bot commented Aug 13, 2026

Copy link
Copy Markdown

Submitted as pull.2203.git.1786653837190.gitgitgadget@gmail.com

To fetch this version into FETCH_HEAD:

git fetch https://github.com/gitgitgadget/git/ pr-2203/nikolauspschuetz/ns/t1402-forbidden-characters-v1

To fetch this version to local tag pr-2203/nikolauspschuetz/ns/t1402-forbidden-characters-v1:

git fetch --no-tags https://github.com/gitgitgadget/git/ tag pr-2203/nikolauspschuetz/ns/t1402-forbidden-characters-v1

@gitgitgadget

gitgitgadget Bot commented Aug 14, 2026

Copy link
Copy Markdown

This patch series was integrated into seen via git@799dea8.

@gitgitgadget gitgitgadget Bot added the seen label Aug 14, 2026
@gitgitgadget

gitgitgadget Bot commented Aug 19, 2026

Copy link
Copy Markdown

Patrick Steinhardt wrote on the Git mailing list (how to reply to this email):

On Thu, Aug 13, 2026 at 08:43:56PM +0000, Nikolaus Schuetz via GitGitGadget wrote:
> From: Nikolaus Schuetz <nikolauspschuetz@gmail.com>
> 
> git-check-ref-format(1) documents that a refname cannot contain a
> space, tilde, caret, colon, question-mark, asterisk or open-bracket,
> and that it cannot be the single character "@".  Of these, only "?"
> was tested as a character embedded in an otherwise-valid refname;
> "*" was checked only as a lone character or with --refspec-pattern.
> 
> Add the remaining forbidden characters in that embedded form, and
> check that "@" alone is rejected even with --allow-onelevel -- where
> "@" is otherwise a valid refname component, as "refs/@" confirms.

Okay.

> diff --git a/t/t1402-check-ref-format.sh b/t/t1402-check-ref-format.sh
> index cabc516ae9..bc1e878a0f 100755
> --- a/t/t1402-check-ref-format.sh
> +++ b/t/t1402-check-ref-format.sh
> @@ -51,12 +51,20 @@ invalid_ref '.refs/foo'
>  invalid_ref 'refs/heads/foo.'
>  invalid_ref 'heads/foo..bar'
>  invalid_ref 'heads/foo?bar'
> +invalid_ref 'heads/foo~bar'
> +invalid_ref 'heads/foo^bar'
> +invalid_ref 'heads/foo:bar'
> +invalid_ref 'heads/foo*bar'
> +invalid_ref 'heads/foo[bar'
> +invalid_ref 'heads/foo bar'

This feels a tiny bit excessive, but I guess it does not hurt to enforce
this property, especially now that it's so easy to add new backends.

One thing I was briefly wondering is whether we could maybe have a
simple loop here, as this feels quite repetitive. We could for example:

    for c in '?' '~' '^' ':' '*' '[' ' '
    do
        invalid_ref "heads/foo${c}bar"
    done

By the way, one weird bit: is it intentional that all of these really
use "heads/something" instead of "refs/heads/something"? I guess it
ultimately doesn't matter.

>  valid_ref 'foo./bar'
>  invalid_ref 'heads/foo.lock'
>  invalid_ref 'heads///foo.lock'
>  invalid_ref 'foo.lock/bar'
>  invalid_ref 'foo.lock///bar'
>  valid_ref 'heads/foo@bar'
> +valid_ref 'refs/@'
> +invalid_ref '@' --allow-onelevel

This one certainly is a good addition, as these are quite a bit more
subtle.

Thanks!

Patrick

@gitgitgadget

gitgitgadget Bot commented Aug 19, 2026

Copy link
Copy Markdown

User Patrick Steinhardt <ps@pks.im> has been added to the cc: list.

@nikolauspschuetz
nikolauspschuetz force-pushed the ns/t1402-forbidden-characters branch from f254db5 to be5b2a5 Compare August 19, 2026 16:25
@gitgitgadget

gitgitgadget Bot commented Aug 19, 2026

Copy link
Copy Markdown

Junio C Hamano wrote on the Git mailing list (how to reply to this email):

Patrick Steinhardt <ps@pks.im> writes:

> On Thu, Aug 13, 2026 at 08:43:56PM +0000, Nikolaus Schuetz via GitGitGadget wrote:
>> From: Nikolaus Schuetz <nikolauspschuetz@gmail.com>
>> 
>> git-check-ref-format(1) documents that a refname cannot contain a
>> space, tilde, caret, colon, question-mark, asterisk or open-bracket,
>> and that it cannot be the single character "@".  Of these, only "?"
>> was tested as a character embedded in an otherwise-valid refname;
>> "*" was checked only as a lone character or with --refspec-pattern.
>> 
>> Add the remaining forbidden characters in that embedded form, and
>> check that "@" alone is rejected even with --allow-onelevel -- where
>> "@" is otherwise a valid refname component, as "refs/@" confirms.
>
> Okay.
>
>> diff --git a/t/t1402-check-ref-format.sh b/t/t1402-check-ref-format.sh
>> index cabc516ae9..bc1e878a0f 100755
>> --- a/t/t1402-check-ref-format.sh
>> +++ b/t/t1402-check-ref-format.sh
>> @@ -51,12 +51,20 @@ invalid_ref '.refs/foo'
>>  invalid_ref 'refs/heads/foo.'
>>  invalid_ref 'heads/foo..bar'
>>  invalid_ref 'heads/foo?bar'
>> +invalid_ref 'heads/foo~bar'
>> +invalid_ref 'heads/foo^bar'
>> +invalid_ref 'heads/foo:bar'
>> +invalid_ref 'heads/foo*bar'
>> +invalid_ref 'heads/foo[bar'
>> +invalid_ref 'heads/foo bar'
>
> This feels a tiny bit excessive, but I guess it does not hurt to enforce
> this property, especially now that it's so easy to add new backends.

"Why would we even care to check these insane cases?" was my first
reaction, but I agree with you that these are to protect authors of
new backends from stupid mistakes.

> One thing I was briefly wondering is whether we could maybe have a
> simple loop here, as this feels quite repetitive. We could for example:
>
>     for c in '?' '~' '^' ':' '*' '[' ' '
>     do
>         invalid_ref "heads/foo${c}bar"
>     done

True.  And c does not have to be a single byte. ".." can also be
part of the repertoire.

> By the way, one weird bit: is it intentional that all of these really
> use "heads/something" instead of "refs/heads/something"? I guess it
> ultimately doesn't matter.
>
>>  valid_ref 'foo./bar'
>>  invalid_ref 'heads/foo.lock'
>>  invalid_ref 'heads///foo.lock'
>>  invalid_ref 'foo.lock/bar'
>>  invalid_ref 'foo.lock///bar'
>>  valid_ref 'heads/foo@bar'
>> +valid_ref 'refs/@'
>> +invalid_ref '@' --allow-onelevel
>
> This one certainly is a good addition, as these are quite a bit more
> subtle.
>
> Thanks!
>
> Patrick

git-check-ref-format(1) documents that a refname cannot contain a
space, tilde, caret, colon, question-mark, asterisk, open-bracket or
backslash, nor the sequence "..", and cannot be the single character
"@".  Of these, only "?", "\" and ".." were tested embedded in an
otherwise-valid refname; "*" was checked only as a lone character or
with --refspec-pattern.

Test all of them in that embedded form with a single loop, and check
that "@" alone is rejected even with --allow-onelevel -- where "@" is
otherwise a valid refname component, as "refs/@" confirms.

Signed-off-by: Nikolaus Schuetz <nikolauspschuetz@gmail.com>
@nikolauspschuetz
nikolauspschuetz force-pushed the ns/t1402-forbidden-characters branch 2 times, most recently from be5b2a5 to cc01349 Compare August 20, 2026 14:26
@gitgitgadget

gitgitgadget Bot commented Aug 20, 2026

Copy link
Copy Markdown

Nikolaus Schuetz wrote on the Git mailing list (how to reply to this email):

> True.  And c does not have to be a single byte. ".." can also be
> part of the repertoire.

Agreed and updated accordingly: forbidden chars are looped over,
and I folded ".." in along with "\" (the same forbidden-char list).
The other refname rules enforced by refs.c are well covered,
so I kept the loop to the embedded forbidden tokens.

> By the way, one weird bit: is it intentional that all of these really
> use "heads/something" instead of "refs/heads/something"?

Not intentional -- the file already mixes them (e.g. 'refs/heads/foo.'
vs 'heads/foo..bar'). check-ref-format validates each component
regardless of a refs/ prefix, so it doesn't change what's tested; I
kept 'heads/' to match the neighbours.

Thanks,
Nikolaus

@nikolauspschuetz

Copy link
Copy Markdown
Author

/submit

@gitgitgadget

gitgitgadget Bot commented Aug 20, 2026

Copy link
Copy Markdown

Submitted as pull.2203.v2.git.1787264417682.gitgitgadget@gmail.com

To fetch this version into FETCH_HEAD:

git fetch https://github.com/gitgitgadget/git/ pr-2203/nikolauspschuetz/ns/t1402-forbidden-characters-v2

To fetch this version to local tag pr-2203/nikolauspschuetz/ns/t1402-forbidden-characters-v2:

git fetch --no-tags https://github.com/gitgitgadget/git/ tag pr-2203/nikolauspschuetz/ns/t1402-forbidden-characters-v2

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant