loop-protect
v2.1.6
Published
Prevent infinite loops in dynamically eval'd JavaScript.
Downloads
2,168
Readme
loop-protect
JS Bin's loop protection implementation as a reusable library.
This code protects use cases where user code includes an infinite loop using a while
, for
or do
loop.
Note that this does not solve the halting problem but simply rewrites JavaScript (using Babel's AST) wrapping loops with a conditional break. This also does not protect against recursive loops.
Example
With loop protection in place, it means that a user can enter the code as follows on JS Bin, and the final console.log
will still work.
The code is transformed from this:
while (true) {
doSomething();
}
console.log('All finished');
…to this:
let i = 0;
var _LP = Date.now();
while (true) {
if (Date.now() - _LP > 100)
break;
doSomething();
}
console.log('All finished');
Usage
The loop protection is a babel transform, so can be used on the server or in the client.
The previous implementation used an injected library to handle tracking loops - this version does not.
Example (client) implementation
import Babel from 'babel-standalone';
import protect from 'loop-protect';
const timeout = 100; // defaults to 100ms
Babel.registerPlugin('loopProtection', protect(timeout));
const transform = source => Babel.transform(source, {
plugins: ['loopProtection'],
}).code;
// rewrite the user's JavaScript to protect loops
var processed = transform(getUserCode());
// run in an iframe, and expose the loopProtect variable under a new name
var iframe = getNewFrame();
// append the iframe to allow our code to run as soon as .close is called
document.body.appendChild(iframe);
// open the iframe and write the code to it
var win = iframe.contentWindow;
var doc = win.document;
doc.open();
doc.write('<script>' + processed + '<' + '/script>');
doc.close();
// code now runs, and if there's an infinite loop, it's cleanly exited
Contributors
- Author: Remy Sharp
- All contributors