From acf0d09f043b195e37bfbc1b580f0a81ec6d67c9 Mon Sep 17 00:00:00 2001 From: Martin Aeschlimann Date: Thu, 9 Aug 2018 12:03:23 +0200 Subject: [PATCH] isMalformedFileUri fix and tests --- src/vs/base/common/resources.ts | 10 +++++++++- src/vs/base/test/common/resources.test.ts | 22 +++++++++++++++++++++- src/vs/workbench/api/node/apiCommands.ts | 9 ++++++--- 3 files changed, 36 insertions(+), 5 deletions(-) diff --git a/src/vs/base/common/resources.ts b/src/vs/base/common/resources.ts index df50dfeb419..8a20f1b859e 100644 --- a/src/vs/base/common/resources.ts +++ b/src/vs/base/common/resources.ts @@ -8,7 +8,7 @@ import * as paths from 'vs/base/common/paths'; import URI from 'vs/base/common/uri'; import { equalsIgnoreCase } from 'vs/base/common/strings'; import { Schemas } from 'vs/base/common/network'; -import { isLinux } from 'vs/base/common/platform'; +import { isLinux, isWindows } from 'vs/base/common/platform'; import { CharCode } from 'vs/base/common/charCode'; export function getComparisonKey(resource: URI): string { @@ -133,3 +133,11 @@ export function distinctParents(items: T[], resourceAccessor: (item: T) => UR return distinctParents; } + +export function isMalformedFileUri(candidate: URI): URI | undefined { + if (!candidate.scheme || isWindows && candidate.scheme.match(/^[a-zA-Z]$/)) { + return URI.file((candidate.scheme ? candidate.scheme + ':' : '') + candidate.path); + } + return void 0; +} + diff --git a/src/vs/base/test/common/resources.test.ts b/src/vs/base/test/common/resources.test.ts index ac6c9db534d..e35a9bb438d 100644 --- a/src/vs/base/test/common/resources.test.ts +++ b/src/vs/base/test/common/resources.test.ts @@ -5,7 +5,7 @@ 'use strict'; import * as assert from 'assert'; -import { dirname, basename, distinctParents, joinPath, isEqual, isEqualOrParent, hasToIgnoreCase, normalizePath, isAbsolutePath } from 'vs/base/common/resources'; +import { dirname, basename, distinctParents, joinPath, isEqual, isEqualOrParent, hasToIgnoreCase, normalizePath, isAbsolutePath, isMalformedFileUri } from 'vs/base/common/resources'; import URI from 'vs/base/common/uri'; import { isWindows } from 'vs/base/common/platform'; @@ -204,4 +204,24 @@ suite('Resources', () => { assert.equal(isEqualOrParent(fileURI3, fileURI, true), false, '15'); assert.equal(isEqualOrParent(fileURI5, fileURI5, true), true, '16'); }); + + function assertMalformedFileUri(path: string, expected: string) { + const newURI = isMalformedFileUri(URI.parse(path)); + assert.equal(newURI && newURI.toString(), expected); + } + + test('isMalformedFileUri', () => { + if (isWindows) { + assertMalformedFileUri('c:/foo/bar', 'file:///c%3A/foo/bar'); + assertMalformedFileUri('c:\\foo\\bar', 'file:///c%3A/foo/bar'); + assertMalformedFileUri('\\\\localhost\\c$\\devel\\test', 'file://localhost/c%24/devel/test'); + } + assertMalformedFileUri('/foo/bar', 'file:///foo/bar'); + + assertMalformedFileUri('file:///foo/bar', void 0); + assertMalformedFileUri('file:///c%3A/foo/bar', void 0); + assertMalformedFileUri('file://localhost/c$/devel/test', void 0); + assertMalformedFileUri('foo://dadie/foo/bar', void 0); + assertMalformedFileUri('foo:///dadie/foo/bar', void 0); + }); }); \ No newline at end of file diff --git a/src/vs/workbench/api/node/apiCommands.ts b/src/vs/workbench/api/node/apiCommands.ts index 6be39d21aaa..d04d6b2334c 100644 --- a/src/vs/workbench/api/node/apiCommands.ts +++ b/src/vs/workbench/api/node/apiCommands.ts @@ -5,6 +5,7 @@ 'use strict'; import URI from 'vs/base/common/uri'; +import { isMalformedFileUri } from 'vs/base/common/resources'; import * as vscode from 'vscode'; import * as typeConverters from 'vs/workbench/api/node/extHostTypeConverters'; import { CommandsRegistry, ICommandService, ICommandHandler } from 'vs/platform/commands/common/commands'; @@ -48,9 +49,11 @@ export class OpenFolderAPICommand { if (!uri) { return executor.executeCommand('_files.pickFolderAndOpen', forceNewWindow); } - if (!uri.scheme) { - console.warn(`'vscode.openFolder' command invoked with an invalid URI (scheme missing): '${uri}'. Converted to a 'file://' URI.`); - uri = URI.file(uri.toString()); + let correctedUri = isMalformedFileUri(uri); + if (correctedUri) { + // workaround for #55916 and #55891, will be removed in 1.28 + console.warn(`'vscode.openFolder' command invoked with an invalid URI (file:// scheme missing): '${uri}'. Converted to a 'file://' URI: ${correctedUri}`); + uri = correctedUri; } return executor.executeCommand('_files.windowOpen', [uri], forceNewWindow); -- GitLab