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

Function walkRedirectedStatement

src/utils/bash/ast.ts:1017–1065  ·  view source on GitHub ↗

* A `redirected_statement` wraps a command (or pipeline) plus one or more * `file_redirect`/`heredoc_redirect` nodes. Extract redirects, walk the * inner command, attach redirects to the LAST command (the one whose output * is being redirected).

(
  node: Node,
  commands: SimpleCommand[],
  varScope: Map<string, string>,
)

Source from the content-addressed store, hash-verified

1015 * is being redirected).
1016 */
1017function walkRedirectedStatement(
1018 node: Node,
1019 commands: SimpleCommand[],
1020 varScope: Map<string, string>,
1021): ParseForSecurityResult | null {
1022 const redirects: Redirect[] = []
1023 let innerCommand: Node | null = null
1024
1025 for (const child of node.children) {
1026 if (!child) continue
1027 if (child.type === 'file_redirect') {
1028 // Thread `commands` so $() in redirect targets (e.g., `> $(mktemp)`)
1029 // extracts the inner command for permission checking.
1030 const r = walkFileRedirect(child, commands, varScope)
1031 if ('kind' in r) return r
1032 redirects.push(r)
1033 } else if (child.type === 'heredoc_redirect') {
1034 const r = walkHeredocRedirect(child)
1035 if (r) return r
1036 } else if (
1037 child.type === 'command' ||
1038 child.type === 'pipeline' ||
1039 child.type === 'list' ||
1040 child.type === 'negated_command' ||
1041 child.type === 'declaration_command' ||
1042 child.type === 'unset_command'
1043 ) {
1044 innerCommand = child
1045 } else {
1046 return tooComplex(child)
1047 }
1048 }
1049
1050 if (!innerCommand) {
1051 // `> file` alone is valid bash (truncates file). Represent as a command
1052 // with empty argv so downstream sees the write.
1053 commands.push({ argv: [], envVars: [], redirects, text: node.text })
1054 return null
1055 }
1056
1057 const before = commands.length
1058 const err = collectCommands(innerCommand, commands, varScope)
1059 if (err) return err
1060 if (commands.length > before && redirects.length > 0) {
1061 const last = commands[commands.length - 1]
1062 if (last) last.redirects.push(...redirects)
1063 }
1064 return null
1065}
1066
1067/**
1068 * Extract operator + target from a `file_redirect` node. The target must be

Callers 1

collectCommandsFunction · 0.85

Calls 5

walkFileRedirectFunction · 0.85
walkHeredocRedirectFunction · 0.85
tooComplexFunction · 0.85
collectCommandsFunction · 0.85
pushMethod · 0.45

Tested by

no test coverage detected