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

Function parseForSecurityFromAst

src/utils/bash/ast.ts:400–460  ·  view source on GitHub ↗
(
  cmd: string,
  root: Node | typeof PARSE_ABORTED,
)

Source from the content-addressed store, hash-verified

398 * successful parse doesn't.
399 */
400export function parseForSecurityFromAst(
401 cmd: string,
402 root: Node | typeof PARSE_ABORTED,
403): ParseForSecurityResult {
404 // Pre-checks: characters that cause tree-sitter and bash to disagree on
405 // word boundaries. These run before tree-sitter because they're the known
406 // tree-sitter/bash differentials. Everything after this point trusts
407 // tree-sitter's tokenization.
408 if (CONTROL_CHAR_RE.test(cmd)) {
409 return { kind: 'too-complex', reason: 'Contains control characters' }
410 }
411 if (UNICODE_WHITESPACE_RE.test(cmd)) {
412 return { kind: 'too-complex', reason: 'Contains Unicode whitespace' }
413 }
414 if (BACKSLASH_WHITESPACE_RE.test(cmd)) {
415 return {
416 kind: 'too-complex',
417 reason: 'Contains backslash-escaped whitespace',
418 }
419 }
420 if (ZSH_TILDE_BRACKET_RE.test(cmd)) {
421 return {
422 kind: 'too-complex',
423 reason: 'Contains zsh ~[ dynamic directory syntax',
424 }
425 }
426 if (ZSH_EQUALS_EXPANSION_RE.test(cmd)) {
427 return {
428 kind: 'too-complex',
429 reason: 'Contains zsh =cmd equals expansion',
430 }
431 }
432 if (BRACE_WITH_QUOTE_RE.test(maskBracesInQuotedContexts(cmd))) {
433 return {
434 kind: 'too-complex',
435 reason: 'Contains brace with quote character (expansion obfuscation)',
436 }
437 }
438
439 const trimmed = cmd.trim()
440 if (trimmed === '') {
441 return { kind: 'simple', commands: [] }
442 }
443
444 if (root === PARSE_ABORTED) {
445 // SECURITY: module loaded but parse aborted (timeout / node budget /
446 // panic). Adversarially triggerable — `(( a[0][0]... ))` with ~2800
447 // subscripts hits PARSE_TIMEOUT_MICROS under the 10K length limit.
448 // Previously indistinguishable from module-not-loaded → routed to
449 // legacy (parse-unavailable), which lacks EVAL_LIKE_BUILTINS — `trap`,
450 // `enable`, `hash` leaked with Bash(*). Fail closed: too-complex → ask.
451 return {
452 kind: 'too-complex',
453 reason:
454 'Parser aborted (timeout or resource limit) — possible adversarial input',
455 nodeType: 'PARSE_ABORT',
456 }
457 }

Callers 2

bashToolHasPermissionFunction · 0.85
parseForSecurityFunction · 0.85

Calls 2

walkProgramFunction · 0.85

Tested by

no test coverage detected