Skip to content

Commit 7196946

Browse files
authored
url: reduce pathToFileURL cpp calls
PR-URL: #48709 Reviewed-By: Luigi Pinca <[email protected]> Reviewed-By: Stephen Belanger <[email protected]> Reviewed-By: Antoine du Hamel <[email protected]>
1 parent a67cb6c commit 7196946

File tree

1 file changed

+31
-18
lines changed

1 file changed

+31
-18
lines changed

lib/internal/url.js

+31-18
Original file line numberDiff line numberDiff line change
@@ -1422,25 +1422,27 @@ const backslashRegEx = /\\/g;
14221422
const newlineRegEx = /\n/g;
14231423
const carriageReturnRegEx = /\r/g;
14241424
const tabRegEx = /\t/g;
1425+
const questionRegex = /\?/g;
1426+
const hashRegex = /#/g;
14251427

14261428
function encodePathChars(filepath) {
1427-
if (StringPrototypeIncludes(filepath, '%'))
1429+
if (StringPrototypeIndexOf(filepath, '%') !== -1)
14281430
filepath = RegExpPrototypeSymbolReplace(percentRegEx, filepath, '%25');
14291431
// In posix, backslash is a valid character in paths:
1430-
if (!isWindows && StringPrototypeIncludes(filepath, '\\'))
1432+
if (!isWindows && StringPrototypeIndexOf(filepath, '\\') !== -1)
14311433
filepath = RegExpPrototypeSymbolReplace(backslashRegEx, filepath, '%5C');
1432-
if (StringPrototypeIncludes(filepath, '\n'))
1434+
if (StringPrototypeIndexOf(filepath, '\n') !== -1)
14331435
filepath = RegExpPrototypeSymbolReplace(newlineRegEx, filepath, '%0A');
1434-
if (StringPrototypeIncludes(filepath, '\r'))
1436+
if (StringPrototypeIndexOf(filepath, '\r') !== -1)
14351437
filepath = RegExpPrototypeSymbolReplace(carriageReturnRegEx, filepath, '%0D');
1436-
if (StringPrototypeIncludes(filepath, '\t'))
1438+
if (StringPrototypeIndexOf(filepath, '\t') !== -1)
14371439
filepath = RegExpPrototypeSymbolReplace(tabRegEx, filepath, '%09');
14381440
return filepath;
14391441
}
14401442

14411443
function pathToFileURL(filepath) {
1442-
const outURL = new URL('file://');
14431444
if (isWindows && StringPrototypeStartsWith(filepath, '\\\\')) {
1445+
const outURL = new URL('file://');
14441446
// UNC path format: \\server\share\resource
14451447
const hostnameEndIndex = StringPrototypeIndexOf(filepath, '\\', 2);
14461448
if (hostnameEndIndex === -1) {
@@ -1461,18 +1463,29 @@ function pathToFileURL(filepath) {
14611463
outURL.hostname = domainToASCII(hostname);
14621464
outURL.pathname = encodePathChars(
14631465
RegExpPrototypeSymbolReplace(backslashRegEx, StringPrototypeSlice(filepath, hostnameEndIndex), '/'));
1464-
} else {
1465-
let resolved = path.resolve(filepath);
1466-
// path.resolve strips trailing slashes so we must add them back
1467-
const filePathLast = StringPrototypeCharCodeAt(filepath,
1468-
filepath.length - 1);
1469-
if ((filePathLast === CHAR_FORWARD_SLASH ||
1470-
(isWindows && filePathLast === CHAR_BACKWARD_SLASH)) &&
1471-
resolved[resolved.length - 1] !== path.sep)
1472-
resolved += '/';
1473-
outURL.pathname = encodePathChars(resolved);
1474-
}
1475-
return outURL;
1466+
return outURL;
1467+
}
1468+
let resolved = path.resolve(filepath);
1469+
// path.resolve strips trailing slashes so we must add them back
1470+
const filePathLast = StringPrototypeCharCodeAt(filepath,
1471+
filepath.length - 1);
1472+
if ((filePathLast === CHAR_FORWARD_SLASH ||
1473+
(isWindows && filePathLast === CHAR_BACKWARD_SLASH)) &&
1474+
resolved[resolved.length - 1] !== path.sep)
1475+
resolved += '/';
1476+
1477+
// Call encodePathChars first to avoid encoding % again for ? and #.
1478+
resolved = encodePathChars(resolved);
1479+
1480+
// Question and hash character should be included in pathname.
1481+
// Therefore, encoding is required to eliminate parsing them in different states.
1482+
// This is done as an optimization to not creating a URL instance and
1483+
// later triggering pathname setter, which impacts performance
1484+
if (StringPrototypeIndexOf(resolved, '?') !== -1)
1485+
resolved = RegExpPrototypeSymbolReplace(questionRegex, resolved, '%3F');
1486+
if (StringPrototypeIndexOf(resolved, '#') !== -1)
1487+
resolved = RegExpPrototypeSymbolReplace(hashRegex, resolved, '%23');
1488+
return new URL(`file://${resolved}`);
14761489
}
14771490

14781491
function toPathIfFileURL(fileURLOrPath) {

0 commit comments

Comments
 (0)