Skip to content

Commit d164cd4

Browse files
committed
vm: properly handle defining symbol props
This PR is a follow-up of nodejs#46615. When bumping V8 for node 18, various bugs appeared around vm. Some have been fixed along the flow, but there is at least one remaining and described at: jestjs/jest#13338. The current fix does nothing on node 20: the new bump of v8 done for node 20 seems to fix it. But it would fix the problem in both node 18 and node 19. I confirmed it would fix node 19 by cherry-picking the commit on v19.x-staging and launching `make -j4 jstest` on it.
1 parent 17570c0 commit d164cd4

File tree

3 files changed

+81
-26
lines changed

3 files changed

+81
-26
lines changed

src/node_contextify.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -527,6 +527,7 @@ void ContextifyContext::PropertySetterCallback(
527527
!is_function)
528528
return;
529529

530+
if (!is_declared && property->IsSymbol()) return;
530531
if (ctx->sandbox()->Set(context, property, value).IsNothing()) return;
531532

532533
Local<Value> desc;
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
'use strict';
2+
require('../common');
3+
const assert = require('assert');
4+
const vm = require('vm');
5+
6+
// These assertions check that we can set new keys to the global context,
7+
// get them back and also list them via getOwnProperty*.
8+
//
9+
// Related to:
10+
// - https://github.com/nodejs/node/issues/45983
11+
12+
const global = vm.runInContext('this', vm.createContext());
13+
14+
const totoSymbol = Symbol.for('toto');
15+
Object.defineProperty(global, totoSymbol, {
16+
enumerable: true,
17+
writable: true,
18+
value: 4,
19+
configurable: true,
20+
});
21+
assert.strictEqual(global[totoSymbol], 4);
22+
assert.ok(Object.getOwnPropertySymbols(global).includes(totoSymbol));
23+
Object.defineProperty(global, totoSymbol, {
24+
enumerable: true,
25+
writable: true,
26+
value: 44,
27+
configurable: true,
28+
});
29+
assert.strictEqual(global[totoSymbol], 44);
30+
assert.ok(Object.getOwnPropertySymbols(global).includes(totoSymbol));
31+
32+
const totoKey = 'toto';
33+
Object.defineProperty(global, totoKey, {
34+
enumerable: true,
35+
writable: true,
36+
value: 5,
37+
configurable: true,
38+
});
39+
assert.strictEqual(global[totoKey], 5);
40+
assert.ok(Object.getOwnPropertyNames(global).includes(totoKey));
41+
Object.defineProperty(global, totoKey, {
42+
enumerable: true,
43+
writable: true,
44+
value: 55,
45+
configurable: true,
46+
});
47+
assert.strictEqual(global[totoKey], 55);
48+
assert.ok(Object.getOwnPropertyNames(global).includes(totoKey));
49+
50+
const titiSymbol = Symbol.for('titi');
51+
global[titiSymbol] = 6;
52+
assert.strictEqual(global[titiSymbol], 6);
53+
assert.ok(Object.getOwnPropertySymbols(global).includes(titiSymbol));
54+
global[titiSymbol] = 66;
55+
assert.strictEqual(global[titiSymbol], 66);
56+
assert.ok(Object.getOwnPropertySymbols(global).includes(titiSymbol));
57+
58+
const titiKey = 'titi';
59+
global[titiKey] = 7;
60+
assert.strictEqual(global[titiKey], 7);
61+
assert.ok(Object.getOwnPropertyNames(global).includes(titiKey));
62+
global[titiKey] = 77;
63+
assert.strictEqual(global[titiKey], 77);
64+
assert.ok(Object.getOwnPropertyNames(global).includes(titiKey));
65+
66+
const tutuSymbol = Symbol.for('tutu');
67+
global[tutuSymbol] = () => {};
68+
assert.strictEqual(typeof global[tutuSymbol], 'function');
69+
assert.ok(Object.getOwnPropertySymbols(global).includes(tutuSymbol));
70+
global[tutuSymbol] = () => {};
71+
assert.strictEqual(typeof global[tutuSymbol], 'function');
72+
assert.ok(Object.getOwnPropertySymbols(global).includes(tutuSymbol));
73+
74+
const tutuKey = 'tutu';
75+
global[tutuKey] = () => {};
76+
assert.strictEqual(typeof global[tutuKey], 'function');
77+
assert.ok(Object.getOwnPropertyNames(global).includes(tutuKey));
78+
global[tutuKey] = () => {};
79+
assert.strictEqual(typeof global[tutuKey], 'function');
80+
assert.ok(Object.getOwnPropertyNames(global).includes(tutuKey));

test/parallel/test-vm-global-symbol.js

Lines changed: 0 additions & 26 deletions
This file was deleted.

0 commit comments

Comments
 (0)