(
tokens: string[],
startIndex: number,
config: ExternalCommandConfig,
options?: {
commandName?: string
rawCommand?: string
xargsTargetCommands?: string[]
},
)
| 1682 | * @returns true if all flags are valid, false otherwise |
| 1683 | */ |
| 1684 | export function validateFlags( |
| 1685 | tokens: string[], |
| 1686 | startIndex: number, |
| 1687 | config: ExternalCommandConfig, |
| 1688 | options?: { |
| 1689 | commandName?: string |
| 1690 | rawCommand?: string |
| 1691 | xargsTargetCommands?: string[] |
| 1692 | }, |
| 1693 | ): boolean { |
| 1694 | let i = startIndex |
| 1695 | |
| 1696 | while (i < tokens.length) { |
| 1697 | let token = tokens[i] |
| 1698 | if (!token) { |
| 1699 | i++ |
| 1700 | continue |
| 1701 | } |
| 1702 | |
| 1703 | // Special handling for xargs: once we find the target command, stop validating flags |
| 1704 | if ( |
| 1705 | options?.xargsTargetCommands && |
| 1706 | options.commandName === 'xargs' && |
| 1707 | (!token.startsWith('-') || token === '--') |
| 1708 | ) { |
| 1709 | if (token === '--' && i + 1 < tokens.length) { |
| 1710 | i++ |
| 1711 | token = tokens[i] |
| 1712 | } |
| 1713 | if (token && options.xargsTargetCommands.includes(token)) { |
| 1714 | break |
| 1715 | } |
| 1716 | return false |
| 1717 | } |
| 1718 | |
| 1719 | if (token === '--') { |
| 1720 | // SECURITY: Only break if the tool respects POSIX `--` (default: true). |
| 1721 | // Tools like pyright don't respect `--` — they treat it as a file path |
| 1722 | // and continue processing subsequent tokens as flags. Breaking here |
| 1723 | // would let `pyright -- --createstub os` auto-approve a file-write flag. |
| 1724 | if (config.respectsDoubleDash !== false) { |
| 1725 | i++ |
| 1726 | break // Everything after -- is arguments |
| 1727 | } |
| 1728 | // Tool doesn't respect --: treat as positional arg, keep validating |
| 1729 | i++ |
| 1730 | continue |
| 1731 | } |
| 1732 | |
| 1733 | if (token.startsWith('-') && token.length > 1 && FLAG_PATTERN.test(token)) { |
| 1734 | // Handle --flag=value format |
| 1735 | // SECURITY: Track whether the token CONTAINS `=` separately from |
| 1736 | // whether the value is non-empty. `-E=` has `hasEquals=true` but |
| 1737 | // `inlineValue=''` (falsy). Without `hasEquals`, the falsy check at |
| 1738 | // line ~1813 would fall through to "consume next token" — but GNU |
| 1739 | // getopt for short options with mandatory arg sees `-E=` as `-E` with |
| 1740 | // ATTACHED arg `=` (it doesn't strip `=` for short options). Parser |
| 1741 | // differential: validator advances 2 tokens, GNU advances 1. |
no test coverage detected