Git: is_safe_refname rejects legal git ref names containing + (and other git-valid characters)
Summary
crates/buzz-relay/src/api/git/manifest.rs — is_safe_refname() allows only [a-zA-Z0-9_./-] (plus the structural refs/ checks). Git's own rules (git check-ref-format) additionally permit characters like +, @, =, ,, !, and ] in ref components. Refs that git happily creates therefore cannot be pushed to Buzz at all.
This is not hypothetical: OriginTrail/dkg (a real upstream repo) contains the branch
refs/heads/test/842+841-devnet
and pushing it fails with HTTP 400 — it is the single ref out of 1,339 that cannot be mirrored into Buzz git.
Reproduction
git init t && cd t && git commit --allow-empty -m x
git branch "test/842+841-devnet" # git accepts this name fine
git push <buzz-remote> refs/heads/test/842+841-devnet:refs/heads/test/842+841-devnet
# → error: RPC failed; HTTP 400
git check-ref-format --branch "test/842+841-devnet" exits 0 — the name is legal git.
Suggested fix
Widen the allowed alphabet in is_safe_refname to the git-legal set while keeping the structural protections that actually matter for the object-store keys (no .., no //, no control chars, no leading/trailing slash, refs/ prefix). Since refnames are used as object-store key components, characters outside the current set could be percent-encoded at the storage boundary instead of rejected at the protocol boundary — the doc comment already notes the predicate is shared symmetrically by write validation and hydration, so a single encode/decode pair at that seam keeps the "valid CAS, un-clone-able output" invariant intact.
A conservative first step that covers the observed real-world case: add + (and ideally @) to the alphabet — neither has meaning to the object-store key scheme nor to path traversal.
Environment
Relay at 63496cc1d; observed 2026-08-01 while mirroring OriginTrail/dkg.
Git:
is_safe_refnamerejects legal git ref names containing+(and other git-valid characters)Summary
crates/buzz-relay/src/api/git/manifest.rs—is_safe_refname()allows only[a-zA-Z0-9_./-](plus the structuralrefs/checks). Git's own rules (git check-ref-format) additionally permit characters like+,@,=,,,!, and]in ref components. Refs that git happily creates therefore cannot be pushed to Buzz at all.This is not hypothetical:
OriginTrail/dkg(a real upstream repo) contains the branchand pushing it fails with
HTTP 400— it is the single ref out of 1,339 that cannot be mirrored into Buzz git.Reproduction
git check-ref-format --branch "test/842+841-devnet"exits 0 — the name is legal git.Suggested fix
Widen the allowed alphabet in
is_safe_refnameto the git-legal set while keeping the structural protections that actually matter for the object-store keys (no.., no//, no control chars, no leading/trailing slash,refs/prefix). Since refnames are used as object-store key components, characters outside the current set could be percent-encoded at the storage boundary instead of rejected at the protocol boundary — the doc comment already notes the predicate is shared symmetrically by write validation and hydration, so a single encode/decode pair at that seam keeps the "valid CAS, un-clone-able output" invariant intact.A conservative first step that covers the observed real-world case: add
+(and ideally@) to the alphabet — neither has meaning to the object-store key scheme nor to path traversal.Environment
Relay at
63496cc1d; observed 2026-08-01 while mirroringOriginTrail/dkg.