diff options
Diffstat (limited to 'lib/internal/url.js')
-rw-r--r-- | lib/internal/url.js | 53 |
1 files changed, 38 insertions, 15 deletions
diff --git a/lib/internal/url.js b/lib/internal/url.js index ffd8f10eda..2afd2db9b7 100644 --- a/lib/internal/url.js +++ b/lib/internal/url.js @@ -20,13 +20,16 @@ const { ERR_MISSING_ARGS } = require('internal/errors').codes; const { - CHAR_PERCENT, - CHAR_PLUS, CHAR_AMPERSAND, + CHAR_BACKWARD_SLASH, CHAR_EQUAL, + CHAR_FORWARD_SLASH, CHAR_LOWERCASE_A, CHAR_LOWERCASE_Z, + CHAR_PERCENT, + CHAR_PLUS } = require('internal/constants'); +const path = require('path'); // Lazy loaded for startup performance. let querystring; @@ -1392,11 +1395,12 @@ function getPathFromURLPosix(url) { return decodeURIComponent(pathname); } -function getPathFromURL(path) { - if (path == null || !path[searchParams] || - !path[searchParams][searchParams]) { - return path; - } +function fileURLToPath(path) { + if (typeof path === 'string') + path = new URL(path); + else if (path == null || !path[searchParams] || + !path[searchParams][searchParams]) + throw new ERR_INVALID_ARG_TYPE('path', ['string', 'URL'], path); if (path.protocol !== 'file:') throw new ERR_INVALID_URL_SCHEME('file'); return isWindows ? getPathFromURLWin32(path) : getPathFromURLPosix(path); @@ -1406,12 +1410,30 @@ function getPathFromURL(path) { // as this is the only character that won't be percent encoded by // default URL percent encoding when pathname is set. const percentRegEx = /%/g; -function getURLFromFilePath(filepath) { - const tmp = new URL('file://'); - if (filepath.includes('%')) - filepath = filepath.replace(percentRegEx, '%25'); - tmp.pathname = filepath; - return tmp; +const backslashRegEx = /\\/g; +function pathToFileURL(filepath) { + let resolved = path.resolve(filepath); + // path.resolve strips trailing slashes so we must add them back + const filePathLast = filepath.charCodeAt(filepath.length - 1); + if ((filePathLast === CHAR_FORWARD_SLASH || + isWindows && filePathLast === CHAR_BACKWARD_SLASH) && + resolved[resolved.length - 1] !== path.sep) + resolved += '/'; + const outURL = new URL('file://'); + if (resolved.includes('%')) + resolved = resolved.replace(percentRegEx, '%25'); + // in posix, "/" is a valid character in paths + if (!isWindows && resolved.includes('\\')) + resolved = resolved.replace(backslashRegEx, '%5C'); + outURL.pathname = resolved; + return outURL; +} + +function toPathIfFileURL(fileURLOrPath) { + if (fileURLOrPath == null || !fileURLOrPath[searchParams] || + !fileURLOrPath[searchParams][searchParams]) + return fileURLOrPath; + return fileURLToPath(fileURLOrPath); } function NativeURL(ctx) { @@ -1441,8 +1463,9 @@ setURLConstructor(constructUrl); module.exports = { toUSVString, - getPathFromURL, - getURLFromFilePath, + fileURLToPath, + pathToFileURL, + toPathIfFileURL, URL, URLSearchParams, domainToASCII, |