Skip to content

Commit

Permalink
url: faster encodePathChars function
Browse files Browse the repository at this point in the history
This is roughly twice as fast as before.

Signed-off-by: Ruben Bridgewater <ruben@bridgewater.de>
  • Loading branch information
BridgeAR committed Jun 25, 2022
1 parent d96a2ea commit d348cc5
Showing 1 changed file with 31 additions and 19 deletions.
50 changes: 31 additions & 19 deletions lib/internal/url.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,9 @@ const {
ReflectApply,
ReflectGetOwnPropertyDescriptor,
ReflectOwnKeys,
RegExp,
String,
StringPrototypeCharCodeAt,
StringPrototypeIncludes,
StringPrototypeReplace,
StringPrototypeSlice,
StringPrototypeSplit,
StringPrototypeStartsWith,
Expand Down Expand Up @@ -1500,25 +1499,38 @@ function fileURLToPath(path) {
// - CR: The carriage return character is also stripped out by the `pathname`
// setter.
// - TAB: The tab character is also stripped out by the `pathname` setter.
const percentRegEx = /%/g;
const backslashRegEx = /\\/g;
const newlineRegEx = /\n/g;
const carriageReturnRegEx = /\r/g;
const tabRegEx = /\t/g;
const escapePathRegExp = new RegExp(`%|\\n|\\r|\\t${isWindows ? '' : '|\\\\'}`);
const escapedPathChars = {
'%': '%25',
'\n': '%0A',
'\r': '%0D',
'\t': '%09',
'\\': '%5C',
};

// As of V8 10.2 the hand written replacer is faster than using replace with a
// replacer function.
function encodePathChars(filepath) {
if (StringPrototypeIncludes(filepath, '%'))
filepath = StringPrototypeReplace(filepath, percentRegEx, '%25');
// In posix, backslash is a valid character in paths:
if (!isWindows && StringPrototypeIncludes(filepath, '\\'))
filepath = StringPrototypeReplace(filepath, backslashRegEx, '%5C');
if (StringPrototypeIncludes(filepath, '\n'))
filepath = StringPrototypeReplace(filepath, newlineRegEx, '%0A');
if (StringPrototypeIncludes(filepath, '\r'))
filepath = StringPrototypeReplace(filepath, carriageReturnRegEx, '%0D');
if (StringPrototypeIncludes(filepath, '\t'))
filepath = StringPrototypeReplace(filepath, tabRegEx, '%09');
return filepath;
if (!escapePathRegExp.test(filepath)) {
return filepath;
}
let result = '';
let last = 0;
for (let i = 0; i < filepath.length; i++) {
const point = filepath.charCodeAt(i);
if (point <= 13 || point === 37 || (!isWindows && point === 92)) {
const replacingChar = escapedPathChars[filepath[i]];
if (replacingChar !== undefined) {
result += `${filepath.slice(last, i)}${replacingChar}`;
last = i + 1;
}
}
}

if (last !== filepath.length) {
result += filepath.slice(last);
}
return result;
}

function pathToFileURL(filepath) {
Expand Down

0 comments on commit d348cc5

Please sign in to comment.