void WorkerScriptController::evaluate(const ScriptSourceCode& sourceCode, Deprecated::ScriptValue* exception) { if (isExecutionForbidden()) return; initScriptIfNeeded(); ExecState* exec = m_workerGlobalScopeWrapper->globalExec(); JSLockHolder lock(exec); JSValue evaluationException; JSC::evaluate(exec, sourceCode.jsSourceCode(), m_workerGlobalScopeWrapper.get(), &evaluationException); if ((evaluationException && isTerminatedExecutionException(evaluationException)) || m_workerGlobalScopeWrapper->vm().watchdog.didFire()) { forbidExecution(); return; } if (evaluationException) { String errorMessage; int lineNumber = 0; int columnNumber = 0; String sourceURL = sourceCode.url().string(); if (m_workerGlobalScope->sanitizeScriptError(errorMessage, lineNumber, columnNumber, sourceURL, sourceCode.cachedScript())) *exception = Deprecated::ScriptValue(*m_vm, exec->vm().throwException(exec, createError(exec, errorMessage.impl()))); else *exception = Deprecated::ScriptValue(*m_vm, evaluationException); } }
void WorkerScriptController::evaluate(const ScriptSourceCode& sourceCode, NakedPtr<JSC::Exception>& returnedException) { if (isExecutionForbidden()) return; initScriptIfNeeded(); ExecState* exec = m_workerGlobalScopeWrapper->globalExec(); JSLockHolder lock(exec); JSC::evaluate(exec, sourceCode.jsSourceCode(), m_workerGlobalScopeWrapper->globalThis(), returnedException); VM& vm = exec->vm(); if ((returnedException && isTerminatedExecutionException(returnedException)) || isTerminatingExecution()) { forbidExecution(); return; } if (returnedException) { String errorMessage; int lineNumber = 0; int columnNumber = 0; String sourceURL = sourceCode.url().string(); if (m_workerGlobalScope->sanitizeScriptError(errorMessage, lineNumber, columnNumber, sourceURL, sourceCode.cachedScript())) { vm.throwException(exec, createError(exec, errorMessage.impl())); returnedException = vm.exception(); vm.clearException(); } } }
void WorkerScriptController::evaluate(const ScriptSourceCode& sourceCode, ScriptValue* exception) { if (isExecutionForbidden()) return; initScriptIfNeeded(); ExecState* exec = m_workerContextWrapper->globalExec(); JSLockHolder lock(exec); m_workerContextWrapper->globalData().timeoutChecker.start(); JSValue evaluationException; JSC::evaluate(exec, sourceCode.jsSourceCode(), m_workerContextWrapper.get(), &evaluationException); m_workerContextWrapper->globalData().timeoutChecker.stop(); if ((evaluationException && isTerminatedExecutionException(evaluationException)) || m_workerContextWrapper->globalData().terminator.shouldTerminate()) { forbidExecution(); return; } if (evaluationException) { String errorMessage; int lineNumber = 0; String sourceURL = sourceCode.url().string(); if (m_workerContext->sanitizeScriptError(errorMessage, lineNumber, sourceURL)) *exception = ScriptValue(*m_globalData, throwError(exec, createError(exec, errorMessage.impl()))); else *exception = ScriptValue(*m_globalData, evaluationException); } }
ScriptValue WorkerScriptController::evaluate(const ScriptSourceCode& sourceCode, ScriptValue* exception) { if (isExecutionForbidden()) return ScriptValue(); initScriptIfNeeded(); JSLock lock(SilenceAssertionsOnly); ExecState* exec = m_workerContextWrapper->globalExec(); m_workerContextWrapper->globalData().timeoutChecker.start(); Completion comp = JSC::evaluate(exec, exec->dynamicGlobalObject()->globalScopeChain(), sourceCode.jsSourceCode(), m_workerContextWrapper.get()); m_workerContextWrapper->globalData().timeoutChecker.stop(); ComplType completionType = comp.complType(); if (completionType == Terminated || m_workerContextWrapper->globalData().terminator.shouldTerminate()) { forbidExecution(); return ScriptValue(); } if (completionType == JSC::Normal || completionType == ReturnValue) return ScriptValue(*m_globalData, comp.value()); if (completionType == Throw) { String errorMessage; int lineNumber = 0; String sourceURL = sourceCode.url().string(); if (m_workerContext->sanitizeScriptError(errorMessage, lineNumber, sourceURL)) *exception = ScriptValue(*m_globalData, throwError(exec, createError(exec, errorMessage.impl()))); else *exception = ScriptValue(*m_globalData, comp.value()); } return ScriptValue(); }
ScriptValue WorkerOrWorkletScriptController::evaluate( const String& script, const String& fileName, const TextPosition& scriptStartPosition, CachedMetadataHandler* cacheHandler, V8CacheOptions v8CacheOptions) { TRACE_EVENT1("devtools.timeline", "EvaluateScript", "data", InspectorEvaluateScriptEvent::data(nullptr, fileName, scriptStartPosition)); if (!initializeContextIfNeeded()) return ScriptValue(); ScriptState::Scope scope(m_scriptState.get()); if (!m_disableEvalPending.isEmpty()) { m_scriptState->context()->AllowCodeGenerationFromStrings(false); m_scriptState->context()->SetErrorMessageForCodeGenerationFromStrings( v8String(m_isolate, m_disableEvalPending)); m_disableEvalPending = String(); } v8::TryCatch block(m_isolate); v8::Local<v8::Script> compiledScript; v8::MaybeLocal<v8::Value> maybeResult; if (v8Call(V8ScriptRunner::compileScript( script, fileName, String(), scriptStartPosition, m_isolate, cacheHandler, SharableCrossOrigin, v8CacheOptions), compiledScript, block)) maybeResult = V8ScriptRunner::runCompiledScript(m_isolate, compiledScript, m_globalScope); if (!block.CanContinue()) { forbidExecution(); return ScriptValue(); } if (block.HasCaught()) { v8::Local<v8::Message> message = block.Message(); m_executionState->hadException = true; m_executionState->errorMessage = toCoreString(message->Get()); m_executionState->m_location = SourceLocation::fromMessage( m_isolate, message, m_scriptState->getExecutionContext()); m_executionState->exception = ScriptValue(m_scriptState.get(), block.Exception()); block.Reset(); } else { m_executionState->hadException = false; } v8::Local<v8::Value> result; if (!maybeResult.ToLocal(&result) || result->IsUndefined()) return ScriptValue(); return ScriptValue(m_scriptState.get(), result); }
ScriptValue WorkerScriptController::evaluate(const String& script, const String& fileName, const TextPosition& scriptStartPosition, CachedMetadataHandler* cacheHandler, V8CacheOptions v8CacheOptions) { if (!initializeContextIfNeeded()) return ScriptValue(); ScriptState::Scope scope(m_scriptState.get()); if (!m_disableEvalPending.isEmpty()) { m_scriptState->context()->AllowCodeGenerationFromStrings(false); m_scriptState->context()->SetErrorMessageForCodeGenerationFromStrings(v8String(isolate(), m_disableEvalPending)); m_disableEvalPending = String(); } v8::TryCatch block(isolate()); v8::Local<v8::Script> compiledScript; v8::MaybeLocal<v8::Value> maybeResult; if (v8Call(V8ScriptRunner::compileScript(script, fileName, String(), scriptStartPosition, isolate(), cacheHandler, SharableCrossOrigin, v8CacheOptions), compiledScript, block)) maybeResult = V8ScriptRunner::runCompiledScript(isolate(), compiledScript, m_workerGlobalScope); if (!block.CanContinue()) { forbidExecution(); return ScriptValue(); } if (block.HasCaught()) { v8::Local<v8::Message> message = block.Message(); m_executionState->hadException = true; m_executionState->errorMessage = toCoreString(message->Get()); if (v8Call(message->GetLineNumber(m_scriptState->context()), m_executionState->lineNumber) && v8Call(message->GetStartColumn(m_scriptState->context()), m_executionState->columnNumber)) { ++m_executionState->columnNumber; } else { m_executionState->lineNumber = 0; m_executionState->columnNumber = 0; } TOSTRING_DEFAULT(V8StringResource<>, sourceURL, message->GetScriptOrigin().ResourceName(), ScriptValue()); m_executionState->sourceURL = sourceURL; m_executionState->exception = ScriptValue(m_scriptState.get(), block.Exception()); block.Reset(); } else { m_executionState->hadException = false; } v8::Local<v8::Value> result; if (!maybeResult.ToLocal(&result) || result->IsUndefined()) return ScriptValue(); return ScriptValue(m_scriptState.get(), result); }
void JSEventListener::handleEvent(ScriptExecutionContext* scriptExecutionContext, Event* event) { ASSERT(scriptExecutionContext); if (!scriptExecutionContext || scriptExecutionContext->isJSExecutionForbidden()) return; VM& vm = scriptExecutionContext->vm(); JSLockHolder lock(vm); auto scope = DECLARE_CATCH_SCOPE(vm); // See https://dom.spec.whatwg.org/#dispatching-events spec on calling handleEvent. // "If this throws an exception, report the exception." It should not propagate the // exception. JSObject* jsFunction = this->jsFunction(scriptExecutionContext); if (!jsFunction) return; JSDOMGlobalObject* globalObject = toJSDOMGlobalObject(scriptExecutionContext, *m_isolatedWorld); if (!globalObject) return; if (scriptExecutionContext->isDocument()) { JSDOMWindow* window = jsCast<JSDOMWindow*>(globalObject); if (!window->wrapped().isCurrentlyDisplayedInFrame()) return; if (wasCreatedFromMarkup() && !scriptExecutionContext->contentSecurityPolicy()->allowInlineEventHandlers(sourceURL(), sourcePosition().m_line)) return; // FIXME: Is this check needed for other contexts? ScriptController& script = window->wrapped().frame()->script(); if (!script.canExecuteScripts(AboutToExecuteScript) || script.isPaused()) return; } ExecState* exec = globalObject->globalExec(); JSValue handleEventFunction = jsFunction; CallData callData; CallType callType = getCallData(handleEventFunction, callData); // If jsFunction is not actually a function, see if it implements the EventListener interface and use that if (callType == CallType::None) { handleEventFunction = jsFunction->get(exec, Identifier::fromString(exec, "handleEvent")); if (UNLIKELY(scope.exception())) { auto* exception = scope.exception(); scope.clearException(); event->target()->uncaughtExceptionInEventHandler(); reportException(exec, exception); return; } callType = getCallData(handleEventFunction, callData); } if (callType != CallType::None) { Ref<JSEventListener> protectedThis(*this); MarkedArgumentBuffer args; args.append(toJS(exec, globalObject, event)); Event* savedEvent = globalObject->currentEvent(); globalObject->setCurrentEvent(event); VMEntryScope entryScope(vm, vm.entryScope ? vm.entryScope->globalObject() : globalObject); InspectorInstrumentationCookie cookie = JSMainThreadExecState::instrumentFunctionCall(scriptExecutionContext, callType, callData); JSValue thisValue = handleEventFunction == jsFunction ? toJS(exec, globalObject, event->currentTarget()) : jsFunction; NakedPtr<JSC::Exception> exception; JSValue retval = scriptExecutionContext->isDocument() ? JSMainThreadExecState::profiledCall(exec, JSC::ProfilingReason::Other, handleEventFunction, callType, callData, thisValue, args, exception) : JSC::profiledCall(exec, JSC::ProfilingReason::Other, handleEventFunction, callType, callData, thisValue, args, exception); InspectorInstrumentation::didCallFunction(cookie, scriptExecutionContext); globalObject->setCurrentEvent(savedEvent); if (is<WorkerGlobalScope>(*scriptExecutionContext)) { auto scriptController = downcast<WorkerGlobalScope>(*scriptExecutionContext).script(); bool terminatorCausedException = (scope.exception() && isTerminatedExecutionException(scope.exception())); if (terminatorCausedException || scriptController->isTerminatingExecution()) scriptController->forbidExecution(); } if (exception) { event->target()->uncaughtExceptionInEventHandler(); reportException(exec, exception); } else { if (!retval.isUndefinedOrNull() && is<BeforeUnloadEvent>(*event)) downcast<BeforeUnloadEvent>(*event).setReturnValue(retval.toWTFString(exec)); if (m_isAttribute) { if (retval.isFalse()) event->preventDefault(); } } } }