Change:
Version: 1.62.0-insider (Universal) Commit: Date: 2021-10-28T05:14:00.367Z Electron: 13.5.1 Chrome: 91.0.4472.164 14.16.0 V8: 9.1.269.39-electron.0 OS: Darwin arm64 20.6.0 Setting , on the markdown document of a completion item, an tag cannot load a PNG file if the path given as a URI with . If the path given as the path of a local filesystem, it can load the file. Steps to Reproduce: one of images cannot be loaded. !
Can I pick this up?
Sure, the relevant code where we fix image paths is:
For the markdown syntax images, if the URI schema is , that's being changed to . For the HTML tag images, the file URI remains as is. The HTML image with URI doesn't load due to CSP violation.
Yes uris are blocked for security reasons. The problem is that raw html tags don't go through the transform that I linked to One thing to try would be to look for image nodes in the rendered markdown and then transform their uris instead of relying on the markdown parser to handle the transform. Try looking at for that
/verified

Discussion:
const _href = function (href: string, isDomUri: boolean): string { const data = markdown.uris && markdown.uris[href]; <del> if (!data) { return href; // no uri exists } </del> let uri = URI.revive(data); if (isDomUri) { if (href.startsWith(Schemas.data + ':')) { return href; } <ins> if (!uri) { uri = URI.parse(href); } </ins> // this URI will end up as "src"-attribute of a dom node // and because of that special rewriting needs to be done // so that the URI uses a protocol that's understood by // browsers (like http or https) return FileAccess.asBrowserUri(uri).toString(true); } <ins> if (!uri) { return href; } </ins> if (URI.parse(href).toString() === uri.toString()) { return href; // no transformation performed }

const withInnerHTML = new Promise<void>(c => signalInnerHTML = c); const renderer = new marked.Renderer(); renderer.image = (href: string, title: string, text: string) => { let dimensions: string[] = []; let attributes: string[] = []; if (href) { ({ href, dimensions } = parseHrefAndDimensions(href)); <del> href = _href(href, true); try { const hrefAsUri = URI.parse(href); if (options.baseUrl && hrefAsUri.scheme === Schemas.file) { // absolute or relative local path, or file: uri href = resolvePath(options.baseUrl, href).toString(); } } catch (err) { } </del> attributes.push(`src="${href}"`); } if (text) {

renderedMarkdown = elements.map(e => typeof e === 'string' ? e : e.outerHTML).join(''); } <del> element.innerHTML = sanitizeRenderedMarkdown(markdown, renderedMarkdown) as unknown as string; </del> <ins> const htmlParser = new DOMParser(); const markdownHtmlDoc = htmlParser.parseFromString(sanitizeRenderedMarkdown(markdown, renderedMarkdown) as unknown as string, 'text/html'); markdownHtmlDoc.body.querySelectorAll('img') .forEach(img => { if (img.src) { let href = _href(img.src, true); try { const hrefAsUri = URI.parse(href); if (options.baseUrl && hrefAsUri.scheme === Schemas.file) { // absolute or relative local path, or file: uri href = resolvePath(options.baseUrl, href).toString(); } } catch (err) { } img.src = href; } }); element.innerHTML = sanitizeRenderedMarkdown(markdown, markdownHtmlDoc.body.innerHTML) as unknown as string; </ins> // signal that async code blocks can be now be inserted signalInnerHTML!();

const result: HTMLElement = renderMarkdown({ value: `![image](http://example.com/cat.gif|height=200,width=100 'caption')` }).element; assertNodeEquals(result, `<div><p><img height="200" width="100" title="caption" alt="image" src="http://example.com/cat.gif"></p></div>`); }); <ins> test('image with file uri should render as same origin uri', () => { const result: HTMLElement = renderMarkdown({ value: `![image](file:///images/cat.gif)` }).element; assertNodeEquals(result, '<div><p><img src="vscode-file://vscode-app/images/cat.gif" alt="image"></p></div>'); }); </ins> }); suite('Code block renderer', () => {

mds.appendMarkdown(`[$(zap)-link](#link)`); let result: HTMLElement = renderMarkdown(mds).element; <del> assert.strictEqual(result.innerHTML, `<p><a title="#link" data-href="#link" href="#"><span class="codicon codicon-zap"></span>-link</a></p>`); </del> <ins> assert.strictEqual(result.innerHTML, `<p><a href="#" data-href="#link" title="#link"><span class="codicon codicon-zap"></span>-link</a></p>`); </ins> }); test('render icon in table', () => {

</thead> <tbody><tr> <td><span class="codicon codicon-zap"></span></td> <del> <td><a title="#link" data-href="#link" href="#"><span class="codicon codicon-zap"></span>-link</a></td> </del> <ins> <td><a href="#" data-href="#link" title="#link"><span class="codicon codicon-zap"></span>-link</a></td> </ins> </tr> </tbody></table> `);

const result = renderMarkdown(mds).element; assert.strictEqual(result.innerHTML, `<p>a&lt;b&gt;b&lt;/b&gt;c</p>`); }); <ins> test('Should render html images', () => { const mds = new MarkdownString(undefined, { supportHtml: true }); mds.appendMarkdown(`<img src="http://example.com/cat.gif">`); const result = renderMarkdown(mds).element; assert.strictEqual(result.innerHTML, `<img src="http://example.com/cat.gif">`); }); test('Should render html images with file uri as same origin uri', () => { const mds = new MarkdownString(undefined, { supportHtml: true }); mds.appendMarkdown(`<img src="file:///images/cat.gif">`); const result = renderMarkdown(mds).element; assert.strictEqual(result.innerHTML, `<img src="vscode-file://vscode-app/images/cat.gif">`); }); </ins> }); });