Skip to content

Commit

Permalink
fix #5917: 1. add Path.normalize methos; 2. normalize uri for Navigat…
Browse files Browse the repository at this point in the history
…ableWidgetOpenHandler

Signed-off-by: Cai Xuye <[email protected]>
  • Loading branch information
a1994846931931 committed Aug 13, 2019
1 parent 11badc8 commit f446b5d
Show file tree
Hide file tree
Showing 3 changed files with 125 additions and 1 deletion.
3 changes: 2 additions & 1 deletion packages/core/src/browser/navigatable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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`.
Expand Down Expand Up @@ -87,7 +88,7 @@ export abstract class NavigatableWidgetOpenHandler<W extends NavigatableWidget>
}

protected serializeUri(uri: URI): string {
return uri.withoutFragment().toString();
return Path.normalize(uri.withoutFragment().toString());
}

}
94 changes: 94 additions & 0 deletions packages/core/src/common/path.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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);
});
}

});
29 changes: 29 additions & 0 deletions packages/core/src/common/path.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down

0 comments on commit f446b5d

Please sign in to comment.