Reputation: 792
Considering the following execution of a JS program in a JS settlement, how can I implement a time limit to prevent infinite loops in program
?
try {
var x = eval(document.getElementById("program").value);
} catch(e) {
...
}
Note: the call should be able to specify a maximum execution time, just in case program
enters an infinite loop.
Upvotes: 1
Views: 285
Reputation: 138447
You could use a webworker to run this in another thread:
// Worker-helper.js
self.onmessage = function(e) {
self.postMessage(eval(e.data));
};
Them use the worker as:
var worker = new Worker('Worker-helper.js');
worker.postMessage(document.getElementById("program").value);
worker.onmessage = result => {
alert(result);
};
setTimeout(() => worker.terminate(), 10 * 1000);
...which will kill the worker after 10 seconds.
Easy to use utility:
function funToWorker(fn) {
var response = "(" + fn.toString() + ")()";
var blob;
try {
blob = new Blob([response], {type: 'application/javascript'});
} catch (e) { // Backwards-compatibility
window.BlobBuilder = window.BlobBuilder || window.WebKitBlobBuilder || window.MozBlobBuilder;
blob = new BlobBuilder();
blob.append(response);
blob = blob.getBlob();
}
return new Worker(URL.createObjectURL(blob));
}
function limitedEval(string, timeout) {
return new Promise((resolve, reject) => {
const worker = funToWorker(function() {
self.onmessage = e => {
self.postMessage(eval(e.data));
}
});
worker.onmessage = e => resolve(e.data);
worker.postMessage(string);
setTimeout(() => {
worker.terminate();
reject();
}, timeout);
});
}
Usable as:
limitedEval("1 + 2", 1000)
.then(console.log)
.catch(console.error);
Upvotes: 1