tools: add prefer-proto rule

fixup: add support for `Object.create(null)`

fixup: extend to any 1-argument Object.create call

fixup: add tests
PR-URL: https://github.com/nodejs/node/pull/46083
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Geoffrey Booth <webadmin@geoffreybooth.com>
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
Reviewed-By: Mohammed Keyvanzadeh <mohammadkeyvanzade94@gmail.com>
Reviewed-By: Darshan Sen <raisinten@gmail.com>
Reviewed-By: Michaël Zasso <targos@protonmail.com>
Reviewed-By: Jacob Smith <jacob@frende.me>
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
This commit is contained in:
Jordan Harband 2023-01-09 21:38:36 -08:00 committed by GitHub
parent 5d9a9a6ba3
commit 757c104147
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
87 changed files with 307 additions and 231 deletions

View File

@ -314,6 +314,7 @@ module.exports = {
// Custom rules from eslint-plugin-node-core
'node-core/no-unescaped-regexp-dot': 'error',
'node-core/no-duplicate-requires': 'error',
'node-core/prefer-proto': 'error',
},
globals: {
ByteLengthQueuingStrategy: 'readable',

View File

@ -25,7 +25,7 @@ function runObject(n) {
}
function runNullProtoObject(n) {
const m = Object.create(null);
const m = { __proto__: null };
bench.start();
for (let i = 0; i < n; i++) {
m[`i${i}`] = i;
@ -51,7 +51,7 @@ function runNullProtoLiteralObject(n) {
}
function StorageObject() {}
StorageObject.prototype = Object.create(null);
StorageObject.prototype = { __proto__: null };
function runStorageObject(n) {
const m = new StorageObject();

View File

@ -664,7 +664,7 @@ const obj3 = {
b: 1,
},
};
const obj4 = Object.create(obj1);
const obj4 = { __proto__: obj1 };
assert.deepEqual(obj1, obj1);
// OK
@ -699,7 +699,7 @@ const obj3 = {
b: 1,
},
};
const obj4 = Object.create(obj1);
const obj4 = { __proto__: obj1 };
assert.deepEqual(obj1, obj1);
// OK
@ -1623,7 +1623,7 @@ const obj3 = {
b: 1,
},
};
const obj4 = Object.create(obj1);
const obj4 = { __proto__: obj1 };
assert.notDeepEqual(obj1, obj1);
// AssertionError: { a: { b: 1 } } notDeepEqual { a: { b: 1 } }
@ -1656,7 +1656,7 @@ const obj3 = {
b: 1,
},
};
const obj4 = Object.create(obj1);
const obj4 = { __proto__: obj1 };
assert.notDeepEqual(obj1, obj1);
// AssertionError: { a: { b: 1 } } notDeepEqual { a: { b: 1 } }

View File

@ -32,7 +32,6 @@ const {
FunctionPrototypeCall,
NumberIsNaN,
NumberParseInt,
ObjectCreate,
ObjectKeys,
ObjectSetPrototypeOf,
ObjectValues,
@ -111,9 +110,9 @@ function Agent(options) {
// Don't confuse net and make it think that we're connecting to a pipe
this.options.path = null;
this.requests = ObjectCreate(null);
this.sockets = ObjectCreate(null);
this.freeSockets = ObjectCreate(null);
this.requests = { __proto__: null };
this.sockets = { __proto__: null };
this.freeSockets = { __proto__: null };
this.keepAliveMsecs = this.options.keepAliveMsecs || 1000;
this.keepAlive = this.options.keepAlive || false;
this.maxSockets = this.options.maxSockets || Agent.defaultMaxSockets;

View File

@ -28,7 +28,6 @@ const {
MathAbs,
MathFloor,
NumberPrototypeToString,
ObjectCreate,
ObjectDefineProperty,
ObjectKeys,
ObjectValues,
@ -217,7 +216,7 @@ ObjectDefineProperty(OutgoingMessage.prototype, '_headers', {
if (val == null) {
this[kOutHeaders] = null;
} else if (typeof val === 'object') {
const headers = this[kOutHeaders] = ObjectCreate(null);
const headers = this[kOutHeaders] = { __proto__: null };
const keys = ObjectKeys(val);
// Retain for(;;) loop for performance reasons
// Refs: https://github.com/nodejs/node/pull/30958
@ -244,7 +243,7 @@ ObjectDefineProperty(OutgoingMessage.prototype, '_headerNames', {
get: internalUtil.deprecate(function() {
const headers = this[kOutHeaders];
if (headers !== null) {
const out = ObjectCreate(null);
const out = { __proto__: null };
const keys = ObjectKeys(headers);
// Retain for(;;) loop for performance reasons
// Refs: https://github.com/nodejs/node/pull/30958
@ -667,7 +666,7 @@ OutgoingMessage.prototype.setHeader = function setHeader(name, value) {
let headers = this[kOutHeaders];
if (headers === null)
this[kOutHeaders] = headers = ObjectCreate(null);
this[kOutHeaders] = headers = { __proto__: null };
headers[StringPrototypeToLowerCase(name)] = [name, value];
return this;
@ -764,7 +763,7 @@ OutgoingMessage.prototype.getRawHeaderNames = function getRawHeaderNames() {
// Returns a shallow copy of the current outgoing headers.
OutgoingMessage.prototype.getHeaders = function getHeaders() {
const headers = this[kOutHeaders];
const ret = ObjectCreate(null);
const ret = { __proto__: null };
if (headers) {
const keys = ObjectKeys(headers);
// Retain for(;;) loop for performance reasons

View File

@ -26,7 +26,6 @@ const tls = require('tls');
const {
ArrayPrototypePush,
JSONParse,
ObjectCreate,
RegExpPrototypeSymbolReplace,
} = primordials;
@ -131,7 +130,7 @@ function translatePeerCertificate(c) {
}
if (c.infoAccess != null) {
const info = c.infoAccess;
c.infoAccess = ObjectCreate(null);
c.infoAccess = { __proto__: null };
// XXX: More key validation?
RegExpPrototypeSymbolReplace(/([^\n:]*):([^\n]*)(?:\n|$)/g, info,

View File

@ -33,7 +33,6 @@ const {
NumberIsNaN,
NumberMAX_SAFE_INTEGER,
NumberMIN_SAFE_INTEGER,
ObjectCreate,
ObjectDefineProperties,
ObjectDefineProperty,
ObjectSetPrototypeOf,
@ -146,7 +145,7 @@ const constants = ObjectDefineProperties({}, {
Buffer.poolSize = 8 * 1024;
let poolSize, poolOffset, allocPool;
const encodingsMap = ObjectCreate(null);
const encodingsMap = { __proto__: null };
for (let i = 0; i < encodings.length; ++i)
encodingsMap[encodings[i]] = i;
@ -845,7 +844,7 @@ Buffer.prototype[customInspectSymbol] = function inspect(recurseTimes, ctx) {
if (ctx) {
let extras = false;
const filter = ctx.showHidden ? ALL_PROPERTIES : ONLY_ENUMERABLE;
const obj = ObjectCreate(null);
const obj = { __proto__: null };
ArrayPrototypeForEach(getOwnNonIndexProperties(this, filter),
(key) => {
extras = true;

View File

@ -4,7 +4,6 @@ const {
ArrayPrototypeIndexOf,
ArrayPrototypePush,
ArrayPrototypeSplice,
ObjectCreate,
ObjectGetPrototypeOf,
ObjectSetPrototypeOf,
SymbolHasInstance,
@ -92,7 +91,7 @@ class Channel {
publish() {}
}
const channels = ObjectCreate(null);
const channels = { __proto__: null };
function channel(name) {
let channel;

View File

@ -35,7 +35,6 @@ const {
FunctionPrototypeCall,
NumberIsNaN,
NumberMAX_SAFE_INTEGER,
ObjectCreate,
ObjectDefineProperty,
ObjectDefineProperties,
ObjectGetPrototypeOf,
@ -344,7 +343,7 @@ EventEmitter.init = function(opts) {
if (this._events === undefined ||
this._events === ObjectGetPrototypeOf(this)._events) {
this._events = ObjectCreate(null);
this._events = { __proto__: null };
this._eventsCount = 0;
}
@ -553,7 +552,7 @@ function _addListener(target, type, listener, prepend) {
events = target._events;
if (events === undefined) {
events = target._events = ObjectCreate(null);
events = target._events = { __proto__: null };
target._eventsCount = 0;
} else {
// To avoid recursion in the case that type === "newListener"! Before
@ -691,7 +690,7 @@ EventEmitter.prototype.removeListener =
if (list === listener || list.listener === listener) {
if (--this._eventsCount === 0)
this._events = ObjectCreate(null);
this._events = { __proto__: null };
else {
delete events[type];
if (events.removeListener)
@ -746,11 +745,11 @@ EventEmitter.prototype.removeAllListeners =
// Not listening for removeListener, no need to emit
if (events.removeListener === undefined) {
if (arguments.length === 0) {
this._events = ObjectCreate(null);
this._events = { __proto__: null };
this._eventsCount = 0;
} else if (events[type] !== undefined) {
if (--this._eventsCount === 0)
this._events = ObjectCreate(null);
this._events = { __proto__: null };
else
delete events[type];
}
@ -764,7 +763,7 @@ EventEmitter.prototype.removeAllListeners =
this.removeAllListeners(key);
}
this.removeAllListeners('removeListener');
this._events = ObjectCreate(null);
this._events = { __proto__: null };
this._eventsCount = 0;
return this;
}

View File

@ -6,7 +6,6 @@ const {
Error,
ErrorCaptureStackTrace,
MathMax,
ObjectCreate,
ObjectDefineProperty,
ObjectGetPrototypeOf,
ObjectKeys,
@ -48,7 +47,7 @@ const kMaxShortLength = 12;
function copyError(source) {
const keys = ObjectKeys(source);
const target = ObjectCreate(ObjectGetPrototypeOf(source));
const target = { __proto__: ObjectGetPrototypeOf(source) };
for (const key of keys) {
target[key] = source[key];
}

View File

@ -49,7 +49,6 @@ const {
ArrayPrototypePush,
ArrayPrototypeSlice,
Error,
ObjectCreate,
ObjectDefineProperty,
ObjectKeys,
ObjectPrototypeHasOwnProperty,
@ -129,7 +128,7 @@ const schemelessBlockList = new SafeSet([
// Set up process.binding() and process._linkedBinding().
{
const bindingObj = ObjectCreate(null);
const bindingObj = { __proto__: null };
process.binding = function binding(module) {
module = String(module);
@ -167,7 +166,7 @@ const schemelessBlockList = new SafeSet([
*/
let internalBinding;
{
const bindingObj = ObjectCreate(null);
const bindingObj = { __proto__: null };
// eslint-disable-next-line no-global-assign
internalBinding = function internalBinding(module) {
let mod = bindingObj[module];

View File

@ -3,7 +3,6 @@
const {
ArrayIsArray,
Boolean,
ObjectCreate,
SafeMap,
} = primordials;
@ -19,7 +18,7 @@ function RoundRobinHandle(key, address, { port, fd, flags, backlog, readableAll,
this.key = key;
this.all = new SafeMap();
this.free = new SafeMap();
this.handles = init(ObjectCreate(null));
this.handles = init({ __proto__: null });
this.handle = null;
this.server = net.createServer(assert.fail);

View File

@ -15,7 +15,6 @@ const {
MathFloor,
Number,
NumberPrototypeToFixed,
ObjectCreate,
ObjectDefineProperties,
ObjectDefineProperty,
ObjectKeys,
@ -572,7 +571,7 @@ const consoleMethods = {
return final([iterKey, valuesKey], [getIndexArray(length), values]);
}
const map = ObjectCreate(null);
const map = { __proto__: null };
let hasPrimitives = false;
const valuesKeyArray = [];
const indexKeyArray = ObjectKeys(tabularData);

View File

@ -14,7 +14,6 @@
const {
FunctionPrototypeBind,
ObjectCreate,
ReflectDefineProperty,
ReflectGetOwnPropertyDescriptor,
ReflectOwnKeys,
@ -24,7 +23,7 @@ const {
Console
} = require('internal/console/constructor');
const globalConsole = ObjectCreate({});
const globalConsole = { __proto__: {} };
// Since Console is not on the prototype chain of the global console,
// the symbol properties on Console.prototype have to be looked up from

View File

@ -9,7 +9,6 @@ const {
NumberParseInt,
RegExpPrototypeExec,
RegExpPrototypeSymbolReplace,
ObjectCreate,
Symbol,
} = primordials;
@ -286,7 +285,7 @@ function setDefaultResultOrder(value) {
}
function createResolverClass(resolver) {
const resolveMap = ObjectCreate(null);
const resolveMap = { __proto__: null };
class Resolver extends ResolverBase {}

View File

@ -5,7 +5,6 @@
const {
Boolean,
ObjectCreate,
ObjectDefineProperties,
ObjectGetOwnPropertyDescriptors,
ObjectSetPrototypeOf,
@ -350,9 +349,9 @@ class TextEncoder {
if (typeof depth === 'number' && depth < 0)
return this;
const ctor = getConstructorOf(this);
const obj = ObjectCreate({
const obj = { __proto__: {
constructor: ctor === null ? TextEncoder : ctor
});
} };
obj.encoding = this.encoding;
// Lazy to avoid circular dependency
return require('internal/util/inspect').inspect(obj, opts);
@ -571,7 +570,7 @@ const sharedProperties = ObjectGetOwnPropertyDescriptors({
if (typeof depth === 'number' && depth < 0)
return this;
const constructor = getConstructorOf(this) || TextDecoder;
const obj = ObjectCreate({ constructor });
const obj = { __proto__: { constructor } };
obj.encoding = this.encoding;
obj.fatal = this.fatal;
obj.ignoreBOM = this.ignoreBOM;

View File

@ -33,7 +33,7 @@ const errors = {
const errorConstructorNames = new SafeSet(ObjectKeys(errors));
function TryGetAllProperties(object, target = object) {
const all = ObjectCreate(null);
const all = { __proto__: null };
if (object === null)
return all;
ObjectAssign(all,

View File

@ -6,7 +6,6 @@ const {
Boolean,
FunctionPrototypeBind,
ObjectAssign,
ObjectCreate,
ObjectKeys,
ObjectPrototypeHasOwnProperty,
Proxy,
@ -483,8 +482,8 @@ class Http2ServerResponse extends Stream {
sendDate: true,
statusCode: HTTP_STATUS_OK,
};
this[kHeaders] = ObjectCreate(null);
this[kTrailers] = ObjectCreate(null);
this[kHeaders] = { __proto__: null };
this[kTrailers] = { __proto__: null };
this[kStream] = stream;
stream[kProxySocket] = null;
stream[kResponse] = this;
@ -603,7 +602,7 @@ class Http2ServerResponse extends Stream {
}
getHeaders() {
const headers = ObjectCreate(null);
const headers = { __proto__: null };
return ObjectAssign(headers, this[kHeaders]);
}
@ -851,7 +850,7 @@ class Http2ServerResponse extends Stream {
writeEarlyHints(hints) {
validateObject(hints, 'hints');
const headers = ObjectCreate(null);
const headers = { __proto__: null };
const linkHeaderValue = validateLinkHeaderValue(hints.link);

View File

@ -12,7 +12,6 @@ const {
FunctionPrototypeCall,
MathMin,
ObjectAssign,
ObjectCreate,
ObjectKeys,
ObjectDefineProperty,
ObjectPrototypeHasOwnProperty,
@ -1753,7 +1752,7 @@ class ClientHttp2Session extends Http2Session {
assertIsObject(headers, 'headers');
assertIsObject(options, 'options');
headers = ObjectAssign(ObjectCreate(null), headers);
headers = ObjectAssign({ __proto__: null }, headers);
options = { ...options };
if (headers[HTTP2_HEADER_METHOD] === undefined)
@ -2252,7 +2251,7 @@ class Http2Stream extends Duplex {
throw new ERR_HTTP2_TRAILERS_NOT_READY();
assertIsObject(headers, 'headers');
headers = ObjectAssign(ObjectCreate(null), headers);
headers = ObjectAssign({ __proto__: null }, headers);
debugStreamObj(this, 'sending trailers');
@ -2420,7 +2419,7 @@ function callStreamClose(stream) {
function processHeaders(oldHeaders, options) {
assertIsObject(oldHeaders, 'headers');
const headers = ObjectCreate(null);
const headers = { __proto__: null };
if (oldHeaders !== null && oldHeaders !== undefined) {
// This loop is here for performance reason. Do not change.
@ -2696,7 +2695,7 @@ class ServerHttp2Stream extends Http2Stream {
options.endStream = !!options.endStream;
assertIsObject(headers, 'headers');
headers = ObjectAssign(ObjectCreate(null), headers);
headers = ObjectAssign({ __proto__: null }, headers);
if (headers[HTTP2_HEADER_METHOD] === undefined)
headers[HTTP2_HEADER_METHOD] = HTTP2_METHOD_GET;
@ -2931,7 +2930,7 @@ class ServerHttp2Stream extends Http2Stream {
throw new ERR_HTTP2_HEADERS_AFTER_RESPOND();
assertIsObject(headers, 'headers');
headers = ObjectAssign(ObjectCreate(null), headers);
headers = ObjectAssign({ __proto__: null }, headers);
debugStreamObj(this, 'sending additional headers');

View File

@ -8,7 +8,6 @@ const {
Error,
MathMax,
Number,
ObjectCreate,
ObjectDefineProperty,
ObjectKeys,
SafeSet,
@ -279,7 +278,7 @@ function updateOptionsBuffer(options) {
function getDefaultSettings() {
settingsBuffer[IDX_SETTINGS_FLAGS] = 0;
binding.refreshDefaultSettings();
const holder = ObjectCreate(null);
const holder = { __proto__: null };
const flags = settingsBuffer[IDX_SETTINGS_FLAGS];
@ -588,7 +587,7 @@ const assertWithinRange = hideStackFrames(
);
function toHeaderObject(headers, sensitiveHeaders) {
const obj = ObjectCreate(null);
const obj = { __proto__: null };
for (let n = 0; n < headers.length; n += 2) {
const name = headers[n];
let value = headers[n + 1];

View File

@ -38,7 +38,6 @@ const {
Boolean,
Error,
JSONParse,
ObjectCreate,
ObjectDefineProperty,
ObjectFreeze,
ObjectGetOwnPropertyDescriptor,
@ -146,7 +145,7 @@ const {
const { kEvaluated } = internalBinding('module_wrap');
const isWindows = process.platform === 'win32';
const relativeResolveCache = ObjectCreate(null);
const relativeResolveCache = { __proto__: null };
let requireDepth = 0;
let statCache = null;
@ -208,9 +207,9 @@ function Module(id = '', parent) {
this.children = [];
}
Module._cache = ObjectCreate(null);
Module._pathCache = ObjectCreate(null);
Module._extensions = ObjectCreate(null);
Module._cache = { __proto__: null };
Module._pathCache = { __proto__: null };
Module._extensions = { __proto__: null };
let modulePaths = [];
Module.globalPaths = [];

View File

@ -3,7 +3,6 @@
const {
ArrayPrototypeFilter,
ArrayPrototypeIncludes,
ObjectCreate,
ObjectValues,
ObjectPrototypeHasOwnProperty,
} = primordials;
@ -53,7 +52,7 @@ const supportedAssertionTypes = ArrayPrototypeFilter(
* @throws {TypeError} If the format and assertion type are incompatible.
*/
function validateAssertions(url, format,
importAssertions = ObjectCreate(null)) {
importAssertions = { __proto__: null }) {
const validType = formatTypeMap[format];
switch (validType) {

View File

@ -4,7 +4,6 @@ const {
ArrayPrototypeJoin,
ArrayPrototypeMap,
JSONStringify,
ObjectCreate,
SafeSet,
} = primordials;
@ -40,12 +39,12 @@ import.meta.done();
const readyfns = new SafeSet();
const reflect = {
exports: ObjectCreate(null),
exports: { __proto__: null },
onReady: (cb) => { readyfns.add(cb); },
};
if (imports.length)
reflect.imports = ObjectCreate(null);
reflect.imports = { __proto__: null };
const { setCallbackForWrap } = require('internal/modules/esm/utils');
setCallbackForWrap(m, {
initializeImportMeta: (meta, wrap) => {

View File

@ -7,7 +7,6 @@ const {
Array,
ArrayIsArray,
FunctionPrototypeCall,
ObjectCreate,
ObjectSetPrototypeOf,
SafePromiseAllReturnArrayLike,
SafeWeakMap,
@ -303,7 +302,7 @@ class ESMLoader {
async resolve(
originalSpecifier,
parentURL,
importAssertions = ObjectCreate(null),
importAssertions = { __proto__: null },
) {
if (this.#hooks) {
return this.#hooks.resolve(originalSpecifier, parentURL, importAssertions);

View File

@ -5,7 +5,6 @@ const {
ArrayPrototypePush,
ArrayPrototypeSome,
FunctionPrototype,
ObjectCreate,
ObjectSetPrototypeOf,
PromiseResolve,
PromisePrototypeThen,
@ -51,7 +50,7 @@ const isCommonJSGlobalLikeNotDefinedError = (errorMessage) =>
class ModuleJob {
// `loader` is the Loader instance used for loading dependencies.
// `moduleProvider` is a function
constructor(loader, url, importAssertions = ObjectCreate(null),
constructor(loader, url, importAssertions = { __proto__: null },
moduleProvider, isMain, inspectBrk) {
this.loader = loader;
this.importAssertions = importAssertions;

View File

@ -2,7 +2,6 @@
const { kImplicitAssertType } = require('internal/modules/esm/assert');
const {
ObjectCreate,
SafeMap,
} = primordials;
let debug = require('internal/util/debuglog').debuglog('esm', (fn) => {
@ -31,7 +30,7 @@ class ModuleMap extends SafeMap {
debug(`Storing ${url} (${
type === kImplicitAssertType ? 'implicit type' : type
}) in ModuleMap`);
const cachedJobsForUrl = super.get(url) ?? ObjectCreate(null);
const cachedJobsForUrl = super.get(url) ?? { __proto__: null };
cachedJobsForUrl[type] = job;
return super.set(url, cachedJobsForUrl);
}

View File

@ -1,7 +1,6 @@
'use strict';
const {
ObjectCreate,
StringPrototypeEndsWith,
} = primordials;
@ -54,7 +53,7 @@ function runMainESM(mainPath) {
handleMainPromise(loadESM((esmLoader) => {
const main = path.isAbsolute(mainPath) ?
pathToFileURL(mainPath).href : mainPath;
return esmLoader.import(main, undefined, ObjectCreate(null));
return esmLoader.import(main, undefined, { __proto__: null });
}));
}

View File

@ -4,7 +4,6 @@
const {
ArrayIsArray,
ArrayPrototypeSort,
ObjectCreate,
ObjectEntries,
ObjectFreeze,
ObjectKeys,
@ -178,7 +177,7 @@ class DependencyMapperInstance {
/**
* @type {Record<string, string>}
*/
const normalizedDependencyMap = ObjectCreate(null);
const normalizedDependencyMap = { __proto__: null };
for (let specifier in dependencies) {
const target = dependencies[specifier];
specifier = canonicalizeSpecifier(specifier, manifest.href);
@ -443,10 +442,10 @@ class Manifest {
this.#reaction = reaction;
const jsonResourcesEntries = ObjectEntries(
obj.resources ?? ObjectCreate(null)
obj.resources ?? { __proto__: null }
);
const jsonScopesEntries = ObjectEntries(obj.scopes ?? ObjectCreate(null));
const defaultDependencies = obj.dependencies ?? ObjectCreate(null);
const jsonScopesEntries = ObjectEntries(obj.scopes ?? { __proto__: null });
const defaultDependencies = obj.dependencies ?? { __proto__: null };
this.#defaultDependencies = new DependencyMapperInstance(
'default',

View File

@ -4,13 +4,12 @@ const {
Number,
NumberIsNaN,
NumberParseInt,
ObjectCreate,
} = primordials;
const REPL = require('repl');
const { kStandaloneREPL } = require('internal/repl/utils');
module.exports = ObjectCreate(REPL);
module.exports = { __proto__: REPL };
module.exports.createInternalRepl = createRepl;
function createRepl(env, opts, cb) {

View File

@ -3,7 +3,6 @@
const {
ArrayPrototypeMap,
JSONParse,
ObjectCreate,
ObjectKeys,
ObjectGetOwnPropertyDescriptor,
ObjectPrototypeHasOwnProperty,
@ -280,7 +279,7 @@ function sourcesToAbsolute(baseURL, data) {
// Get serialized representation of source-map cache, this is used
// to persist a cache of source-maps to disk when NODE_V8_COVERAGE is enabled.
function sourceMapCacheToObject() {
const obj = ObjectCreate(null);
const obj = { __proto__: null };
for (const { 0: k, 1: v } of esmSourceMapCache) {
obj[k] = v;

View File

@ -1,7 +1,6 @@
'use strict';
const {
ArrayPrototypePush,
ObjectCreate,
ObjectGetOwnPropertyDescriptor,
SafePromiseAllReturnArrayLike,
RegExp,
@ -128,7 +127,7 @@ async function getReportersMap(reporters, destinations) {
}
const { esmLoader } = require('internal/process/esm_loader');
reporter = await esmLoader.import(name, parentURL, ObjectCreate(null));
reporter = await esmLoader.import(name, parentURL, { __proto__: null });
}
if (reporter?.default) {

View File

@ -77,7 +77,6 @@ const {
MathTrunc,
NumberIsFinite,
NumberMIN_SAFE_INTEGER,
ObjectCreate,
ReflectApply,
Symbol,
} = primordials;
@ -154,7 +153,7 @@ const timerListQueue = new PriorityQueue(compareTimersLists, setPosition);
//
// - key = time in milliseconds
// - value = linked list
const timerListMap = ObjectCreate(null);
const timerListMap = { __proto__: null };
function initAsyncResource(resource, type) {
const asyncId = resource[async_id_symbol] = newAsyncId();

View File

@ -10,7 +10,6 @@ const {
FunctionPrototypeBind,
Int8Array,
Number,
ObjectCreate,
ObjectDefineProperties,
ObjectDefineProperty,
ObjectGetOwnPropertySymbols,
@ -673,7 +672,7 @@ class URL {
return this;
const constructor = getConstructorOf(this) || URL;
const obj = ObjectCreate({ constructor });
const obj = { __proto__: { constructor } };
obj.href = this.href;
obj.origin = this.origin;
@ -1295,7 +1294,7 @@ function merge(out, start, mid, end, lBuffer, rBuffer) {
// https://heycam.github.io/webidl/#dfn-default-iterator-object
function createSearchParamsIterator(target, kind) {
const iterator = ObjectCreate(URLSearchParamsIteratorPrototype);
const iterator = { __proto__: URLSearchParamsIteratorPrototype };
iterator[context] = {
target,
kind,
@ -1305,7 +1304,7 @@ function createSearchParamsIterator(target, kind) {
}
// https://heycam.github.io/webidl/#dfn-iterator-prototype-object
const URLSearchParamsIteratorPrototype = ObjectCreate(IteratorPrototype);
const URLSearchParamsIteratorPrototype = { __proto__: IteratorPrototype };
defineIDLClass(URLSearchParamsIteratorPrototype, 'URLSearchParams Iterator', {
next() {
@ -1585,7 +1584,7 @@ function constructUrl(flags, protocol, username, password,
ctx.fragment = fragment;
ctx.host = host;
const url = ObjectCreate(URL.prototype);
const url = { __proto__: URL.prototype };
url[context] = ctx;
const params = new URLSearchParams();
url[searchParams] = params;

View File

@ -9,7 +9,6 @@ const {
ArrayPrototypeSort,
Error,
FunctionPrototypeCall,
ObjectCreate,
ObjectDefineProperties,
ObjectDefineProperty,
ObjectGetOwnPropertyDescriptor,
@ -289,7 +288,7 @@ function getSignalsToNamesMapping() {
if (signalsToNamesMapping !== undefined)
return signalsToNamesMapping;
signalsToNamesMapping = ObjectCreate(null);
signalsToNamesMapping = { __proto__: null };
for (const key in signals) {
signalsToNamesMapping[signals[key]] = key;
}
@ -610,14 +609,14 @@ const lazyDOMException = hideStackFrames((message, name) => {
return new _DOMException(message, name);
});
const kEnumerableProperty = ObjectCreate(null);
const kEnumerableProperty = { __proto__: null };
kEnumerableProperty.enumerable = true;
ObjectFreeze(kEnumerableProperty);
const kEmptyObject = ObjectFreeze(ObjectCreate(null));
const kEmptyObject = ObjectFreeze({ __proto__: null });
function filterOwnProperties(source, keys) {
const filtered = ObjectCreate(null);
const filtered = { __proto__: null };
for (let i = 0; i < keys.length; i++) {
const key = keys[i];
if (ObjectPrototypeHasOwnProperty(source, key)) {

View File

@ -1,7 +1,6 @@
'use strict';
const {
ObjectCreate,
ObjectDefineProperty,
RegExp,
RegExpPrototypeExec,
@ -20,7 +19,7 @@ let testEnabled;
// `debugEnv` is initial value of process.env.NODE_DEBUG
function initializeDebugEnv(debugEnv) {
debugImpls = ObjectCreate(null);
debugImpls = { __proto__: null };
if (debugEnv) {
// This is run before any user code, it's OK not to use primordials.
debugEnv = debugEnv.replace(/[|\\{}()[\]^$+?.]/g, '\\$&')

View File

@ -43,7 +43,6 @@ const {
NumberPrototypeValueOf,
Object,
ObjectAssign,
ObjectCreate,
ObjectDefineProperty,
ObjectGetOwnPropertyDescriptor,
ObjectGetOwnPropertyNames,
@ -460,7 +459,7 @@ defineColorAlias('doubleunderline', 'doubleUnderline');
// TODO(BridgeAR): Add function style support for more complex styles.
// Don't use 'blue' not visible on cmd.exe
inspect.styles = ObjectAssign(ObjectCreate(null), {
inspect.styles = ObjectAssign({ __proto__: null }, {
special: 'cyan',
number: 'yellow',
bigint: 'yellow',

View File

@ -6,7 +6,6 @@ const {
ArrayPrototypeForEach,
ArrayPrototypeIndexOf,
ArrayPrototypeSome,
ObjectCreate,
ObjectDefineProperty,
ObjectGetPrototypeOf,
ObjectSetPrototypeOf,
@ -234,7 +233,7 @@ class Module {
return this;
const constructor = getConstructorOf(this) || Module;
const o = ObjectCreate({ constructor });
const o = { __proto__: { constructor } };
o.status = this.status;
o.identifier = this.identifier;
o.context = this.context;

View File

@ -8,7 +8,6 @@ const {
FunctionPrototypeCall,
MathMax,
NumberIsNaN,
ObjectCreate,
PromisePrototypeThen,
PromiseResolve,
PromiseReject,
@ -54,20 +53,11 @@ const {
const kState = Symbol('kState');
const kType = Symbol('kType');
const AsyncIterator = ObjectCreate(AsyncIteratorPrototype, {
next: {
__proto__: null,
configurable: true,
enumerable: true,
writable: true,
},
return: {
__proto__: null,
configurable: true,
enumerable: true,
writable: true,
},
});
const AsyncIterator = {
__proto__: AsyncIteratorPrototype,
next: undefined,
return: undefined,
};
function extractHighWaterMark(value, defaultHWM) {
if (value === undefined) return defaultHWM;

View File

@ -8,7 +8,6 @@ const {
FunctionPrototypeBind,
JSONStringify,
MathMax,
ObjectCreate,
ObjectEntries,
Promise,
PromiseResolve,
@ -173,7 +172,7 @@ class Worker extends EventEmitter {
let env;
if (typeof options.env === 'object' && options.env !== null) {
env = ObjectCreate(null);
env = { __proto__: null };
ArrayPrototypeForEach(
ObjectEntries(options.env),
({ 0: key, 1: value }) => { env[key] = `${value}`; }

View File

@ -278,7 +278,7 @@ ObjectDefineProperty(MessagePort.prototype, inspect.custom, {
// e.g. when accessing the prototype directly.
ref = FunctionPrototypeCall(MessagePortPrototype.hasRef, this);
} catch { return this; }
return ObjectAssign(ObjectCreate(MessagePort.prototype),
return ObjectAssign({ __proto__: MessagePort.prototype },
ref === undefined ? {
active: false,
} : {

View File

@ -34,7 +34,6 @@ const {
ObjectDefineProperty,
ObjectSetPrototypeOf,
Symbol,
ObjectCreate,
} = primordials;
const EventEmitter = require('events');
@ -1977,16 +1976,16 @@ function onconnection(err, clientHandle) {
if (self.maxConnections && self._connections >= self.maxConnections) {
if (clientHandle.getsockname || clientHandle.getpeername) {
const data = ObjectCreate(null);
const data = { __proto__: null };
if (clientHandle.getsockname) {
const localInfo = ObjectCreate(null);
const localInfo = { __proto__: null };
clientHandle.getsockname(localInfo);
data.localAddress = localInfo.address;
data.localPort = localInfo.port;
data.localFamily = localInfo.family;
}
if (clientHandle.getpeername) {
const remoteInfo = ObjectCreate(null);
const remoteInfo = { __proto__: null };
clientHandle.getpeername(remoteInfo);
data.remoteAddress = remoteInfo.address;
data.remotePort = remoteInfo.port;

View File

@ -29,7 +29,6 @@ const {
Int8Array,
MathAbs,
NumberIsFinite,
ObjectCreate,
ObjectKeys,
String,
StringPrototypeCharCodeAt,
@ -316,7 +315,7 @@ function addKeyVal(obj, key, value, keyEncoded, valEncoded, decode) {
* @returns {Record<string, string | string[]>}
*/
function parse(qs, sep, eq, options) {
const obj = ObjectCreate(null);
const obj = { __proto__: null };
if (typeof qs !== 'string' || qs.length === 0) {
return obj;

View File

@ -66,7 +66,6 @@ const {
NumberIsNaN,
NumberParseFloat,
ObjectAssign,
ObjectCreate,
ObjectDefineProperty,
ObjectGetOwnPropertyDescriptor,
ObjectGetOwnPropertyNames,
@ -773,7 +772,7 @@ function REPLServer(prompt,
self.resetContext();
this.commands = ObjectCreate(null);
this.commands = { __proto__: null };
defineDefaultCommands(this);
// Figure out which "writer" function to use

View File

@ -23,7 +23,6 @@
const {
MathTrunc,
ObjectCreate,
ObjectDefineProperty,
SymbolToPrimitive
} = primordials;
@ -72,7 +71,7 @@ const {
// This stores all the known timer async ids to allow users to clearTimeout and
// clearInterval using those ids, to match the spec and the rest of the web
// platform.
const knownTimersById = ObjectCreate(null);
const knownTimersById = { __proto__: null };
// Remove a timer. Cancels the timeout and resets the relevant timer properties.
function unenroll(item) {

View File

@ -23,7 +23,6 @@
const {
Int8Array,
ObjectCreate,
ObjectKeys,
SafeSet,
StringPrototypeCharCodeAt,
@ -267,7 +266,7 @@ Url.prototype.parse = function parse(url, parseQueryString, slashesDenoteHost) {
}
} else if (parseQueryString) {
this.search = null;
this.query = ObjectCreate(null);
this.query = { __proto__: null };
}
return this;
}
@ -477,7 +476,7 @@ Url.prototype.parse = function parse(url, parseQueryString, slashesDenoteHost) {
} else if (parseQueryString) {
// No query string, but parseQueryString still requested
this.search = null;
this.query = ObjectCreate(null);
this.query = { __proto__: null };
}
const useQuestionIdx =

View File

@ -100,7 +100,7 @@ module.exports = function verifyGraph(hooks, graph) {
assert.strictEqual(errors.length, 0);
// Verify that all expected types are present (but more/others are allowed)
const expTypes = Object.create(null);
const expTypes = { __proto__: null };
for (let i = 0; i < graph.length; i++) {
if (expTypes[graph[i].type] == null) expTypes[graph[i].type] = 0;
expTypes[graph[i].type]++;

View File

@ -235,9 +235,9 @@ assert.strictEqual(newObject.test_string, 'test string');
// i.e.: includes prototypes, only enumerable properties, skips symbols,
// and includes indices and converts them to strings.
const object = Object.create({
const object = { __proto__: {
inherited: 1
});
} };
const fooSymbol = Symbol('foo');

View File

@ -103,7 +103,7 @@ const { setTimeout: sleep } = require('timers/promises');
NaN,
true,
'AbortController',
Object.create(AbortController.prototype),
{ __proto__: AbortController.prototype },
];
for (const badController of badAbortControllers) {
throws(
@ -134,7 +134,7 @@ const { setTimeout: sleep } = require('timers/promises');
NaN,
true,
'AbortSignal',
Object.create(AbortSignal.prototype),
{ __proto__: AbortSignal.prototype },
];
for (const badSignal of badAbortSignals) {
throws(

View File

@ -1190,7 +1190,7 @@ assert.throws(
});
assertNotDeepOrStrict(a, b);
a = Object.create(null);
a = { __proto__: null };
b = new RangeError('abc');
Object.defineProperty(a, Symbol.toStringTag, {
value: 'Error'

View File

@ -290,7 +290,7 @@ assert.throws(() => new Blob({}), {
{
// Testing the defaults
[undefined, null, Object.create(null), { type: undefined }, {
[undefined, null, { __proto__: null }, { type: undefined }, {
get type() {}, // eslint-disable-line getter-return
}].forEach((options) => {
assert.strictEqual(

View File

@ -40,7 +40,7 @@ deepStrictEqual(
{ valueOf() { return null; } },
{ valueOf() { return undefined; } },
{ valueOf: null },
Object.create(null),
{ __proto__: null },
new Number(true),
new MyBadPrimitive(),
Symbol(),

View File

@ -192,7 +192,7 @@ function setPrototypeOfQuux(root) {
// Test various supported types, directly and nested:
[
undefined, null, false, true, 42, 42n, Symbol('42'), NaN, Infinity, {}, [],
() => {}, async () => {}, Promise.resolve(), Math, Object.create(null),
() => {}, async () => {}, Promise.resolve(), Math, { __proto__: null },
].forEach((target) => {
assert.deepStrictEqual(mustNotMutateObjectDeep(target), target);
assert.deepStrictEqual(mustNotMutateObjectDeep({ target }), { target });

View File

@ -211,7 +211,7 @@ const der = Buffer.from(
// Verify that legacy encoding works
const legacyObjectCheck = {
subject: Object.assign(Object.create(null), {
subject: Object.assign({ __proto__: null }, {
C: 'US',
ST: 'CA',
L: 'SF',
@ -220,7 +220,7 @@ const der = Buffer.from(
CN: 'agent1',
emailAddress: 'ry@tinyclouds.org',
}),
issuer: Object.assign(Object.create(null), {
issuer: Object.assign({ __proto__: null }, {
C: 'US',
ST: 'CA',
L: 'SF',
@ -229,7 +229,7 @@ const der = Buffer.from(
CN: 'ca1',
emailAddress: 'ry@tinyclouds.org',
}),
infoAccess: Object.assign(Object.create(null), {
infoAccess: Object.assign({ __proto__: null }, {
'OCSP - URI': ['http://ocsp.nodejs.org/'],
'CA Issuers - URI': ['http://ca.nodejs.org/ca.cert']
}),

View File

@ -33,7 +33,7 @@ strictEqual(
);
strictEqual(
determineSpecificType(Object.create(null)),
determineSpecificType({ __proto__: null }),
'[Object: null prototype] {}',
);

View File

@ -0,0 +1,71 @@
'use strict';
const common = require('../common');
if ((!common.hasCrypto) || (!common.hasIntl)) {
common.skip('ESLint tests require crypto and Intl');
}
common.skipIfEslintMissing();
const RuleTester = require('../../tools/node_modules/eslint').RuleTester;
const rule = require('../../tools/eslint-rules/prefer-proto');
new RuleTester({
parserOptions: { ecmaVersion: 2022 }
}).run('prefer-common-mustsucceed', rule, {
valid: [
'({ __proto__: null })',
'const x = { __proto__: null };',
`
class X {
field = { __proto__: null };
constructor() {
this.x = { __proto__: X };
}
}
`,
'foo({ __proto__: Array.prototype })',
'({ "__proto__": null })',
"({ '__proto__': null })",
'ObjectCreate(null, undefined)',
'Object.create(null, undefined)',
'Object.create(null, undefined, undefined)',
'ObjectCreate(null, descriptors)',
'Object.create(null, descriptors)',
'ObjectCreate(Foo.prototype, descriptors)',
'Object.create(Foo.prototype, descriptors)',
],
invalid: [
{
code: 'ObjectCreate(null)',
output: '{ __proto__: null }',
errors: [{ messageId: 'error', data: { value: 'null' } }],
},
{
code: 'Object.create(null)',
output: '{ __proto__: null }',
errors: [{ messageId: 'error', data: { value: 'null' } }],
},
{
code: 'ObjectCreate(null,)',
output: '{ __proto__: null }',
errors: [{ messageId: 'error', data: { value: 'null' } }],
},
{
code: 'Object.create(null,)',
output: '{ __proto__: null }',
errors: [{ messageId: 'error', data: { value: 'null' } }],
},
{
code: 'ObjectCreate(Foo)',
output: '{ __proto__: Foo }',
errors: [{ messageId: 'error', data: { value: 'Foo' } }],
},
{
code: 'Object.create(Foo)',
output: '{ __proto__: Foo }',
errors: [{ messageId: 'error', data: { value: 'Foo' } }],
},
]
});

View File

@ -8,7 +8,7 @@ const EE = new EventEmitter();
// Works as expected if the context has no `constructor.name`
{
const ctx = Object.create(null);
const ctx = { __proto__: null };
assert.throws(
() => EE.emit.call(ctx, 'error', new Error('foo')),
common.expectsError({ name: 'Error', message: 'foo' })

View File

@ -50,7 +50,7 @@ const rangeFile = fixtures.path('x.txt');
}
{
const file = fs.createReadStream(fn, Object.create({ encoding: 'utf8' }));
const file = fs.createReadStream(fn, { __proto__: { encoding: 'utf8' } });
file.length = 0;
file.on('data', function(data) {
assert.strictEqual(typeof data, 'string');
@ -68,7 +68,7 @@ const rangeFile = fixtures.path('x.txt');
}
{
const options = Object.create({ bufferSize: 1, start: 1, end: 2 });
const options = { __proto__: { bufferSize: 1, start: 1, end: 2 } };
const file = fs.createReadStream(rangeFile, options);
assert.strictEqual(file.start, 1);
assert.strictEqual(file.end, 2);
@ -82,7 +82,7 @@ const rangeFile = fixtures.path('x.txt');
}
{
const options = Object.create({ bufferSize: 1, start: 1 });
const options = { __proto__: { bufferSize: 1, start: 1 } };
const file = fs.createReadStream(rangeFile, options);
assert.strictEqual(file.start, 1);
file.data = '';
@ -96,7 +96,7 @@ const rangeFile = fixtures.path('x.txt');
// https://github.com/joyent/node/issues/2320
{
const options = Object.create({ bufferSize: 1.23, start: 1 });
const options = { __proto__: { bufferSize: 1.23, start: 1 } };
const file = fs.createReadStream(rangeFile, options);
assert.strictEqual(file.start, 1);
file.data = '';
@ -115,7 +115,7 @@ const rangeFile = fixtures.path('x.txt');
assert.throws(
() => {
fs.createReadStream(rangeFile, Object.create({ start: 10, end: 2 }));
fs.createReadStream(rangeFile, { __proto__: { start: 10, end: 2 } });
},
{
code: 'ERR_OUT_OF_RANGE',
@ -125,7 +125,7 @@ const rangeFile = fixtures.path('x.txt');
}
{
const options = Object.create({ start: 0, end: 0 });
const options = { __proto__: { start: 0, end: 0 } };
const stream = fs.createReadStream(rangeFile, options);
assert.strictEqual(stream.start, 0);
assert.strictEqual(stream.end, 0);
@ -150,7 +150,7 @@ const rangeFile = fixtures.path('x.txt');
{
let data = '';
let file =
fs.createReadStream(rangeFile, Object.create({ autoClose: false }));
fs.createReadStream(rangeFile, { __proto__: { autoClose: false } });
assert.strictEqual(file.autoClose, false);
file.on('data', (chunk) => { data += chunk; });
file.on('end', common.mustCall(function() {
@ -164,7 +164,7 @@ const rangeFile = fixtures.path('x.txt');
function fileNext() {
// This will tell us if the fd is usable again or not.
file = fs.createReadStream(null, Object.create({ fd: file.fd, start: 0 }));
file = fs.createReadStream(null, { __proto__: { fd: file.fd, start: 0 } });
file.data = '';
file.on('data', function(data) {
file.data += data;
@ -181,7 +181,7 @@ const rangeFile = fixtures.path('x.txt');
// Just to make sure autoClose won't close the stream because of error.
{
const options = Object.create({ fd: 13337, autoClose: false });
const options = { __proto__: { fd: 13337, autoClose: false } };
const file = fs.createReadStream(null, options);
file.on('data', common.mustNotCall());
file.on('error', common.mustCall());

View File

@ -81,7 +81,7 @@ const server = createServer(
['X-Res-a', 'X-Res-b', 'Connection', 'x-res-c', 'x-res-d']
);
const headers = Object.create(null);
const headers = { __proto__: null };
Object.assign(headers, {
'x-res-a': [ 'AAA', 'BBB', 'CCC' ],
'x-res-b': [ 'DDD', 'EEE', 'FFF', 'GGG' ],

View File

@ -44,7 +44,7 @@ const s = http.createServer(common.mustCall((req, res) => {
case 'headers': {
// Check that header-related functions work before setting any headers
const headers = res.getHeaders();
const exoticObj = Object.create(null);
const exoticObj = { __proto__: null };
assert.deepStrictEqual(headers, exoticObj);
assert.deepStrictEqual(res.getHeaderNames(), []);
assert.deepStrictEqual(res.getRawHeaderNames(), []);

View File

@ -17,7 +17,7 @@ common.expectWarning('DeprecationWarning', warn, 'DEP0066');
// Tests _headerNames getter result after setting a header.
const outgoingMessage = new OutgoingMessage();
outgoingMessage.setHeader('key', 'value');
const expect = Object.create(null);
const expect = { __proto__: null };
expect.key = 'key';
assert.deepStrictEqual(outgoingMessage._headerNames, expect);
}

View File

@ -102,7 +102,7 @@ server.listen(0, common.mustCall(function() {
response.setHeader(real, expectedValue);
const expectedHeaderNames = [real];
assert.deepStrictEqual(response.getHeaderNames(), expectedHeaderNames);
const expectedHeaders = Object.create(null);
const expectedHeaders = { __proto__: null };
expectedHeaders[real] = expectedValue;
assert.deepStrictEqual(response.getHeaders(), expectedHeaders);

View File

@ -8,7 +8,7 @@ const http2 = require('http2');
const server = http2.createServer();
const src = Object.create(null);
const src = { __proto__: null };
src['www-authenticate'] = 'foo';
src['WWW-Authenticate'] = 'bar';
src['WWW-AUTHENTICATE'] = 'baz';

View File

@ -8,7 +8,7 @@ const http2 = require('http2');
const server = http2.createServer();
const src = Object.create(null);
const src = { __proto__: null };
src.accept = [ 'abc', 'def' ];
src.Accept = 'ghijklmnop';
src['www-authenticate'] = 'foo';

View File

@ -11,8 +11,8 @@ const {
Http2ServerResponse,
} = http2;
const protoRequest = Object.create(Http2ServerRequest.prototype);
const protoResponse = Object.create(Http2ServerResponse.prototype);
const protoRequest = { __proto__: Http2ServerRequest.prototype };
const protoResponse = { __proto__: Http2ServerResponse.prototype };
assert.strictEqual(protoRequest instanceof Http2ServerRequest, true);
assert.strictEqual(protoResponse instanceof Http2ServerResponse, true);

View File

@ -30,7 +30,7 @@ function makeUrl(headers) {
const server = http2.createServer();
server.on('stream', common.mustCall((stream, headers) => {
const obj = Object.create(null);
const obj = { __proto__: null };
switch (remaining--) {
case 3: {
const url = new URL(makeUrl(headers));

View File

@ -11,7 +11,7 @@ const {
[
undefined,
{},
Object.create(null),
{ __proto__: null },
new Date(),
new (class Foo {})(),
].forEach((input) => {

View File

@ -149,7 +149,7 @@ const {
{
// Only own properties are used
const base = { 'abc': 1 };
const headers = Object.create(base);
const headers = { __proto__: base };
headers[':status'] = 200;
headers.xyz = [1, 2, 3, 4];
headers.foo = [];

View File

@ -8,4 +8,4 @@ const assert = require('assert');
// https://github.com/nodejs/node/issues/7592
const F = () => {};
F.prototype = {};
assert(Object.create(F.prototype) instanceof F);
assert({ __proto__: F.prototype } instanceof F);

View File

@ -12,7 +12,7 @@ const NOT_HTTP_QUOTED_STRING_CODE_POINT = '\n';
const mime = new MIMEType('application/ecmascript; ');
const mime_descriptors = Object.getOwnPropertyDescriptors(mime);
const mime_proto = Object.getPrototypeOf(mime);
const mime_impersonator = Object.create(mime_proto);
const mime_impersonator = { __proto__: mime_proto };
for (const key of Object.keys(mime_descriptors)) {
const descriptor = mime_descriptors[key];
if (descriptor.get) {

View File

@ -26,7 +26,7 @@ fs.writeFileSync(dotfileWithExtension, 'console.log(__filename);', 'utf8');
delete require.cache[file];
delete require.extensions['.bar'];
delete require.extensions['.foo.bar'];
Module._pathCache = Object.create(null);
Module._pathCache = { __proto__: null };
}
{
@ -40,7 +40,7 @@ fs.writeFileSync(dotfileWithExtension, 'console.log(__filename);', 'utf8');
require(`${modulePath}.foo.bar`);
delete require.cache[file];
delete require.extensions['.foo.bar'];
Module._pathCache = Object.create(null);
Module._pathCache = { __proto__: null };
}
{
@ -50,7 +50,7 @@ fs.writeFileSync(dotfileWithExtension, 'console.log(__filename);', 'utf8');
(err) => err.message.startsWith(`Cannot find module '${modulePath}'`)
);
delete require.cache[file];
Module._pathCache = Object.create(null);
Module._pathCache = { __proto__: null };
}
{
@ -61,7 +61,7 @@ fs.writeFileSync(dotfileWithExtension, 'console.log(__filename);', 'utf8');
delete require.cache[file];
delete require.extensions['.bar'];
delete require.extensions['.foo.bar'];
Module._pathCache = Object.create(null);
Module._pathCache = { __proto__: null };
}
{
@ -72,7 +72,7 @@ fs.writeFileSync(dotfileWithExtension, 'console.log(__filename);', 'utf8');
(err) => err.message.startsWith(`Cannot find module '${modulePath}'`)
);
delete require.extensions['.foo.bar'];
Module._pathCache = Object.create(null);
Module._pathCache = { __proto__: null };
}
{
@ -80,7 +80,7 @@ fs.writeFileSync(dotfileWithExtension, 'console.log(__filename);', 'utf8');
require(dotfile);
delete require.cache[dotfile];
delete require.extensions['.bar'];
Module._pathCache = Object.create(null);
Module._pathCache = { __proto__: null };
}
{
@ -90,5 +90,5 @@ fs.writeFileSync(dotfileWithExtension, 'console.log(__filename);', 'utf8');
delete require.cache[dotfileWithExtension];
delete require.extensions['.bar'];
delete require.extensions['.foo.bar'];
Module._pathCache = Object.create(null);
Module._pathCache = { __proto__: null };
}

View File

@ -973,7 +973,7 @@ test('tokens:true should not include the default options after the args input',
test('proto as default value must be ignored', () => {
const args = [];
const options = Object.create(null);
const options = { __proto__: null };
// eslint-disable-next-line no-proto
options.__proto__ = { type: 'string', default: 'HELLO' };

View File

@ -28,7 +28,7 @@ const inspect = require('util').inspect;
const qs = require('querystring');
function createWithNoPrototype(properties) {
const noProto = Object.create(null);
const noProto = { __proto__: null };
properties.forEach((property) => {
noProto[property.key] = property.value;
});

View File

@ -10,13 +10,13 @@ const tls = require('tls');
// Ensure accessing ._external doesn't hit an assert in the accessor method.
{
const pctx = tls.createSecureContext().context;
const cctx = Object.create(pctx);
const cctx = { __proto__: pctx };
assert.throws(() => cctx._external, TypeError);
pctx._external; // eslint-disable-line no-unused-expressions
}
{
const pctx = tls.createSecurePair().credentials.context;
const cctx = Object.create(pctx);
const cctx = { __proto__: pctx };
assert.throws(() => cctx._external, TypeError);
pctx._external; // eslint-disable-line no-unused-expressions
}

View File

@ -53,7 +53,7 @@ deepStrictEqual(
}
deepStrictEqual(translatePeerCertificate({ infoAccess: '' }),
{ infoAccess: Object.create(null) });
{ infoAccess: { __proto__: null } });
deepStrictEqual(translatePeerCertificate({ infoAccess: null }),
{ infoAccess: null });
{
@ -61,7 +61,7 @@ deepStrictEqual(translatePeerCertificate({ infoAccess: null }),
'__proto__:mostly harmless\n' +
'hasOwnProperty:not a function\n' +
'OCSP - URI:file:///etc/passwd\n';
const expected = Object.create(null);
const expected = { __proto__: null };
expected.__proto__ = ['mostly harmless'];
expected.hasOwnProperty = ['not a function'];
expected['OCSP - URI'] = ['file:///etc/passwd'];

View File

@ -6,7 +6,7 @@ const fs = require('fs');
const path = require('path');
const util = require('util');
const tests = Object.create(null);
const tests = { __proto__: null };
let gid = 1;
let uid = 1;

View File

@ -6,7 +6,7 @@ const fs = require('fs');
const path = require('path');
const util = require('util');
const tests = Object.create(null);
const tests = { __proto__: null };
let gid = 1;
let uid = 1;

View File

@ -4,7 +4,7 @@ const assert = require('assert');
const url = require('url');
function createWithNoPrototype(properties = []) {
const noProto = Object.create(null);
const noProto = { __proto__: null };
properties.forEach((property) => {
noProto[property.key] = property.value;
});

View File

@ -219,7 +219,7 @@ assert.strictEqual(util.format('%s', -Infinity), '-Infinity');
function D() {
C.call(this);
}
D.prototype = Object.create(C.prototype);
D.prototype = { __proto__: C.prototype };
assert.strictEqual(
util.format('%s', new B()),
@ -264,7 +264,7 @@ assert.strictEqual(util.format('%s', -Infinity), '-Infinity');
);
assert.strictEqual(
util.format('%s', Object.create(null)),
util.format('%s', { __proto__: null }),
'[Object: null prototype] {}'
);
}

View File

@ -100,7 +100,7 @@ assert.strictEqual(
`"${Array(75).fill(1)}'\\n" +\n '\\x1D\\n' +\n '\\x03\\x85\\x7F~\\x9F '`
);
assert.strictEqual(util.inspect([]), '[]');
assert.strictEqual(util.inspect(Object.create([])), 'Array {}');
assert.strictEqual(util.inspect({ __proto__: [] }), 'Array {}');
assert.strictEqual(util.inspect([1, 2]), '[ 1, 2 ]');
assert.strictEqual(util.inspect([1, [2, 3]]), '[ 1, [ 2, 3 ] ]');
assert.strictEqual(util.inspect({}), '{}');
@ -796,7 +796,7 @@ assert.strictEqual(util.inspect(-5e-324), '-5e-324');
});
// https://github.com/nodejs/node-v0.x-archive/issues/1941
assert.strictEqual(util.inspect(Object.create(Date.prototype)), 'Date {}');
assert.strictEqual(util.inspect({ __proto__: Date.prototype }), 'Date {}');
// https://github.com/nodejs/node-v0.x-archive/issues/1944
{
@ -1467,7 +1467,7 @@ if (typeof Symbol !== 'undefined') {
}
{
const x = Object.create(null);
const x = { __proto__: null };
assert.strictEqual(util.inspect(x), '[Object: null prototype] {}');
}
@ -1631,7 +1631,7 @@ util.inspect(process);
"Foo [bar] { foo: 'bar' }");
assert.strictEqual(
util.inspect(Object.create(Object.create(Foo.prototype), {
util.inspect(Object.create({ __proto__: Foo.prototype }, {
foo: { value: 'bar', enumerable: true }
})),
"Foo [bar] { foo: 'bar' }");
@ -2396,7 +2396,7 @@ assert.strictEqual(
);
function StorageObject() {}
StorageObject.prototype = Object.create(null);
StorageObject.prototype = { __proto__: null };
assert.strictEqual(
util.inspect(new StorageObject()),
'StorageObject <[Object: null prototype] {}> {}'
@ -2406,17 +2406,17 @@ assert.strictEqual(
Object.setPrototypeOf(obj, Number.prototype);
assert.strictEqual(inspect(obj), "Number { '0': 1, '1': 2, '2': 3 }");
Object.setPrototypeOf(obj, Object.create(null));
Object.setPrototypeOf(obj, { __proto__: null });
assert.strictEqual(
inspect(obj),
"Array <[Object: null prototype] {}> { '0': 1, '1': 2, '2': 3 }"
);
StorageObject.prototype = Object.create(null);
Object.setPrototypeOf(StorageObject.prototype, Object.create(null));
StorageObject.prototype = { __proto__: null };
Object.setPrototypeOf(StorageObject.prototype, { __proto__: null });
Object.setPrototypeOf(
Object.getPrototypeOf(StorageObject.prototype),
Object.create(null)
{ __proto__: null }
);
assert.strictEqual(
util.inspect(new StorageObject()),
@ -2991,7 +2991,7 @@ assert.strictEqual(
'}'
);
const obj = Object.create({ abc: true, def: 5, toString() {} });
const obj = { __proto__: { abc: true, def: 5, toString() {} } };
assert.strictEqual(
inspect(obj, { showHidden: true, colors: true }),
'{ \x1B[2mabc: \x1B[33mtrue\x1B[39m\x1B[22m, ' +
@ -3107,7 +3107,7 @@ assert.strictEqual(
return this.stylized;
}
})
`, Object.create(null));
`, { __proto__: null });
assert.strictEqual(target.ctx, undefined);
{

View File

@ -132,19 +132,19 @@ for (const [ value, _method ] of [
const bigInt64Array = new BigInt64Array(arrayBuffer);
const bigUint64Array = new BigUint64Array(arrayBuffer);
const fakeBuffer = Object.create(Buffer.prototype);
const fakeDataView = Object.create(DataView.prototype);
const fakeUint8Array = Object.create(Uint8Array.prototype);
const fakeUint8ClampedArray = Object.create(Uint8ClampedArray.prototype);
const fakeUint16Array = Object.create(Uint16Array.prototype);
const fakeUint32Array = Object.create(Uint32Array.prototype);
const fakeInt8Array = Object.create(Int8Array.prototype);
const fakeInt16Array = Object.create(Int16Array.prototype);
const fakeInt32Array = Object.create(Int32Array.prototype);
const fakeFloat32Array = Object.create(Float32Array.prototype);
const fakeFloat64Array = Object.create(Float64Array.prototype);
const fakeBigInt64Array = Object.create(BigInt64Array.prototype);
const fakeBigUint64Array = Object.create(BigUint64Array.prototype);
const fakeBuffer = { __proto__: Buffer.prototype };
const fakeDataView = { __proto__: DataView.prototype };
const fakeUint8Array = { __proto__: Uint8Array.prototype };
const fakeUint8ClampedArray = { __proto__: Uint8ClampedArray.prototype };
const fakeUint16Array = { __proto__: Uint16Array.prototype };
const fakeUint32Array = { __proto__: Uint32Array.prototype };
const fakeInt8Array = { __proto__: Int8Array.prototype };
const fakeInt16Array = { __proto__: Int16Array.prototype };
const fakeInt32Array = { __proto__: Int32Array.prototype };
const fakeFloat32Array = { __proto__: Float32Array.prototype };
const fakeFloat64Array = { __proto__: Float64Array.prototype };
const fakeBigInt64Array = { __proto__: BigInt64Array.prototype };
const fakeBigUint64Array = { __proto__: BigUint64Array.prototype };
const stealthyDataView =
Object.setPrototypeOf(new DataView(arrayBuffer), Uint8Array.prototype);

View File

@ -38,7 +38,7 @@ assert.strictEqual(util.isArray({}), false);
assert.strictEqual(util.isArray({ push: function() {} }), false);
assert.strictEqual(util.isArray(/regexp/), false);
assert.strictEqual(util.isArray(new Error()), false);
assert.strictEqual(util.isArray(Object.create(Array.prototype)), false);
assert.strictEqual(util.isArray({ __proto__: Array.prototype }), false);
// isRegExp
assert.strictEqual(util.isRegExp(/regexp/), true);
@ -48,7 +48,7 @@ assert.strictEqual(util.isRegExp(context('RegExp')()), true);
assert.strictEqual(util.isRegExp({}), false);
assert.strictEqual(util.isRegExp([]), false);
assert.strictEqual(util.isRegExp(new Date()), false);
assert.strictEqual(util.isRegExp(Object.create(RegExp.prototype)), false);
assert.strictEqual(util.isRegExp({ __proto__: RegExp.prototype }), false);
// isDate
assert.strictEqual(util.isDate(new Date()), true);
@ -58,7 +58,7 @@ assert.strictEqual(util.isDate(Date()), false);
assert.strictEqual(util.isDate({}), false);
assert.strictEqual(util.isDate([]), false);
assert.strictEqual(util.isDate(new Error()), false);
assert.strictEqual(util.isDate(Object.create(Date.prototype)), false);
assert.strictEqual(util.isDate({ __proto__: Date.prototype }), false);
// isError
assert.strictEqual(util.isError(new Error()), true);
@ -70,7 +70,7 @@ assert.strictEqual(util.isError(new (context('SyntaxError'))()), true);
assert.strictEqual(util.isError({}), false);
assert.strictEqual(util.isError({ name: 'Error', message: '' }), false);
assert.strictEqual(util.isError([]), false);
assert.strictEqual(util.isError(Object.create(Error.prototype)), true);
assert.strictEqual(util.isError({ __proto__: Error.prototype }), true);
// isObject
assert.strictEqual(util.isObject({}), true);
@ -170,7 +170,7 @@ assert.strictEqual(util.toUSVString('string\ud801'), 'string\ufffd');
);
assert.strictEqual(util.types.isNativeError([]), false);
assert.strictEqual(
util.types.isNativeError(Object.create(Error.prototype)),
util.types.isNativeError({ __proto__: Error.prototype }),
false
);
assert.strictEqual(

View File

@ -21,11 +21,11 @@ let result = vm.runInContext('Object.hasOwnProperty(this, "propBase");',
assert.strictEqual(result, false);
// Ref: https://github.com/nodejs/node/issues/5350
base = Object.create(null);
base = { __proto__: null };
base.x = 1;
base.y = 2;
sandbox = Object.create(base);
sandbox = { __proto__: base };
sandbox.z = 3;
assert.deepStrictEqual(Object.keys(sandbox), ['z']);

View File

@ -85,7 +85,7 @@ const util = require('util');
assert.strictEqual(util.inspect(m, { depth: -1 }), '[SourceTextModule]');
assert.throws(
() => m[util.inspect.custom].call(Object.create(null)),
() => m[util.inspect.custom].call({ __proto__: null }),
{
code: 'ERR_VM_MODULE_NOT_MODULE',
message: 'Provided module is not an instance of Module'

View File

@ -239,7 +239,7 @@ const { hasOpenSSL3 } = common;
checkServerIdentity: (hostname, peerCert) => {
assert.strictEqual(hostname, 'example.com');
assert.deepStrictEqual(peerCert.infoAccess,
Object.assign(Object.create(null),
Object.assign({ __proto__: null },
expected.legacy));
// toLegacyObject() should also produce the same properties. However,
@ -352,7 +352,7 @@ const { hasOpenSSL3 } = common;
servername: 'example.com',
checkServerIdentity: (hostname, peerCert) => {
assert.strictEqual(hostname, 'example.com');
const expectedObject = Object.assign(Object.create(null),
const expectedObject = Object.assign({ __proto__: null },
expected.legacy);
assert.deepStrictEqual(peerCert.subject, expectedObject);
// The issuer MUST be the same as the subject since the cert is

View File

@ -42,7 +42,7 @@ function FakeStream() {
this.readable = true;
}
FakeStream.prototype = Object.create(Stream.prototype);
FakeStream.prototype = { __proto__: Stream.prototype };
FakeStream.prototype.write = function(chunk) {
console.error(this.ID, 'write', this.wait);

View File

@ -35,7 +35,7 @@ import * as common from './common.mjs';
import * as typeParser from './type-parser.mjs';
import buildCSSForFlavoredJS from './buildCSSForFlavoredJS.mjs';
const dynamicSizes = Object.create(null);
const dynamicSizes = { __proto__: null };
const { highlight, getLanguage } = highlightJs;
@ -398,8 +398,8 @@ function versionSort(a, b) {
const DEPRECATION_HEADING_PATTERN = /^DEP\d+:/;
export function buildToc({ filename, apilinks }) {
return (tree, file) => {
const idCounters = Object.create(null);
const legacyIdCounters = Object.create(null);
const idCounters = { __proto__: null };
const legacyIdCounters = { __proto__: null };
let toc = '';
let depth = 0;

View File

@ -0,0 +1,53 @@
/**
* @fileoverview null objects can be created with `ObjectCreate(null)`, or with
* syntax: `{ __proto__: null }`. This linter rule forces use of
* syntax over ObjectCreate.
* @author Jordan Harband <ljharb@gmail.com>
*/
'use strict';
// Cribbed from `eslint-module-utils/declaredScope`
function declaredScope(context, name) {
const references = context.getScope().references;
const reference = references.find((x) => x.identifier.name === name);
if (!reference) return undefined;
return reference.resolved.scope.type;
}
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
module.exports = {
meta: {
fixable: 'code',
messages: {
error: 'Use `{ __proto__: {{value}} }` instead of `ObjectCreate({{value}})` or `Object.create({{value}})`.',
},
},
create(context) {
return {
/* eslint max-len: 0 */
'CallExpression[arguments.length=1]:matches(\
[callee.type="Identifier"][callee.name="ObjectCreate"],\
[callee.type="MemberExpression"][callee.object.name="Object"][callee.property.name="create"]\
)'(node) {
if (node.callee.type === 'MemberExpression') {
const scope = declaredScope(context, node.callee.object);
if (scope && scope !== 'module' && scope !== 'global') {
return;
}
}
const value = context.getSourceCode().getText(node.arguments[0]);
context.report({
node,
messageId: 'error',
data: { value },
fix(fixer) {
return fixer.replaceText(node, `{ __proto__: ${value} }`);
},
});
},
};
},
};