Skip to content

Commit

Permalink
url: reduce pathToFileURL cpp calls
Browse files Browse the repository at this point in the history
  • Loading branch information
anonrig committed Jul 9, 2023
1 parent eece8d7 commit ce3764d
Showing 1 changed file with 26 additions and 13 deletions.
39 changes: 26 additions & 13 deletions lib/internal/url.js
Original file line number Diff line number Diff line change
Expand Up @@ -1414,6 +1414,8 @@ const backslashRegEx = /\\/g;
const newlineRegEx = /\n/g;
const carriageReturnRegEx = /\r/g;
const tabRegEx = /\t/g;
const questionRegex = /\?/;
const hashRegex = /#/;

function encodePathChars(filepath) {
if (StringPrototypeIncludes(filepath, '%'))
Expand All @@ -1431,8 +1433,8 @@ function encodePathChars(filepath) {
}

function pathToFileURL(filepath) {
const outURL = new URL('file://');
if (isWindows && StringPrototypeStartsWith(filepath, '\\\\')) {
const outURL = new URL('file://');
// UNC path format: \\server\share\resource
const hostnameEndIndex = StringPrototypeIndexOf(filepath, '\\', 2);
if (hostnameEndIndex === -1) {
Expand All @@ -1453,18 +1455,29 @@ function pathToFileURL(filepath) {
outURL.hostname = domainToASCII(hostname);
outURL.pathname = encodePathChars(
RegExpPrototypeSymbolReplace(backslashRegEx, StringPrototypeSlice(filepath, hostnameEndIndex), '/'));
} else {
let resolved = path.resolve(filepath);
// path.resolve strips trailing slashes so we must add them back
const filePathLast = StringPrototypeCharCodeAt(filepath,
filepath.length - 1);
if ((filePathLast === CHAR_FORWARD_SLASH ||
(isWindows && filePathLast === CHAR_BACKWARD_SLASH)) &&
resolved[resolved.length - 1] !== path.sep)
resolved += '/';
outURL.pathname = encodePathChars(resolved);
}
return outURL;
return outURL;
}
let resolved = path.resolve(filepath);
// path.resolve strips trailing slashes so we must add them back
const filePathLast = StringPrototypeCharCodeAt(filepath,
filepath.length - 1);
if ((filePathLast === CHAR_FORWARD_SLASH ||
(isWindows && filePathLast === CHAR_BACKWARD_SLASH)) &&
resolved[resolved.length - 1] !== path.sep)
resolved += '/';

// Call encodePathChars first to avoid encoding % again for ? and #.
resolved = encodePathChars(resolved);

// Question and hash character should be included in pathname.
// Therefore, encoding is required to eliminate parsing them in different states.
// This is done as an optimization to not creating a URL instance and
// later triggering pathname setter, which impacts performance
if (StringPrototypeIncludes(resolved, '?'))
resolved = RegExpPrototypeSymbolReplace(questionRegex, resolved, '%3F');
if (StringPrototypeIncludes(resolved, '#'))
resolved = RegExpPrototypeSymbolReplace(hashRegex, resolved, '%23');
return new URL(`file://${resolved}`);
}

function toPathIfFileURL(fileURLOrPath) {
Expand Down

0 comments on commit ce3764d

Please sign in to comment.