提交 2c1c691b 编写于 作者: J Johannes Rieken

uri - remove strict mode, use file when scheme is missing

上级 259b7bfb
...@@ -10,26 +10,11 @@ const _schemePattern = /^\w[\w\d+.-]*$/; ...@@ -10,26 +10,11 @@ const _schemePattern = /^\w[\w\d+.-]*$/;
const _singleSlashStart = /^\//; const _singleSlashStart = /^\//;
const _doubleSlashStart = /^\/\//; const _doubleSlashStart = /^\/\//;
let _throwOnMissingSchema: boolean = true; function _validateUri(ret: URI): void {
/**
* @internal
*/
export function setUriThrowOnMissingScheme(value: boolean): boolean {
const old = _throwOnMissingSchema;
_throwOnMissingSchema = value;
return old;
}
function _validateUri(ret: URI, _strict?: boolean): void {
// scheme, must be set // scheme, must be set
if (!ret.scheme) { if (!ret.scheme) {
if (_strict || _throwOnMissingSchema) { throw new Error(`[UriError]: Scheme is missing: {scheme: "", authority: "${ret.authority}", path: "${ret.path}", query: "${ret.query}", fragment: "${ret.fragment}"}`);
throw new Error(`[UriError]: Scheme is missing: {scheme: "", authority: "${ret.authority}", path: "${ret.path}", query: "${ret.query}", fragment: "${ret.fragment}"}`);
} else {
console.warn(`[UriError]: Scheme is missing: {scheme: "", authority: "${ret.authority}", path: "${ret.path}", query: "${ret.query}", fragment: "${ret.fragment}"}`);
}
} }
// scheme, https://tools.ietf.org/html/rfc3986#section-3.1 // scheme, https://tools.ietf.org/html/rfc3986#section-3.1
...@@ -56,14 +41,8 @@ function _validateUri(ret: URI, _strict?: boolean): void { ...@@ -56,14 +41,8 @@ function _validateUri(ret: URI, _strict?: boolean): void {
} }
} }
// for a while we allowed uris *without* schemes and this is the migration // graceful behaviour when scheme is missing: fallback to using 'file'-scheme
// for them, e.g. an uri without scheme and without strict-mode warns and falls function _schemeFix(scheme: string): string {
// back to the file-scheme. that should cause the least carnage and still be a
// clear warning
function _schemeFix(scheme: string, _strict: boolean): string {
if (_strict || _throwOnMissingSchema) {
return scheme || _empty;
}
if (!scheme) { if (!scheme) {
console.trace('BAD uri lacks scheme, falling back to file-scheme.'); console.trace('BAD uri lacks scheme, falling back to file-scheme.');
scheme = 'file'; scheme = 'file';
...@@ -159,7 +138,7 @@ export class URI implements UriComponents { ...@@ -159,7 +138,7 @@ export class URI implements UriComponents {
/** /**
* @internal * @internal
*/ */
protected constructor(scheme: string, authority?: string, path?: string, query?: string, fragment?: string, _strict?: boolean); protected constructor(scheme: string, authority?: string, path?: string, query?: string, fragment?: string);
/** /**
* @internal * @internal
...@@ -169,7 +148,7 @@ export class URI implements UriComponents { ...@@ -169,7 +148,7 @@ export class URI implements UriComponents {
/** /**
* @internal * @internal
*/ */
protected constructor(schemeOrData: string | UriComponents, authority?: string, path?: string, query?: string, fragment?: string, _strict: boolean = false) { protected constructor(schemeOrData: string | UriComponents, authority?: string, path?: string, query?: string, fragment?: string) {
if (typeof schemeOrData === 'object') { if (typeof schemeOrData === 'object') {
this.scheme = schemeOrData.scheme || _empty; this.scheme = schemeOrData.scheme || _empty;
...@@ -181,13 +160,13 @@ export class URI implements UriComponents { ...@@ -181,13 +160,13 @@ export class URI implements UriComponents {
// that creates uri components. // that creates uri components.
// _validateUri(this); // _validateUri(this);
} else { } else {
this.scheme = _schemeFix(schemeOrData, _strict); this.scheme = _schemeFix(schemeOrData);
this.authority = authority || _empty; this.authority = authority || _empty;
this.path = _referenceResolution(this.scheme, path || _empty); this.path = _referenceResolution(this.scheme, path || _empty);
this.query = query || _empty; this.query = query || _empty;
this.fragment = fragment || _empty; this.fragment = fragment || _empty;
_validateUri(this, _strict); _validateUri(this);
} }
} }
...@@ -226,7 +205,7 @@ export class URI implements UriComponents { ...@@ -226,7 +205,7 @@ export class URI implements UriComponents {
// ---- modify to new ------------------------- // ---- modify to new -------------------------
with(change: { scheme?: string; authority?: string | null; path?: string | null; query?: string | null; fragment?: string | null }): URI { with(change: { scheme?: string; authority?: string | null; path?: string | null; query?: string | null; fragment?: string | null; }): URI {
if (!change) { if (!change) {
return this; return this;
...@@ -279,7 +258,7 @@ export class URI implements UriComponents { ...@@ -279,7 +258,7 @@ export class URI implements UriComponents {
* *
* @param value A string which represents an URI (see `URI#toString`). * @param value A string which represents an URI (see `URI#toString`).
*/ */
static parse(value: string, _strict: boolean = false): URI { static parse(value: string): URI {
const match = _regexp.exec(value); const match = _regexp.exec(value);
if (!match) { if (!match) {
return new _URI(_empty, _empty, _empty, _empty, _empty); return new _URI(_empty, _empty, _empty, _empty, _empty);
...@@ -289,8 +268,7 @@ export class URI implements UriComponents { ...@@ -289,8 +268,7 @@ export class URI implements UriComponents {
decodeURIComponent(match[4] || _empty), decodeURIComponent(match[4] || _empty),
decodeURIComponent(match[5] || _empty), decodeURIComponent(match[5] || _empty),
decodeURIComponent(match[7] || _empty), decodeURIComponent(match[7] || _empty),
decodeURIComponent(match[9] || _empty), decodeURIComponent(match[9] || _empty)
_strict
); );
} }
...@@ -342,7 +320,7 @@ export class URI implements UriComponents { ...@@ -342,7 +320,7 @@ export class URI implements UriComponents {
return new _URI('file', authority, path, _empty, _empty); return new _URI('file', authority, path, _empty, _empty);
} }
static from(components: { scheme: string; authority?: string; path?: string; query?: string; fragment?: string }): URI { static from(components: { scheme: string; authority?: string; path?: string; query?: string; fragment?: string; }): URI {
return new _URI( return new _URI(
components.scheme, components.scheme,
components.authority, components.authority,
...@@ -466,7 +444,7 @@ class _URI extends URI { ...@@ -466,7 +444,7 @@ class _URI extends URI {
} }
// reserved characters: https://tools.ietf.org/html/rfc3986#section-2.2 // reserved characters: https://tools.ietf.org/html/rfc3986#section-2.2
const encodeTable: { [ch: number]: string } = { const encodeTable: { [ch: number]: string; } = {
[CharCode.Colon]: '%3A', // gen-delims [CharCode.Colon]: '%3A', // gen-delims
[CharCode.Slash]: '%2F', [CharCode.Slash]: '%2F',
[CharCode.QuestionMark]: '%3F', [CharCode.QuestionMark]: '%3F',
......
...@@ -55,7 +55,6 @@ declare namespace monaco { ...@@ -55,7 +55,6 @@ declare namespace monaco {
*/ */
readonly onCancellationRequested: IEvent<any>; readonly onCancellationRequested: IEvent<any>;
} }
/** /**
* Uniform Resource Identifier (Uri) http://tools.ietf.org/html/rfc3986. * Uniform Resource Identifier (Uri) http://tools.ietf.org/html/rfc3986.
* This class is a simple parser which creates the basic component parts * This class is a simple parser which creates the basic component parts
...@@ -132,7 +131,7 @@ declare namespace monaco { ...@@ -132,7 +131,7 @@ declare namespace monaco {
* *
* @param value A string which represents an Uri (see `Uri#toString`). * @param value A string which represents an Uri (see `Uri#toString`).
*/ */
static parse(value: string, _strict?: boolean): Uri; static parse(value: string): Uri;
/** /**
* Creates a new Uri from a file system path, e.g. `c:\my\files`, * Creates a new Uri from a file system path, e.g. `c:\my\files`,
* `/usr/home`, or `\\server\share\some\path`. * `/usr/home`, or `\\server\share\some\path`.
......
...@@ -255,12 +255,12 @@ export namespace MarkdownString { ...@@ -255,12 +255,12 @@ export namespace MarkdownString {
} }
// extract uris into a separate object // extract uris into a separate object
const resUris: { [href: string]: UriComponents } = Object.create(null); const resUris: { [href: string]: UriComponents; } = Object.create(null);
res.uris = resUris; res.uris = resUris;
const collectUri = (href: string): string => { const collectUri = (href: string): string => {
try { try {
let uri = URI.parse(href, true); let uri = URI.parse(href);
uri = uri.with({ query: _uriMassage(uri.query, resUris) }); uri = uri.with({ query: _uriMassage(uri.query, resUris) });
resUris[href] = uri; resUris[href] = uri;
} catch (e) { } catch (e) {
...@@ -277,7 +277,7 @@ export namespace MarkdownString { ...@@ -277,7 +277,7 @@ export namespace MarkdownString {
return res; return res;
} }
function _uriMassage(part: string, bucket: { [n: string]: UriComponents }): string { function _uriMassage(part: string, bucket: { [n: string]: UriComponents; }): string {
if (!part) { if (!part) {
return part; return part;
} }
...@@ -513,7 +513,7 @@ export namespace WorkspaceEdit { ...@@ -513,7 +513,7 @@ export namespace WorkspaceEdit {
export namespace SymbolKind { export namespace SymbolKind {
const _fromMapping: { [kind: number]: modes.SymbolKind } = Object.create(null); const _fromMapping: { [kind: number]: modes.SymbolKind; } = Object.create(null);
_fromMapping[types.SymbolKind.File] = modes.SymbolKind.File; _fromMapping[types.SymbolKind.File] = modes.SymbolKind.File;
_fromMapping[types.SymbolKind.Module] = modes.SymbolKind.Module; _fromMapping[types.SymbolKind.Module] = modes.SymbolKind.Module;
_fromMapping[types.SymbolKind.Namespace] = modes.SymbolKind.Namespace; _fromMapping[types.SymbolKind.Namespace] = modes.SymbolKind.Namespace;
...@@ -903,7 +903,7 @@ export namespace DocumentLink { ...@@ -903,7 +903,7 @@ export namespace DocumentLink {
let target: URI | undefined = undefined; let target: URI | undefined = undefined;
if (link.url) { if (link.url) {
try { try {
target = typeof link.url === 'string' ? URI.parse(link.url, true) : URI.revive(link.url); target = typeof link.url === 'string' ? URI.parse(link.url) : URI.revive(link.url);
} catch (err) { } catch (err) {
// ignore // ignore
} }
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
import { timeout } from 'vs/base/common/async'; import { timeout } from 'vs/base/common/async';
import * as errors from 'vs/base/common/errors'; import * as errors from 'vs/base/common/errors';
import { DisposableStore } from 'vs/base/common/lifecycle'; import { DisposableStore } from 'vs/base/common/lifecycle';
import { URI, setUriThrowOnMissingScheme } from 'vs/base/common/uri'; import { URI } from 'vs/base/common/uri';
import { IURITransformer } from 'vs/base/common/uriIpc'; import { IURITransformer } from 'vs/base/common/uriIpc';
import { IMessagePassingProtocol } from 'vs/base/parts/ipc/common/ipc'; import { IMessagePassingProtocol } from 'vs/base/parts/ipc/common/ipc';
import { IInitData, MainContext, MainThreadConsoleShape } from 'vs/workbench/api/common/extHost.protocol'; import { IInitData, MainContext, MainThreadConsoleShape } from 'vs/workbench/api/common/extHost.protocol';
...@@ -22,10 +22,6 @@ import { IExtHostRpcService, ExtHostRpcService } from 'vs/workbench/api/common/e ...@@ -22,10 +22,6 @@ import { IExtHostRpcService, ExtHostRpcService } from 'vs/workbench/api/common/e
import { IURITransformerService, URITransformerService } from 'vs/workbench/api/common/extHostUriTransformerService'; import { IURITransformerService, URITransformerService } from 'vs/workbench/api/common/extHostUriTransformerService';
import { IExtHostExtensionService, IHostUtils } from 'vs/workbench/api/common/extHostExtensionService'; import { IExtHostExtensionService, IHostUtils } from 'vs/workbench/api/common/extHostExtensionService';
// we don't (yet) throw when extensions parse
// uris that have no scheme
setUriThrowOnMissingScheme(false);
export interface IExitFn { export interface IExitFn {
(code?: number): any; (code?: number): any;
} }
......
...@@ -22,11 +22,13 @@ suite('ExtHostTypeConverter', function () { ...@@ -22,11 +22,13 @@ suite('ExtHostTypeConverter', function () {
data = MarkdownString.from('Hello [link](foo)'); data = MarkdownString.from('Hello [link](foo)');
assert.equal(data.value, 'Hello [link](foo)'); assert.equal(data.value, 'Hello [link](foo)');
assert.equal(isEmptyObject(data.uris), true); // no scheme, no uri assert.equal(size(data.uris!), 1);
assert.ok(!!data.uris!['foo']);
data = MarkdownString.from('Hello [link](www.noscheme.bad)'); data = MarkdownString.from('Hello [link](www.noscheme.bad)');
assert.equal(data.value, 'Hello [link](www.noscheme.bad)'); assert.equal(data.value, 'Hello [link](www.noscheme.bad)');
assert.equal(isEmptyObject(data.uris), true); // no scheme, no uri assert.equal(size(data.uris!), 1);
assert.ok(!!data.uris!['www.noscheme.bad']);
data = MarkdownString.from('Hello [link](foo:path)'); data = MarkdownString.from('Hello [link](foo:path)');
assert.equal(data.value, 'Hello [link](foo:path)'); assert.equal(data.value, 'Hello [link](foo:path)');
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册