From 5e5c49a99cdee57b80a367a3d37105e1907781c8 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Wed, 14 Jan 2026 05:56:33 +0000 Subject: [PATCH] fix(security): handle non-string inputs in escapeHtml to prevent crashes - Update `escapeHtml` to explicitly coerce input to string - Handle null/undefined values safely - Add unit tests for non-string input types (numbers, booleans, objects) --- src/shared/utils.ts | 6 +++--- tests/unit/Security.test.ts | 16 ++++++++++++++++ 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/src/shared/utils.ts b/src/shared/utils.ts index 6c33ede..130f462 100644 --- a/src/shared/utils.ts +++ b/src/shared/utils.ts @@ -165,9 +165,9 @@ export function createDebugLogger( * @param str - The string to escape * @returns Escaped string */ -export function escapeHtml(str: string): string { - if (!str) return str; - return str +export function escapeHtml(str: unknown): string { + if (str === null || str === undefined) return ''; + return String(str) .replace(/&/g, "&") .replace(//g, ">") diff --git a/tests/unit/Security.test.ts b/tests/unit/Security.test.ts index c4cb5fe..d50f329 100644 --- a/tests/unit/Security.test.ts +++ b/tests/unit/Security.test.ts @@ -1,5 +1,6 @@ import { describe, it, expect } from 'vitest'; import { formatValue } from '../../src/info-panel/ValueFormatter'; +import { escapeHtml } from '../../src/shared/utils'; describe('Security', () => { describe('formatValue', () => { @@ -51,4 +52,19 @@ describe('Security', () => { expect(renderedValue).toContain('<script>'); }); }); + + describe('Robustness', () => { + it('should safely handle non-string inputs in escapeHtml', () => { + expect(escapeHtml(123)).toBe('123'); + expect(escapeHtml(0)).toBe('0'); + expect(escapeHtml(true)).toBe('true'); + expect(escapeHtml(false)).toBe('false'); + expect(escapeHtml(null)).toBe(''); + expect(escapeHtml(undefined)).toBe(''); + + // Object with toString + const obj = { toString: () => '