Skip to content

fix(cli): prevent CPU hang and quote swallowing on @ within code (#29434) - #29557

Merged
DavidAPierce merged 6 commits into
google-gemini:mainfrom
elberthc-byte:b-565379206-regex-issue
Sep 30, 2026
Merged

DavidAPierce merged 6 commits into
google-gemini:mainfrom
elberthc-byte:b-565379206-regex-issue

Conversation

@elberthc-byte

@elberthc-byte elberthc-byte commented Sep 29, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Fixes an uninterruptible 100% CPU lockup in headless / non-interactive mode (-p with piped stdin) caused by catastrophic quote-swallowing when code contains scoped packages (@scope/pkg) followed by quoted strings. Incorporates reviewer feedback to protect against brace-expansion ReDoS in minimatch, sanitize paths against directory traversal (..), and exclude absolute paths and glob metacharacters from fallback searches.

Details

Problem

  1. When input is piped to gemini -p, atCommandProcessor scans for @<path> references.
  2. In AT_COMMAND_PATH_REGEX_SOURCE, the double-quoted string branch "(?:[^"]*)" was nested inside a repeated outer group (?: ... )+ and allowed arbitrary characters (including newlines and delimiters) across unescaped quotes.
  3. When parsing code such as import { useThing } from "@scope/pkg"; followed by subsequent imports or quoted strings, the @ inside quotes was matched and the closing quote after pkg was parsed as the start of a "(?:[^"]*)" quoted span. This greedily swallowed entire source files (thousands of characters across tens or hundreds of lines) into a single @path token.
  4. When direct resolution failed, resolveFilePaths fell back to recursive glob search (config.getEnableRecursiveFileSearch()), constructing **/*${pathName}* with the unvalidated multi-kilobyte string.
  5. In npm glob / minimatch, the presence of dozens of import statements with curly braces ({ a, b, c }) triggered combinatorial explosion in brace-expansion (reaching its ceiling of 100,000 patterns) and synchronous preprocessing in minimatch on the Node main V8 thread. This starved the event loop, pegged CPU at 100%, and ignored SIGINT / SIGTERM / AbortSignal.

Solution

  1. Tighten AT_COMMAND_PATH_REGEX_SOURCE (atCommandProcessor.ts):
    • Disallow newlines inside double-quoted paths ("[^"\n\r]*").
    • Separate quoted path alternatives from unquoted paths so an unquoted path cannot seamlessly chain into a quoted span across quotes.
    • Add quotes (", ', `) to delimiters for unquoted path tokens so unquoted paths stop immediately before quotes.
  2. Pre-Glob Defense-in-Depth Guard (resolveFilePaths in atCommandProcessor.ts):
    • Enforce that pathName.length > 0 && pathName.length <= MAX_GLOB_SEARCH_PATH_LENGTH (255) && !path.isAbsolute(pathName) && !pathName.includes('..') && !/[\r\n\t\0{}*?\[\]]/.test(pathName) before invoking globTool.buildAndExecute.
    • Disallows newlines, null bytes, and curly braces ({, }) in recursive glob search paths, eliminating combinatorial brace expansion in minimatch (per code review feedback #5355588500).
    • Sanitizes paths against directory traversal sequences (..) to prevent path traversal during glob fallback (per code review feedback #5356587921).
    • Excludes absolute paths (!path.isAbsolute(pathName)) and glob metacharacters (*, ?, [, ], \t) to prevent invalid search patterns and runaway wildcard matching (per code review feedback #5356733854).
    • Preserves token reporting and telemetry integrity without breaking backwards compatibility.

Related Issues

Fixes #29434

How to Validate

1. Automated Vitest Tests

Run the updated regression test suite:

npm test -w @google/gemini-cli -- src/ui/hooks/atCommandProcessor.test.ts

Expected: All 72 tests pass, including:

  • does not greedily consume code across quotes when @ is inside quotes (#29434)
  • does not hang when input contains @scope/pkg followed by many imports (#29434)
  • does not invoke recursive glob search on paths exceeding MAX_GLOB_SEARCH_PATH_LENGTH (#29434)
  • does not invoke recursive glob search on paths containing newlines (#29434)
  • does not invoke recursive glob search on paths containing curly braces (#29434)
  • does not invoke recursive glob search on paths containing directory traversal sequences (#29434)
  • does not invoke recursive glob search on absolute paths that do not exist (#29434)
  • does not invoke recursive glob search on paths containing glob wildcards (#29434)

2. Manual Reproduction Verification

Create a test file with 60 TypeScript/ESM imports:

node -e '
let content = `import { useThing } from "@scope/pkg";\n`;
for (let i = 1; i <= 60; i++) {
  content += `import { alpha${i}, beta${i}, gamma${i} } from "~/modules/feature${i}/index";\n`;
}
fs.writeFileSync("/tmp/repro.txt", content);
'
cat /tmp/repro.txt | node bundle/gemini.js --skip-trust --approval-mode plan -p "Summarize"

Expected: The CLI processes the input and dispatches to the model in < 1 second instead of freezing at 100% CPU.

3. File Reference Regressions

Verify that standard @path/to/file.txt, escaped spaces (@path\ with\ spaces/file.txt), and Windows quoted paths (@"path with spaces/file.txt") continue to resolve and attach correctly.

Pre-Merge Checklist

  • Updated relevant documentation and README (if needed)
  • Added/updated tests (if needed)
  • Noted breaking changes (if any)
  • Validated on required platforms/methods:
    • MacOS
      • npm run
      • npx
      • Docker
      • Podman
      • Seatbelt
    • Windows
      • npm run
      • npx
      • Docker
    • Linux
      • npm run
      • npx
      • Docker

@elberthc-byte
elberthc-byte requested a review from a team as a code owner September 29, 2026 16:33
@gemini-code-assist

Copy link
Copy Markdown
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request addresses a critical performance issue where the CLI would hang at 100% CPU usage when processing specific code snippets containing scoped package imports. By tightening the path-parsing regex and adding defensive validation before invoking recursive glob searches, the changes prevent the parser from greedily consuming large blocks of code and protect the system from combinatorial explosions in the glob matching engine.

Highlights

  • Regex Hardening: Updated the AT_COMMAND_PATH_REGEX_SOURCE to prevent greedy matching across quotes and newlines, ensuring that scoped package imports do not cause catastrophic token consumption.
  • Glob Search Guard: Implemented a validation check in resolveFilePaths to restrict glob search execution to paths under 255 characters that do not contain invalid characters like newlines or null bytes.
  • Regression Testing: Added comprehensive regression tests to verify that code containing imports, long paths, and newlines no longer triggers CPU hangs or incorrect glob behavior.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize the Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counterproductive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution. ↩

@github-actions github-actions Bot added the size/m A medium sized PR label Sep 29, 2026
@github-actions

github-actions Bot commented Sep 29, 2026 •

Copy link
Copy Markdown

📊 PR Size: size/M

  • Lines changed: 209
  • Additions: +203
  • Deletions: -6
  • Files changed: 2

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request addresses issue #29434 by updating the '@' command path regex to prevent catastrophic multi-line matches and introducing constraints on glob search paths (such as a maximum length of 255 characters and excluding newlines/null bytes) to avoid runaway searches. Regression tests are also added to verify these fixes. The reviewer identified a potential Denial of Service vulnerability where paths containing curly braces could still trigger CPU hangs via brace expansion in 'minimatch', and suggested explicitly disallowing '{' and '}' in the glob suitability check.

Comment thread packages/cli/src/ui/hooks/atCommandProcessor.ts Outdated
@gemini-cli gemini-cli Bot added priority/p1 Important and should be addressed in the near term. area/core Issues related to User Interface, OS Support, Core Functionality labels Sep 29, 2026
@elberthc-byte

Copy link
Copy Markdown
Contributor Author

/gemini review

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request addresses issue #29434 by updating the @ command path regex to prevent catastrophic multi-line matches and runaway glob searches when processing quoted strings (e.g., imports). It also introduces constraints on recursive glob searches, limiting path lengths to 255 characters and rejecting paths with newlines, null bytes, or curly braces, supported by comprehensive regression tests. Feedback on these changes suggests further securing the glob search path validation by explicitly checking for and rejecting directory traversal sequences (..) to prevent path traversal vulnerabilities.

Comment thread packages/cli/src/ui/hooks/atCommandProcessor.ts Outdated
@elberthc-byte

Copy link
Copy Markdown
Contributor Author

/gemini review

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request addresses issue #29434 by preventing runaway glob searches and hangs when processing @ commands. It updates the path regex to avoid matching across quotes and multi-line imports, adds validation to skip recursive glob searches for unsuitable paths (such as excessively long paths, directory traversals, or invalid characters), and includes comprehensive regression tests. The review feedback suggests further strengthening the path validation by also excluding absolute paths and glob metacharacters (such as *, ?, [, ]) to avoid unexpected matching behavior and unnecessary CPU usage.

Comment thread packages/cli/src/ui/hooks/atCommandProcessor.ts Outdated
@elberthc-byte

Copy link
Copy Markdown
Contributor Author

/gemini review

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request resolves issue #29434 by preventing runaway glob searches and hangs when processing @ commands. It refactors the regular expression in atCommandProcessor.ts to avoid catastrophic multi-line matches on quoted strings and restricts unquoted paths from containing unescaped quotes. It also introduces safety checks to skip recursive glob searches for paths that are excessively long, absolute, contain directory traversal sequences, or contain invalid/wildcard characters. Robust regression tests have been added to cover these scenarios. I have no feedback to provide on these changes.

@elberthc-byte

Copy link
Copy Markdown
Contributor Author

/gemini review

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request addresses issue #29434 by preventing runaway glob searches and hangs when processing '@' commands. It updates the regular expression in atCommandProcessor.ts to avoid catastrophic multi-line matches on quoted strings (such as package imports) and introduces strict criteria (isPathSuitableForGlob) to skip recursive glob searches on unsuitable paths (e.g., excessively long paths, absolute paths, directory traversals, or paths containing invalid characters). Comprehensive regression tests have also been added to validate these safety checks. No review comments were provided, so I have no additional feedback to offer.

@DavidAPierce
DavidAPierce added this pull request to the merge queue Sep 30, 2026
Merged via the queue into google-gemini:main with commit 2044ea3 Sep 30, 2026
33 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/core Issues related to User Interface, OS Support, Core Functionality priority/p1 Important and should be addressed in the near term. size/m A medium sized PR

Projects

None yet

2 participants