Skip to content

Commit 377c583

Browse files
ljharbaddaleax
authored andcommitted
domain: set .domain non-enumerable on resources
In particular, this comes into play in the node repl, which apparently enables domains by default. Whenever any Promise gets inspected, a `.domain` property is displayed, which is *very confusing*, especially since it has some kind of WeakReference attached to it, which is not yet a language feature. This change will prevent it from showing up in casual inspection, but will leave it available for use. PR-URL: #26210 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de> Reviewed-By: Michaël Zasso <targos@protonmail.com> Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: Gus Caplan <me@gus.host> Reviewed-By: Luigi Pinca <luigipinca@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Сковорода Никита Андреевич <chalkerx@gmail.com> Reviewed-By: Tobias Nießen <tniessen@tnie.de>
1 parent 8cbbe73 commit 377c583

5 files changed

+53
-7
lines changed

lib/domain.js

+42-7
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,12 @@ const asyncHook = createHook({
5858
if (process.domain !== null && process.domain !== undefined) {
5959
// If this operation is created while in a domain, let's mark it
6060
pairing.set(asyncId, process.domain[kWeak]);
61-
resource.domain = process.domain;
61+
Object.defineProperty(resource, 'domain', {
62+
configurable: true,
63+
enumerable: false,
64+
value: process.domain,
65+
writable: true
66+
});
6267
}
6368
},
6469
before(asyncId) {
@@ -196,7 +201,12 @@ Domain.prototype._errorHandler = function(er) {
196201
var caught = false;
197202

198203
if (!util.isPrimitive(er)) {
199-
er.domain = this;
204+
Object.defineProperty(er, 'domain', {
205+
configurable: true,
206+
enumerable: false,
207+
value: this,
208+
writable: true
209+
});
200210
er.domainThrown = true;
201211
}
202212

@@ -313,7 +323,12 @@ Domain.prototype.add = function(ee) {
313323
}
314324
}
315325

316-
ee.domain = this;
326+
Object.defineProperty(ee, 'domain', {
327+
configurable: true,
328+
enumerable: false,
329+
value: this,
330+
writable: true
331+
});
317332
this.members.push(ee);
318333
};
319334

@@ -352,7 +367,12 @@ function intercepted(_this, self, cb, fnargs) {
352367
var er = fnargs[0];
353368
er.domainBound = cb;
354369
er.domainThrown = false;
355-
er.domain = self;
370+
Object.defineProperty(er, 'domain', {
371+
configurable: true,
372+
enumerable: false,
373+
value: self,
374+
writable: true
375+
});
356376
self.emit('error', er);
357377
return;
358378
}
@@ -406,7 +426,12 @@ Domain.prototype.bind = function(cb) {
406426
return bound(this, self, cb, arguments);
407427
}
408428

409-
runBound.domain = this;
429+
Object.defineProperty(runBound, 'domain', {
430+
configurable: true,
431+
enumerable: false,
432+
value: this,
433+
writable: true
434+
});
410435

411436
return runBound;
412437
};
@@ -416,7 +441,12 @@ EventEmitter.usingDomains = true;
416441

417442
const eventInit = EventEmitter.init;
418443
EventEmitter.init = function() {
419-
this.domain = null;
444+
Object.defineProperty(this, 'domain', {
445+
configurable: true,
446+
enumerable: false,
447+
value: null,
448+
writable: true
449+
});
420450
if (exports.active && !(this instanceof exports.Domain)) {
421451
this.domain = exports.active;
422452
}
@@ -445,7 +475,12 @@ EventEmitter.prototype.emit = function(...args) {
445475

446476
if (typeof er === 'object') {
447477
er.domainEmitter = this;
448-
er.domain = domain;
478+
Object.defineProperty(er, 'domain', {
479+
configurable: true,
480+
enumerable: false,
481+
value: domain,
482+
writable: true
483+
});
449484
er.domainThrown = false;
450485
}
451486

test/parallel/test-domain-add-remove.js

+4
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,15 @@ require('../common');
44
const assert = require('assert');
55
const domain = require('domain');
66
const EventEmitter = require('events');
7+
const isEnumerable = Function.call.bind(Object.prototype.propertyIsEnumerable);
78

89
const d = new domain.Domain();
910
const e = new EventEmitter();
1011
const e2 = new EventEmitter();
1112

1213
d.add(e);
1314
assert.strictEqual(e.domain, d);
15+
assert.strictEqual(isEnumerable(e, 'domain'), false);
1416

1517
// Adding the same event to a domain should not change the member count
1618
let previousMemberCount = d.members.length;
@@ -19,8 +21,10 @@ assert.strictEqual(previousMemberCount, d.members.length);
1921

2022
d.add(e2);
2123
assert.strictEqual(e2.domain, d);
24+
assert.strictEqual(isEnumerable(e2, 'domain'), false);
2225

2326
previousMemberCount = d.members.length;
2427
d.remove(e2);
2528
assert.notStrictEqual(e2.domain, d);
29+
assert.strictEqual(isEnumerable(e2, 'domain'), false);
2630
assert.strictEqual(previousMemberCount - 1, d.members.length);

test/parallel/test-domain-async-id-map-leak.js

+3
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ const assert = require('assert');
66
const async_hooks = require('async_hooks');
77
const domain = require('domain');
88
const EventEmitter = require('events');
9+
const isEnumerable = Function.call.bind(Object.prototype.propertyIsEnumerable);
910

1011
// This test makes sure that the (async id → domain) map which is part of the
1112
// domain module does not get in the way of garbage collection.
@@ -21,7 +22,9 @@ d.run(() => {
2122

2223
emitter.linkToResource = resource;
2324
assert.strictEqual(emitter.domain, d);
25+
assert.strictEqual(isEnumerable(emitter, 'domain'), false);
2426
assert.strictEqual(resource.domain, d);
27+
assert.strictEqual(isEnumerable(resource, 'domain'), false);
2528

2629
// This would otherwise be a circular chain now:
2730
// emitter → resource → async id ⇒ domain → emitter.

test/parallel/test-domain-implicit-binding.js

+2
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,15 @@ const common = require('../common');
44
const assert = require('assert');
55
const domain = require('domain');
66
const fs = require('fs');
7+
const isEnumerable = Function.call.bind(Object.prototype.propertyIsEnumerable);
78

89
{
910
const d = new domain.Domain();
1011

1112
d.on('error', common.mustCall((err) => {
1213
assert.strictEqual(err.message, 'foobar');
1314
assert.strictEqual(err.domain, d);
15+
assert.strictEqual(isEnumerable(err, 'domain'), false);
1416
assert.strictEqual(err.domainEmitter, undefined);
1517
assert.strictEqual(err.domainBound, undefined);
1618
assert.strictEqual(err.domainThrown, true);

test/parallel/test-domain-timer.js

+2
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,14 @@
33
const common = require('../common');
44
const assert = require('assert');
55
const domain = require('domain');
6+
const isEnumerable = Function.call.bind(Object.prototype.propertyIsEnumerable);
67

78
const d = new domain.Domain();
89

910
d.on('error', common.mustCall((err) => {
1011
assert.strictEqual(err.message, 'foobar');
1112
assert.strictEqual(err.domain, d);
13+
assert.strictEqual(isEnumerable(err, 'domain'), false);
1214
assert.strictEqual(err.domainEmitter, undefined);
1315
assert.strictEqual(err.domainBound, undefined);
1416
assert.strictEqual(err.domainThrown, true);

0 commit comments

Comments
 (0)