Automerge backed Markdown editor for the Atmosphere
Something went wrong. Try again.
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879import assert from 'node:assert/strict'import { test } from 'node:test'import { chromium } from 'playwright'import { createServer } from 'vite'
test('untrusted Markdown image URLs cannot request their URL during render', async () => { const server = await createServer({ configFile: false, server: { host: '127.0.0.1', port: 0 }, logLevel: 'error' }) let browser try { await server.listen() const address = server.httpServer.address() assert.ok(address && typeof address !== 'string') browser = await chromium.launch({ executablePath: process.env.PLAYWRIGHT_CHROMIUM_BIN }) const page = await browser.newPage() const attempted = [] // Establish the Vite origin without booting the app or its dev WebSocket. await page.goto(`http://127.0.0.1:${address.port}/src/plugin/markdown-renderer-impl.ts`) await page.evaluate(() => import('/src/plugin/markdown-renderer-impl.ts')) await page.route('**/*', async route => { attempted.push(route.request().url()) await route.abort() }) // Positive control: this browser/route must see a real image fetch. await page.evaluate(() => { const img = document.createElement('img') img.src = 'https://example.test/control' document.body.appendChild(img) }) await page.waitForFunction(() => document.querySelector('img')?.complete) assert.deepEqual(attempted, ['https://example.test/control']) attempted.length = 0
const result = await page.evaluate(async () => { const { renderMarkdownToElement, registerPostProcessor, clearAllPostProcessors } = await import('/src/plugin/markdown-renderer-impl.ts') const el = document.createElement('section') document.body.appendChild(el) window.__markdownProofExecuted = false let processors = 0 registerPostProcessor('browser-proof', () => { processors++ }) try { await renderMarkdownToElement( '> [!note] Safe **title**\n> \n\n\n\n\n\n\n\n![reference][ref]\n\n[ref]: https://example.test/reference\n\n<img src="https://example.test/raw" onerror="window.__markdownProofExecuted=true">\n\n<iframe srcdoc="<script>window.__markdownProofExecuted=true</script>" src="https://example.test/frame"></iframe>\n\n<svg onload="window.__markdownProofExecuted=true"><image href="https://example.test/svg"/></svg>\n\n<math><mtext>inert</mtext></math>\n\n[unsafe](javascript:window.__markdownProofExecuted=true)\n\n[link](https://example.org/)', el, '/untrusted.md', null, ) return { callout: !!el.querySelector('.callout'), title: el.querySelector('.callout-title')?.textContent, text: el.textContent, images: el.querySelectorAll('img').length, link: el.querySelector('a')?.getAttribute('href'), unsafeLink: [...el.querySelectorAll('a')].find(a => a.textContent === 'unsafe')?.getAttribute('href'), activeNodes: el.querySelectorAll('iframe, svg, math, script, img').length, executed: window.__markdownProofExecuted, processors, } } finally { clearAllPostProcessors() } }) await page.waitForTimeout(250) assert.deepEqual(attempted, []) assert.equal(result.callout, true) assert.equal(result.images, 0) assert.equal(result.activeNodes, 0) assert.equal(result.executed, false) assert.equal(result.unsafeLink, '#') assert.equal(await page.evaluate(() => { document.querySelector('a[href="#"]')?.click(); return window.__markdownProofExecuted }), false) assert.ok(page.url().startsWith(`http://127.0.0.1:${address.port}/`)) assert.equal(result.link, '#') assert.match(result.title, /Safe title/) assert.match(result.text, /private/) assert.ok(result.processors > 0) } finally { await browser?.close() await server.close() }})