Skip to content
This repository was archived by the owner on Nov 25, 2021. It is now read-only.

Commit dd2d93b

Browse files
committed
fix(hoveroverlay): do not sanitize syntax highlighting away
1 parent 5eef578 commit dd2d93b

File tree

2 files changed

+33
-10
lines changed

2 files changed

+33
-10
lines changed

src/helpers.test.ts

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,28 @@
1+
// Bring in all languages for testing
2+
import 'highlight.js'
3+
14
import assert from 'assert'
2-
import { highlightCodeSafe } from './helpers'
5+
import { highlightCodeSafe, renderMarkdown } from './helpers'
36

47
describe('helpers', () => {
58
describe('highlightCodeSafe()', () => {
69
it('escapes HTML and does not attempt to highlight plaintext', () => {
710
assert.strictEqual(highlightCodeSafe('foo<"bar>', 'plaintext'), 'foo&lt;"bar&gt;')
811
})
912
})
13+
describe('renderMarkdown()', () => {
14+
it('renders markdown and sanitizes dangerous elements', () => {
15+
const markdown = 'You have been <script>alert("Pwned!")</script>'
16+
const rendered = renderMarkdown(markdown)
17+
assert.strictEqual(rendered, '<p>You have been </p>\n')
18+
})
19+
it('renders markdown without sanitizing syntax highlighting away', () => {
20+
const markdown = ['Example:', '```javascript', 'const foo = 123', '```'].join('\n')
21+
const rendered = renderMarkdown(markdown)
22+
assert.strictEqual(
23+
rendered,
24+
'<p>Example:</p>\n<pre><code class="language-javascript"><span class="hljs-keyword">const</span> foo = <span class="hljs-number">123</span></code></pre>\n'
25+
)
26+
})
27+
})
1028
})

src/helpers.ts

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -91,15 +91,20 @@ export const highlightCodeSafe = (code: string, language?: string): string => {
9191
* Renders the given markdown to HTML, highlighting code and sanitizing dangerous HTML.
9292
* Can throw an exception on parse errors.
9393
*/
94-
export const renderMarkdown = (markdown: string): string =>
95-
sanitize(
96-
marked(markdown, {
97-
gfm: true,
98-
breaks: true,
99-
sanitize: false,
100-
highlight: (code, language) => '<code>' + highlightCodeSafe(code, language) + '</code>',
101-
})
102-
)
94+
export const renderMarkdown = (markdown: string): string => {
95+
const rendered = marked(markdown, {
96+
gfm: true,
97+
breaks: true,
98+
sanitize: false,
99+
highlight: (code, language) => highlightCodeSafe(code, language),
100+
})
101+
return sanitize(rendered, {
102+
allowedTags: [...sanitize.defaults.allowedTags, 'span'],
103+
allowedClasses: {
104+
'*': [/^hljs-.+/ as any],
105+
},
106+
})
107+
}
103108

104109
/**
105110
* Converts a synthetic React event to a persisted, native Event object.

0 commit comments

Comments
 (0)