fix(cli): prevent OOM crash by limiting file search traversal and adding timeout (#16696)

This commit is contained in:
Gal Zahavi
2026-01-15 12:04:22 -08:00
committed by GitHub
parent 48fdb9872f
commit e77d7b2e1e
7 changed files with 126 additions and 3 deletions

View File

@@ -5,6 +5,7 @@
*/
import { useEffect, useReducer, useRef } from 'react';
import { setTimeout as setTimeoutPromise } from 'node:timers/promises';
import type { Config, FileSearch } from '@google/gemini-cli-core';
import { FileSearchFactory, escapePath } from '@google/gemini-cli-core';
import type { Suggestion } from '../components/SuggestionsDisplay.js';
@@ -12,6 +13,8 @@ import { MAX_SUGGESTIONS_TO_SHOW } from '../components/SuggestionsDisplay.js';
import { CommandKind } from '../commands/types.js';
import { AsyncFzf } from 'fzf';
const DEFAULT_SEARCH_TIMEOUT_MS = 5000;
export enum AtCompletionStatus {
IDLE = 'idle',
INITIALIZING = 'initializing',
@@ -257,6 +260,7 @@ export function useAtCompletion(props: UseAtCompletionProps): void {
config?.getEnableRecursiveFileSearch() ?? true,
disableFuzzySearch:
config?.getFileFilteringDisableFuzzySearch() ?? false,
maxFiles: config?.getFileFilteringOptions()?.maxFileCount,
});
await searcher.initialize();
fileSearch.current = searcher;
@@ -285,6 +289,22 @@ export function useAtCompletion(props: UseAtCompletionProps): void {
dispatch({ type: 'SET_LOADING', payload: true });
}, 200);
const timeoutMs =
config?.getFileFilteringOptions()?.searchTimeout ??
DEFAULT_SEARCH_TIMEOUT_MS;
// eslint-disable-next-line @typescript-eslint/no-floating-promises
(async () => {
try {
await setTimeoutPromise(timeoutMs, undefined, {
signal: controller.signal,
});
controller.abort();
} catch {
// ignore
}
})();
try {
const results = await fileSearch.current.search(state.pattern, {
signal: controller.signal,
@@ -332,6 +352,8 @@ export function useAtCompletion(props: UseAtCompletionProps): void {
if (!(error instanceof Error && error.name === 'AbortError')) {
dispatch({ type: 'ERROR' });
}
} finally {
controller.abort();
}
};