Change formatting to prevent UI redressing attacks (#17611)

This commit is contained in:
Tommaso Sciortino
2026-01-27 08:56:01 -08:00
committed by GitHub
parent 6be42be575
commit 8b2b71c8ef
6 changed files with 26 additions and 24 deletions

View File

@@ -13,31 +13,34 @@ import {
escapeAnsiCtrlCodes,
stripUnsafeCharacters,
getCachedStringWidth,
sanitizeForListDisplay,
sanitizeForDisplay,
} from './textUtils.js';
describe('textUtils', () => {
describe('sanitizeForListDisplay', () => {
it('should strip ANSI codes and replace newlines/tabs with spaces', () => {
const input = '\u001b[31mLine 1\nLine 2\tTabbed\r\nEnd\u001b[0m';
expect(sanitizeForListDisplay(input)).toBe('Line 1 Line 2 Tabbed End');
expect(sanitizeForDisplay(input)).toBe('Line 1 Line 2 Tabbed End');
});
it('should collapse multiple consecutive whitespace characters into a single space', () => {
const input = 'Multiple \n\n newlines and \t\t tabs';
expect(sanitizeForListDisplay(input)).toBe('Multiple newlines and tabs');
expect(sanitizeForDisplay(input)).toBe('Multiple newlines and tabs');
});
it('should truncate long strings', () => {
const longInput = 'a'.repeat(50);
expect(sanitizeForListDisplay(longInput, 20)).toBe(
'a'.repeat(17) + '...',
);
expect(sanitizeForDisplay(longInput, 20)).toBe('a'.repeat(17) + '...');
});
it('should handle empty or null input', () => {
expect(sanitizeForListDisplay('')).toBe('');
expect(sanitizeForListDisplay(null as unknown as string)).toBe('');
expect(sanitizeForDisplay('')).toBe('');
expect(sanitizeForDisplay(null as unknown as string)).toBe('');
});
it('should strip control characters like backspace', () => {
const input = 'Hello\x08 World';
expect(sanitizeForDisplay(input)).toBe('Hello World');
});
});

View File

@@ -124,18 +124,16 @@ export function stripUnsafeCharacters(str: string): string {
}
/**
* Sanitize a string for display in list-like UI components (e.g. Help, Suggestions).
* Removes ANSI codes, collapses whitespace characters into a single space, and optionally truncates.
* Sanitize a string for display in inline UI components (e.g. Help, Suggestions).
* Removes ANSI codes, dangerous control characters, collapses whitespace
* characters into a single space, and optionally truncates.
*/
export function sanitizeForListDisplay(
str: string,
maxLength?: number,
): string {
export function sanitizeForDisplay(str: string, maxLength?: number): string {
if (!str) {
return '';
}
let sanitized = stripAnsi(str).replace(/\s+/g, ' ');
let sanitized = stripUnsafeCharacters(str).replace(/\s+/g, ' ');
if (maxLength && sanitized.length > maxLength) {
sanitized = sanitized.substring(0, maxLength - 3) + '...';