Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

vm: introduce vanilla contexts via vm.constants.DONT_CONTEXTIFY #54394

Merged
merged 4 commits into from
Aug 29, 2024

Conversation

joyeecheung
Copy link
Member

@joyeecheung joyeecheung commented Aug 15, 2024

vm: introduce vanilla contexts via vm.constants.DONT_CONTEXTIFY

Text for releasers:

new option for vm.createContext() to create a context with a freezable globalThis

This implements a flavor of vm.createContext() and friends that creates a context without contextifying its global object when vm.constants.DONT_CONTEXTIFY is used.
This is suitable when users want to freeze the context (impossible when the global is contextified i.e. has interceptors installed) or speed up the global access if they don't need the interceptor behavior.

const vm = require('node:vm');

{
  const oldContext = vm.createContext();
  console.log(vm.runInContext('globalThis', context) === oldContext);  // false
  console.log(oldContext.Array);  // undefined

  // In contextified contexts, freezing doesn't work
  try {
    vm.runInContext('Object.freeze(globalThis);', oldContext);
  } catch {
    // TypeError: Cannot freeze
  }
  console.log(vm.runInContext('globalThis.foo = 1; foo;', oldContext));  // 1
}

{
  const newContext = vm.createContext(vm.constants.DONT_CONTEXTIFY);
  console.log(vm.runInContext('globalThis', newContext) === newContext);  // true
  console.log(newContext.Array);  // [Function: Array]

  // In contexts without its global contextifyed, freezing works and prevents scripts from
  // accidentally leaking globals.
  vm.runInContext('Object.freeze(globalThis);', newContext);
  try {
    vm.runInContext('globalThis.foo = 1; foo;', newContext);
  } catch(e) {
    console.log(e); // Uncaught ReferenceError: foo is not defined
  }
}

@nodejs-github-bot nodejs-github-bot added c++ Issues and PRs that require attention from people who are familiar with C++. lib / src Issues and PRs related to general changes in the lib or src directory. needs-ci PRs that need a full CI run. labels Aug 15, 2024
@joyeecheung joyeecheung added semver-minor PRs that contain new features and should be released in the next minor version. notable-change PRs with changes that should be highlighted in changelogs. labels Aug 15, 2024
Copy link
Contributor

The notable-change PRs with changes that should be highlighted in changelogs. label has been added by @joyeecheung.

Please suggest a text for the release notes if you'd like to include a more detailed summary, then proceed to update the PR description with the text or a link to the notable change suggested text comment. Otherwise, the commit will be placed in the Other Notable Changes section.

@joyeecheung joyeecheung added request-ci Add this label to start a Jenkins CI on a PR. and removed request-ci Add this label to start a Jenkins CI on a PR. labels Aug 15, 2024
@nodejs-github-bot

This comment was marked as outdated.

Copy link

codecov bot commented Aug 15, 2024

Codecov Report

Attention: Patch coverage is 82.14286% with 10 lines in your changes missing coverage. Please review.

Project coverage is 87.33%. Comparing base (9edf4a0) to head (d43c426).
Report is 62 commits behind head on main.

Files with missing lines Patch % Lines
src/node_contextify.cc 80.43% 1 Missing and 8 partials ⚠️
src/node_contextify.h 75.00% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@           Coverage Diff           @@
##             main   #54394   +/-   ##
=======================================
  Coverage   87.32%   87.33%           
=======================================
  Files         649      649           
  Lines      182603   182590   -13     
  Branches    35042    35039    -3     
=======================================
+ Hits       159464   159470    +6     
+ Misses      16400    16391    -9     
+ Partials     6739     6729   -10     
Files with missing lines Coverage Δ
lib/vm.js 99.28% <100.00%> (+<0.01%) ⬆️
src/node_contextify.h 82.35% <75.00%> (-3.37%) ⬇️
src/node_contextify.cc 80.84% <80.43%> (+0.21%) ⬆️

... and 46 files with indirect coverage changes

doc/api/vm.md Outdated Show resolved Hide resolved
doc/api/vm.md Outdated Show resolved Hide resolved
@joyeecheung joyeecheung force-pushed the vanilla-context branch 4 times, most recently from 94e06f3 to 8241574 Compare August 19, 2024 15:53
@joyeecheung joyeecheung changed the title vm: introduce vanilla contexts via vm.constants.VANILLA_CONTEXT vm: introduce vanilla contexts via vm.constants.DONT_CONTEXTIFY Aug 19, 2024
@joyeecheung joyeecheung added the request-ci Add this label to start a Jenkins CI on a PR. label Aug 19, 2024
@github-actions github-actions bot removed the request-ci Add this label to start a Jenkins CI on a PR. label Aug 19, 2024
@nodejs-github-bot
Copy link
Collaborator

@joyeecheung joyeecheung added the request-ci Add this label to start a Jenkins CI on a PR. label Aug 22, 2024
@github-actions github-actions bot removed the request-ci Add this label to start a Jenkins CI on a PR. label Aug 22, 2024
@nodejs-github-bot
Copy link
Collaborator

Copy link
Member

@legendecas legendecas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall LGTM. Thanks!

if (!ctor_name->Equals(v8_context, env->object_string())
.FromMaybe(false) &&
new_context_global
->DefineOwnProperty(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not really relevant to this PR but I think we should not automatically create an own @@ToStringTag property on the global object: #54522.

src/node_contextify.cc Outdated Show resolved Hide resolved
test/parallel/test-vm-context-dont-contextify.js Outdated Show resolved Hide resolved
This implements a flavor of vm.createContext() and friends
that creates a context without contextifying its global object.
This is suitable when users want to freeze the context (impossible
when the global is contextified i.e. has interceptors installed)
or speed up the global access if they don't need the interceptor
behavior.

```js
const vm = require('node:vm');

const context = vm.createContext(vm.constants.DONT_CONTEXTIFY);

// In contexts with contextified global objects, this is false.
// In vanilla contexts this is true.
console.log(vm.runInContext('globalThis', context) === context);

// In contexts with contextified global objects, this would throw,
// but in vanilla contexts freezing the global object works.
vm.runInContext('Object.freeze(globalThis);', context);

// In contexts with contextified global objects, freezing throws
// and won't be effective. In vanilla contexts, freezing works
// and prevents scripts from accidentally leaking globals.
try {
  vm.runInContext('globalThis.foo = 1; foo;', context);
} catch(e) {
  console.log(e); // Uncaught ReferenceError: foo is not defined
}

console.log(context.Array);  // [Function: Array]
```
@github-actions github-actions bot removed the request-ci Add this label to start a Jenkins CI on a PR. label Aug 27, 2024
@nodejs-github-bot
Copy link
Collaborator

@nodejs-github-bot
Copy link
Collaborator

src/node_contextify.h Outdated Show resolved Hide resolved
Co-authored-by: Chengzhong Wu <legendecas@gmail.com>
@joyeecheung joyeecheung added the request-ci Add this label to start a Jenkins CI on a PR. label Aug 28, 2024
@github-actions github-actions bot removed the request-ci Add this label to start a Jenkins CI on a PR. label Aug 28, 2024
@nodejs-github-bot
Copy link
Collaborator

@nodejs-github-bot
Copy link
Collaborator

@joyeecheung
Copy link
Member Author

CI is finally green. Can I get some re-review please? @addaleax @jasnell @legendecas ?

@legendecas legendecas added commit-queue Add this label to land a pull request using GitHub Actions. commit-queue-squash Add this label to instruct the Commit Queue to squash all the PR commits into the first one. labels Aug 29, 2024
@nodejs-github-bot nodejs-github-bot removed the commit-queue Add this label to land a pull request using GitHub Actions. label Aug 29, 2024
@nodejs-github-bot nodejs-github-bot merged commit d98cfcc into nodejs:main Aug 29, 2024
58 checks passed
@nodejs-github-bot
Copy link
Collaborator

Landed in d98cfcc

sendoru pushed a commit to sendoru/node that referenced this pull request Aug 29, 2024
This implements a flavor of vm.createContext() and friends
that creates a context without contextifying its global object.
This is suitable when users want to freeze the context (impossible
when the global is contextified i.e. has interceptors installed)
or speed up the global access if they don't need the interceptor
behavior.

```js
const vm = require('node:vm');

const context = vm.createContext(vm.constants.DONT_CONTEXTIFY);

// In contexts with contextified global objects, this is false.
// In vanilla contexts this is true.
console.log(vm.runInContext('globalThis', context) === context);

// In contexts with contextified global objects, this would throw,
// but in vanilla contexts freezing the global object works.
vm.runInContext('Object.freeze(globalThis);', context);

// In contexts with contextified global objects, freezing throws
// and won't be effective. In vanilla contexts, freezing works
// and prevents scripts from accidentally leaking globals.
try {
  vm.runInContext('globalThis.foo = 1; foo;', context);
} catch(e) {
  console.log(e); // Uncaught ReferenceError: foo is not defined
}

console.log(context.Array);  // [Function: Array]
```

PR-URL: nodejs#54394
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Chengzhong Wu <legendecas@gmail.com>
@legendecas legendecas added the vm Issues and PRs related to the vm subsystem. label Aug 30, 2024
RafaelGSS pushed a commit that referenced this pull request Aug 30, 2024
This implements a flavor of vm.createContext() and friends
that creates a context without contextifying its global object.
This is suitable when users want to freeze the context (impossible
when the global is contextified i.e. has interceptors installed)
or speed up the global access if they don't need the interceptor
behavior.

```js
const vm = require('node:vm');

const context = vm.createContext(vm.constants.DONT_CONTEXTIFY);

// In contexts with contextified global objects, this is false.
// In vanilla contexts this is true.
console.log(vm.runInContext('globalThis', context) === context);

// In contexts with contextified global objects, this would throw,
// but in vanilla contexts freezing the global object works.
vm.runInContext('Object.freeze(globalThis);', context);

// In contexts with contextified global objects, freezing throws
// and won't be effective. In vanilla contexts, freezing works
// and prevents scripts from accidentally leaking globals.
try {
  vm.runInContext('globalThis.foo = 1; foo;', context);
} catch(e) {
  console.log(e); // Uncaught ReferenceError: foo is not defined
}

console.log(context.Array);  // [Function: Array]
```

PR-URL: #54394
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Chengzhong Wu <legendecas@gmail.com>
RafaelGSS pushed a commit that referenced this pull request Aug 30, 2024
This implements a flavor of vm.createContext() and friends
that creates a context without contextifying its global object.
This is suitable when users want to freeze the context (impossible
when the global is contextified i.e. has interceptors installed)
or speed up the global access if they don't need the interceptor
behavior.

```js
const vm = require('node:vm');

const context = vm.createContext(vm.constants.DONT_CONTEXTIFY);

// In contexts with contextified global objects, this is false.
// In vanilla contexts this is true.
console.log(vm.runInContext('globalThis', context) === context);

// In contexts with contextified global objects, this would throw,
// but in vanilla contexts freezing the global object works.
vm.runInContext('Object.freeze(globalThis);', context);

// In contexts with contextified global objects, freezing throws
// and won't be effective. In vanilla contexts, freezing works
// and prevents scripts from accidentally leaking globals.
try {
  vm.runInContext('globalThis.foo = 1; foo;', context);
} catch(e) {
  console.log(e); // Uncaught ReferenceError: foo is not defined
}

console.log(context.Array);  // [Function: Array]
```

PR-URL: #54394
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Chengzhong Wu <legendecas@gmail.com>
RafaelGSS pushed a commit that referenced this pull request Aug 30, 2024
This implements a flavor of vm.createContext() and friends
that creates a context without contextifying its global object.
This is suitable when users want to freeze the context (impossible
when the global is contextified i.e. has interceptors installed)
or speed up the global access if they don't need the interceptor
behavior.

```js
const vm = require('node:vm');

const context = vm.createContext(vm.constants.DONT_CONTEXTIFY);

// In contexts with contextified global objects, this is false.
// In vanilla contexts this is true.
console.log(vm.runInContext('globalThis', context) === context);

// In contexts with contextified global objects, this would throw,
// but in vanilla contexts freezing the global object works.
vm.runInContext('Object.freeze(globalThis);', context);

// In contexts with contextified global objects, freezing throws
// and won't be effective. In vanilla contexts, freezing works
// and prevents scripts from accidentally leaking globals.
try {
  vm.runInContext('globalThis.foo = 1; foo;', context);
} catch(e) {
  console.log(e); // Uncaught ReferenceError: foo is not defined
}

console.log(context.Array);  // [Function: Array]
```

PR-URL: #54394
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Chengzhong Wu <legendecas@gmail.com>
RafaelGSS added a commit that referenced this pull request Aug 30, 2024
Notable changes:

net:
  * (SEMVER-MINOR) exclude ipv6 loopback addresses from server.listen (Giovanni Bucci) #54264
src:
  * (SEMVER-MINOR) add JS APIs for compile cache and NODE_DISABLE_COMPILE_CACHE (Joyee Cheung) #54501
src,lib:
  * (SEMVER-MINOR) add performance.uvMetricsInfo (Rafael Gonzaga) #54413
test_runner:
  * (SEMVER-MINOR) add support for coverage thresholds (Aviv Keller) #54429
  * (SEMVER-MINOR) support running tests in process (Colin Ihrig) #53927
  * (SEMVER-MINOR) defer inheriting hooks until run() (Colin Ihrig) #53927
vm:
  * (SEMVER-MINOR) introduce vanilla contexts via vm.constants.DONT_CONTEXTIFY (Joyee Cheung) #54394

PR-URL: #54560
RafaelGSS added a commit that referenced this pull request Aug 30, 2024
Notable changes:

net:
  * (SEMVER-MINOR) exclude ipv6 loopback addresses from server.listen (Giovanni Bucci) #54264
src:
  * (SEMVER-MINOR) add JS APIs for compile cache and NODE_DISABLE_COMPILE_CACHE (Joyee Cheung) #54501
src,lib:
  * (SEMVER-MINOR) add performance.uvMetricsInfo (Rafael Gonzaga) #54413
test_runner:
  * (SEMVER-MINOR) add support for coverage thresholds (Aviv Keller) #54429
  * (SEMVER-MINOR) support running tests in process (Colin Ihrig) #53927
  * (SEMVER-MINOR) defer inheriting hooks until run() (Colin Ihrig) #53927
vm:
  * (SEMVER-MINOR) introduce vanilla contexts via vm.constants.DONT_CONTEXTIFY (Joyee Cheung) #54394

PR-URL: #54560
@RafaelGSS RafaelGSS mentioned this pull request Aug 30, 2024
RafaelGSS added a commit that referenced this pull request Aug 31, 2024
Notable changes:

net:
  * (SEMVER-MINOR) exclude ipv6 loopback addresses from server.listen (Giovanni Bucci) #54264
src:
  * (SEMVER-MINOR) add JS APIs for compile cache and NODE_DISABLE_COMPILE_CACHE (Joyee Cheung) #54501
src,lib:
  * (SEMVER-MINOR) add performance.uvMetricsInfo (Rafael Gonzaga) #54413
test_runner:
  * (SEMVER-MINOR) add support for coverage thresholds (Aviv Keller) #54429
  * (SEMVER-MINOR) support running tests in process (Colin Ihrig) #53927
  * (SEMVER-MINOR) defer inheriting hooks until run() (Colin Ihrig) #53927
vm:
  * (SEMVER-MINOR) introduce vanilla contexts via vm.constants.DONT_CONTEXTIFY (Joyee Cheung) #54394

PR-URL: #54560
RafaelGSS added a commit that referenced this pull request Aug 31, 2024
Notable changes:

net:
  * (SEMVER-MINOR) exclude ipv6 loopback addresses from server.listen (Giovanni Bucci) #54264
src:
  * (SEMVER-MINOR) add JS APIs for compile cache and NODE_DISABLE_COMPILE_CACHE (Joyee Cheung) #54501
src,lib:
  * (SEMVER-MINOR) add performance.uvMetricsInfo (Rafael Gonzaga) #54413
test_runner:
  * (SEMVER-MINOR) add support for coverage thresholds (Aviv Keller) #54429
  * (SEMVER-MINOR) support running tests in process (Colin Ihrig) #53927
  * (SEMVER-MINOR) defer inheriting hooks until run() (Colin Ihrig) #53927
vm:
  * (SEMVER-MINOR) introduce vanilla contexts via vm.constants.DONT_CONTEXTIFY (Joyee Cheung) #54394

PR-URL: #54560
RafaelGSS added a commit that referenced this pull request Sep 1, 2024
Notable changes:

net:
  * (SEMVER-MINOR) exclude ipv6 loopback addresses from server.listen (Giovanni Bucci) #54264
src:
  * (SEMVER-MINOR) add JS APIs for compile cache and NODE_DISABLE_COMPILE_CACHE (Joyee Cheung) #54501
src,lib:
  * (SEMVER-MINOR) add performance.uvMetricsInfo (Rafael Gonzaga) #54413
test_runner:
  * (SEMVER-MINOR) add support for coverage thresholds (Aviv Keller) #54429
  * (SEMVER-MINOR) support running tests in process (Colin Ihrig) #53927
  * (SEMVER-MINOR) defer inheriting hooks until run() (Colin Ihrig) #53927
vm:
  * (SEMVER-MINOR) introduce vanilla contexts via vm.constants.DONT_CONTEXTIFY (Joyee Cheung) #54394

PR-URL: #54560
RafaelGSS added a commit that referenced this pull request Sep 2, 2024
Notable changes:

net:
  * (SEMVER-MINOR) exclude ipv6 loopback addresses from server.listen (Giovanni Bucci) #54264
src:
  * (SEMVER-MINOR) add JS APIs for compile cache and NODE_DISABLE_COMPILE_CACHE (Joyee Cheung) #54501
src,lib:
  * (SEMVER-MINOR) add performance.uvMetricsInfo (Rafael Gonzaga) #54413
test_runner:
  * (SEMVER-MINOR) add support for coverage thresholds (Aviv Keller) #54429
  * (SEMVER-MINOR) support running tests in process (Colin Ihrig) #53927
  * (SEMVER-MINOR) defer inheriting hooks until run() (Colin Ihrig) #53927
vm:
  * (SEMVER-MINOR) introduce vanilla contexts via vm.constants.DONT_CONTEXTIFY (Joyee Cheung) #54394

PR-URL: #54560
RafaelGSS added a commit that referenced this pull request Sep 3, 2024
Notable changes:

net:
  * (SEMVER-MINOR) exclude ipv6 loopback addresses from server.listen (Giovanni Bucci) #54264
src:
  * (SEMVER-MINOR) add JS APIs for compile cache and NODE_DISABLE_COMPILE_CACHE (Joyee Cheung) #54501
src,lib:
  * (SEMVER-MINOR) add performance.uvMetricsInfo (Rafael Gonzaga) #54413
test_runner:
  * (SEMVER-MINOR) add support for coverage thresholds (Aviv Keller) #54429
  * (SEMVER-MINOR) support running tests in process (Colin Ihrig) #53927
  * (SEMVER-MINOR) defer inheriting hooks until run() (Colin Ihrig) #53927
vm:
  * (SEMVER-MINOR) introduce vanilla contexts via vm.constants.DONT_CONTEXTIFY (Joyee Cheung) #54394

PR-URL: #54560
RafaelGSS added a commit that referenced this pull request Sep 3, 2024
Notable changes:

net:
  * (SEMVER-MINOR) exclude ipv6 loopback addresses from server.listen (Giovanni Bucci) #54264
src:
  * (SEMVER-MINOR) add JS APIs for compile cache and NODE_DISABLE_COMPILE_CACHE (Joyee Cheung) #54501
src,lib:
  * (SEMVER-MINOR) add performance.uvMetricsInfo (Rafael Gonzaga) #54413
test_runner:
  * (SEMVER-MINOR) add support for coverage thresholds (Aviv Keller) #54429
  * (SEMVER-MINOR) support running tests in process (Colin Ihrig) #53927
  * (SEMVER-MINOR) defer inheriting hooks until run() (Colin Ihrig) #53927
vm:
  * (SEMVER-MINOR) introduce vanilla contexts via vm.constants.DONT_CONTEXTIFY (Joyee Cheung) #54394

PR-URL: #54560
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
c++ Issues and PRs that require attention from people who are familiar with C++. commit-queue-squash Add this label to instruct the Commit Queue to squash all the PR commits into the first one. lib / src Issues and PRs related to general changes in the lib or src directory. needs-ci PRs that need a full CI run. notable-change PRs with changes that should be highlighted in changelogs. semver-minor PRs that contain new features and should be released in the next minor version. vm Issues and PRs related to the vm subsystem.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants