Skip to content

Commit

Permalink
lib: avoid unsafe String methods that depend on RegExp prototype methods
Browse files Browse the repository at this point in the history
  • Loading branch information
ExE-Boss committed Nov 27, 2021
1 parent a257294 commit eeb3a9b
Show file tree
Hide file tree
Showing 22 changed files with 111 additions and 96 deletions.
18 changes: 10 additions & 8 deletions lib/_tls_common.js
Expand Up @@ -26,7 +26,7 @@ const tls = require('tls');
const {
ArrayPrototypePush,
ObjectCreate,
StringPrototypeReplace,
RegExpPrototypeSymbolReplace,
} = primordials;

const {
Expand Down Expand Up @@ -135,13 +135,15 @@ function translatePeerCertificate(c) {
c.infoAccess = ObjectCreate(null);

// XXX: More key validation?
StringPrototypeReplace(info, /([^\n:]*):([^\n]*)(?:\n|$)/g,
(all, key, val) => {
if (key in c.infoAccess)
ArrayPrototypePush(c.infoAccess[key], val);
else
c.infoAccess[key] = [val];
});
RegExpPrototypeSymbolReplace(
/([^\n:]*):([^\n]*)(?:\n|$)/g,
info,
(all, key, val) => {
if (key in c.infoAccess)
ArrayPrototypePush(c.infoAccess[key], val);
else
c.infoAccess[key] = [val];
});
}
return c;
}
Expand Down
10 changes: 6 additions & 4 deletions lib/_tls_wrap.js
Expand Up @@ -31,8 +31,9 @@ const {
ObjectSetPrototypeOf,
ReflectApply,
RegExp,
RegExpPrototypeSymbolReplace,
RegExpPrototypeTest,
StringPrototypeReplace,
StringPrototypeReplaceAll,
StringPrototypeSlice,
Symbol,
SymbolFor,
Expand Down Expand Up @@ -1444,9 +1445,10 @@ Server.prototype.addContext = function(servername, context) {
throw new ERR_TLS_REQUIRED_SERVER_NAME();
}

const re = new RegExp('^' + StringPrototypeReplace(
StringPrototypeReplace(servername, /([.^$+?\-\\[\]{}])/g, '\\$1'),
/\*/g, '[^.]*'
const re = new RegExp('^' + StringPrototypeReplaceAll(
RegExpPrototypeSymbolReplace(/([.^$+?\-\\[\]{}])/g, servername, '\\$1'),
'*',
'[^.]*',
) + '$');
ArrayPrototypePush(this._contexts,
[re, tls.createSecureContext(context).context]);
Expand Down
12 changes: 7 additions & 5 deletions lib/assert.js
Expand Up @@ -35,13 +35,14 @@ const {
ObjectKeys,
ObjectPrototypeIsPrototypeOf,
ReflectApply,
RegExpPrototypeSymbolReplace,
RegExpPrototypeTest,
SafeMap,
String,
StringPrototypeCharCodeAt,
StringPrototypeIncludes,
StringPrototypeIndexOf,
StringPrototypeReplace,
StringPrototypeReplaceAll,
StringPrototypeSlice,
StringPrototypeSplit,
StringPrototypeStartsWith,
Expand Down Expand Up @@ -271,9 +272,10 @@ function parseCode(code, offset) {

return [
node.node.start,
StringPrototypeReplace(StringPrototypeSlice(code,
node.node.start, node.node.end),
escapeSequencesRegExp, escapeFn),
RegExpPrototypeSymbolReplace(
escapeSequencesRegExp,
StringPrototypeSlice(code, node.node.start, node.node.end),
escapeFn),
];
}

Expand Down Expand Up @@ -346,7 +348,7 @@ function getErrMessage(message, fn) {
// Always normalize indentation, otherwise the message could look weird.
if (StringPrototypeIncludes(message, '\n')) {
if (EOL === '\r\n') {
message = StringPrototypeReplace(message, /\r\n/g, '\n');
message = StringPrototypeReplaceAll(message, '\r\n', '\n');
}
const frames = StringPrototypeSplit(message, '\n');
message = ArrayPrototypeShift(frames);
Expand Down
6 changes: 3 additions & 3 deletions lib/buffer.js
Expand Up @@ -36,8 +36,8 @@ const {
ObjectDefineProperties,
ObjectDefineProperty,
ObjectSetPrototypeOf,
RegExpPrototypeSymbolReplace,
StringPrototypeCharCodeAt,
StringPrototypeReplace,
StringPrototypeSlice,
StringPrototypeToLowerCase,
StringPrototypeTrim,
Expand Down Expand Up @@ -832,8 +832,8 @@ Buffer.prototype[customInspectSymbol] = function inspect(recurseTimes, ctx) {
const max = INSPECT_MAX_BYTES;
const actualMax = MathMin(max, this.length);
const remaining = this.length - max;
let str = StringPrototypeTrim(StringPrototypeReplace(
this.hexSlice(0, actualMax), /(.{2})/g, '$1 '));
let str = StringPrototypeTrim(RegExpPrototypeSymbolReplace(
/(.{2})/g, this.hexSlice(0, actualMax), '$1 '));
if (remaining > 0)
str += ` ... ${remaining} more byte${remaining > 1 ? 's' : ''}`;
// Inspect special properties as well, if possible.
Expand Down
4 changes: 2 additions & 2 deletions lib/internal/console/constructor.js
Expand Up @@ -29,7 +29,7 @@ const {
StringPrototypeIncludes,
StringPrototypePadStart,
StringPrototypeRepeat,
StringPrototypeReplace,
StringPrototypeReplaceAll,
StringPrototypeSlice,
StringPrototypeSplit,
Symbol,
Expand Down Expand Up @@ -265,7 +265,7 @@ ObjectDefineProperties(Console.prototype, {

if (groupIndent.length !== 0) {
if (StringPrototypeIncludes(string, '\n')) {
string = StringPrototypeReplace(string, /\n/g, `\n${groupIndent}`);
string = StringPrototypeReplaceAll(string, '\n', `\n${groupIndent}`);
}
string = groupIndent + string;
}
Expand Down
11 changes: 6 additions & 5 deletions lib/internal/dns/utils.js
Expand Up @@ -7,8 +7,8 @@ const {
ArrayPrototypePush,
FunctionPrototypeBind,
NumberParseInt,
StringPrototypeMatch,
StringPrototypeReplace,
RegExpPrototypeExec,
RegExpPrototypeSymbolReplace,
} = primordials;

const errors = require('internal/errors');
Expand Down Expand Up @@ -86,21 +86,22 @@ class Resolver {
if (ipVersion !== 0)
return ArrayPrototypePush(newSet, [ipVersion, serv, IANA_DNS_PORT]);

const match = StringPrototypeMatch(serv, IPv6RE);
const match = RegExpPrototypeExec(IPv6RE, serv);

// Check for an IPv6 in brackets.
if (match) {
ipVersion = isIP(match[1]);

if (ipVersion !== 0) {
const port = NumberParseInt(
StringPrototypeReplace(serv, addrSplitRE, '$2')) || IANA_DNS_PORT;
RegExpPrototypeSymbolReplace(addrSplitRE, serv, '$2')
) || IANA_DNS_PORT;
return ArrayPrototypePush(newSet, [ipVersion, match[1], port]);
}
}

// addr::port
const addrSplitMatch = StringPrototypeMatch(serv, addrSplitRE);
const addrSplitMatch = RegExpPrototypeExec(addrSplitRE, serv);

if (addrSplitMatch) {
const hostIP = addrSplitMatch[1];
Expand Down
4 changes: 2 additions & 2 deletions lib/internal/errors.js
Expand Up @@ -41,14 +41,14 @@ const {
ObjectPrototypeHasOwnProperty,
RangeError,
ReflectApply,
RegExpPrototypeExec,
RegExpPrototypeTest,
SafeArrayIterator,
SafeMap,
SafeWeakMap,
String,
StringPrototypeEndsWith,
StringPrototypeIncludes,
StringPrototypeMatch,
StringPrototypeSlice,
StringPrototypeSplit,
StringPrototypeStartsWith,
Expand Down Expand Up @@ -422,7 +422,7 @@ function getMessage(key, args, self) {
}

const expectedLength =
(StringPrototypeMatch(msg, /%[dfijoOs]/g) || []).length;
(RegExpPrototypeExec(/%[dfijoOs]/g, msg) || []).length;
assert(
expectedLength === args.length,
`Code: ${key}; The provided arguments length (${args.length}) does not ` +
Expand Down
4 changes: 2 additions & 2 deletions lib/internal/fs/utils.js
Expand Up @@ -19,7 +19,7 @@ const {
ReflectOwnKeys,
StringPrototypeEndsWith,
StringPrototypeIncludes,
StringPrototypeReplace,
StringPrototypeReplaceAll,
Symbol,
TypedArrayPrototypeIncludes,
} = primordials;
Expand Down Expand Up @@ -393,7 +393,7 @@ function preprocessSymlinkDestination(path, type, linkPath) {
return pathModule.toNamespacedPath(path);
}
// Windows symlinks don't tolerate forward slashes.
return StringPrototypeReplace(path, /\//g, '\\');
return StringPrototypeReplaceAll(path, '/', '\\');
}

// Constructor for file stats.
Expand Down
12 changes: 6 additions & 6 deletions lib/internal/main/print_help.js
Expand Up @@ -8,11 +8,11 @@ const {
MathMax,
ObjectKeys,
RegExp,
RegExpPrototypeSymbolReplace,
StringPrototypeLocaleCompare,
StringPrototypeSlice,
StringPrototypeTrimLeft,
StringPrototypeRepeat,
StringPrototypeReplace,
SafeMap,
} = primordials;

Expand Down Expand Up @@ -77,14 +77,14 @@ const envVars = new SafeMap(ArrayPrototypeConcat([


function indent(text, depth) {
return StringPrototypeReplace(text, /^/gm, StringPrototypeRepeat(' ', depth));
return RegExpPrototypeSymbolReplace(/^/gm, text, StringPrototypeRepeat(' ', depth));
}

function fold(text, width) {
return StringPrototypeReplace(text,
new RegExp(`([^\n]{0,${width}})( |$)`, 'g'),
(_, newLine, end) =>
newLine + (end === ' ' ? '\n' : ''));
return RegExpPrototypeSymbolReplace(
new RegExp(`([^\n]{0,${width}})( |$)`, 'g'),
text,
(_, newLine, end) => newLine + (end === ' ' ? '\n' : ''));
}

function getArgDescription(type) {
Expand Down
3 changes: 1 addition & 2 deletions lib/internal/modules/cjs/loader.js
Expand Up @@ -58,7 +58,6 @@ const {
StringPrototypeEndsWith,
StringPrototypeLastIndexOf,
StringPrototypeIndexOf,
StringPrototypeMatch,
StringPrototypeRepeat,
StringPrototypeSlice,
StringPrototypeSplit,
Expand Down Expand Up @@ -472,7 +471,7 @@ const EXPORTS_PATTERN = /^((?:@[^/\\%]+\/)?[^./\\%][^/\\%]*)(\/.*)?$/;
function resolveExports(nmPath, request) {
// The implementation's behavior is meant to mirror resolution in ESM.
const { 1: name, 2: expansion = '' } =
StringPrototypeMatch(request, EXPORTS_PATTERN) || [];
RegExpPrototypeExec(EXPORTS_PATTERN, request) || [];
if (!name)
return;
const pkgPath = path.resolve(nmPath, name);
Expand Down
18 changes: 9 additions & 9 deletions lib/internal/modules/esm/module_job.js
Expand Up @@ -12,12 +12,12 @@ const {
PromiseResolve,
PromisePrototypeCatch,
ReflectApply,
RegExpPrototypeExec,
RegExpPrototypeTest,
RegExpPrototypeSymbolReplace,
SafeArrayIterator,
SafeSet,
StringPrototypeIncludes,
StringPrototypeMatch,
StringPrototypeReplace,
StringPrototypeSplit,
StringPrototypeStartsWith,
} = primordials;
Expand Down Expand Up @@ -136,14 +136,14 @@ class ModuleJob {
StringPrototypeIncludes(e.message,
' does not provide an export named')) {
const splitStack = StringPrototypeSplit(e.stack, '\n');
const parentFileUrl = StringPrototypeReplace(
splitStack[0],
const parentFileUrl = RegExpPrototypeSymbolReplace(
/:\d+$/,
splitStack[0],
''
);
const { 1: childSpecifier, 2: name } = StringPrototypeMatch(
e.message,
/module '(.*)' does not provide an export named '(.+)'/);
const { 1: childSpecifier, 2: name } = RegExpPrototypeExec(
/module '(.*)' does not provide an export named '(.+)'/,
e.message);
const { url: childFileURL } = await this.loader.resolve(
childSpecifier, parentFileUrl,
);
Expand All @@ -162,9 +162,9 @@ class ModuleJob {
// line which causes the error. For multi-line import statements we
// cannot generate an equivalent object destructuring assignment by
// just parsing the error stack.
const oneLineNamedImports = StringPrototypeMatch(importStatement, /{.*}/);
const oneLineNamedImports = RegExpPrototypeExec(/{.*}/, importStatement);
const destructuringAssignment = oneLineNamedImports &&
StringPrototypeReplace(oneLineNamedImports, /\s+as\s+/g, ': ');
RegExpPrototypeSymbolReplace(/\s+as\s+/g, oneLineNamedImports, ': ');
e.message = `Named export '${name}' not found. The requested module` +
` '${childSpecifier}' is a CommonJS module, which may not support` +
' all module.exports as named exports.\nCommonJS modules can ' +
Expand Down
7 changes: 3 additions & 4 deletions lib/internal/modules/esm/translators.js
Expand Up @@ -13,7 +13,7 @@ const {
SafeArrayIterator,
SafeMap,
SafeSet,
StringPrototypeReplace,
StringPrototypeReplaceAll,
StringPrototypeSlice,
StringPrototypeStartsWith,
SyntaxErrorPrototype,
Expand Down Expand Up @@ -164,14 +164,13 @@ function enrichCJSError(err, content, filename) {

// Strategy for loading a node-style CommonJS module
const isWindows = process.platform === 'win32';
const winSepRegEx = /\//g;
translators.set('commonjs', async function commonjsStrategy(url, source,
isMain) {
debug(`Translating CJSModule ${url}`);

let filename = internalURLModule.fileURLToPath(new URL(url));
if (isWindows)
filename = StringPrototypeReplace(filename, winSepRegEx, '\\');
filename = StringPrototypeReplaceAll(filename, '/', '\\');

if (!cjsParse) await initCJSParse();
const { module, exportNames } = cjsPreparseModuleExports(filename);
Expand Down Expand Up @@ -290,7 +289,7 @@ translators.set('json', async function jsonStrategy(url, source) {
let module;
if (pathname) {
modulePath = isWindows ?
StringPrototypeReplace(pathname, winSepRegEx, '\\') : pathname;
StringPrototypeReplaceAll(pathname, '/', '\\') : pathname;
module = CJSModule._cache[modulePath];
if (module && module.loaded) {
const exports = module.exports;
Expand Down
6 changes: 3 additions & 3 deletions lib/internal/policy/manifest.js
Expand Up @@ -10,11 +10,11 @@ const {
ObjectKeys,
ObjectSetPrototypeOf,
RegExpPrototypeExec,
RegExpPrototypeSymbolReplace,
RegExpPrototypeTest,
SafeMap,
SafeSet,
StringPrototypeEndsWith,
StringPrototypeReplace,
Symbol,
uncurryThis,
} = primordials;
Expand Down Expand Up @@ -651,10 +651,10 @@ const emptyOrProtocolOrResolve = (resourceHREF, base) => {
if (resourceHREF === '') return '';
if (StringPrototypeEndsWith(resourceHREF, ':')) {
// URL parse will trim these anyway, save the compute
resourceHREF = StringPrototypeReplace(
resourceHREF,
resourceHREF = RegExpPrototypeSymbolReplace(
// eslint-disable-next-line
/^[\x00-\x1F\x20]|\x09\x0A\x0D|[\x00-\x1F\x20]$/g,
resourceHREF,
''
);
if (RegExpPrototypeTest(/^[a-zA-Z][a-zA-Z+\-.]*:$/, resourceHREF)) {
Expand Down

0 comments on commit eeb3a9b

Please sign in to comment.