Issue #2686 - Don't rely on return value of ExecutionContext::Compile when the context may forbid running scripts

This is relevant if scripting is terminated due to execution timeout but there are setTimeout/Interval callbacks pending
or if scripting is disabled altogether.
This commit is contained in:
Martok 2025-01-26 21:46:31 +01:00 committed by roytam1
commit 0590764f1f
4 changed files with 12 additions and 8 deletions

View file

@ -12941,10 +12941,11 @@ nsGlobalWindow::RunTimeoutHandler(Timeout* aTimeout,
nsJSUtils::ExecutionContext exec(aes.cx(), global);
rv = exec.Compile(options, handler->GetHandlerText());
if (rv == NS_OK) {
JS::Rooted<JSScript*> script(aes.cx(), exec.GetScript());
if (script) {
LoadedScript* initiatingScript = handler->GetInitiatingScript();
if (initiatingScript) {
initiatingScript->AssociateWithScript(exec.GetScript());
initiatingScript->AssociateWithScript(script);
}
rv = exec.ExecScript();

View file

@ -315,8 +315,11 @@ nsJSUtils::ExecutionContext::JoinDecode(void **aOffThreadToken)
}
JSScript* nsJSUtils::ExecutionContext::GetScript() {
if (mSkip) {
return nullptr;
}
#ifdef DEBUG
MOZ_ASSERT(!mSkip);
MOZ_ASSERT(mScript);
mScriptUsed = true;
#endif

View file

@ -163,7 +163,10 @@ public:
// thread.
nsresult JoinDecode(void** aOffThreadToken);
// Get a successfully compiled script.
// Get the compiled script if present, or nullptr.
//
// Compilation may succeed without producing a script when scripting is disabled for the global. Causes for this can
// be the global pref or dynamic change when script execution in a global is terminated due to max_script_run_time.
JSScript* GetScript();
// Execute the compiled script and ignore the return value.

View file

@ -2377,10 +2377,7 @@ ScriptLoader::EvaluateScript(ScriptLoadRequest* aRequest)
rv = exec.Compile(options, srcBuf);
}
if (rv == NS_OK) {
JS::Rooted<JSScript*> script(cx);
script = exec.GetScript();
// With scripts disabled GetScript() will return nullptr
JS::Rooted<JSScript*> script(cx, exec.GetScript());
if (script) {
// Create a ClassicScript object and associate it with the
// JSScript.