Repository navigation
Function returned by vm.compileFunction can't accept arguments when cachedData is passed #48175
Copy link
Copy link
Closed
Labels
vmIssues and PRs related to the vm subsystem.Issues and PRs related to the vm subsystem.
Description
Activity
- addedvmIssues and PRs related to the vm subsystem.Issues and PRs related to the vm subsystem.
on May 25, 2023 cc @nodejs/vm
If you use the same functions / parameters it works as expected:
const vm = require('vm'); const code = ` const os = require('os'); console.log(os.release()); `; const fn = vm.compileFunction(code, ['require'], { produceCachedData: true, }); console.log(`fn: [${fn.toString()}]`); fn(require); const fn2 = vm.compileFunction(code, ['require'], { cachedData: fn.cachedData, }); console.log(`fn2: [${fn2.toString()}]`); fn2(require);
perhaps we can update the documentation to make this more clear?
Reacted by Chengzhong Wu and Darshan Sen- added a commit that references this issue
on May 26, 2023 Done - #48193
- added a commit that references this issue
on May 29, 2023 The current implementation seems unsafe. Can we validate the cached data somehow? Maybe we can put our own header on the bytes.
Note it's not just parameters, the code is not validated either:
> vm = require('vm') > f = vm.compileFunction('return 1', [], {produceCachedData: true}) [Function (anonymous)] { cachedDataProduced: true, cachedData: <Buffer 62 05 de c0 0f 3a dc 34 08 00 00 00 2f 12 c5 a8 90 01 00 00 15 22 82 81 01 1c 53 01 20 07 a8 60 00 00 00 00 03 00 00 00 5d 07 d9 01 01 0c 4b 61 00 00 ... 374 more bytes> } > vm.compileFunction('return 2', [], {cachedData: f.cachedData})() 1
Doing something intelligent here would break tools like bytenode which rely on us not verifying that the code matches the cached data (although we could work with them to minimize breakage). Any change here is probably semver-major.
- added a commit that references this issue
on May 30, 2023 - added a commit that references this issue
on Jul 6, 2023 - added a commit that references this issue
on Jul 6, 2023 - added 2 commits that reference this issue
on Aug 14, 2023
Metadata
Metadata
Assignees
Labels
vmIssues and PRs related to the vm subsystem.Issues and PRs related to the vm subsystem.
Version
v20.2.0
Platform
Darwin Darshans-MacBook-Pro.local 22.4.0 Darwin Kernel Version 22.4.0: Mon Mar 6 21:00:17 PST 2023; root:xnu-8796.101.5~3/RELEASE_X86_64 x86_64Subsystem
vm
What steps will reproduce the bug?
test.js
Also, note that when I print the function, it doesn't have the
function (...) {and}wrappers. I have no idea how that's even possible.However, if I comment out the part where
cachedDatais being passed tovm.compileFunction, it doesn't run into errors.test.js
$ node test.js fn: [function (require) { const os = require('os'); console.log(os.release()); }] 22.4.0How often does it reproduce? Is there a required condition?
Reproduces always consistently.
What is the expected behavior?
The returned function should have the params wrapped in.
Why is that the expected behavior?
The doc says that this would return a function with the passed params wrapped in but in this case, it doesn't seem to do so.
What do you see instead?
The returned function does not have the params wrapped in.
Additional information
AFAICT, Node.js simply passes the args to V8's
ScriptCompiler::CompileFunctionfunction innode/src/node_contextify.cc
Lines 1248 to 1256 in e530098