From f446b5dc9d3993bb85d79afcb328403d3ee61887 Mon Sep 17 00:00:00 2001 From: Cai Xuye Date: Tue, 13 Aug 2019 19:15:27 +0800 Subject: [PATCH] fix #5917: 1. add Path.normalize methos; 2. normalize uri for NavigatableWidgetOpenHandler Signed-off-by: Cai Xuye --- packages/core/src/browser/navigatable.ts | 3 +- packages/core/src/common/path.spec.ts | 94 ++++++++++++++++++++++++ packages/core/src/common/path.ts | 29 ++++++++ 3 files changed, 125 insertions(+), 1 deletion(-) diff --git a/packages/core/src/browser/navigatable.ts b/packages/core/src/browser/navigatable.ts index cd6321f6750f7..62bbcc04c7e97 100644 --- a/packages/core/src/browser/navigatable.ts +++ b/packages/core/src/browser/navigatable.ts @@ -18,6 +18,7 @@ import URI from '../common/uri'; import { MaybeArray } from '../common/types'; import { Widget, BaseWidget } from './widgets'; import { WidgetOpenHandler, WidgetOpenerOptions } from './widget-open-handler'; +import { Path } from '../common/path'; /** * `Navigatable` provides an access to an URI of an underlying instance of `Resource`. @@ -87,7 +88,7 @@ export abstract class NavigatableWidgetOpenHandler } protected serializeUri(uri: URI): string { - return uri.withoutFragment().toString(); + return Path.normalize(uri.withoutFragment().toString()); } } diff --git a/packages/core/src/common/path.spec.ts b/packages/core/src/common/path.spec.ts index 24457a304acd4..9edc6f25e907d 100644 --- a/packages/core/src/common/path.spec.ts +++ b/packages/core/src/common/path.spec.ts @@ -153,4 +153,98 @@ describe('Path', () => { }); } + assertNormalize({ + from: '/', + expectation: '/' + }); + + assertNormalize({ + from: '/c://', + expectation: '/c:/' + }); + + assertNormalize({ + from: '/foo', + expectation: '/foo' + }); + + assertNormalize({ + from: '/foo/', + expectation: '/foo/' + }); + + assertNormalize({ + from: '/foo/bar', + expectation: '/foo/bar' + }); + + assertNormalize({ + from: '/foo/../file.txt', + expectation: '/file.txt' + }); + + assertNormalize({ + from: '/foo/bar/../file.txt', + expectation: '/foo/file.txt' + }); + + assertNormalize({ + from: '/foo/../../file.txt', + expectation: '/file.txt' + }); + + assertNormalize({ + from: '', + expectation: '.' + }); + + assertNormalize({ + from: '.', + expectation: '.' + }); + + assertNormalize({ + from: '..', + expectation: '..' + }); + + assertNormalize({ + from: './foo', + expectation: 'foo' + }); + + assertNormalize({ + from: './foo/./.', + expectation: 'foo' + }); + + assertNormalize({ + from: './foo/', + expectation: 'foo/' + }); + + assertNormalize({ + from: '../foo', + expectation: '../foo' + }); + + assertNormalize({ + from: 'foo/..', + expectation: '.' + }); + + assertNormalize({ + from: 'foo/bar/../../../', + expectation: '../' + }); + + function assertNormalize({ from, expectation }: { + from: string, + expectation: string + }): void { + it(`path ${from} should be normalized as ${expectation}`, () => { + assert.deepStrictEqual(Path.normalize(from), expectation); + }); + } + }); diff --git a/packages/core/src/common/path.ts b/packages/core/src/common/path.ts index 6ead3e1f01884..057277307cffe 100644 --- a/packages/core/src/common/path.ts +++ b/packages/core/src/common/path.ts @@ -59,6 +59,35 @@ export class Path { return path; } + static normalize(raw: string): string { + const path = new Path(raw); + const trailingSlash = raw.endsWith('/'); + const pathArray = path.toString().split('/'); + const resultArray: string[] = []; + pathArray.forEach((value, index) => { + if (!value || value === '.') { + return; + } + if (value === '..') { + if (resultArray.length && resultArray[resultArray.length - 1] !== '..') { + resultArray.pop(); + } else if (!path.isAbsolute) { + resultArray.push('..'); + } + } else { + resultArray.push(value); + } + }); + if (resultArray.length === 0) { + if (path.isRoot) { + return '/'; + } else { + return '.'; + } + } + return (path.isAbsolute ? '/' : '') + resultArray.join('/') + (trailingSlash ? '/' : ''); + } + readonly isAbsolute: boolean; readonly isRoot: boolean; readonly root: Path | undefined;