diff --git a/dist/index.js b/dist/index.js index c2cadc5f1..77bc44885 100644 --- a/dist/index.js +++ b/dist/index.js @@ -107479,11 +107479,30 @@ var has = Object.prototype.hasOwnProperty * Decode a URI encoded string. * * @param {String} input The URI encoded string. - * @returns {String} The decoded string. + * @returns {String|Null} The decoded string. * @api private */ function decode(input) { - return decodeURIComponent(input.replace(/\+/g, ' ')); + try { + return decodeURIComponent(input.replace(/\+/g, ' ')); + } catch (e) { + return null; + } +} + +/** + * Attempts to encode a given input. + * + * @param {String} input The string that needs to be encoded. + * @returns {String|Null} The encoded string. + * @api private + */ +function encode(input) { + try { + return encodeURIComponent(input); + } catch (e) { + return null; + } } /** @@ -107494,7 +107513,7 @@ function decode(input) { * @api public */ function querystring(query) { - var parser = /([^=?&]+)=?([^&]*)/g + var parser = /([^=?#&]+)=?([^&]*)/g , result = {} , part; @@ -107507,7 +107526,10 @@ function querystring(query) { // methods like `toString` or __proto__ are not overriden by malicious // querystrings. // - if (key in result) continue; + // In the case if failed decoding, we want to omit the key/value pairs + // from the result. + // + if (key === null || value === null || key in result) continue; result[key] = value; } @@ -107546,7 +107568,15 @@ function querystringify(obj, prefix) { value = ''; } - pairs.push(encodeURIComponent(key) +'='+ encodeURIComponent(value)); + key = encode(key); + value = encode(value); + + // + // If we failed to encode the strings, we should bail out as we don't + // want to add invalid strings to the query. + // + if (key === null || value === null) continue; + pairs.push(key +'='+ value); } } @@ -127026,8 +127056,21 @@ module.exports = async function updateDotenv (env) { var required = __nccwpck_require__(44742) , qs = __nccwpck_require__(13319) - , protocolre = /^([a-z][a-z0-9.+-]*:)?(\/\/)?([\S\s]*)/i - , slashes = /^[A-Za-z][A-Za-z0-9+-.]*:\/\//; + , slashes = /^[A-Za-z][A-Za-z0-9+-.]*:\/\// + , protocolre = /^([a-z][a-z0-9.+-]*:)?(\/\/)?([\\/]+)?([\S\s]*)/i + , windowsDriveLetter = /^[a-zA-Z]:/ + , whitespace = '[\\x09\\x0A\\x0B\\x0C\\x0D\\x20\\xA0\\u1680\\u180E\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200A\\u202F\\u205F\\u3000\\u2028\\u2029\\uFEFF]' + , left = new RegExp('^'+ whitespace +'+'); + +/** + * Trim a given string. + * + * @param {String} str String to trim. + * @public + */ +function trimLeft(str) { + return (str ? str : '').toString().replace(left, ''); +} /** * These are the parse rules for the URL parser, it informs the parser @@ -127044,8 +127087,8 @@ var required = __nccwpck_require__(44742) var rules = [ ['#', 'hash'], // Extract from the back. ['?', 'query'], // Extract from the back. - function sanitize(address) { // Sanitize what is left of the address - return address.replace('\\', '/'); + function sanitize(address, url) { // Sanitize what is left of the address + return isSpecial(url.protocol) ? address.replace(/\\/g, '/') : address; }, ['/', 'pathname'], // Extract from the back. ['@', 'auth', 1], // Extract from the front. @@ -127110,6 +127153,24 @@ function lolcation(loc) { return finaldestination; } +/** + * Check whether a protocol scheme is special. + * + * @param {String} The protocol scheme of the URL + * @return {Boolean} `true` if the protocol scheme is special, else `false` + * @private + */ +function isSpecial(scheme) { + return ( + scheme === 'file:' || + scheme === 'ftp:' || + scheme === 'http:' || + scheme === 'https:' || + scheme === 'ws:' || + scheme === 'wss:' + ); +} + /** * @typedef ProtocolExtract * @type Object @@ -127122,16 +127183,57 @@ function lolcation(loc) { * Extract protocol information from a URL with/without double slash ("//"). * * @param {String} address URL we want to extract from. + * @param {Object} location * @return {ProtocolExtract} Extracted information. * @private */ -function extractProtocol(address) { +function extractProtocol(address, location) { + address = trimLeft(address); + location = location || {}; + var match = protocolre.exec(address); + var protocol = match[1] ? match[1].toLowerCase() : ''; + var forwardSlashes = !!match[2]; + var otherSlashes = !!match[3]; + var slashesCount = 0; + var rest; + + if (forwardSlashes) { + if (otherSlashes) { + rest = match[2] + match[3] + match[4]; + slashesCount = match[2].length + match[3].length; + } else { + rest = match[2] + match[4]; + slashesCount = match[2].length; + } + } else { + if (otherSlashes) { + rest = match[3] + match[4]; + slashesCount = match[3].length; + } else { + rest = match[4] + } + } + + if (protocol === 'file:') { + if (slashesCount >= 2) { + rest = rest.slice(2); + } + } else if (isSpecial(protocol)) { + rest = match[4]; + } else if (protocol) { + if (forwardSlashes) { + rest = rest.slice(2); + } + } else if (slashesCount >= 2 && isSpecial(location.protocol)) { + rest = match[4]; + } return { - protocol: match[1] ? match[1].toLowerCase() : '', - slashes: !!match[2], - rest: match[3] + protocol: protocol, + slashes: forwardSlashes || isSpecial(protocol), + slashesCount: slashesCount, + rest: rest }; } @@ -127144,6 +127246,8 @@ function extractProtocol(address) { * @private */ function resolve(relative, base) { + if (relative === '') return base; + var path = (base || '/').split('/').slice(0, -1).concat(relative.split('/')) , i = path.length , last = path[i - 1] @@ -127184,6 +127288,8 @@ function resolve(relative, base) { * @private */ function Url(address, location, parser) { + address = trimLeft(address); + if (!(this instanceof Url)) { return new Url(address, location, parser); } @@ -127217,7 +127323,7 @@ function Url(address, location, parser) { // // Extract protocol information before running the instructions. // - extracted = extractProtocol(address || ''); + extracted = extractProtocol(address || '', location); relative = !extracted.protocol && !extracted.slashes; url.slashes = extracted.slashes || relative && location.slashes; url.protocol = extracted.protocol || location.protocol || ''; @@ -127227,13 +127333,22 @@ function Url(address, location, parser) { // When the authority component is absent the URL starts with a path // component. // - if (!extracted.slashes) instructions[3] = [/(.*)/, 'pathname']; + if ( + extracted.protocol === 'file:' && ( + extracted.slashesCount !== 2 || windowsDriveLetter.test(address)) || + (!extracted.slashes && + (extracted.protocol || + extracted.slashesCount < 2 || + !isSpecial(url.protocol))) + ) { + instructions[3] = [/(.*)/, 'pathname']; + } for (; i < instructions.length; i++) { instruction = instructions[i]; if (typeof instruction === 'function') { - address = instruction(address); + address = instruction(address, url); continue; } @@ -127287,6 +127402,14 @@ function Url(address, location, parser) { url.pathname = resolve(url.pathname, location.pathname); } + // + // Default to a / for pathname if none exists. This normalizes the URL + // to always have a / + // + if (url.pathname.charAt(0) !== '/' && isSpecial(url.protocol)) { + url.pathname = '/' + url.pathname; + } + // // We should not add port numbers if they are already the default port number // for a given protocol. As the host also contains the port number we're going @@ -127303,11 +127426,11 @@ function Url(address, location, parser) { url.username = url.password = ''; if (url.auth) { instruction = url.auth.split(':'); - url.username = instruction[0] || ''; + url.username = instruction[0]; url.password = instruction[1] || ''; } - url.origin = url.protocol && url.host && url.protocol !== 'file:' + url.origin = url.protocol !== 'file:' && isSpecial(url.protocol) && url.host ? url.protocol +'//'+ url.host : 'null'; @@ -127390,8 +127513,15 @@ function set(part, value, fn) { } break; - default: - url[part] = value; + case 'username': + case 'password': + url[part] = encodeURIComponent(value); + break; + + case 'auth': + var splits = value.split(':'); + url.username = splits[0]; + url.password = splits.length === 2 ? splits[1] : ''; } for (var i = 0; i < rules.length; i++) { @@ -127400,7 +127530,9 @@ function set(part, value, fn) { if (ins[4]) url[ins[1]] = url[ins[1]].toLowerCase(); } - url.origin = url.protocol && url.host && url.protocol !== 'file:' + url.auth = url.password ? url.username +':'+ url.password : url.username; + + url.origin = url.protocol !== 'file:' && isSpecial(url.protocol) && url.host ? url.protocol +'//'+ url.host : 'null'; @@ -127425,12 +127557,17 @@ function toString(stringify) { if (protocol && protocol.charAt(protocol.length - 1) !== ':') protocol += ':'; - var result = protocol + (url.slashes ? '//' : ''); + var result = + protocol + + ((url.protocol && url.slashes) || isSpecial(url.protocol) ? '//' : ''); if (url.username) { result += url.username; if (url.password) result += ':'+ url.password; result += '@'; + } else if (url.password) { + result += ':'+ url.password; + result += '@'; } result += url.host + url.pathname; @@ -127451,6 +127588,7 @@ Url.prototype = { set: set, toString: toString }; // Url.extractProtocol = extractProtocol; Url.location = lolcation; +Url.trimLeft = trimLeft; Url.qs = qs; module.exports = Url; diff --git a/yarn.lock b/yarn.lock index ab58b5425..762384b2d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5041,10 +5041,10 @@ qs@~6.5.2: resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA== -querystringify@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-2.1.0.tgz#7ded8dfbf7879dcc60d0a644ac6754b283ad17ef" - integrity sha512-sluvZZ1YiTLD5jsqZcDmFyV2EwToyXZBfpoVOmktMmW+VEnhgakFHnasVph65fOjGPTWN0Nw3+XQaSeMayr0kg== +querystringify@^2.1.1: + version "2.2.0" + resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-2.2.0.tgz#3345941b4153cb9d082d8eee4cda2016a9aef7f6" + integrity sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ== quick-format-unescaped@^4.0.1: version "4.0.1" @@ -6034,11 +6034,11 @@ url-parse-lax@^3.0.0: prepend-http "^2.0.0" url-parse@^1.4.3: - version "1.4.4" - resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.4.4.tgz#cac1556e95faa0303691fec5cf9d5a1bc34648f8" - integrity sha512-/92DTTorg4JjktLNLe6GPS2/RvAd/RGr6LuktmWSMLEOa6rjnlrFXNgSbSmkNvCoL2T028A0a1JaJLzRMlFoHg== + version "1.5.4" + resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.5.4.tgz#e4f645a7e2a0852cc8a66b14b292a3e9a11a97fd" + integrity sha512-ITeAByWWoqutFClc/lRZnFplgXgEZr3WJ6XngMM/N9DMIm4K8zXPCZ1Jdu0rERwO84w1WC5wkle2ubwTA4NTBg== dependencies: - querystringify "^2.0.0" + querystringify "^2.1.1" requires-port "^1.0.0" util-deprecate@^1.0.1: