Skip to content

vm: DONT_CONTEXTIFY when no contextObject set#62459

Open
legendecas wants to merge 1 commit intonodejs:mainfrom
legendecas:vm-strict
Open

vm: DONT_CONTEXTIFY when no contextObject set#62459
legendecas wants to merge 1 commit intonodejs:mainfrom
legendecas:vm-strict

Conversation

@legendecas
Copy link
Copy Markdown
Member

@legendecas legendecas commented Mar 27, 2026

When contextObject is not passed in vm.createContext, do not
contextify by default. This reduces the chance that the script semantics
are broken by the interceptors.

It's getting harder to maintain a spec-compliant behavior in a
vm contextified context. Hopefully this could reduce the breakage where
the contextObject is not set, like a simple vm.createContext()
usage.

Refs: #61898 (comment)

@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 Mar 27, 2026
@legendecas legendecas force-pushed the vm-strict branch 2 times, most recently from 0a1dc2d to cde6206 Compare March 27, 2026 14:44
@legendecas legendecas added the vm Issues and PRs related to the vm subsystem. label Mar 27, 2026
// Refs: https://chromium-review.googlesource.com/c/v8/v8/+/7474608
{
const ctx = vm.createContext({});
assert.throws(() => vm.runInContext(`"use strict"; x = 42`, ctx),
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

This assert.throws needs to be removed when #61898 lands.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I assume that if this lands first, 61898 will CI will fail or...? Just want to make sure it's not easily missed.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

if this lands first, 61898 will need updating this test as a known issue, as #61898 (comment).

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Or, we can land after #61898. This PR is trying to remediate #61898 (comment).

When `contextObject` is not passed in `vm.createContext`, do not
contextify by default. This reduces the chance that the script semantics
are broken by the interceptors.
@joyeecheung
Copy link
Copy Markdown
Member

joyeecheung commented Mar 27, 2026

I think this is technically semver-major e.g. it affects proxy/accessor behavior?

@legendecas
Copy link
Copy Markdown
Member Author

legendecas commented Mar 27, 2026

I think this is technically semver-major e.g. it affects proxy/accessor behavior?

This only changes vm.createContext() with no arguments. The result should not be observable given that the user didn't pass in a custom context object.

And inside the vm, the context behavior is more aligned with spec, so this could be even a bug-fix for the case. I think this does not necessarily consist as a breaking change?

@joyeecheung
Copy link
Copy Markdown
Member

joyeecheung commented Mar 27, 2026

I am thinking more about what happens when the manipulation happens in the script for the global proxy or it's passed out with other stuff installed, e.g.

> vm.runInNewContext('Object.freeze(globalThis)')
evalmachine.<anonymous>:1
Object.freeze(globalThis)
       ^

Uncaught TypeError: Cannot freeze
    at Object.freeze (<anonymous>)
    at evalmachine.<anonymous>:1:8
    at Script.runInContext (node:vm:149:12)
    at Script.runInNewContext (node:vm:154:17)
    at Object.runInNewContext (node:vm:310:38)
    at REPL2:1:4
    at ContextifyScript.runInThisContext (node:vm:137:12)
    at REPLServer.defaultEval (node:repl:600:22)
    at bound (node:domain:433:15)
    at REPLServer.runBound [as eval] (node:domain:444:12)

> vm.runInNewContext('Object.freeze(globalThis)', vm.constants.DONT_CONTEXTIFY)
{}

> Object.freeze(vm.runInNewContext('globalThis'))
Uncaught TypeError: Cannot freeze
    at Object.freeze (<anonymous>)

> Object.freeze(vm.runInNewContext('globalThis', vm.constants.DONT_CONTEXTIFY))
{}

@joyeecheung
Copy link
Copy Markdown
Member

Actually this seems more easily observable than I thought..

> vm.createContext(vm.constants.DONT_CONTEXTIFY).Array
[Function: Array]
> vm.createContext().Array
undefined

@codecov
Copy link
Copy Markdown

codecov bot commented Mar 27, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 89.71%. Comparing base (38647b3) to head (5b9187e).
⚠️ Report is 5 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main   #62459      +/-   ##
==========================================
- Coverage   89.71%   89.71%   -0.01%     
==========================================
  Files         676      678       +2     
  Lines      206751   207260     +509     
  Branches    39645    39755     +110     
==========================================
+ Hits       185482   185937     +455     
- Misses      13403    13449      +46     
- Partials     7866     7874       +8     
Files with missing lines Coverage Δ
lib/vm.js 99.28% <100.00%> (ø)

... and 62 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@legendecas legendecas added the semver-major PRs that contain breaking changes and should be released in the next major version. label Mar 27, 2026
@legendecas
Copy link
Copy Markdown
Member Author

Added semver-major.

@joyeecheung
Copy link
Copy Markdown
Member

I realized the docs need some updates, e.g. the parts that talk about the differences when it's contexified or not https://nodejs.org/api/vm.html#scriptruninnewcontextcontextobject-options

Copy link
Copy Markdown
Member

@jasnell jasnell left a comment

Choose a reason for hiding this comment

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

LGTM with the doc edit @joyeecheung is suggesting

@legendecas legendecas added the blocked PRs that are blocked by other issues or PRs. label Mar 27, 2026
@legendecas
Copy link
Copy Markdown
Member Author

Taking @jasnell's comment on #62459 (comment) into consideration, I think given that #62371 has fixed CI for #61898, it would be easier to land this PR after the V8 upgrade.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

blocked PRs that are blocked by other issues or PRs. 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. semver-major PRs that contain breaking changes and should be released in the next major version. vm Issues and PRs related to the vm subsystem.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants