VM : setTimeout is not working in browser vm.runInNewContext

641 Views Asked by At

I am executing a JS script using vm module in browser like this with details below.

vm.runInNewContext(codeToEval, sandboxObject);

setTimeout, setInterval and other interval built in methods do not work, even if I expose them in sandboxObject created using vm.createContext({setTimeout})

console.log('start');
setTimeout(()=> {
     console.log('hello timeout');
 }, 2000);

 console.log('end');

output:

start
end

It is to be noted that when I add .bind(this) , then timeout works and breaks at that line saying .bind is not a function.

console.log('start');
setTimeout(()=> {
     console.log('hello timeout');
 }, 2000).bind(this);

 console.log('end');

output:

start
hello timeout
// and an error in console saying setTimeout(...).bind is not a function
// and end is not printed

Chrome 70

Platform Ubuntu 18.04

V8

1

There are 1 best solutions below

1
On

Put setTimeout and other context dependencies into into sandboxObject and execute code like this

let executionContext = {
  setTimeout,
}
vm.createContext(executionContext);
vm.runInContext(code, executionContext)