神刀安全网

Detecting Infinite Loops with Web Workers

When allowing a user to input code that could potentially cause an infinite loop, it is nice to test the code first, right? Even, if the code doesn’t run infinitely, it would be nice to know if it takes longer than you would want. One way to nicely test for infinite loops or long running code is by using web workers. The following is a function which uses eval() in a web worker to execute the code and adds a timeout so that if the code takes too long to run, the web worker will be terminated:

Now let’s say that the user inputs the following loop in your textbox which has an ID of txtCode :

for (var i = 0; i != 10; i++) {   if (i % 2 == 0) {     i *= 2;   } }

Unfortunately, the above loop will run infinitely because i will progress as shown below:

0 1 4 5 12 13 14 29 30 61 62 125 126 253 254 509 510 1021 ...

If you don’t believe me you can try the following code in the console Detecting Infinite Loops with Web Workers :

// Let's stop the loop once we get to or above 1000 for (var i = 0; console.log(i + ' != 10'), i != 10 && i < 1000; i++) {   if (i % 2 == 0) {     i *= 2;   } }

The good thing about web workers is that any code that runs in them will not interfere with your JS in the main process but the downside is that you cant innately determine if a web worker is still running after a specified amount of time (well not as easily as you might hope). Fortunately, with the limitEval() function we find a way around this issue by sending and receiving messages. Feel free to check out how I accomplish this by analyzing the code.

Now let’s setup a way to determine if the user’s input, found in txtCode , takes more than 3 seconds to run:

var code = document.getElementById('txtCode').value; limitEval(code, function(success, returnValue) {   if (success) {     // do whatever you want with the return value (returnValue)   }   else {     alert('The code takes too long to run.  Is there is an infinite loop?');   } }, 3000);

So, if the code takes more than 3 seconds to run an alert will be shown after 3 seconds and the eval will be terminated.

As you can see limitEval takes two required parameters and one optional one:

  1. code {string}:
    The JS code to be eval’d.
  2. fnOnStop {Function}:
    The function which will be called either after the eval completes or after the timeout occurs. The following are the arguments that will be passed:
    1. success {boolean}:
      true will be passed if the eval executed successfully before the timeout. Otherwise false will be passed.
    2. opt_returnValue {*}:
      If the eval executes successfully this will be the return value. If the timeout occurs this will not be passed and arguments.length will be 1 .
  3. opt_timeoutInMS {number}:
    Optional. Defaults to 1000 . The number of milliseconds before timing out.

It is important to note that this solution, although very useful, only works on newer browsers. According to MDN, it will work in the following browsers and higher:

  • Chrome 23
  • Firefox (Gecko) 21
  • Internet Explorer 11
  • Safari (WebKit) 7

Hopefully you find the limitEval() function useful. Have fun! Detecting Infinite Loops with Web Workers

转载本站任何文章请注明:转载至神刀安全网,谢谢神刀安全网 » Detecting Infinite Loops with Web Workers

分享到:更多 ()

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
分享按钮