Skip to content

Commit a4c2c93

Browse files
committed
chore: move out escapeHtml function to shared util, update imports
1 parent 7d69561 commit a4c2c93

4 files changed

Lines changed: 17 additions & 21 deletions

File tree

server/utils/docs/render.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ import type { DenoDocNode, JsDocTag } from '#shared/types/deno-doc'
1010
import { highlightCodeBlock } from '../shiki'
1111
import { formatParam, formatType, getNodeSignature } from './format'
1212
import { groupMergedByKind } from './processing'
13-
import { createSymbolId, escapeHtml, parseJsDocLinks, renderMarkdown } from './text'
13+
import { escapeHtml } from '#shared/utils/html'
14+
import { createSymbolId, parseJsDocLinks, renderMarkdown } from './text'
1415
import type { MergedSymbol, SymbolLookup } from './types'
1516

1617
// =============================================================================

server/utils/docs/text.ts

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
import { highlightCodeBlock } from '../shiki'
1111
import type { SymbolLookup } from './types'
12+
import { escapeHtml } from '#shared/utils/html'
1213

1314
/**
1415
* Strip ANSI escape codes from text.
@@ -21,20 +22,6 @@ export function stripAnsi(text: string): string {
2122
return text.replace(ANSI_PATTERN, '')
2223
}
2324

24-
/**
25-
* Escape HTML special characters.
26-
*
27-
* @internal Exported for testing
28-
*/
29-
export function escapeHtml(text: string): string {
30-
return text
31-
.replace(/&/g, '&')
32-
.replace(/</g, '&lt;')
33-
.replace(/>/g, '&gt;')
34-
.replace(/"/g, '&quot;')
35-
.replace(/'/g, '&#39;')
36-
}
37-
3825
/**
3926
* Clean up symbol names by stripping esm.sh prefixes.
4027
*

shared/utils/html.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
/**
2+
* Escape HTML special characters to prevent XSS and ensure safe embedding.
3+
* Handles text content and attribute values (`&`, `<`, `>`, `"`, `'`).
4+
*/
5+
export function escapeHtml(text: string): string {
6+
return text
7+
.replace(/&/g, '&amp;')
8+
.replace(/</g, '&lt;')
9+
.replace(/>/g, '&gt;')
10+
.replace(/"/g, '&quot;')
11+
.replace(/'/g, '&#39;')
12+
}

test/unit/server/utils/docs/text.spec.ts

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,7 @@
11
import { describe, expect, it } from 'vitest'
22
import * as fc from 'fast-check'
3-
import {
4-
escapeHtml,
5-
parseJsDocLinks,
6-
renderMarkdown,
7-
stripAnsi,
8-
} from '../../../../../server/utils/docs/text'
3+
import { escapeHtml } from '#shared/utils/html'
4+
import { parseJsDocLinks, renderMarkdown, stripAnsi } from '../../../../../server/utils/docs/text'
95
import type { SymbolLookup } from '../../../../../server/utils/docs/types'
106

117
describe('stripAnsi', () => {

0 commit comments

Comments
 (0)