From cc0dba435e6c572af17b0fd0dcd3c43d31f51213 Mon Sep 17 00:00:00 2001 From: Haileyesus Date: Tue, 24 Feb 2026 13:47:01 +0300 Subject: [PATCH] fix(code-editor): escape HTML in toolbar labels for security --- .../code-editor/utils/editorToolbarPanel.ts | 35 +++++++++++++++---- 1 file changed, 28 insertions(+), 7 deletions(-) diff --git a/src/components/code-editor/utils/editorToolbarPanel.ts b/src/components/code-editor/utils/editorToolbarPanel.ts index 963406d..4f03794 100644 --- a/src/components/code-editor/utils/editorToolbarPanel.ts +++ b/src/components/code-editor/utils/editorToolbarPanel.ts @@ -39,6 +39,15 @@ const getExpandIcon = (isExpanded: boolean) => { return ''; }; +const escapeHtml = (value: string): string => ( + value + .replace(/&/g, '&') + .replace(//g, '>') + .replace(/"/g, '"') + .replace(/'/g, ''') +); + export const createEditorToolbarPanelExtension = ({ file, showDiff, @@ -67,19 +76,31 @@ export const createEditorToolbarPanelExtension = ({ const chunkCount = chunks.length; const maxChunkIndex = Math.max(0, chunkCount - 1); currentIndex = Math.max(0, Math.min(currentIndex, maxChunkIndex)); + const escapedLabels = { + changes: escapeHtml(labels.changes), + previousChange: escapeHtml(labels.previousChange), + nextChange: escapeHtml(labels.nextChange), + hideDiff: escapeHtml(labels.hideDiff), + showDiff: escapeHtml(labels.showDiff), + collapse: escapeHtml(labels.collapse), + expand: escapeHtml(labels.expand), + }; + // Icons are static SVG path fragments controlled by this module. + const diffVisibilityIcon = getDiffVisibilityIcon(showDiff); + const expandIcon = getExpandIcon(isExpanded); let toolbarHtml = '
'; toolbarHtml += '
'; if (hasDiff) { toolbarHtml += ` - ${chunkCount > 0 ? `${currentIndex + 1}/${chunkCount}` : '0'} ${labels.changes} - - `; @@ -112,9 +133,9 @@ export const createEditorToolbarPanelExtension = ({ if (isSidebar && onToggleExpand) { toolbarHtml += ` - `;