mirror of
https://github.com/nodejs/node.git
synced 2026-10-28 10:15:07 +08:00
lib: add lint rule to enforce use of kEmptyObject
Signed-off-by: Antoine du Hamel <duhamelantoine1995@gmail.com> PR-URL: https://github.com/nodejs/node/pull/63790 Reviewed-By: Filip Skokan <panva.ip@gmail.com> Reviewed-By: Chemi Atlow <chemi@atlow.co.il> Reviewed-By: Jake Yuesong Li <jake.yuesong@gmail.com> Reviewed-By: Marco Ippolito <marcoippolito54@gmail.com> Reviewed-By: Luigi Pinca <luigipinca@gmail.com> Reviewed-By: Trivikram Kamat <trivikr.dev@gmail.com> Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
This commit is contained in:
1 parent
19c46abbef
commit
1778eeb6e4
25 files changed
+138
-45
No files matched your search
@@ -33,7 +33,7 @@ const { triggerUncaughtException } = internalBinding('errors');
|
||||
const dc_binding = internalBinding('diagnostics_channel');
|
||||
const { subscribers: subscriberCounts } = dc_binding;
|
||||
|
||||
const { WeakReference } = require('internal/util');
|
||||
const { WeakReference, kEmptyObject } = require('internal/util');
|
||||
const { isPromise } = require('internal/util/types');
|
||||
|
||||
// Can't delete when weakref count reaches 0 as it could increment again.
|
||||
@@ -390,7 +390,7 @@ class BoundedChannel {
|
||||
return done;
|
||||
}
|
||||
|
||||
withScope(context = {}) {
|
||||
withScope(context = kEmptyObject) {
|
||||
return new BoundedChannelScope(this, context);
|
||||
}
|
||||
|
||||
@@ -514,7 +514,7 @@ class TracingChannel {
|
||||
return done;
|
||||
}
|
||||
|
||||
traceSync(fn, context = {}, thisArg, ...args) {
|
||||
traceSync(fn, context = { __proto__: null }, thisArg, ...args) {
|
||||
if (!this.hasSubscribers) {
|
||||
return ReflectApply(fn, thisArg, args);
|
||||
}
|
||||
@@ -534,7 +534,7 @@ class TracingChannel {
|
||||
}
|
||||
}
|
||||
|
||||
tracePromise(fn, context = {}, thisArg, ...args) {
|
||||
tracePromise(fn, context = { __proto__: null }, thisArg, ...args) {
|
||||
if (!this.hasSubscribers) {
|
||||
const result = ReflectApply(fn, thisArg, args);
|
||||
if (typeof result?.then !== 'function') {
|
||||
@@ -589,7 +589,7 @@ class TracingChannel {
|
||||
}
|
||||
}
|
||||
|
||||
traceCallback(fn, position = -1, context = {}, thisArg, ...args) {
|
||||
traceCallback(fn, position = -1, context = kEmptyObject, thisArg, ...args) {
|
||||
if (!this.hasSubscribers) {
|
||||
return ReflectApply(fn, thisArg, args);
|
||||
}
|
||||
|
||||
@@ -1840,7 +1840,7 @@ function readdirSync(path, options) {
|
||||
* ) => any} [callback]
|
||||
* @returns {void}
|
||||
*/
|
||||
function fstat(fd, options = { bigint: false }, callback) {
|
||||
function fstat(fd, options = { __proto__: null, bigint: false }, callback) {
|
||||
if (typeof options === 'function') {
|
||||
callback = options;
|
||||
options = kEmptyObject;
|
||||
@@ -1867,7 +1867,7 @@ function fstat(fd, options = { bigint: false }, callback) {
|
||||
* ) => any} callback
|
||||
* @returns {void}
|
||||
*/
|
||||
function lstat(path, options = { bigint: false }, callback) {
|
||||
function lstat(path, options = { __proto__: null, bigint: false }, callback) {
|
||||
if (typeof options === 'function') {
|
||||
callback = options;
|
||||
options = kEmptyObject;
|
||||
@@ -1899,7 +1899,7 @@ function lstat(path, options = { bigint: false }, callback) {
|
||||
* ) => any} callback
|
||||
* @returns {void}
|
||||
*/
|
||||
function stat(path, options = { bigint: false, throwIfNoEntry: true }, callback) {
|
||||
function stat(path, options = { __proto__: null, bigint: false, throwIfNoEntry: true }, callback) {
|
||||
if (typeof options === 'function') {
|
||||
callback = options;
|
||||
options = kEmptyObject;
|
||||
@@ -1922,7 +1922,7 @@ function stat(path, options = { bigint: false, throwIfNoEntry: true }, callback)
|
||||
binding.stat(getValidatedPath(path), options.bigint, req, options.throwIfNoEntry);
|
||||
}
|
||||
|
||||
function statfs(path, options = { bigint: false }, callback) {
|
||||
function statfs(path, options = { __proto__: null, bigint: false }, callback) {
|
||||
if (typeof options === 'function') {
|
||||
callback = options;
|
||||
options = kEmptyObject;
|
||||
@@ -1957,7 +1957,7 @@ function statfs(path, options = { bigint: false }, callback) {
|
||||
* @param {{ bigint?: boolean; }} [options]
|
||||
* @returns {Stats | undefined}
|
||||
*/
|
||||
function fstatSync(fd, options = { bigint: false }) {
|
||||
function fstatSync(fd, options = { __proto__: null, bigint: false }) {
|
||||
const h = vfsState.handlers;
|
||||
if (h !== null) {
|
||||
const result = h.fstatSync(fd);
|
||||
@@ -1980,7 +1980,7 @@ function fstatSync(fd, options = { bigint: false }) {
|
||||
* }} [options]
|
||||
* @returns {Stats | undefined}
|
||||
*/
|
||||
function lstatSync(path, options = { bigint: false, throwIfNoEntry: true }) {
|
||||
function lstatSync(path, options = { __proto__: null, bigint: false, throwIfNoEntry: true }) {
|
||||
const h = vfsState.handlers;
|
||||
if (h !== null) {
|
||||
const result = h.lstatSync(path, options);
|
||||
@@ -2014,7 +2014,7 @@ function lstatSync(path, options = { bigint: false, throwIfNoEntry: true }) {
|
||||
* }} [options]
|
||||
* @returns {Stats}
|
||||
*/
|
||||
function statSync(path, options = { bigint: false, throwIfNoEntry: true }) {
|
||||
function statSync(path, options = { __proto__: null, bigint: false, throwIfNoEntry: true }) {
|
||||
const h = vfsState.handlers;
|
||||
if (h !== null) {
|
||||
const result = h.statSync(path, options);
|
||||
@@ -2032,7 +2032,7 @@ function statSync(path, options = { bigint: false, throwIfNoEntry: true }) {
|
||||
return getStatsFromBinding(stats);
|
||||
}
|
||||
|
||||
function statfsSync(path, options = { bigint: false }) {
|
||||
function statfsSync(path, options = { __proto__: null, bigint: false }) {
|
||||
const h = vfsState.handlers;
|
||||
if (h !== null) {
|
||||
const result = h.statfsSync(path, options);
|
||||
|
||||
@@ -13,6 +13,7 @@ const AsyncContextFrame = require('internal/async_context_frame');
|
||||
const { AsyncResource } = require('async_hooks');
|
||||
|
||||
const RunScope = require('internal/async_local_storage/run_scope');
|
||||
const { kEmptyObject } = require('internal/util');
|
||||
|
||||
class AsyncLocalStorage {
|
||||
#defaultValue = undefined;
|
||||
@@ -26,7 +27,7 @@ class AsyncLocalStorage {
|
||||
/**
|
||||
* @param {AsyncLocalStorageOptions} [options]
|
||||
*/
|
||||
constructor(options = {}) {
|
||||
constructor(options = kEmptyObject) {
|
||||
validateObject(options, 'options');
|
||||
this.#defaultValue = options.defaultValue;
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ const {
|
||||
} = require('async_hooks');
|
||||
|
||||
const RunScope = require('internal/async_local_storage/run_scope');
|
||||
const { kEmptyObject } = require('internal/util');
|
||||
|
||||
const storageList = [];
|
||||
const storageHook = createHook({
|
||||
@@ -44,7 +45,7 @@ class AsyncLocalStorage {
|
||||
/**
|
||||
* @param {AsyncLocalStorageOptions} [options]
|
||||
*/
|
||||
constructor(options = {}) {
|
||||
constructor(options = kEmptyObject) {
|
||||
this.kResourceStore = Symbol('kResourceStore');
|
||||
this.enabled = false;
|
||||
validateObject(options, 'options');
|
||||
|
||||
@@ -541,7 +541,7 @@ function createBlobReaderStream(reader) {
|
||||
// unbounded memory growth when the DataQueue has a large burst of data.
|
||||
const kMaxBatchChunks = 16;
|
||||
|
||||
async function* createBlobReaderIterable(reader, options = {}) {
|
||||
async function* createBlobReaderIterable(reader, options = kEmptyObject) {
|
||||
const { getReadError } = options;
|
||||
let wakeup = PromiseWithResolvers();
|
||||
reader.setWakeup(wakeup.resolve);
|
||||
|
||||
@@ -58,7 +58,7 @@ const assert = require('internal/assert');
|
||||
|
||||
const LazyTransform = require('internal/streams/lazy_transform');
|
||||
|
||||
const { normalizeEncoding } = require('internal/util');
|
||||
const { normalizeEncoding, kEmptyObject } = require('internal/util');
|
||||
|
||||
const { StringDecoder } = require('string_decoder');
|
||||
|
||||
@@ -255,7 +255,7 @@ addCipherPrototypeFunctions(Decipheriv);
|
||||
|
||||
const kMinNid = 1;
|
||||
const kMaxNid = 2_147_483_647;
|
||||
function getCipherInfo(nameOrNid, options = {}) {
|
||||
function getCipherInfo(nameOrNid, options = kEmptyObject) {
|
||||
validateObject(options, 'options');
|
||||
let { keyLength, ivLength } = options;
|
||||
if (keyLength !== undefined) {
|
||||
|
||||
@@ -1715,7 +1715,7 @@ async function symlink(target, path, type) {
|
||||
);
|
||||
}
|
||||
|
||||
async function fstat(handle, options = { bigint: false }) {
|
||||
async function fstat(handle, options = { __proto__: null, bigint: false }) {
|
||||
const result = await PromisePrototypeThen(
|
||||
binding.fstat(handle.fd, options.bigint, kUsePromises),
|
||||
undefined,
|
||||
@@ -1724,7 +1724,7 @@ async function fstat(handle, options = { bigint: false }) {
|
||||
return getStatsFromBinding(result);
|
||||
}
|
||||
|
||||
async function lstat(path, options = { bigint: false }) {
|
||||
async function lstat(path, options = { __proto__: null, bigint: false }) {
|
||||
const h = vfsState.handlers;
|
||||
if (h !== null) {
|
||||
const promise = h.lstat(path, options);
|
||||
@@ -1743,7 +1743,7 @@ async function lstat(path, options = { bigint: false }) {
|
||||
return getStatsFromBinding(result);
|
||||
}
|
||||
|
||||
async function stat(path, options = { bigint: false, throwIfNoEntry: true }) {
|
||||
async function stat(path, options = { __proto__: null, bigint: false, throwIfNoEntry: true }) {
|
||||
const h = vfsState.handlers;
|
||||
if (h !== null) {
|
||||
const promise = h.stat(path, options);
|
||||
@@ -1761,7 +1761,7 @@ async function stat(path, options = { bigint: false, throwIfNoEntry: true }) {
|
||||
return getStatsFromBinding(result);
|
||||
}
|
||||
|
||||
async function statfs(path, options = { bigint: false }) {
|
||||
async function statfs(path, options = { __proto__: null, bigint: false }) {
|
||||
const h = vfsState.handlers;
|
||||
if (h !== null) {
|
||||
const result = h.statfs(path, options);
|
||||
|
||||
@@ -3813,7 +3813,7 @@ function getUnpackedSettings(buf, options = kEmptyObject) {
|
||||
return settings;
|
||||
}
|
||||
|
||||
function performServerHandshake(socket, options = {}) {
|
||||
function performServerHandshake(socket, options = kEmptyObject) {
|
||||
options = initializeOptions(options);
|
||||
return new ServerHttp2Session(options, socket, undefined);
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ const {
|
||||
} = require('internal/inspector/network');
|
||||
const { Network } = require('inspector');
|
||||
const EventEmitter = require('events');
|
||||
const { kEmptyObject } = require('internal/util');
|
||||
|
||||
const kRequestUrl = Symbol('kRequestUrl');
|
||||
|
||||
@@ -36,7 +37,7 @@ function getRequestURL(request, host) {
|
||||
}
|
||||
|
||||
// Convert a Headers object (Map<string, number | string | string[]>) to a plain object (Map<string, string>)
|
||||
const convertHeaderObject = (headers = {}) => {
|
||||
const convertHeaderObject = (headers = kEmptyObject) => {
|
||||
// The 'host' header that contains the host and port of the URL.
|
||||
let host;
|
||||
let charset;
|
||||
|
||||
@@ -30,11 +30,12 @@ const {
|
||||
} = internalBinding('http2').constants;
|
||||
const EventEmitter = require('events');
|
||||
const { Buffer } = require('buffer');
|
||||
const { kEmptyObject } = require('internal/util');
|
||||
|
||||
const kRequestUrl = Symbol('kRequestUrl');
|
||||
|
||||
// Convert a Headers object (Map<string, number | string | string[]>) to a plain object (Map<string, string>)
|
||||
function convertHeaderObject(headers = {}) {
|
||||
function convertHeaderObject(headers = kEmptyObject) {
|
||||
let scheme;
|
||||
let authority;
|
||||
let path;
|
||||
|
||||
@@ -354,7 +354,7 @@ class AsyncLoaderHooksOnLoaderHookWorker {
|
||||
* @param {object} context Metadata about the module
|
||||
* @returns {Promise<{ format: ModuleFormat, source: ModuleSource }>}
|
||||
*/
|
||||
async load(url, context = {}) {
|
||||
async load(url, context = kEmptyObject) {
|
||||
const chain = this.#chains.load;
|
||||
const meta = {
|
||||
chainFinished: null,
|
||||
|
||||
@@ -30,7 +30,7 @@ const { getOptionValue } = require('internal/options');
|
||||
// Do not eagerly grab .manifest, it may be in TDZ
|
||||
const { sep, posix: { relative: relativePosixPath }, resolve } = require('path');
|
||||
const { URL, pathToFileURL, fileURLToPath, isURL, URLParse } = require('internal/url');
|
||||
const { getCWDURL, setOwnProperty } = require('internal/util');
|
||||
const { getCWDURL, setOwnProperty, kEmptyObject } = require('internal/util');
|
||||
const { canParse: URLCanParse } = internalBinding('url');
|
||||
const { legacyMainResolve: FSLegacyMainResolve } = internalBinding('fs');
|
||||
const {
|
||||
@@ -944,7 +944,7 @@ function throwIfInvalidParentURL(parentURL) {
|
||||
* @param {string[]} [context.conditions] - The conditions for resolving the specifier.
|
||||
* @returns {{url: string, format?: string}}
|
||||
*/
|
||||
function defaultResolve(specifier, context = {}) {
|
||||
function defaultResolve(specifier, context = kEmptyObject) {
|
||||
let { parentURL, conditions } = context;
|
||||
throwIfInvalidParentURL(parentURL);
|
||||
|
||||
|
||||
@@ -543,14 +543,14 @@ function hasObserver(type) {
|
||||
}
|
||||
|
||||
|
||||
function startPerf(target, key, context = {}) {
|
||||
function startPerf(target, key, context = kEmptyObject) {
|
||||
target[key] = {
|
||||
...context,
|
||||
startTime: now(),
|
||||
};
|
||||
}
|
||||
|
||||
function stopPerf(target, key, context = {}) {
|
||||
function stopPerf(target, key, context = kEmptyObject) {
|
||||
const ctx = target[key];
|
||||
if (!ctx) {
|
||||
return;
|
||||
|
||||
@@ -31,7 +31,7 @@ const ESCAPE_CODE_TIMEOUT = 500;
|
||||
* accepts a readable Stream instance and makes it emit "keypress" events
|
||||
*/
|
||||
|
||||
function emitKeypressEvents(stream, iface = {}) {
|
||||
function emitKeypressEvents(stream, iface = { __proto__: null }) {
|
||||
if (stream[KEYPRESS_DECODER]) return;
|
||||
|
||||
stream[KEYPRESS_DECODER] = new StringDecoder('utf8');
|
||||
|
||||
@@ -12,6 +12,7 @@ const {
|
||||
|
||||
const {
|
||||
sleep,
|
||||
kEmptyObject,
|
||||
} = require('internal/util');
|
||||
|
||||
const {
|
||||
@@ -131,7 +132,7 @@ class Utf8Stream extends EventEmitter {
|
||||
contentMode = kContentModeUtf8,
|
||||
mode,
|
||||
// Provides for a custom fs implementation. Mostly useful for testing.
|
||||
fs: overrideFs = {},
|
||||
fs: overrideFs = kEmptyObject,
|
||||
} = options;
|
||||
|
||||
super();
|
||||
|
||||
@@ -4,6 +4,7 @@ const {
|
||||
MathFloor,
|
||||
} = primordials;
|
||||
|
||||
const { kEmptyObject } = require('internal/util');
|
||||
const {
|
||||
validateNumber,
|
||||
validateObject,
|
||||
@@ -14,7 +15,7 @@ const kMaxSamplingIntervalUs = 0x7FFFFFFF;
|
||||
const kMaxSamplingIntervalMs = kMaxSamplingIntervalUs / kMicrosPerMilli;
|
||||
const kMaxSamplesUnlimited = 0xFFFF_FFFF;
|
||||
|
||||
function normalizeCpuProfileOptions(options = {}) {
|
||||
function normalizeCpuProfileOptions(options = kEmptyObject) {
|
||||
validateObject(options, 'options');
|
||||
|
||||
// TODO(ishabi): add support for 'mode' and 'filterContext' options
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
'use strict';
|
||||
|
||||
const { kEmptyObject } = require('internal/util');
|
||||
const {
|
||||
validateBoolean,
|
||||
validateInteger,
|
||||
@@ -14,7 +15,7 @@ const {
|
||||
kSamplingIncludeObjectsCollectedByMinorGC,
|
||||
} = internalBinding('v8');
|
||||
|
||||
function normalizeHeapProfileOptions(options = {}) {
|
||||
function normalizeHeapProfileOptions(options = kEmptyObject) {
|
||||
validateObject(options, 'options');
|
||||
const {
|
||||
sampleInterval = 512 * 1024,
|
||||
|
||||
@@ -18,6 +18,7 @@ const {
|
||||
} = internalBinding('constants');
|
||||
|
||||
const { getStatsFromBinding } = require('internal/fs/utils');
|
||||
const { kEmptyObject } = require('internal/util');
|
||||
|
||||
// Default block size for virtual files (4KB)
|
||||
const kDefaultBlockSize = 4096;
|
||||
@@ -91,7 +92,7 @@ function fillBigIntStatsArray(
|
||||
* @param {boolean} [options.bigint] Return BigIntStats
|
||||
* @returns {Stats}
|
||||
*/
|
||||
function createFileStats(size, options = {}) {
|
||||
function createFileStats(size, options = kEmptyObject) {
|
||||
const now = DateNow();
|
||||
const mode = (options.mode ?? 0o644) | S_IFREG;
|
||||
const nlink = options.nlink ?? 1;
|
||||
@@ -150,7 +151,7 @@ function createFileStats(size, options = {}) {
|
||||
* @param {number} [options.birthtimeMs] Birth time in ms
|
||||
* @returns {Stats}
|
||||
*/
|
||||
function createDirectoryStats(options = {}) {
|
||||
function createDirectoryStats(options = kEmptyObject) {
|
||||
const now = DateNow();
|
||||
const mode = (options.mode ?? 0o755) | S_IFDIR;
|
||||
const uid = options.uid ?? (process.getuid?.() ?? 0);
|
||||
@@ -208,7 +209,7 @@ function createDirectoryStats(options = {}) {
|
||||
* @param {number} [options.birthtimeMs] Birth time in ms
|
||||
* @returns {Stats}
|
||||
*/
|
||||
function createSymlinkStats(size, options = {}) {
|
||||
function createSymlinkStats(size, options = kEmptyObject) {
|
||||
const now = DateNow();
|
||||
const mode = (options.mode ?? 0o777) | S_IFLNK;
|
||||
const uid = options.uid ?? (process.getuid?.() ?? 0);
|
||||
|
||||
@@ -18,6 +18,7 @@ const {
|
||||
setInterval,
|
||||
clearInterval,
|
||||
} = require('timers');
|
||||
const { kEmptyObject } = require('internal/util');
|
||||
|
||||
/**
|
||||
* VFSWatcher - Polling-based file/directory watcher for VFS.
|
||||
@@ -47,7 +48,7 @@ class VFSWatcher extends EventEmitter {
|
||||
* @param {boolean} [options.recursive] Watch subdirectories (default: false)
|
||||
* @param {AbortSignal} [options.signal] AbortSignal for cancellation
|
||||
*/
|
||||
constructor(provider, path, options = {}) {
|
||||
constructor(provider, path, options = kEmptyObject) {
|
||||
super();
|
||||
|
||||
this.#vfs = provider;
|
||||
@@ -395,7 +396,7 @@ class VFSStatWatcher extends EventEmitter {
|
||||
* @param {number} [options.interval] Polling interval in ms (default: 5007)
|
||||
* @param {boolean} [options.persistent] Keep process alive (default: true)
|
||||
*/
|
||||
constructor(provider, path, options = {}) {
|
||||
constructor(provider, path, options = kEmptyObject) {
|
||||
super();
|
||||
|
||||
this.#vfs = provider;
|
||||
@@ -586,7 +587,7 @@ class VFSWatchAsyncIterable {
|
||||
* @param {string} path The path to watch (provider-relative)
|
||||
* @param {object} [options] Options
|
||||
*/
|
||||
constructor(provider, path, options = {}) {
|
||||
constructor(provider, path, options = kEmptyObject) {
|
||||
// Strip signal from options passed to VFSWatcher - we handle abort
|
||||
// at the iterable level to reject pending next() with AbortError
|
||||
// instead of resolving with done:true via the 'close' event.
|
||||
|
||||
+1
-1
@@ -967,7 +967,7 @@ class REPLServer extends Interface {
|
||||
|
||||
self.displayPrompt();
|
||||
}
|
||||
setupHistory(historyConfig = {}, cb) {
|
||||
setupHistory(historyConfig = { __proto__: null }, cb) {
|
||||
// TODO(puskin94): necessary because historyConfig can be a string for backwards compatibility
|
||||
const options = typeof historyConfig === 'string' ?
|
||||
{ filePath: historyConfig } :
|
||||
|
||||
+2
-1
@@ -96,6 +96,7 @@ const {
|
||||
getSystemErrorMessage: internalErrorMessage,
|
||||
promisify,
|
||||
defineLazyProperties,
|
||||
kEmptyObject,
|
||||
} = require('internal/util');
|
||||
|
||||
let abortController;
|
||||
@@ -584,7 +585,7 @@ function getCallSites(frameCount = 10, options) {
|
||||
};
|
||||
|
||||
// Public util.deprecate API
|
||||
function deprecate(fn, msg, code, { modifyPrototype } = {}) {
|
||||
function deprecate(fn, msg, code, { modifyPrototype } = kEmptyObject) {
|
||||
return internalDeprecate(fn, msg, code, undefined, modifyPrototype);
|
||||
}
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
const {
|
||||
ArrayPrototypeForEach,
|
||||
ObjectFreeze,
|
||||
ObjectPrototype,
|
||||
PromiseReject,
|
||||
ReflectApply,
|
||||
Symbol,
|
||||
@@ -222,7 +223,7 @@ function getContextOptions(options) {
|
||||
}
|
||||
|
||||
let defaultContextNameIndex = 1;
|
||||
function createContext(contextObject = {}, options = kEmptyObject) {
|
||||
function createContext(contextObject = { __proto__: ObjectPrototype }, options = kEmptyObject) {
|
||||
if (contextObject !== vm_context_no_contextify && isContext(contextObject)) {
|
||||
return contextObject;
|
||||
}
|
||||
|
||||
+1
-1
@@ -111,7 +111,7 @@ class WASI {
|
||||
|
||||
finalizeBindings(instance, {
|
||||
memory = instance?.exports?.memory,
|
||||
} = {}) {
|
||||
} = kEmptyObject) {
|
||||
if (this[kStarted]) {
|
||||
throw new ERR_WASI_ALREADY_STARTED();
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ const RuleTester = require('../../tools/eslint/node_modules/eslint').RuleTester;
|
||||
const rule = require('../../tools/eslint-rules/avoid-prototype-pollution');
|
||||
|
||||
new RuleTester()
|
||||
.run('property-descriptor-no-prototype-pollution', rule, {
|
||||
.run('avoid-prototype-pollution', rule, {
|
||||
valid: [
|
||||
'ObjectDefineProperties({}, {})',
|
||||
'ObjectCreate(null, {})',
|
||||
@@ -63,6 +63,18 @@ new RuleTester()
|
||||
'new Proxy({}, { __proto__: null, ...{} })',
|
||||
'async function name(){return await SafePromiseAll([])}',
|
||||
'async function name(){const val = await SafePromiseAll([])}',
|
||||
'async function name(options = kEmptyObject){}',
|
||||
'function name(options = kEmptyObject){}',
|
||||
'function name(options = { __proto__: ObjectPrototype }){}',
|
||||
'function name(options = { __proto__: null }){}',
|
||||
'new class { name(options = kEmptyObject){} }',
|
||||
'const name = (options = kEmptyObject) => {}',
|
||||
'async function name(options = { __proto__: null, key: 1 }){}',
|
||||
'const name = ({ destr } = { destr: 1 }) => {}',
|
||||
'function name({ destr } = kEmptyObject){}',
|
||||
'function name({ [Symbol.match]: m } = kEmptyObject){}',
|
||||
'function name({ [Symbol.match]: m } = { __proto__: null, [Symbol.match]: 1 }){}',
|
||||
'function name({ [Symbol.match]: m, c } = { __proto__: null, c: 1 }){}',
|
||||
],
|
||||
invalid: [
|
||||
{
|
||||
@@ -330,5 +342,53 @@ new RuleTester()
|
||||
code: 'ArrayPrototypeConcat([])',
|
||||
errors: [{ message: /\bisConcatSpreadable\b/ }]
|
||||
},
|
||||
{
|
||||
code: 'function name(options = {}) {}',
|
||||
errors: [{ message: /\bkEmptyObject\b/ }]
|
||||
},
|
||||
{
|
||||
code: 'async function name(options = { key: 1 }) {}',
|
||||
errors: [{ message: /\b__proto__: null\b/ }]
|
||||
},
|
||||
{
|
||||
code: 'new class { name(options = {}) {} }',
|
||||
errors: [{ message: /\bkEmptyObject\b/ }]
|
||||
},
|
||||
{
|
||||
code: 'new class { async name(options = {}) {} }',
|
||||
errors: [{ message: /\bkEmptyObject\b/ }]
|
||||
},
|
||||
{
|
||||
code: 'const name = (options = {}) => {}',
|
||||
errors: [{ message: /\bkEmptyObject\b/ }]
|
||||
},
|
||||
{
|
||||
code: 'const name = async (options = {}) => {}',
|
||||
errors: [{ message: /\bkEmptyObject\b/ }]
|
||||
},
|
||||
{
|
||||
code: 'function name({ destr } = {}) {}',
|
||||
errors: [{ message: /\bkEmptyObject\b/ }]
|
||||
},
|
||||
{
|
||||
code: 'async function name({ destr } = {}) {}',
|
||||
errors: [{ message: /\bkEmptyObject\b/ }]
|
||||
},
|
||||
{
|
||||
code: 'new class { name({ destr } = {}) {} }',
|
||||
errors: [{ message: /\bkEmptyObject\b/ }]
|
||||
},
|
||||
{
|
||||
code: 'new class { async name({ destr } = {}) {} }',
|
||||
errors: [{ message: /\bkEmptyObject\b/ }]
|
||||
},
|
||||
{
|
||||
code: 'const name = ({ destr } = {}) => {}',
|
||||
errors: [{ message: /\bkEmptyObject\b/ }]
|
||||
},
|
||||
{
|
||||
code: 'const name = async ({ destr } = {}) => {}',
|
||||
errors: [{ message: /\bkEmptyObject\b/ }]
|
||||
},
|
||||
]
|
||||
});
|
||||
@@ -232,6 +232,28 @@ module.exports = {
|
||||
'which can be subject to prototype pollution',
|
||||
});
|
||||
},
|
||||
|
||||
'AssignmentPattern[right.type="ObjectExpression"]'(node) {
|
||||
if (!node.right.properties.length) {
|
||||
context.report({
|
||||
node: node.right,
|
||||
message: 'Use kEmptyObject instead of declaring a new empty object, or define a __proto__ property',
|
||||
});
|
||||
return;
|
||||
}
|
||||
const propertyIsIdentifier = (p) => p.key.type === 'Identifier';
|
||||
if (node.left.type === 'ObjectPattern' &&
|
||||
node.left.properties.every(propertyIsIdentifier) &&
|
||||
node.right.properties.every(propertyIsIdentifier)) {
|
||||
const rightNames = node.right.properties.map((p) => p.key.name);
|
||||
if (node.left.properties.every((p) => rightNames.includes(p.key.name))) return;
|
||||
}
|
||||
if (node.right.properties.some((p) => p.key.name === '__proto__')) return;
|
||||
context.report({
|
||||
node: node.right,
|
||||
message: `Add '__proto__: null' to avoid inheriting from Object.prototype, or '__proto__: ObjectPrototype' if inheritance is desirable`,
|
||||
});
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
Reference in new issue
Block a user