Avoid uri parse warnings for markdown uris

Fixes #58566

We only support local file links or a small set of normal schemes, like `http` and `mailto`. Use this to avoid calling `Uri.parse` with scheme-less paths such as `Uri.parse('/images/cat.gif')`
This commit is contained in:
Matt Bierner
2018-09-13 14:28:59 -07:00
parent de57f74a3a
commit 4096b5d68e
3 changed files with 46 additions and 14 deletions

View File

@@ -3,34 +3,38 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as vscode from 'vscode';
import * as path from 'path';
import * as vscode from 'vscode';
import { OpenDocumentLinkCommand } from '../commands/openDocumentLink';
import { getUriForLinkWithKnownExternalScheme } from '../util/links';
function normalizeLink(
document: vscode.TextDocument,
link: string,
base: string
): vscode.Uri {
const uri = vscode.Uri.parse(link);
if (uri.scheme) {
return uri;
const externalSchemeUri = getUriForLinkWithKnownExternalScheme(link);
if (externalSchemeUri) {
return externalSchemeUri;
}
// assume it must be a file
let resourcePath = uri.path;
if (!uri.path) {
// Assume it must be an relative or absolute file path
// Use a fake scheme to avoid parse warnings
const tempUri = vscode.Uri.parse(`fake-scheme:${link}`);
let resourcePath = tempUri.path;
if (!tempUri.path) {
resourcePath = document.uri.path;
} else if (uri.path[0] === '/') {
} else if (tempUri.path[0] === '/') {
const root = vscode.workspace.getWorkspaceFolder(document.uri);
if (root) {
resourcePath = path.join(root.uri.fsPath, uri.path);
resourcePath = path.join(root.uri.fsPath, tempUri.path);
}
} else {
resourcePath = path.join(base, uri.path);
resourcePath = path.join(base, tempUri.path);
}
return OpenDocumentLinkCommand.createCommandUri(resourcePath, uri.fragment);
return OpenDocumentLinkCommand.createCommandUri(resourcePath, tempUri.fragment);
}
function matchAll(

View File

@@ -8,6 +8,7 @@ import * as path from 'path';
import * as vscode from 'vscode';
import { MarkdownContributions } from './markdownExtensions';
import { Slugifier } from './slugify';
import { getUriForLinkWithKnownExternalScheme } from './util/links';
const FrontMatterRegex = /^---\s*[^]*?(-{3}|\.{3})\s*/;
@@ -146,8 +147,17 @@ export class MarkdownEngine {
const normalizeLink = md.normalizeLink;
md.normalizeLink = (link: string) => {
try {
let uri = vscode.Uri.parse(link);
if (!uri.scheme && uri.path) {
const externalSchemeUri = getUriForLinkWithKnownExternalScheme(link);
if (externalSchemeUri) {
return normalizeLink(externalSchemeUri.toString());
}
// Assume it must be an relative or absolute file path
// Use a fake scheme to avoid parse warnings
let uri = vscode.Uri.parse(`fake-scheme:${link}`);
if (uri.path) {
// Assume it must be a file
const fragment = uri.fragment;
if (uri.path[0] === '/') {
@@ -165,7 +175,7 @@ export class MarkdownEngine {
});
}
return normalizeLink(uri.with({ scheme: 'vscode-resource' }).toString(true));
} else if (!uri.scheme && !uri.path && uri.fragment) {
} else if (!uri.path && uri.fragment) {
return normalizeLink(uri.with({
fragment: this.slugifier.fromHeading(uri.fragment).value
}).toString(true));

View File

@@ -0,0 +1,18 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as vscode from 'vscode';
const knownSchemes = ['http:', 'https:', 'file:', 'mailto:'];
export function getUriForLinkWithKnownExternalScheme(
link: string,
): vscode.Uri | undefined {
if (knownSchemes.some(knownScheme => link.toLowerCase().startsWith(knownScheme))) {
return vscode.Uri.parse(link);
}
return undefined;
}