diff --git a/packages/cli/src/ui/utils/textUtils.test.ts b/packages/cli/src/ui/utils/textUtils.test.ts index eaf501a1fb..f9a90c63b4 100644 --- a/packages/cli/src/ui/utils/textUtils.test.ts +++ b/packages/cli/src/ui/utils/textUtils.test.ts @@ -9,9 +9,26 @@ import type { ToolCallConfirmationDetails, ToolEditConfirmationDetails, } from '@google/gemini-cli-core'; -import { escapeAnsiCtrlCodes, stripUnsafeCharacters } from './textUtils.js'; +import { + escapeAnsiCtrlCodes, + stripUnsafeCharacters, + getCachedStringWidth, +} from './textUtils.js'; describe('textUtils', () => { + describe('getCachedStringWidth', () => { + it('should handle unicode characters that crash string-width', () => { + // U+0602 caused string-width to crash (see #16418) + const char = '؂'; + expect(getCachedStringWidth(char)).toBe(1); + }); + + it('should handle unicode characters that crash string-width with ANSI codes', () => { + const charWithAnsi = '\u001b[31m' + '؂' + '\u001b[0m'; + expect(getCachedStringWidth(charWithAnsi)).toBe(1); + }); + }); + describe('stripUnsafeCharacters', () => { it('should not strip tab characters', () => { const input = 'hello world'; diff --git a/packages/cli/src/ui/utils/textUtils.ts b/packages/cli/src/ui/utils/textUtils.ts index 5da186c423..13c009a136 100644 --- a/packages/cli/src/ui/utils/textUtils.ts +++ b/packages/cli/src/ui/utils/textUtils.ts @@ -136,7 +136,15 @@ export const getCachedStringWidth = (str: string): number => { return stringWidthCache.get(str)!; } - const width = stringWidth(str); + let width: number; + try { + width = stringWidth(str); + } catch { + // Fallback for characters that cause string-width to crash (e.g. U+0602) + // See: https://github.com/google-gemini/gemini-cli/issues/16418 + width = toCodePoints(stripAnsi(str)).length; + } + stringWidthCache.set(str, width); return width;