From 8d8dfae0fa17279c442536ac1aa6190ce8f2e4cd Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Tue, 18 Oct 2022 09:22:37 -0700 Subject: [PATCH] Safer construction of notebook html --- .../browser/view/cellParts/cellOutput.ts | 10 +++++--- .../browser/view/renderers/webviewPreloads.ts | 25 ------------------- 2 files changed, 7 insertions(+), 28 deletions(-) diff --git a/src/vs/workbench/contrib/notebook/browser/view/cellParts/cellOutput.ts b/src/vs/workbench/contrib/notebook/browser/view/cellParts/cellOutput.ts index e2b8ea102ab11..13301228ca74c 100644 --- a/src/vs/workbench/contrib/notebook/browser/view/cellParts/cellOutput.ts +++ b/src/vs/workbench/contrib/notebook/browser/view/cellParts/cellOutput.ts @@ -236,16 +236,20 @@ class CellOutputElement extends Disposable { private _renderSearchForMimetype(viewModel: ICellOutputViewModel, mimeType: string): IInsetRenderOutput { const query = `@tag:notebookRenderer ${mimeType}`; + + const p = DOM.$('p', undefined, `No renderer could be found for mimetype "${mimeType}", but one might be available on the Marketplace.`); + const a = DOM.$('a', { href: `command:workbench.extensions.search?%22${query}%22`, class: 'monaco-button monaco-text-button', tabindex: 0, role: 'button', style: 'padding: 8px; text-decoration: none; color: rgb(255, 255, 255); background-color: rgb(14, 99, 156); max-width: 200px;' }, `Search Marketplace`); + return { type: RenderOutputType.Html, source: viewModel, - htmlContent: `

No renderer could be found for mimetype "${mimeType}", but one might be available on the Marketplace.

- Search Marketplace` + htmlContent: p.outerHTML + a.outerHTML }; } private _renderMessage(viewModel: ICellOutputViewModel, message: string): IInsetRenderOutput { - return { type: RenderOutputType.Html, source: viewModel, htmlContent: `

${message}

` }; + const el = DOM.$('p', undefined, message); + return { type: RenderOutputType.Html, source: viewModel, htmlContent: el.outerHTML }; } private async _attachToolbar(outputItemDiv: HTMLElement, notebookTextModel: NotebookTextModel, kernel: INotebookKernel | undefined, index: number, mimeTypes: readonly IOrderedMimeType[]) { diff --git a/src/vs/workbench/contrib/notebook/browser/view/renderers/webviewPreloads.ts b/src/vs/workbench/contrib/notebook/browser/view/renderers/webviewPreloads.ts index 6b92ec4521c80..e66f7487784bd 100644 --- a/src/vs/workbench/contrib/notebook/browser/view/renderers/webviewPreloads.ts +++ b/src/vs/workbench/contrib/notebook/browser/view/renderers/webviewPreloads.ts @@ -182,30 +182,6 @@ async function webviewPreloads(ctx: PreloadContext) { document.body.addEventListener('click', handleInnerClick); - const preservedScriptAttributes: (keyof HTMLScriptElement)[] = [ - 'type', 'src', 'nonce', 'noModule', 'async', - ]; - - // derived from https://github.com/jquery/jquery/blob/d0ce00cdfa680f1f0c38460bc51ea14079ae8b07/src/core/DOMEval.js - const domEval = (container: Element) => { - const arr = Array.from(container.getElementsByTagName('script')); - for (let n = 0; n < arr.length; n++) { - const node = arr[n]; - const scriptTag = document.createElement('script'); - const trustedScript = ttPolicy?.createScript(node.innerText) ?? node.innerText; - scriptTag.text = trustedScript as string; - for (const key of preservedScriptAttributes) { - const val = node[key] || node.getAttribute && node.getAttribute(key); - if (val) { - scriptTag.setAttribute(key, val as any); - } - } - - // TODO@connor4312: should script with src not be removed? - container.appendChild(scriptTag).parentNode!.removeChild(scriptTag); - } - }; - async function loadScriptSource(url: string, originalUri: string): Promise { const res = await fetch(url); const text = await res.text(); @@ -2312,7 +2288,6 @@ async function webviewPreloads(ctx: PreloadContext) { if (content.type === 0 /* RenderOutputType.Html */) { const trustedHtml = ttPolicy?.createHTML(content.htmlContent) ?? content.htmlContent; this.element.innerHTML = trustedHtml as string; - domEval(this.element); } else if (preloadErrors.some(e => e instanceof Error)) { const errors = preloadErrors.filter((e): e is Error => e instanceof Error); showRenderError(`Error loading preloads`, this.element, errors);