10

On a page, something like jsFiddle, that executes user inputed Javascript, is there a way to stop / disrupt "problem" scripts running in an iframe?

The major class of problem scripts would be infinite loops, I think. Browsers deal with multiple alerts quite well, but a script like, ​for (var i = 0; ++i; i < 100) { /* do stuff */ }​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​ will go forever.

How can I either detect and not run, or run and stop, say after 10 seconds of running, a script?

Removing the iframe is fine, but I only want to remove it if the script is still running after 10 seconds, but I don't want to remove it if the script has stopped running.


Here is how I imagine the page will work. If you have a better solution, let me know...

The input page contains a textarea and a blank iframe. The user enters their script into the textarea, and when ready they click on run. Then (backstage) a separate page is created that contains the user script in executable form on an HTML page. The src of the iframe is set to the page with the executable code. This all happens dynamically without a page refresh.

Peter Ajtai
  • 56,972
  • 13
  • 121
  • 140
  • You deleted the other question before I had a chance to answer, but remember that running `eval` means that the code your user input can actually interact with the codes you write, meaning it can modify variable, run functions, etc, etc. This is why you'd want the `iframe` solution sites like jsfiddle use to isolate the code. – Yi Jiang Aug 28 '10 at 03:44
  • @Yi Jiang, Perhaps you can delete the `iframe` after, say, five seconds, to terminate the script? – strager Aug 28 '10 at 03:53
  • @Yi Jiang - Thanks for the suggestion. So you somehow make the src of the iframe the eval of the user inputed script? – Peter Ajtai Aug 28 '10 at 03:58
  • Does your iframe generate the html code with the parts of the user? – andres descalzo Sep 11 '10 at 22:43
  • @andres - The `iframe` has an `src` that points to a page that contains the user generated Javascript. – Peter Ajtai Sep 11 '10 at 23:38
  • ok, but do you have the possibility to also put code on that page for control user javascript ? – andres descalzo Sep 12 '10 at 13:26
  • @andres - Yes, by including it in the "src" of that ifram or any other method you can think of. – Peter Ajtai Sep 15 '10 at 16:08
  • I made some tests, but this type of code block everything, also the "setTimeout" pending. the only thing that comes to mind is the thread in html5, but I do not know much – andres descalzo Sep 15 '10 at 16:53

5 Answers5

2

I haven't used this jsandbox script, but it appears to have what you want.

Mottie
  • 84,355
  • 30
  • 126
  • 241
  • This or a similar approach should work because it uses HTML5 web workers, which run in parallel to the main page. As SimpleCoder said, many browsers run a single thread for all JavaScript, so JavaScript on the page would not be running if the JavaScript in the iframe is running in a tight loop. – Annie Sep 16 '10 at 03:35
  • I'm going to go with this answer. Thanks for the suggestion. It does look like a promising avenue to go down. I didn't have time to test it yet, but this seems like it is the most promising solution. – Peter Ajtai Sep 17 '10 at 17:30
1

If one script freezes on a page, other scripts will not continue to run. Therefore, there is no way to detect if another script has stopped running, without using a custom plugin or something. Browsers do not use multithreading in that way.

Chris Laplante
  • 29,338
  • 17
  • 103
  • 134
1

You could set a timeout in the main window which stops / deletes the script after 10 seconds. Then you just have to clear the timeout when the script has finished (just add a line like this to the iframe script: window.frames[0].clearTimeout(window.frames[0].timeoutName) -- I don't know if it works, but it should)

Flo Edelmann
  • 2,573
  • 1
  • 20
  • 33
  • 1
    Would this work if the script in the iframe was while(1); for example? I always thought setTimeout had to wait for the first opportunity(no other scripts running) after its timeout time. So if the script never gave a chance for setTimeout to run the browser would hang. With the iframe I am not sure though. – Bishnu Sep 16 '10 at 02:53
0

I think this would largely depend on the script and how browsers handle scripts in iframes.

Let's say there's a while(true) in the iframe.

The browser may either lock up, or crash the tab (like what Chrome does), or it might lock up the iframe. If it locks up or crashes the tab, there's nothing you can do with JS itself to prevent it, other than attempting static analysis on the script to find possibly problematic statements (Static analysis to find problematic scripts like that would never be foolproof)

Assuming the browser only locks up the iframe or does something else while still allowing the scripts in the main page to do things, removing the iframe after a certain period of time is an option.

The browser might also display the "Script is slow" popup. In this case, it will most likely either completely shut down all scripts in the entire tab or just in the iframe. If just the iframe, the other scripts in the tab could still clean up after it after the predefined period of time.

Another alternative would be to pre-evaluate the script in a separate runtime where you can detect things like that yourself. You could run the script in, say, Rhino, and determine if it takes too long to process, or something similar.

Jani Hartikainen
  • 42,745
  • 10
  • 68
  • 86
0

I don't know if this would work exactly, you might be able to get something like this to work with a little bit of tinkering. I take it that you are taking in text JavaScript and then evaling it, right? You could parse or maybe even just use regex to replace all of the for, for..in, while, and function declaration's call with the function call then some logic that calls your code and figures out if it has been running for 10 secs. If it has it will either return; or break; or something. The code would likely freak out afterward and probably start throwing errors, but at least the script would stop.

Bishnu
  • 853
  • 7
  • 11
  • I don't think I'd `eval()` the code. I would create a file that contains an executable version of the code (w PHP through an AJAX call), and then I would set the `src` of the `iframe` to that file. – Peter Ajtai Sep 16 '10 at 00:35