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

Function isCommandList

src/utils/bash/commands.ts:539–603  ·  view source on GitHub ↗
(command: string)

Source from the content-addressed store, hash-verified

537
538// Checks if this is just a list of commands
539function isCommandList(command: string): boolean {
540 // Generate unique placeholders for this parse to prevent injection attacks
541 const placeholders = generatePlaceholders()
542
543 // Extract heredocs before parsing - shell-quote parses << incorrectly
544 const { processedCommand } = extractHeredocs(command)
545
546 const parseResult = tryParseShellCommand(
547 processedCommand
548 .replaceAll('"', `"${placeholders.DOUBLE_QUOTE}`) // parse() strips out quotes :P
549 .replaceAll("'", `'${placeholders.SINGLE_QUOTE}`), // parse() strips out quotes :P
550 varName => `$${varName}`, // Preserve shell variables
551 )
552
553 // If parse failed, it's not a safe command list
554 if (!parseResult.success) {
555 return false
556 }
557
558 const parts = parseResult.tokens
559 for (let i = 0; i < parts.length; i++) {
560 const part = parts[i]
561 const nextPart = parts[i + 1]
562 if (part === undefined) {
563 continue
564 }
565
566 if (typeof part === 'string') {
567 // Strings are safe
568 continue
569 }
570 if ('comment' in part) {
571 // Don't trust comments, they can contain command injection
572 return false
573 }
574 if ('op' in part) {
575 if (part.op === 'glob') {
576 // Globs are safe
577 continue
578 } else if (COMMAND_LIST_SEPARATORS.has(part.op)) {
579 // Command list separators are safe
580 continue
581 } else if (part.op === '>&') {
582 // Redirection to standard input/output/error file descriptors is safe
583 if (
584 nextPart !== undefined &&
585 typeof nextPart === 'string' &&
586 ALLOWED_FILE_DESCRIPTORS.has(nextPart.trim())
587 ) {
588 continue
589 }
590 } else if (part.op === '>') {
591 // Output redirections are validated by pathValidation.ts
592 continue
593 } else if (part.op === '>>') {
594 // Append redirections are validated by pathValidation.ts
595 continue
596 }

Callers 1

Calls 4

generatePlaceholdersFunction · 0.85
extractHeredocsFunction · 0.85
tryParseShellCommandFunction · 0.85
hasMethod · 0.45

Tested by

no test coverage detected