mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-16 10:58:30 -05:00
Merge from vscode 81d7885dc2e9dc617e1522697a2966bc4025a45d (#5949)
* Merge from vscode 81d7885dc2e9dc617e1522697a2966bc4025a45d * Fix vs unit tests and hygiene issue * Fix strict null check issue
This commit is contained in:
@@ -96,6 +96,16 @@ const _empty = '';
|
||||
const _slash = '/';
|
||||
const _regexp = /^(([^:/?#]+?):)?(\/\/([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?/;
|
||||
|
||||
function _isQueryStringScheme(scheme: string) {
|
||||
switch (scheme.toLowerCase()) {
|
||||
case 'http':
|
||||
case 'https':
|
||||
case 'ftp':
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Uniform Resource Identifier (URI) http://tools.ietf.org/html/rfc3986.
|
||||
* This class is a simple parser which creates the basic component parts
|
||||
@@ -282,14 +292,14 @@ export class URI implements UriComponents {
|
||||
static parse(value: string, _strict: boolean = false): URI {
|
||||
const match = _regexp.exec(value);
|
||||
if (!match) {
|
||||
return new _URI(_empty, _empty, _empty, _empty, _empty);
|
||||
return new _URI(_empty, _empty, _empty, _empty, _empty, _strict);
|
||||
}
|
||||
return new _URI(
|
||||
match[2] || _empty,
|
||||
decodeURIComponent(match[4] || _empty),
|
||||
decodeURIComponent(match[5] || _empty),
|
||||
decodeURIComponent(match[7] || _empty),
|
||||
decodeURIComponent(match[9] || _empty),
|
||||
decodeURIComponentFast(match[4] || _empty, false, false),
|
||||
decodeURIComponentFast(match[5] || _empty, true, false),
|
||||
decodeURIComponentFast(match[7] || _empty, false, _isQueryStringScheme(match[2])),
|
||||
decodeURIComponentFast(match[9] || _empty, false, false),
|
||||
_strict
|
||||
);
|
||||
}
|
||||
@@ -321,7 +331,7 @@ export class URI implements UriComponents {
|
||||
|
||||
// normalize to fwd-slashes on windows,
|
||||
// on other systems bwd-slashes are valid
|
||||
// filename character, eg /f\oo/ba\r.txt
|
||||
// filename character, e.g. /f\oo/ba\r.txt
|
||||
if (isWindows) {
|
||||
path = path.replace(/\\/g, _slash);
|
||||
}
|
||||
@@ -385,8 +395,8 @@ export class URI implements UriComponents {
|
||||
return data;
|
||||
} else {
|
||||
const result = new _URI(data);
|
||||
result._fsPath = (<UriState>data).fsPath;
|
||||
result._formatted = (<UriState>data).external;
|
||||
result._fsPath = (<UriState>data)._sep === _pathSepMarker ? (<UriState>data).fsPath : null;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -402,10 +412,12 @@ export interface UriComponents {
|
||||
|
||||
interface UriState extends UriComponents {
|
||||
$mid: number;
|
||||
fsPath: string;
|
||||
external: string;
|
||||
fsPath: string;
|
||||
_sep: 1 | undefined;
|
||||
}
|
||||
|
||||
const _pathSepMarker = isWindows ? 1 : undefined;
|
||||
|
||||
// tslint:disable-next-line:class-name
|
||||
class _URI extends URI {
|
||||
@@ -439,6 +451,7 @@ class _URI extends URI {
|
||||
// cached state
|
||||
if (this._fsPath) {
|
||||
res.fsPath = this._fsPath;
|
||||
res._sep = _pathSepMarker;
|
||||
}
|
||||
if (this._formatted) {
|
||||
res.external = this._formatted;
|
||||
@@ -463,6 +476,84 @@ class _URI extends URI {
|
||||
}
|
||||
}
|
||||
|
||||
function isHex(value: string, pos: number): boolean {
|
||||
if (pos >= value.length) {
|
||||
return false;
|
||||
}
|
||||
const code = value.charCodeAt(pos);
|
||||
return (code >= CharCode.Digit0 && code <= CharCode.Digit9)// 0-9
|
||||
|| (code >= CharCode.a && code <= CharCode.f) //a-f
|
||||
|| (code >= CharCode.A && code <= CharCode.F); //A-F
|
||||
}
|
||||
|
||||
|
||||
function decodeURIComponentFast(uriComponent: string, isPath: boolean, isQueryString: boolean): string {
|
||||
|
||||
let res: string | undefined;
|
||||
let nativeDecodePos = -1;
|
||||
|
||||
for (let pos = 0; pos < uriComponent.length; pos++) {
|
||||
const code = uriComponent.charCodeAt(pos);
|
||||
|
||||
// decoding needed
|
||||
if (code === CharCode.PercentSign && isHex(uriComponent, pos + 1) && isHex(uriComponent, pos + 2)) {
|
||||
|
||||
const chA = uriComponent.charCodeAt(pos + 1);
|
||||
const chB = uriComponent.charCodeAt(pos + 2);
|
||||
|
||||
// when in a path -> check and accept %2f and %2F (fwd slash)
|
||||
// when in a query string -> check and accept %3D, %26, and %3B (equals, ampersand, semi-colon)
|
||||
if (
|
||||
(isPath && chA === CharCode.Digit2 && (chB === CharCode.F || chB === CharCode.f))
|
||||
||
|
||||
(isQueryString && (
|
||||
(chA === CharCode.Digit2 && chB === CharCode.Digit6) // %26
|
||||
||
|
||||
(chA === CharCode.Digit3 && (chB === CharCode.B || chB === CharCode.b || chB === CharCode.D || chB === CharCode.d)) // %3D, %3D
|
||||
))
|
||||
) {
|
||||
if (nativeDecodePos !== -1) {
|
||||
res += decodeURIComponent(uriComponent.substring(nativeDecodePos, pos));
|
||||
nativeDecodePos = -1;
|
||||
}
|
||||
|
||||
if (res !== undefined) {
|
||||
res += uriComponent.substr(pos, 3);
|
||||
}
|
||||
|
||||
pos += 2;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (res === undefined) {
|
||||
res = uriComponent.substring(0, pos);
|
||||
}
|
||||
if (nativeDecodePos === -1) {
|
||||
nativeDecodePos = pos;
|
||||
}
|
||||
|
||||
pos += 2;
|
||||
|
||||
} else {
|
||||
|
||||
if (nativeDecodePos !== -1) {
|
||||
res += decodeURIComponent(uriComponent.substring(nativeDecodePos, pos));
|
||||
nativeDecodePos = -1;
|
||||
}
|
||||
|
||||
if (res !== undefined) {
|
||||
res += String.fromCharCode(code);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (nativeDecodePos !== -1) {
|
||||
res += decodeURIComponent(uriComponent.substr(nativeDecodePos));
|
||||
}
|
||||
|
||||
return res !== undefined ? res : uriComponent;
|
||||
}
|
||||
|
||||
// reserved characters: https://tools.ietf.org/html/rfc3986#section-2.2
|
||||
const encodeTable: { [ch: number]: string } = {
|
||||
[CharCode.Colon]: '%3A', // gen-delims
|
||||
@@ -488,7 +579,7 @@ const encodeTable: { [ch: number]: string } = {
|
||||
[CharCode.Space]: '%20',
|
||||
};
|
||||
|
||||
function encodeURIComponentFast(uriComponent: string, allowSlash: boolean): string {
|
||||
function encodeURIComponentFast(uriComponent: string, isPath: boolean, isQueryString: boolean): string {
|
||||
let res: string | undefined = undefined;
|
||||
let nativeEncodePos = -1;
|
||||
|
||||
@@ -504,7 +595,8 @@ function encodeURIComponentFast(uriComponent: string, allowSlash: boolean): stri
|
||||
|| code === CharCode.Period
|
||||
|| code === CharCode.Underline
|
||||
|| code === CharCode.Tilde
|
||||
|| (allowSlash && code === CharCode.Slash)
|
||||
|| (isPath && code === CharCode.Slash) // path => allow slash AS-IS
|
||||
|| (isQueryString && (code === CharCode.Equals || code === CharCode.Ampersand || code === CharCode.Semicolon)) // query string => allow &=;
|
||||
) {
|
||||
// check if we are delaying native encode
|
||||
if (nativeEncodePos !== -1) {
|
||||
@@ -516,6 +608,20 @@ function encodeURIComponentFast(uriComponent: string, allowSlash: boolean): stri
|
||||
res += uriComponent.charAt(pos);
|
||||
}
|
||||
|
||||
} else if (code === CharCode.PercentSign && isHex(uriComponent, pos + 1) && isHex(uriComponent, pos + 2)) {
|
||||
// at percentage encoded value
|
||||
|
||||
// check if we are delaying native encode
|
||||
if (nativeEncodePos !== -1) {
|
||||
res += encodeURIComponent(uriComponent.substring(nativeEncodePos, pos));
|
||||
nativeEncodePos = -1;
|
||||
}
|
||||
// check if we write into a new string (by default we try to return the param)
|
||||
if (res !== undefined) {
|
||||
res += uriComponent.substr(pos, 3);
|
||||
}
|
||||
pos += 2;
|
||||
|
||||
} else {
|
||||
// encoding needed, we need to allocate a new string
|
||||
if (res === undefined) {
|
||||
@@ -604,6 +710,7 @@ function _asFormatted(uri: URI, skipEncoding: boolean): string {
|
||||
|
||||
let res = '';
|
||||
let { scheme, authority, path, query, fragment } = uri;
|
||||
|
||||
if (scheme) {
|
||||
res += scheme;
|
||||
res += ':';
|
||||
@@ -620,22 +727,22 @@ function _asFormatted(uri: URI, skipEncoding: boolean): string {
|
||||
authority = authority.substr(idx + 1);
|
||||
idx = userinfo.indexOf(':');
|
||||
if (idx === -1) {
|
||||
res += encoder(userinfo, false);
|
||||
res += encoder(userinfo, false, false);
|
||||
} else {
|
||||
// <user>:<pass>@<auth>
|
||||
res += encoder(userinfo.substr(0, idx), false);
|
||||
res += encoder(userinfo.substr(0, idx), false, false);
|
||||
res += ':';
|
||||
res += encoder(userinfo.substr(idx + 1), false);
|
||||
res += encoder(userinfo.substr(idx + 1), false, false);
|
||||
}
|
||||
res += '@';
|
||||
}
|
||||
authority = authority.toLowerCase();
|
||||
idx = authority.indexOf(':');
|
||||
if (idx === -1) {
|
||||
res += encoder(authority, false);
|
||||
res += encoder(authority, false, false);
|
||||
} else {
|
||||
// <auth>:<port>
|
||||
res += encoder(authority.substr(0, idx), false);
|
||||
res += encoder(authority.substr(0, idx), false, false);
|
||||
res += authority.substr(idx);
|
||||
}
|
||||
}
|
||||
@@ -653,15 +760,15 @@ function _asFormatted(uri: URI, skipEncoding: boolean): string {
|
||||
}
|
||||
}
|
||||
// encode the rest of the path
|
||||
res += encoder(path, true);
|
||||
res += encoder(path, true, false);
|
||||
}
|
||||
if (query) {
|
||||
res += '?';
|
||||
res += encoder(query, false);
|
||||
res += encoder(query, false, _isQueryStringScheme(scheme));
|
||||
}
|
||||
if (fragment) {
|
||||
res += '#';
|
||||
res += !skipEncoding ? encodeURIComponentFast(fragment, false) : fragment;
|
||||
res += !skipEncoding ? encodeURIComponentFast(fragment, false, false) : fragment;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user