Skip to content

Commit

Permalink
fixup: add support for Object.create(null)
Browse files Browse the repository at this point in the history
  • Loading branch information
ljharb committed Jan 3, 2023
1 parent 0c92b54 commit bc882da
Show file tree
Hide file tree
Showing 33 changed files with 70 additions and 53 deletions.
4 changes: 2 additions & 2 deletions benchmark/es/map-bench.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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();
Expand Down
2 changes: 1 addition & 1 deletion test/async-hooks/verify-graph.js
Original file line number Diff line number Diff line change
Expand Up @@ -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]++;
Expand Down
2 changes: 1 addition & 1 deletion test/parallel/test-assert-deep.js
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down
2 changes: 1 addition & 1 deletion test/parallel/test-blob.js
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
2 changes: 1 addition & 1 deletion test/parallel/test-buffer-from.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ deepStrictEqual(
{ valueOf() { return null; } },
{ valueOf() { return undefined; } },
{ valueOf: null },
Object.create(null),
{ __proto__: null },
new Number(true),
new MyBadPrimitive(),
Symbol(),
Expand Down
2 changes: 1 addition & 1 deletion test/parallel/test-common-must-not-mutate-object-deep.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -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 });
Expand Down
6 changes: 3 additions & 3 deletions test/parallel/test-crypto-x509.js
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand All @@ -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',
Expand All @@ -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']
}),
Expand Down
2 changes: 1 addition & 1 deletion test/parallel/test-error-value-type-detection.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ strictEqual(
);

strictEqual(
determineSpecificType(Object.create(null)),
determineSpecificType({ __proto__: null }),
'[Object: null prototype] {}',
);

Expand Down
2 changes: 1 addition & 1 deletion test/parallel/test-event-emitter-emit-context.js
Original file line number Diff line number Diff line change
Expand Up @@ -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' })
Expand Down
2 changes: 1 addition & 1 deletion test/parallel/test-fs-opendir.js
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ doAsyncIterBreakTest().then(common.mustCall());
async function doAsyncIterReturnTest() {
const dir = await fs.promises.opendir(testDir);
await (async function() {
for await (const dirent of dir) {
for await (const dirent of dir) { // eslint-disable-line no-unused-vars
return;
}
})();
Expand Down
2 changes: 1 addition & 1 deletion test/parallel/test-http-multiple-headers.js
Original file line number Diff line number Diff line change
Expand Up @@ -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' ],
Expand Down
2 changes: 1 addition & 1 deletion test/parallel/test-http-mutable-headers.js
Original file line number Diff line number Diff line change
Expand Up @@ -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(), []);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
2 changes: 1 addition & 1 deletion test/parallel/test-http2-compat-serverresponse-headers.js
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
2 changes: 1 addition & 1 deletion test/parallel/test-http2-multiheaders-raw.js
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down
2 changes: 1 addition & 1 deletion test/parallel/test-http2-multiheaders.js
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down
2 changes: 1 addition & 1 deletion test/parallel/test-http2-response-splitting.js
Original file line number Diff line number Diff line change
Expand Up @@ -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));
Expand Down
2 changes: 1 addition & 1 deletion test/parallel/test-http2-util-asserts.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ const {
[
undefined,
{},
Object.create(null),
{ __proto__: null },
new Date(),
new (class Foo {})(),
].forEach((input) => {
Expand Down
14 changes: 7 additions & 7 deletions test/parallel/test-module-multi-extensions.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 };
}

{
Expand All @@ -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 };
}

{
Expand All @@ -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 };
}

{
Expand All @@ -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 };
}

{
Expand All @@ -72,15 +72,15 @@ 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 };
}

{
require.extensions['.bar'] = common.mustNotCall();
require(dotfile);
delete require.cache[dotfile];
delete require.extensions['.bar'];
Module._pathCache = Object.create(null);
Module._pathCache = { __proto__: null };
}

{
Expand All @@ -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 };
}
2 changes: 1 addition & 1 deletion test/parallel/test-parse-args.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -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' };
Expand Down
2 changes: 1 addition & 1 deletion test/parallel/test-querystring.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
});
Expand Down
2 changes: 1 addition & 1 deletion test/parallel/test-stream-readable-async-iterators.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ async function tests() {
});

await (async () => {
for await (const d of readable) {
for await (const d of readable) { // eslint-disable-line no-unused-vars
return;
}
})();
Expand Down
4 changes: 2 additions & 2 deletions test/parallel/test-tls-translate-peer-certificate.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,15 +53,15 @@ deepStrictEqual(
}

deepStrictEqual(translatePeerCertificate({ infoAccess: '' }),
{ infoAccess: Object.create(null) });
{ infoAccess: { __proto__: null } });
deepStrictEqual(translatePeerCertificate({ infoAccess: null }),
{ infoAccess: null });
{
const input =
'__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'];
Expand Down
2 changes: 1 addition & 1 deletion test/parallel/test-trace-events-fs-async.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion test/parallel/test-trace-events-fs-sync.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion test/parallel/test-url-parse-query.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
});
Expand Down
2 changes: 1 addition & 1 deletion test/parallel/test-util-format.js
Original file line number Diff line number Diff line change
Expand Up @@ -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] {}'
);
}
Expand Down
14 changes: 7 additions & 7 deletions test/parallel/test-util-inspect.js
Original file line number Diff line number Diff line change
Expand Up @@ -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] {}');
}

Expand Down Expand Up @@ -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] {}> {}'
Expand All @@ -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()),
Expand Down Expand Up @@ -3107,7 +3107,7 @@ assert.strictEqual(
return this.stylized;
}
})
`, Object.create(null));
`, { __proto__: null });
assert.strictEqual(target.ctx, undefined);

{
Expand Down
2 changes: 1 addition & 1 deletion test/parallel/test-vm-inherited_properties.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ 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;

Expand Down
2 changes: 1 addition & 1 deletion test/parallel/test-vm-module-basic.js
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down
Loading

0 comments on commit bc882da

Please sign in to comment.