MCPcopy Create free account
hub / github.com/codeaashu/claude-code / stripSafeHeredocSubstitutions

Function stripSafeHeredocSubstitutions

src/tools/BashTool/bashSecurity.ts:521–578  ·  view source on GitHub ↗
(command: string)

Source from the content-addressed store, hash-verified

519 * Used by the pre-split gate to strip safe heredocs and re-check the remainder.
520 */
521export function stripSafeHeredocSubstitutions(command: string): string | null {
522 if (!HEREDOC_IN_SUBSTITUTION.test(command)) return null
523
524 const heredocPattern =
525 /\$\(cat[ \t]*<<(-?)[ \t]*(?:'+([A-Za-z_]\w*)'+|\\([A-Za-z_]\w*))/g
526 let result = command
527 let found = false
528 let match
529 const ranges: Array<{ start: number; end: number }> = []
530 while ((match = heredocPattern.exec(command)) !== null) {
531 if (match.index > 0 && command[match.index - 1] === '\\') continue
532 const delimiter = match[2] || match[3]
533 if (!delimiter) continue
534 const isDash = match[1] === '-'
535 const operatorEnd = match.index + match[0].length
536
537 const afterOperator = command.slice(operatorEnd)
538 const openLineEnd = afterOperator.indexOf('\n')
539 if (openLineEnd === -1) continue
540 if (!/^[ \t]*$/.test(afterOperator.slice(0, openLineEnd))) continue
541
542 const bodyStart = operatorEnd + openLineEnd + 1
543 const bodyLines = command.slice(bodyStart).split('\n')
544 for (let i = 0; i < bodyLines.length; i++) {
545 const rawLine = bodyLines[i]!
546 const line = isDash ? rawLine.replace(/^\t*/, '') : rawLine
547 if (line.startsWith(delimiter)) {
548 const after = line.slice(delimiter.length)
549 let closePos = -1
550 if (/^[ \t]*\)/.test(after)) {
551 const lineStart =
552 bodyStart +
553 bodyLines.slice(0, i).join('\n').length +
554 (i > 0 ? 1 : 0)
555 closePos = command.indexOf(')', lineStart)
556 } else if (after === '') {
557 const nextLine = bodyLines[i + 1]
558 if (nextLine !== undefined && /^[ \t]*\)/.test(nextLine)) {
559 const nextLineStart =
560 bodyStart + bodyLines.slice(0, i + 1).join('\n').length + 1
561 closePos = command.indexOf(')', nextLineStart)
562 }
563 }
564 if (closePos !== -1) {
565 ranges.push({ start: match.index, end: closePos + 1 })
566 found = true
567 }
568 break
569 }
570 }
571 }
572 if (!found) return null
573 for (let i = ranges.length - 1; i >= 0; i--) {
574 const r = ranges[i]!
575 result = result.slice(0, r.start) + result.slice(r.end)
576 }
577 return result
578}

Callers 2

bashToolHasPermissionFunction · 0.85

Calls 1

pushMethod · 0.45

Tested by

no test coverage detected