Esempio n. 1
0
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();
}
Esempio n. 5
0
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);
}
Esempio n. 7
0
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();
            }
        }
    }
}