import PrettyText, { buildOptions } from "pretty-text/pretty-text"; import { hrefAllowed } from "pretty-text/sanitizer"; QUnit.module("lib:sanitizer"); QUnit.test("sanitize", (assert) => { const pt = new PrettyText( buildOptions({ siteSettings: { allowed_iframes: "https://www.google.com/maps/embed?|https://www.openstreetmap.org/export/embed.html?", }, }) ); const cooked = (input, expected, text) => assert.equal(pt.cook(input), expected.replace(/\/>/g, ">"), text); assert.equal(pt.sanitize('bug'), "bug"); assert.equal( pt.sanitize("
"), "
" ); assert.equal( pt.sanitize("

hello

"), "

hello

" ); assert.equal(pt.sanitize("<3 <3"), "<3 <3"); assert.equal(pt.sanitize("<_<"), "<_<"); cooked( "hello", "

hello

", "it sanitizes while cooking" ); cooked( "disney reddit", '

disney reddit

', "we can embed proper links" ); cooked("
hello
", "hello", "it does not allow centering"); cooked( "
a\n
\n", "
a\n
", "it does not double sanitize" ); cooked( '', "", "it does not allow most iframes" ); cooked( '', '', "it allows iframe to google maps" ); cooked( '', '', "it allows iframe to OpenStreetMap" ); assert.equal(pt.sanitize(""), "hullo"); assert.equal(pt.sanitize(""), "press me!"); assert.equal(pt.sanitize("draw me!"), "draw me!"); assert.equal(pt.sanitize("hello"), "hello"); assert.equal(pt.sanitize("highlight"), "highlight"); cooked( "[the answer](javascript:alert(42))", "

[the answer](javascript:alert(42))

", "it prevents XSS" ); cooked( '\n', "

", "it doesn't circumvent XSS with comments" ); cooked( 'a', "

a

", "it sanitizes spans" ); cooked( 'a', "

a

", "it sanitizes spans" ); cooked( 'a', '

a

', "it sanitizes spans" ); cooked("Ctrl+C", "

Ctrl+C

"); cooked( "it has been 1 day 0 days since our last test failure", "

it has been 1 day 0 days since our last test failure

" ); cooked( `it has been 1 day 0 days since our last test failure`, `

it has been 1 day 0 days since our last test failure

` ); cooked(`
hello
`, `
hello
`); cooked( `1 + 1 is 3 2`, `

1 + 1 is 3 2

` ); cooked( `JS`, `

JS

` ); cooked( `
Forum
Software
`, `
Forum
Software
` ); cooked( `high low HUGE`, `

high low HUGE

` ); cooked(`
RTL text
`, `
RTL text
`); }); QUnit.test("ids on headings", (assert) => { const pt = new PrettyText(buildOptions({ siteSettings: {} })); assert.equal(pt.sanitize("

Test Heading

"), "

Test Heading

"); assert.equal( pt.sanitize(`

Test Heading

`), `

Test Heading

` ); assert.equal( pt.sanitize(`

Test Heading

`), `

Test Heading

` ); assert.equal( pt.sanitize(`

Test Heading

`), `

Test Heading

` ); assert.equal( pt.sanitize(`

Test Heading

`), `

Test Heading

` ); assert.equal( pt.sanitize(`
Test Heading
`), `
Test Heading
` ); assert.equal( pt.sanitize(`
Test Heading
`), `
Test Heading
` ); }); QUnit.test("poorly formed ids on headings", (assert) => { let pt = new PrettyText(buildOptions({ siteSettings: {} })); assert.equal( pt.sanitize(`

Test Heading

`), `

Test Heading

` ); assert.equal( pt.sanitize(`

Test Heading

`), `

Test Heading

` ); assert.equal( pt.sanitize(`

Test Heading

`), `

Test Heading

` ); assert.equal( pt.sanitize(`

Test Heading

`), `

Test Heading

` ); assert.equal( pt.sanitize(`

Test Heading

`), `

Test Heading

` ); assert.equal( pt.sanitize(`

Test Heading

`), `

Test Heading

` ); }); QUnit.test("urlAllowed", (assert) => { const allowed = (url, msg) => assert.equal(hrefAllowed(url), url, msg); allowed("/foo/bar.html", "allows relative urls"); allowed("http://eviltrout.com/evil/trout", "allows full urls"); allowed("https://eviltrout.com/evil/trout", "allows https urls"); allowed("//eviltrout.com/evil/trout", "allows protocol relative urls"); assert.equal( hrefAllowed("http://google.com/test'onmouseover=alert('XSS!');//.swf"), "http://google.com/test%27onmouseover=alert(%27XSS!%27);//.swf", "escape single quotes" ); });