vm2
vm2 copied to clipboard
Executing an array returns weird object.
Code like this:
const { VM } = require('vm2')
const vm = new VM()
const res = vm.run('[1, 2, 3]')
console.log(res)
Prints:
[ 1, 2, 3, '0': 1, '1': 2, '2': 3 ]
Is this a bug or an expected behaviour?
The NodeJS's build in VM returns:
[1, 2, 3]
as expected.
Hi @patriksimek, I quote you as main maintainer. I've this issue too. This happens with VM and with NodeVM.
In my case, inside the NodeVM i have a snippet that -among other things- does this:
const array = [];
array.push({a: 1, b: 2});
console.log(array);
And prints:
[{a: 1, b: 2}, '0': {a: 1, b: 2}]
The console in the NodeVM setup is set to inherit
.
Do you have any clue of what could generate this behavior?
Thank you in advance and sorry to bother.
This object turned out to be a Proxy. I believe that somewhere in Decontextify.instance a wrong object is returned.
Produces expected output under node v8.9.3 and node v8.10.0. The issue is confirmed under node v10.14.2
Ran into this same problem. Frustrating tracking this bug down, thinking it was in my own code. Eventually decided to try a very minimal example and lo and behold, vm2
was the culprit. It appears the for of
loop also does some odd things with arrays.
Produces expected output under node v8.9.3 and node v8.10.0. The issue is confirmed under node v10.14.2
What I can propose is to run a debugger in v.8.10.0 and v10.14.2 and find a line of code where the output is different.
This was caused by using a Proxy.handler.ownKeys() trap. This was an issue in node and seems to be fixed in v12.
Do you plan any fallback for older versions of node?
The problem is only on node 10. We could do a fix, but that would require to check the caller of a function every time and to get the caller we would need to generate a stack trace. I think that it is not worth doing this.
The problem is only on node 10. We could do a fix, but that would require to check the caller of a function every time and to get the caller we would need to generate a stack trace. I think that it is not worth doing this.
What about a config or CLI parameter check instead? The code for that could be pretty minimal.
I add console
to vm._context
vm._context.console = console
vm.run("console.log([1,2,3])")
it's working correctly!
This is back for all versions as the fix broke Object.keys
. As this is only a issue when logging objects this is acceptable.
This was caused by using a Proxy.handler.ownKeys() trap. This was an issue in node and seems to be fixed in v12.
still same now...
The issue is actually a V8 bug. See https://github.com/nodejs/node/issues/41714#issuecomment-1186214383
A work arround for converting the proxy object to a js object (a bit hacky):
value = JSON.parse(JSON.stringify(proxy))