ensure path-component of file, http, and https-uris is absolute, #34449

This commit is contained in:
Johannes Rieken 2018-05-02 16:11:23 +02:00
parent 950d4bff5b
commit 06eebb87fa
3 changed files with 31 additions and 22 deletions

View file

@ -50,6 +50,27 @@ function _validateUri(ret: URI): void {
}
}
// implements a bit of https://tools.ietf.org/html/rfc3986#section-5
function _referenceResolution(scheme: string, path: string): string {
// the slash-character is our 'default base' as we don't
// support constructing URIs relative to other URIs. This
// also means that we alter and potentially break paths.
// see https://tools.ietf.org/html/rfc3986#section-5.1.4
switch (scheme) {
case 'https':
case 'http':
case 'file':
if (!path) {
path = _slash;
} else if (path[0] !== _slash) {
path = _slash + path;
}
break;
}
return path;
}
const _empty = '';
const _slash = '/';
const _regexp = /^(([^:/?#]+?):)?(\/\/([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?/;
@ -142,14 +163,10 @@ export default class URI implements UriComponents {
} else {
this.scheme = schemeOrData || _empty;
this.authority = authority || _empty;
this.path = path || _empty;
this.path = _referenceResolution(this.scheme, path || _empty);
this.query = query || _empty;
this.fragment = fragment || _empty;
// if (this.path[0] !== _slash) {
// this.path = _slash + this.path;
// }
_validateUri(this);
}
}
@ -253,14 +270,6 @@ export default class URI implements UriComponents {
}
}
// the slash-character is our 'default base' as we don't
// support constructing URIs relative to other URIs. This
// also means that we alter and potentially break paths.
// see https://tools.ietf.org/html/rfc3986#section-5.1.4
if (path[0] !== _slash) {
path = _slash + path;
}
return new _URI('file', authority, path, _empty, _empty);
}
@ -377,7 +386,7 @@ class _URI extends URI {
function _makeFsPath(uri: URI): string {
let value: string;
if (uri.authority && uri.path && uri.scheme === 'file') {
if (uri.authority && uri.path.length > 1 && uri.scheme === 'file') {
// unc path: file://shares/c$/far/boo
value = `//${uri.authority}${uri.path}`;
} else if (_driveLetterPath.test(uri.path)) {

View file

@ -36,7 +36,7 @@ suite('Network', () => {
);
assertUrl('http://www.test.com:8000#hash',
'http', 'www.test.com', '8000', '', '', 'hash'
'http', 'www.test.com', '8000', '/', '', 'hash'
);
assertUrl('http://www.test.com/#hash',
@ -44,7 +44,7 @@ suite('Network', () => {
);
assertUrl('http://www.test.com#hash',
'http', 'www.test.com', '', '', '', 'hash'
'http', 'www.test.com', '', '/', '', 'hash'
);
assertUrl('http://www.test.com:8000/this/that/theother.html',
@ -56,7 +56,7 @@ suite('Network', () => {
);
assertUrl('http://www.test.com:8000',
'http', 'www.test.com', '8000', '', '', ''
'http', 'www.test.com', '8000', '/', '', ''
);
assertUrl('http://www.test.com/',

View file

@ -51,15 +51,15 @@ suite('URI', () => {
test('URI#fsPath - no `fsPath` when no `path`', () => {
const value = URI.parse('file://%2Fhome%2Fticino%2Fdesktop%2Fcpluscplus%2Ftest.cpp');
assert.equal(value.authority, '/home/ticino/desktop/cpluscplus/test.cpp');
assert.equal(value.path, '');
assert.equal(value.fsPath, '');
assert.equal(value.path, '/');
assert.equal(value.fsPath, '/');
});
test('http#toString', () => {
assert.equal(URI.from({ scheme: 'http', authority: 'www.msft.com', path: '/my/path' }).toString(), 'http://www.msft.com/my/path');
assert.equal(URI.from({ scheme: 'http', authority: 'www.msft.com', path: '/my/path' }).toString(), 'http://www.msft.com/my/path');
assert.equal(URI.from({ scheme: 'http', authority: 'www.MSFT.com', path: '/my/path' }).toString(), 'http://www.msft.com/my/path');
assert.equal(URI.from({ scheme: 'http', authority: '', path: 'my/path' }).toString(), 'http:my/path');
assert.equal(URI.from({ scheme: 'http', authority: '', path: 'my/path' }).toString(), 'http:/my/path');
assert.equal(URI.from({ scheme: 'http', authority: '', path: '/my/path' }).toString(), 'http:/my/path');
assert.equal(URI.from({ scheme: '', authority: '', path: 'my/path' }).toString(), 'my/path');
assert.equal(URI.from({ scheme: '', authority: '', path: '/my/path' }).toString(), '/my/path');
@ -213,7 +213,7 @@ suite('URI', () => {
value = URI.parse('file:?q');
assert.equal(value.scheme, 'file');
assert.equal(value.authority, '');
assert.equal(value.path, '');
assert.equal(value.path, '/');
assert.equal(value.query, 'q');
assert.equal(value.fragment, '');
@ -227,7 +227,7 @@ suite('URI', () => {
value = URI.parse('file:#d');
assert.equal(value.scheme, 'file');
assert.equal(value.authority, '');
assert.equal(value.path, '');
assert.equal(value.path, '/');
assert.equal(value.query, '');
assert.equal(value.fragment, 'd');