Repository navigation
fix: resolve $ template argv on Windows instead of a shell string - #89
Open
markmybytes wants to merge 1 commit into
Open
markmybytes wants to merge 1 commit into
markmybytes wants to merge 1 commit into
Conversation
child_process.exec defaults to cmd.exe on Windows, which treats POSIX
single quotes as literal characters. Every interpolated git call
(git -C <path> ...) passed quote characters to git and failed with
fatal: cannot change to ''<path>'', breaking pull, push, status, and
commit on Windows entirely.
Run the tokenized command via execFile with no shell. Static text
splits on whitespace; interpolated values glue to adjacent text so
mid-token interpolations (origin/${branch}..HEAD, --max-count=${n})
stay a single argv element, and empty values keep their argv slot so
'commit -m ""' cannot collapse to a bare -m and hang in an editor.
Fall back to a quoted shell one-liner only when the executable is a
.cmd/.bat shim (EINVAL since CVE-2024-27980); that path retains the
cmd.exe percent-expansion and newline ceilings.
All 37 git/gh/op call-site templates use no shell features, so this
is a drop-in replacement that also removes command-injection surface
for commit messages and repo paths.
markmybytes
force-pushed
the
fix/windows-shell-argv
branch
from
October 13, 2026 04:14
0920374 to
2ce387e
Compare
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.
Summary
Fixes #88.
Since the v2 plugin entrypoint (
#81), everygit/ghcommand from the plugin runs through the Node shell shim insrc/shell-node.ts. That shim interpolated values with POSIX single-quote escaping ('...') and executed the result viachild_process.exec— which on Windows spawnscmd.exe.cmd.exedoes not treat single quotes as argument delimiters, sogh/gitreceived quotes literally:This broke
pull,push, and/sync-linkon Windows for any config that reachesensureRepoPrivate()(includeSecrets/includeMcpSecrets/includeSessions/includePromptStash). v0.10.1 was unaffected because the v1 entrypoint used Bun's$template tag, which does its own Windows argv handling.Fix
Drop the shell instead of trying to quote for it — the approach the issue calls preferred, since platform-aware quoting keeps discipline exposed to
cmd.exemetacharacters:buildArgvtokenizes the$-tagged template into an argv array with Bun$semantics: static text splits on whitespace, each${}glues into the current token as one argument (origin/${branch}..HEADstays one element), and an empty value keeps its argv slot (git commit -m ${''}does not collapse to a bare-m, which would hang in an interactive editor).execFilewith no shell, so no platform quoting rules apply at all..cmd/.batshims (refused since CVE-2024-27980) and bare PATHEXT-resolved names (ENOENT). Those re-run as a one-liner throughexec, platform-quoted — MSVCRTlist2cmdlinerules (quoteWin32) on Windows, POSIX single-quote on the rest. The fallback is documented as re-entering a shell, so its PATH resolution and%…%expansion ceiling differ from a direct spawn.&&, pipes, redirects, and globs in template text now arrive as literal argv elements rather than operators. No existing call site uses any of them (verified by scan); the behavior difference is documented in the shim's header for future call sites.