Menu

#99 Timeouts on JavaScript execution

closed
None
5
2012-10-21
2006-07-19
No

Being able to set a timeout on the execution of
javascripts is extremely useful when processing
pages from unknown/untrusted sources as one
might easily encounter snippets of code like:

"
while(true){}
"

At present state, htmlunit just runs infinitely,
using 100% cpu usage along the way. Even when
testing your own "trusted" code, it's not unlikely
that an endless loop can occur. Most browsers
aborts scripts when they detect that the scripts are
taking too long and using too much cpu.

Unsure on how it would be implemented. Probably having
an extra thread killing the thread executing the script
on a timeout. The Spidermonkey javascript engine
has implicit support for timeouts (timed
interrupts/callbacks). I briefly looked at the Rhino API,
but could not find anything similar.

Discussion

  • Marc Guillemot

    Marc Guillemot - 2006-07-28

    Logged In: YES
    user_id=402164

    It would be a good idea

     
  • Brad Clarke

    Brad Clarke - 2006-08-17

    Logged In: YES
    user_id=257129

    "Most browsers aborts scripts when they detect that the
    scripts are taking too long and using too much cpu."

    I've never seen that before (not really looked). Could you
    provide an example or two?

     
  • Andre Soereng

    Andre Soereng - 2006-08-25

    Timeout support for Javascript execution

     
  • Andre Soereng

    Andre Soereng - 2006-08-25

    Logged In: YES
    user_id=1400162

    Here's a patch that adds the support based on the
    ContextFactory example below. The ScriptEngine interface
    is followingly expanded with methods to set and get
    the timeout.

     
  • Marc Guillemot

    Marc Guillemot - 2006-08-28

    Logged In: YES
    user_id=402164

    Interesting. I'd like to remove the ScriptEngine interface
    before to incorporate the patch (see dev mailing list). This
    would allow to remove for instance timeoutSupported().

    What about making the TimeoutContext manage all time
    operations and the throw?
    In the case of htmlunit the exception thrown shouldn't be an
    Error. Remember the description of Error: "An Error is a
    subclass of Throwable that indicates serious problems that a
    reasonable application should not try to catch". Here we
    want to catch it.

    Any answer to yourgod's questions?

     
  • Andre Soereng

    Andre Soereng - 2006-08-28

    Logged In: YES
    user_id=1400162

    You mean remove all the timeout methods from
    ScriptEngine, JavaScriptEngine and HtmlUnitContextFactory
    and only have them in TimeoutContext together with
    some kind of terminateScriptifNecessary method that
    throws the Error? Yes, sounds cleaner, but how
    should the get/set timeout methods be exposed? Through the
    WebClient?

    "In the case of htmlunit the exception thrown shouldn't be
    an Error"

    I presume you here mean the throw in JavaScriptEngine, as
    observeInstructionCount must throw an Error in order to
    terminate the script.

    "Any answer to yourgod's questions?"

    Hmm, thought I already provided an example in
    my intial comment: "while(true){}"

     
  • Marc Guillemot

    Marc Guillemot - 2006-08-28

    Logged In: YES
    user_id=402164

    I meant to set the timeout value on the JavaScriptEngine but
    within the HtmlUnitContextFactory to "hide" all time calls
    in the TimedContext.

    I now see that observeInstructionCount has to throw an
    Error. What about throwing a custom Error to avoid catching
    something else in JavaScriptEngine? As you suggest, I would
    prefer to throw a RuntimeException in JavaScriptEngine too.

    Concerning examples, I meant references to IE or FF behavior
    aborting scripts.

     
  • Andre Soereng

    Andre Soereng - 2006-08-29

    Logged In: YES
    user_id=1400162

    OK, I've attached a slightly modified version with
    a custom error thrown in TimeoutContext and RuntimeException
    thrown from JavaScriptEngine. Still unsure what you really
    meant about the "hide" stuff, but I delegated the get/set
    timeout methods in the context factory to TimeoutContext.

    "Concerning examples, I meant references to IE or FF
    behavior aborting scripts."

    Run "while(true){}" in IE and FF and you will see their
    behavior :) You will probably not find such a reference
    anywhere. Anyway, both IE and FF seems to behave the same.
    After a certain amount of time, a confirm box pops up asking
    if you want to terminate the script. In FF you should
    be able to change the timeout value by going to
    "about:config" and edit the "dom.max_script_run_time" value.

     
  • Andre Soereng

    Andre Soereng - 2006-08-29
     
  • Andre Soereng

    Andre Soereng - 2006-09-04

    Logged In: YES
    user_id=1400162

    Any comments on the updated patch?

     
  • Marc Guillemot

    Marc Guillemot - 2006-09-04

    Logged In: YES
    user_id=402164

    Patch applied. Thanks.

    It seems that the patch was not in the right format: the new
    files didn't get automatically added while applying it.

    I've performed some minor simplifications of the internals
    without impact on the functionality.

     

Log in to post a comment.