Skip to content

fix(shellwrap): quote arguments containing # so the login shell keeps them - #1756

Merged
Dumbris merged 1 commit into
smart-mcp-proxy:mainfrom
rudycelekli:fix/shellescape-hash-20261023-01
Oct 26, 2026
Merged

Dumbris merged 1 commit into
smart-mcp-proxy:mainfrom
rudycelekli:fix/shellescape-hash-20261023-01

Conversation

@rudycelekli

Copy link
Copy Markdown
Contributor

Bug

Stdio upstreams are launched as $SHELL -l -c "<joined command>" (shellwrap.WrapWithUserShell). Each argument goes through Shellescape, but the POSIX branch only quotes when the argument contains one of " \t\n\r\"'\\$;&|<>(){}[]?*~", and #is not in that set. A word that begins with#starts a comment insh/bash/zsh -c`, so the shell silently drops that argument and everything after it.

Trigger

{"name": "slack", "command": "npx", "args": ["-y", "slack-mcp", "#general", "--port", "3000"]}

The shell runs npx -y slack-mcp. #general --port 3000 never reaches the child.

Fix

Add # to the POSIX special-character set, so such arguments are single-quoted like every other metacharacter. The POSIX escaper copy in internal/oauth/spawnargv_round2_test.go is updated to match, since TestPosixShellescape_MatchesProduction pins the two together.

Test

TestShellescape_HashSurvivesShell checks that #general is quoted, then runs sh -c "printf '%s\n' <escaped args>" and asserts that all four arguments (#general --port 3000 a#b) come back unchanged.

Commands run

  • CGO_ENABLED=0 go test -count=1 ./internal/shellwrap: ok
  • CGO_ENABLED=0 go test -count=1 ./internal/oauth: ok
  • CGO_ENABLED=0 go test -count=1 -run 'Shell|Wrap|Escape|Docker' ./internal/upstream/core: ok
  • With the fix reverted (git stash of shellwrap.go), -run HashSurvives fails: it expected '#general' but got #general, and the shell output came back as [""].
  • gofmt -l on the edited files: no output

@codecov-commenter

Copy link
Copy Markdown

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@Dumbris Dumbris left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verified: the PR test fails on main for the reason described and passes on this branch merged with main; race tests for the touched packages and CI lint (bare and server tags) are clean. Also built and tested together with the rest of this batch, independently reviewed, and cross-reviewed with a second model.

@Dumbris
Dumbris merged commit 1f9911d into smart-mcp-proxy:main Oct 26, 2026
46 checks passed
@Dumbris

Dumbris commented Oct 26, 2026

Copy link
Copy Markdown
Member

Merged. Thank you, @rudycelekli! An argument starting with # is no longer swallowed as a comment by the login shell.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants