Skip to content

Commit 0b04869

Browse files
TimothyGuevanlucas
authored andcommitted
src: do not add .domain to promises in VM contexts
The promises are still tracked, and their handlers will still execute in the correct domain. The creation domain is simply hidden. Backport-PR-URL: #16074 PR-URL: #15695 Fixes: #15673 Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: James M Snell <[email protected]> Reviewed-By: Colin Ihrig <[email protected]> Reviewed-By: Ben Noordhuis <[email protected]>
1 parent b1a68f5 commit 0b04869

File tree

4 files changed

+37
-9
lines changed

4 files changed

+37
-9
lines changed

doc/api/domain.md

+6
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
# Domain
22
<!-- YAML
33
changes:
4+
- version: REPLACEME
5+
pr-url: https://github.com/nodejs/node/pull/REPLACEME
6+
description: Any `Promise`s created in VM contexts no longer have a
7+
`.domain` property. Their handlers are still executed in the
8+
proper domain, however, and `Promise`s created in the main
9+
context still possess a `.domain` property.
410
- version: v8.0.0
511
pr-url: https://github.com/nodejs/node/pull/12489
612
description: Handlers for `Promise`s are now invoked in the domain in which

src/env.h

+1
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ class ModuleWrap;
9393
V(npn_buffer_private_symbol, "node:npnBuffer") \
9494
V(processed_private_symbol, "node:processed") \
9595
V(selected_npn_buffer_private_symbol, "node:selectedNpnBuffer") \
96+
V(domain_private_symbol, "node:domain") \
9697

9798
// Strings are per-isolate primitives but Environment proxies them
9899
// for the sake of convenience. Strings should be ASCII-only.

src/node.cc

+23-6
Original file line numberDiff line numberDiff line change
@@ -1161,8 +1161,19 @@ bool ShouldAbortOnUncaughtException(Isolate* isolate) {
11611161
}
11621162

11631163

1164+
Local<Value> GetDomainProperty(Environment* env, Local<Object> object) {
1165+
Local<Value> domain_v =
1166+
object->GetPrivate(env->context(), env->domain_private_symbol())
1167+
.ToLocalChecked();
1168+
if (domain_v->IsObject()) {
1169+
return domain_v;
1170+
}
1171+
return object->Get(env->context(), env->domain_string()).ToLocalChecked();
1172+
}
1173+
1174+
11641175
bool DomainEnter(Environment* env, Local<Object> object) {
1165-
Local<Value> domain_v = object->Get(env->domain_string());
1176+
Local<Value> domain_v = GetDomainProperty(env, object);
11661177
if (domain_v->IsObject()) {
11671178
Local<Object> domain = domain_v.As<Object>();
11681179
if (domain->Get(env->disposed_string())->IsTrue())
@@ -1180,7 +1191,7 @@ bool DomainEnter(Environment* env, Local<Object> object) {
11801191

11811192

11821193
bool DomainExit(Environment* env, v8::Local<v8::Object> object) {
1183-
Local<Value> domain_v = object->Get(env->domain_string());
1194+
Local<Value> domain_v = GetDomainProperty(env, object);
11841195
if (domain_v->IsObject()) {
11851196
Local<Object> domain = domain_v.As<Object>();
11861197
if (domain->Get(env->disposed_string())->IsTrue())
@@ -1205,10 +1216,16 @@ void DomainPromiseHook(PromiseHookType type,
12051216
Local<Context> context = env->context();
12061217

12071218
if (type == PromiseHookType::kInit && env->in_domain()) {
1208-
promise->Set(context,
1209-
env->domain_string(),
1210-
env->domain_array()->Get(context,
1211-
0).ToLocalChecked()).FromJust();
1219+
Local<Value> domain_obj =
1220+
env->domain_array()->Get(context, 0).ToLocalChecked();
1221+
if (promise->CreationContext() == context) {
1222+
promise->Set(context, env->domain_string(), domain_obj).FromJust();
1223+
} else {
1224+
// Do not expose object from another context publicly in promises created
1225+
// in non-main contexts.
1226+
promise->SetPrivate(context, env->domain_private_symbol(), domain_obj)
1227+
.FromJust();
1228+
}
12121229
return;
12131230
}
12141231

test/parallel/test-domain-promise.js

+7-3
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,13 @@ common.crashOnUnhandledRejection();
3131
const d = domain.create();
3232

3333
d.run(common.mustCall(() => {
34-
vm.runInNewContext(`Promise.resolve().then(common.mustCall(() => {
35-
assert.strictEqual(process.domain, d);
36-
}));`, { common, assert, process, d });
34+
vm.runInNewContext(`
35+
const promise = Promise.resolve();
36+
assert.strictEqual(promise.domain, undefined);
37+
promise.then(common.mustCall(() => {
38+
assert.strictEqual(process.domain, d);
39+
}));
40+
`, { common, assert, process, d });
3741
}));
3842
}
3943

0 commit comments

Comments
 (0)