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.
Logged In: YES
user_id=402164
It would be a good idea
Logged In: YES
user_id=1400162
Looking a little bit deeper, this seems to be the
recommended way of doing it:
http://www.mozilla.org/rhino/apidocs/org/mozilla/javascript/ContextFactory.html
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?
Timeout support for Javascript execution
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.
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?
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){}"
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.
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.
Logged In: YES
user_id=1400162
Any comments on the updated patch?
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.