domain: fix vm promise tracking while keeping isolation

PR-URL: https://github.com/nodejs/node/pull/43556
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Chengzhong Wu <legendecas@gmail.com>
This commit is contained in:
Stephen Belanger 2022-07-14 19:05:50 +08:00 committed by GitHub
parent 40515e6259
commit 660d17dde7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 35 additions and 0 deletions

View File

@ -39,6 +39,7 @@ const {
Promise,
ReflectApply,
SafeMap,
SafeWeakMap,
Symbol,
} = primordials;
@ -69,6 +70,7 @@ ObjectDefineProperty(process, 'domain', {
}
});
const vmPromises = new SafeWeakMap();
const pairing = new SafeMap();
const asyncHook = createHook({
init(asyncId, type, triggerAsyncId, resource) {
@ -85,6 +87,11 @@ const asyncHook = createHook({
value: process.domain,
writable: true
});
// Because promises from other contexts don't get a domain field,
// the domain needs to be held alive another way. Stuffing it in a
// weakmap connected to the promise lifetime can fix that.
} else {
vmPromises.set(resource, process.domain);
}
}
},

View File

@ -0,0 +1,28 @@
'use strict';
const common = require('../common');
const assert = require('assert');
const domain = require('domain');
const vm = require('vm');
// A promise created in a VM should not include a domain field but
// domains should still be able to propagate through them.
//
// See; https://github.com/nodejs/node/issues/40999
const context = vm.createContext({});
function run(code) {
const d = domain.createDomain();
d.run(common.mustCall(() => {
const p = vm.runInContext(code, context)();
assert.strictEqual(p.domain, undefined);
p.then(common.mustCall(() => {
assert.strictEqual(process.domain, d);
}));
}));
}
for (let i = 0; i < 1000; i++) {
run('async () => null');
}