plumbing: transport/ssh, Shell-quote path and args#2067
Merged
Conversation
Member
|
Why don't we pass a generic |
Member
Author
|
@aymanbagabas yes, good shout, and this refinement was still on my todo list. Drafting this was primarily to show @pjbgf. I will update once 👧 is 💤. |
2351d59 to
6928ea9
Compare
The SSH transport interpolates `req.URL.Path` and each entry of `req.Args` into the remote-exec command line. The previous formatter wrapped each value in literal single quotes via `'%s'`, which diverges from canonical Git's wire format for any value containing characters that the shell treats specially. Port `sq_quote_buf`[1] from canonical Git into a `writeShellQuote` helper that mirrors upstream's `struct strbuf *dst` signature, and route both the path and each `req.Args` entry through it. The helper escapes the same character set that upstream Git escapes (`'` and `!`), so the bytes go-git puts on the wire match what `git` itself would send for the same input. Benign inputs are byte-identical to the previous output; values containing `'` or `!` now round-trip correctly through any POSIX shell and through `git-shell`'s `sq_dequote_to_argv`. Add a table-driven `TestBuildCommand` covering the plain case, both characters that `sq_quote_buf` escapes, mixed inputs, and inert metacharacters that pass through unchanged. [1]: https://github.com/git/git/blob/v2.54.0/quote.c#L28 Assisted-by: Claude Opus 4.7 Signed-off-by: Hidde Beydals <hidde@hhh.computer>
6928ea9 to
5aee0b9
Compare
hiddeco
added a commit
to hiddeco/go-git
that referenced
this pull request
May 6, 2026
The SSH transport interpolates `ep.Path` into the remote-exec command line via `endpointToCommand`. The previous formatter wrapped the value in literal single quotes via `'%s'`, which diverges from canonical Git's wire format for any path containing characters the shell treats specially. Port `sq_quote_buf`[1] from canonical Git into a `writeShellQuote` helper and route the path through it. The helper escapes the same character set that upstream Git escapes (`'` and `!`), so the bytes go-git puts on the wire match what `git` itself would send for the same input. Benign paths are byte-identical to the previous output; paths containing `'` or `!` now round-trip correctly through any POSIX shell and through `git-shell`'s `sq_dequote_to_argv`. Add a table-driven `TestEndpointToCommand` covering the plain case, both characters that `sq_quote_buf` escapes, mixed inputs, and inert metacharacters that pass through unchanged. Back-port from go-git#2067. [1]: https://github.com/git/git/blob/v2.54.0/quote.c#L28 Assisted-by: Claude Opus 4.7 Signed-off-by: Hidde Beydals <hidde@hhh.computer>
pjbgf
approved these changes
May 7, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The SSH transport interpolates
req.URL.Pathand each entry ofreq.Argsinto the remote-exec command line. The previous formatter wrapped each value in literal single quotes via'%s', which diverges from canonical Git's wire format for any value containing characters that the shell treats specially.Port
sq_quote_buf1 from canonical Git into ashellQuotehelper and route both the path and eachreq.Argsentry through it. The helper escapes the same character set that upstream Git escapes ('and!), so the bytes go-git puts on the wire match whatgititself would send for the same input. Benign inputs are byte-identical to the previous output; values containing'or!now round-trip correctly through any POSIX shell and throughgit-shell'ssq_dequote_to_argv.Add a table-driven
TestBuildCommandcovering the plain case, both characters thatsq_quote_bufescapes, mixed inputs, and inert metacharacters that pass through unchanged.