MCPcopy Index your code
hub / github.com/codeaashu/claude-code / hasDangerousExpansion

Function hasDangerousExpansion

src/utils/bash/commands.ts:830–858  ·  view source on GitHub ↗

* Checks if a redirection target contains shell expansion syntax that could * bypass path validation. These require manual approval for security. * * Design invariant: for every string redirect target, EITHER isSimpleTarget * is TRUE (→ captured → path-validated) OR hasDangerousExpansion is TRUE

(target: ParseEntry | undefined)

Source from the content-addressed store, hash-verified

828 * rejects (except the empty string which is handled separately).
829 */
830function hasDangerousExpansion(target: ParseEntry | undefined): boolean {
831 // shell-quote parses unquoted globs as {op:'glob', pattern:'...'} objects,
832 // not strings. `> *.sh` as a redirect target expands at runtime (single match
833 // → overwrite, multiple → ambiguous-redirect error). Flag these as dangerous.
834 if (typeof target === 'object' && target !== null && 'op' in target) {
835 if (target.op === 'glob') return true
836 return false
837 }
838 if (typeof target !== 'string') return false
839 if (target.length === 0) return false
840 return (
841 target.includes('$') ||
842 target.includes('%') ||
843 target.includes('`') || // Backtick substitution (was only in isSimpleTarget)
844 target.includes('*') || // Glob (was only in isSimpleTarget)
845 target.includes('?') || // Glob (was only in isSimpleTarget)
846 target.includes('[') || // Glob class (was only in isSimpleTarget)
847 target.includes('{') || // Brace expansion (was only in isSimpleTarget)
848 target.startsWith('!') || // History expansion (was only in isSimpleTarget)
849 target.startsWith('=') || // Zsh equals expansion (=cmd -> /path/to/cmd)
850 // ALL tilde-prefixed targets. Previously `~` and `~/path` were carved out
851 // with a comment claiming "handled by expandTilde" — but expandTilde only
852 // runs via validateOutputRedirections(redirections), and for `~/path` the
853 // redirections array is EMPTY (isSimpleTarget rejected it, so it was never
854 // pushed). The carve-out created a gap where `> ~/.bashrc` was neither
855 // captured nor flagged. See bug_007 / bug_022.
856 target.startsWith('~')
857 )
858}
859
860function handleRedirection(
861 part: ParseEntry,

Callers 2

handleRedirectionFunction · 0.85

Calls

no outgoing calls

Tested by

no test coverage detected