예제 #1
0
bool ScriptElement::requestScript(const String& sourceUrl)
{
    Ref<Document> originalDocument(m_element->document());
    if (!m_element->dispatchBeforeLoadEvent(sourceUrl))
        return false;
    if (!m_element->inDocument() || &m_element->document() != &originalDocument.get())
        return false;
    if (!m_element->document().contentSecurityPolicy()->allowScriptNonce(m_element->fastGetAttribute(HTMLNames::nonceAttr), m_element->document().url(), m_startLineNumber, m_element->document().completeURL(sourceUrl)))
        return false;

    ASSERT(!m_cachedScript);
    if (!stripLeadingAndTrailingHTMLSpaces(sourceUrl).isEmpty()) {
        CachedResourceRequest request(ResourceRequest(m_element->document().completeURL(sourceUrl)));

        String crossOriginMode = m_element->fastGetAttribute(HTMLNames::crossoriginAttr);
        if (!crossOriginMode.isNull()) {
            m_requestUsesAccessControl = true;
            StoredCredentials allowCredentials = equalIgnoringCase(crossOriginMode, "use-credentials") ? AllowStoredCredentials : DoNotAllowStoredCredentials;
            updateRequestForAccessControl(request.mutableResourceRequest(), m_element->document().securityOrigin(), allowCredentials);
        }
        request.setCharset(scriptCharset());
        request.setInitiator(element());

        m_cachedScript = m_element->document().cachedResourceLoader()->requestScript(request);
        m_isExternalScript = true;
    }

    if (m_cachedScript) {
        return true;
    }

    dispatchErrorEvent();
    return false;
}
예제 #2
0
void ScriptLoader::notifyFinished(Resource* resource)
{
    ASSERT(!m_willBeParserExecuted);

    RefPtrWillBeRawPtr<Document> elementDocument(m_element->document());
    RefPtrWillBeRawPtr<Document> contextDocument = elementDocument->contextDocument().get();
    if (!contextDocument)
        return;

    ASSERT_UNUSED(resource, resource == m_resource);

    ScriptRunner::ExecutionType runOrder = m_willExecuteInOrder ? ScriptRunner::IN_ORDER_EXECUTION : ScriptRunner::ASYNC_EXECUTION;
    if (m_resource->errorOccurred()) {
        dispatchErrorEvent();
        // The error handler can move the HTMLScriptElement to a new document.
        // In that case, we must notify the ScriptRunner of the new document,
        // not the ScriptRunner of the old docuemnt.
        contextDocument = m_element->document().contextDocument().get();
        if (!contextDocument)
            return;
        contextDocument->scriptRunner()->notifyScriptLoadError(this, runOrder);
        return;
    }
    contextDocument->scriptRunner()->notifyScriptReady(this, runOrder);
    m_pendingScript.stopWatchingForLoad(this);
}
// https://html.spec.whatwg.org/multipage/scripting.html#upgrades
bool ScriptCustomElementDefinition::runConstructor(Element* element) {
  if (!m_scriptState->contextIsValid())
    return false;
  ScriptState::Scope scope(m_scriptState.get());
  v8::Isolate* isolate = m_scriptState->isolate();

  // Step 5 says to rethrow the exception; but there is no one to
  // catch it. The side effect is to report the error.
  v8::TryCatch tryCatch(isolate);
  tryCatch.SetVerbose(true);

  Element* result = runConstructor();

  // To report exception thrown from runConstructor()
  if (tryCatch.HasCaught())
    return false;

  // To report InvalidStateError Exception, when the constructor returns some
  // different object
  if (result != element) {
    const String& message =
        "custom element constructors must call super() first and must "
        "not return a different object";
    v8::Local<v8::Value> exception = V8ThrowException::createDOMException(
        m_scriptState->isolate(), InvalidStateError, message);
    dispatchErrorEvent(isolate, exception, constructor());
    return false;
  }

  return true;
}
예제 #4
0
void ScriptElement::notifyFinished(CachedResource* resource)
{
    ASSERT(!m_willBeParserExecuted);

    // CachedResource possibly invokes this notifyFinished() more than
    // once because ScriptElement doesn't unsubscribe itself from
    // CachedResource here and does it in execute() instead.
    // We use m_cachedScript to check if this function is already called.
    ASSERT_UNUSED(resource, resource == m_cachedScript);
    if (!m_cachedScript)
        return;

    if (m_requestUsesAccessControl
        && !m_element->document()->securityOrigin()->canRequest(m_cachedScript->response().url())
        && !m_cachedScript->passesAccessControlCheck(m_element->document()->securityOrigin())) {

        dispatchErrorEvent();
        DEFINE_STATIC_LOCAL(String, consoleMessage, (ASCIILiteral("Cross-origin script load denied by Cross-Origin Resource Sharing policy.")));
        m_element->document()->addConsoleMessage(JSMessageSource, ErrorMessageLevel, consoleMessage);
        return;
    }

    if (m_willExecuteInOrder)
        m_element->document()->scriptRunner()->notifyScriptReady(this, ScriptRunner::IN_ORDER_EXECUTION);
    else
        m_element->document()->scriptRunner()->notifyScriptReady(this, ScriptRunner::ASYNC_EXECUTION);

    m_cachedScript = 0;
}
예제 #5
0
bool ScriptElement::requestScript(const String& sourceUrl)
{
    RefPtr<Document> originalDocument = m_element->document();
    if (!m_element->dispatchBeforeLoadEvent(sourceUrl))
        return false;
    if (!m_element->inDocument() || m_element->document() != originalDocument)
        return false;

    ASSERT(!m_cachedScript);
    if (!stripLeadingAndTrailingHTMLSpaces(sourceUrl).isEmpty()) {
        ResourceRequest request(m_element->document()->completeURL(sourceUrl));
        m_cachedScript = m_element->document()->cachedResourceLoader()->requestScript(request, scriptCharset());
        m_isExternalScript = true;
    }

    if (m_cachedScript) {
#if PLATFORM(CHROMIUM)      
        ASSERT(m_cachedScriptState == NeverSet);
        m_cachedScriptState = Set;
#endif
        return true;
    }

    dispatchErrorEvent();
    return false;
}
예제 #6
0
bool ScriptElement::requestClassicScript(const String& sourceURL)
{
    Ref<Document> originalDocument(m_element.document());
    if (!m_element.dispatchBeforeLoadEvent(sourceURL))
        return false;
    bool didEventListenerDisconnectThisElement = !m_element.inDocument() || &m_element.document() != originalDocument.ptr();
    if (didEventListenerDisconnectThisElement)
        return false;

    ASSERT(!m_loadableScript);
    if (!stripLeadingAndTrailingHTMLSpaces(sourceURL).isEmpty()) {
        auto request = requestScriptWithCache(m_element.document().completeURL(sourceURL), m_element.attributeWithoutSynchronization(HTMLNames::nonceAttr));
        if (request) {
            m_loadableScript = LoadableClassicScript::create(WTFMove(request));
            m_isExternalScript = true;
        }
    }

    if (m_loadableScript)
        return true;

    callOnMainThread([this, element = Ref<Element>(m_element)] {
        dispatchErrorEvent();
    });
    return false;
}
예제 #7
0
bool ScriptElement::requestScript(const String& sourceUrl)
{
    RefPtr<Document> originalDocument = m_element->document();
    if (!m_element->dispatchBeforeLoadEvent(sourceUrl))
        return false;
    if (!m_element->inDocument() || m_element->document() != originalDocument)
        return false;

    ASSERT(!m_cachedScript);
    if (!stripLeadingAndTrailingHTMLSpaces(sourceUrl).isEmpty()) {
        ResourceRequest request = ResourceRequest(m_element->document()->completeURL(sourceUrl));

        String crossOriginMode = m_element->fastGetAttribute(HTMLNames::crossoriginAttr);
        if (!crossOriginMode.isNull()) {
            m_requestUsesAccessControl = true;
            StoredCredentials allowCredentials = equalIgnoringCase(crossOriginMode, "use-credentials") ? AllowStoredCredentials : DoNotAllowStoredCredentials;
            updateRequestForAccessControl(request, m_element->document()->securityOrigin(), allowCredentials);
        }

        m_cachedScript = m_element->document()->cachedResourceLoader()->requestScript(request, scriptCharset());
        m_isExternalScript = true;
    }

    if (m_cachedScript) {
        return true;
    }

    dispatchErrorEvent();
    return false;
}
예제 #8
0
void ScriptLoader::notifyFinished(Resource* resource)
{
    ASSERT(!m_willBeParserExecuted);

    RefPtrWillBeRawPtr<Document> elementDocument(m_element->document());
    RefPtrWillBeRawPtr<Document> contextDocument = elementDocument->contextDocument().get();
    if (!contextDocument)
        return;

    // Resource possibly invokes this notifyFinished() more than
    // once because ScriptLoader doesn't unsubscribe itself from
    // Resource here and does it in execute() instead.
    // We use m_resource to check if this function is already called.
    ASSERT_UNUSED(resource, resource == m_resource);
    if (!m_resource)
        return;
    if (m_resource->errorOccurred()) {
        dispatchErrorEvent();
        contextDocument->scriptRunner()->notifyScriptLoadError(this, m_willExecuteInOrder ? ScriptRunner::IN_ORDER_EXECUTION : ScriptRunner::ASYNC_EXECUTION);
        return;
    }
    if (m_willExecuteInOrder)
        contextDocument->scriptRunner()->notifyScriptReady(this, ScriptRunner::IN_ORDER_EXECUTION);
    else
        contextDocument->scriptRunner()->notifyScriptReady(this, ScriptRunner::ASYNC_EXECUTION);

    m_resource = 0;
}
예제 #9
0
void ScriptLoader::notifyFinished(Resource* resource) {
    DCHECK(!m_willBeParserExecuted);

    // We do not need this script in the memory cache. The primary goals of
    // sending this fetch request are to let the third party server know
    // about the document.write scripts intervention and populate the http
    // cache for subsequent uses.
    if (m_documentWriteIntervention ==
            DocumentWriteIntervention::FetchDocWrittenScriptDeferIdle) {
        memoryCache()->remove(resource);
        m_pendingScript->stopWatchingForLoad();
        return;
    }

    DCHECK(m_asyncExecType != ScriptRunner::None);

    Document* contextDocument = m_element->document().contextDocument();
    if (!contextDocument) {
        detach();
        return;
    }

    DCHECK_EQ(resource, m_resource);

    if (m_resource->errorOccurred()) {
        contextDocument->scriptRunner()->notifyScriptLoadError(this,
                m_asyncExecType);
        detach();
        dispatchErrorEvent();
        return;
    }
    contextDocument->scriptRunner()->notifyScriptReady(this, m_asyncExecType);
    m_pendingScript->stopWatchingForLoad();
}
예제 #10
0
bool ScriptLoader::fetchScript(const String& sourceUrl, FetchRequest::DeferOption defer)
{
    ASSERT(m_element);

    RefPtrWillBeRawPtr<Document> elementDocument(m_element->document());
    if (!m_element->inDocument() || m_element->document() != elementDocument)
        return false;

    ASSERT(!m_resource);
    if (!stripLeadingAndTrailingHTMLSpaces(sourceUrl).isEmpty()) {
        FetchRequest request(ResourceRequest(elementDocument->completeURL(sourceUrl)), m_element->localName());

        AtomicString crossOriginMode = m_element->fastGetAttribute(HTMLNames::crossoriginAttr);
        if (!crossOriginMode.isNull())
            request.setCrossOriginAccessControl(elementDocument->securityOrigin(), crossOriginMode);
        request.setCharset(scriptCharset());

        bool scriptPassesCSP = elementDocument->contentSecurityPolicy()->allowScriptWithNonce(m_element->fastGetAttribute(HTMLNames::nonceAttr));
        if (scriptPassesCSP)
            request.setContentSecurityCheck(DoNotCheckContentSecurityPolicy);
        request.setDefer(defer);

        m_resource = elementDocument->fetcher()->fetchScript(request);
        m_isExternalScript = true;
    }

    if (m_resource)
        return true;

    dispatchErrorEvent();
    return false;
}
예제 #11
0
void ScriptLoader::execute() {
    DCHECK(!m_willBeParserExecuted);
    DCHECK(m_asyncExecType != ScriptRunner::None);
    DCHECK(m_pendingScript->resource());
    bool errorOccurred = false;
    ScriptSourceCode source = m_pendingScript->getSource(KURL(), errorOccurred);
    m_pendingScript->dispose();
    if (errorOccurred) {
        dispatchErrorEvent();
    } else if (!m_resource->wasCanceled()) {
        if (executeScript(source))
            dispatchLoadEvent();
        else
            dispatchErrorEvent();
    }
    m_resource = nullptr;
}
예제 #12
0
void ScriptLoader::execute()
{
    DCHECK(!m_willBeParserExecuted);
    DCHECK(m_pendingScript->resource());
    bool errorOccurred = false;
    ScriptSourceCode source = m_pendingScript->getSource(KURL(), errorOccurred);
    Element* element = m_pendingScript->releaseElementAndClear();
    ALLOW_UNUSED_LOCAL(element);
    if (errorOccurred) {
        dispatchErrorEvent();
    } else if (!m_resource->wasCanceled()) {
        if (executeScript(source))
            dispatchLoadEvent();
        else
            dispatchErrorEvent();
    }
    m_resource = nullptr;
}
예제 #13
0
void ScriptLoader::execute()
{
    ASSERT(!m_willBeParserExecuted);
    ASSERT(m_pendingScript.resource());
    bool errorOccurred = false;
    ScriptSourceCode source = m_pendingScript.getSource(KURL(), errorOccurred);
    RefPtrWillBeRawPtr<Element> element = m_pendingScript.releaseElementAndClear();
    ALLOW_UNUSED_LOCAL(element);
    if (errorOccurred) {
        dispatchErrorEvent();
    } else if (!m_resource->wasCanceled()) {
        if (executeScript(source))
            dispatchLoadEvent();
        else
            dispatchErrorEvent();
    }
    m_resource = 0;
}
예제 #14
0
void XMLHttpRequest::networkError()
{
    genericError();
    dispatchErrorEvent();
    if (!m_uploadComplete) {
        m_uploadComplete = true;
        if (m_upload)
            m_upload->dispatchErrorEvent();
    }
}
예제 #15
0
void XMLHttpRequest::networkError()
{
    genericError();
    dispatchErrorEvent();
    if (!m_uploadComplete) {
        m_uploadComplete = true;
        if (m_upload && m_uploadEventsAllowed)
            m_upload->dispatchErrorEvent();
    }
    internalAbort();
}
예제 #16
0
void Notification::taskTimerFired(Timer<Notification>* timer)
{
    ASSERT(scriptExecutionContext()->isDocument());
    ASSERT(static_cast<Document*>(scriptExecutionContext())->page());
    ASSERT_UNUSED(timer, timer == m_taskTimer.get());
    if (NotificationController::from(static_cast<Document*>(scriptExecutionContext())->page())->client()->checkPermission(scriptExecutionContext()) != NotificationClient::PermissionAllowed) {
        dispatchErrorEvent();
        return;
    }
    show();
}
예제 #17
0
void ScriptLoader::execute(ScriptResource* resource)
{
    ASSERT(!m_willBeParserExecuted);
    ASSERT(resource);
    if (resource->errorOccurred()) {
        dispatchErrorEvent();
    } else if (!resource->wasCanceled()) {
        executeScript(ScriptSourceCode(resource));
        dispatchLoadEvent();
    }
    resource->removeClient(this);
}
예제 #18
0
void ScriptElement::execute(CachedScript* cachedScript)
{
    ASSERT(!m_willBeParserExecuted);
    ASSERT(cachedScript);
    if (cachedScript->errorOccurred())
        dispatchErrorEvent();
    else if (!cachedScript->wasCanceled()) {
        executeScript(ScriptSourceCode(cachedScript));
        dispatchLoadEvent();
    }
    cachedScript->removeClient(this);
}
예제 #19
0
void Notification::prepareShow() {
  DCHECK_EQ(m_state, State::Loading);
  if (NotificationManager::from(getExecutionContext())->permissionStatus() !=
      mojom::blink::PermissionStatus::GRANTED) {
    dispatchErrorEvent();
    return;
  }

  m_loader = new NotificationResourcesLoader(
      WTF::bind(&Notification::didLoadResources, wrapWeakPersistent(this)));
  m_loader->start(getExecutionContext(), m_data);
}
예제 #20
0
void ScriptElement::executeScriptAndDispatchEvent(LoadableScript& loadableScript)
{
    if (Optional<LoadableScript::Error> error = loadableScript.wasErrored()) {
        if (Optional<LoadableScript::ConsoleMessage> message = error->consoleMessage)
            m_element.document().addConsoleMessage(message->source, message->level, message->message);
        dispatchErrorEvent();
    } else if (!loadableScript.wasCanceled()) {
        ASSERT(!loadableScript.wasErrored());
        loadableScript.execute(*this);
        dispatchLoadEvent();
    }
}
예제 #21
0
void ImageLoader::imageNotifyFinished(ImageResource* resource) {
    RESOURCE_LOADING_DVLOG(1)
            << "ImageLoader::imageNotifyFinished " << this
            << "; m_hasPendingLoadEvent=" << m_hasPendingLoadEvent;

    DCHECK(m_failedLoadURL.isEmpty());
    DCHECK_EQ(resource, m_image.get());

    m_imageComplete = true;

    // Update ImageAnimationPolicy for m_image.
    if (m_image)
        m_image->updateImageAnimationPolicy();

    updateLayoutObject();

    if (m_image && m_image->getImage() && m_image->getImage()->isSVGImage())
        toSVGImage(m_image->getImage())->updateUseCounters(element()->document());

    if (!m_hasPendingLoadEvent)
        return;

    if (resource->errorOccurred()) {
        loadEventSender().cancelEvent(this);
        m_hasPendingLoadEvent = false;

        if (resource->resourceError().isAccessCheck()) {
            crossSiteOrCSPViolationOccurred(
                AtomicString(resource->resourceError().failingURL()));
        }

        // The error event should not fire if the image data update is a result of
        // environment change.
        // https://html.spec.whatwg.org/multipage/embedded-content.html#the-img-element:the-img-element-55
        if (!m_suppressErrorEvents)
            dispatchErrorEvent();

        // Only consider updating the protection ref-count of the Element
        // immediately before returning from this function as doing so might result
        // in the destruction of this ImageLoader.
        updatedHasPendingEvent();
        return;
    }
    if (resource->wasCanceled()) {
        m_hasPendingLoadEvent = false;
        // Only consider updating the protection ref-count of the Element
        // immediately before returning from this function as doing so might result
        // in the destruction of this ImageLoader.
        updatedHasPendingEvent();
        return;
    }
    loadEventSender().dispatchEventSoon(this);
}
예제 #22
0
void Notification::show()
{
    ASSERT(m_state == NotificationStateIdle);
    if (!toDocument(executionContext())->page())
        return;

    if (m_client->checkPermission(executionContext()) != NotificationClient::PermissionAllowed) {
        dispatchErrorEvent();
        return;
    }

    if (m_client->show(this))
        m_state = NotificationStateShowing;
}
예제 #23
0
void Notification::show()
{
    ASSERT(m_state == NotificationStateIdle);
    if (Notification::checkPermission(executionContext()) != WebNotificationPermissionAllowed) {
        dispatchErrorEvent();
        return;
    }

    SecurityOrigin* origin = executionContext()->securityOrigin();
    ASSERT(origin);

    notificationManager()->show(WebSecurityOrigin(origin), m_data, this);

    m_state = NotificationStateShowing;
}
예제 #24
0
void Notification::show()
{
    // prevent double-showing
    if (m_state == Idle) {
        if (!toDocument(scriptExecutionContext())->page())
            return;
        if (NotificationController::from(toDocument(scriptExecutionContext())->page())->client()->checkPermission(scriptExecutionContext()) != NotificationClient::PermissionAllowed) {
            dispatchErrorEvent();
            return;
        }
        if (m_notificationClient->show(this)) {
            m_state = Showing;
            setPendingActivity(this);
        }
    }
}
예제 #25
0
void Worker::notifyFinished(CachedResource* resource)
{
    ASSERT(resource == m_cachedScript.get());
    if (m_cachedScript->errorOccurred())
        dispatchErrorEvent();
    else {
        String userAgent = document()->frame() ? document()->frame()->loader()->userAgent(m_scriptURL) : String();
        RefPtr<WorkerThread> thread = WorkerThread::create(m_scriptURL, userAgent, m_cachedScript->script(), m_messagingProxy);
        m_messagingProxy->workerThreadCreated(thread);
        thread->start();
    }

    m_cachedScript->removeClient(this);
    m_cachedScript = 0;

    unsetPendingActivity(this);
}
예제 #26
0
bool ScriptLoader::fetchScript(const String& sourceUrl, FetchRequest::DeferOption defer)
{
    DCHECK(m_element);

    Document* elementDocument = &(m_element->document());
    if (!m_element->inShadowIncludingDocument() || m_element->document() != elementDocument)
        return false;

    DCHECK(!m_resource);
    if (!stripLeadingAndTrailingHTMLSpaces(sourceUrl).isEmpty()) {
        FetchRequest request(ResourceRequest(elementDocument->completeURL(sourceUrl)), m_element->localName());

        CrossOriginAttributeValue crossOrigin = crossOriginAttributeValue(m_element->fastGetAttribute(HTMLNames::crossoriginAttr));
        if (crossOrigin != CrossOriginAttributeNotSet)
            request.setCrossOriginAccessControl(elementDocument->getSecurityOrigin(), crossOrigin);
        request.setCharset(scriptCharset());

        // Skip fetch-related CSP checks if dynamically injected script is whitelisted and this script is not parser-inserted.
        bool scriptPassesCSPDynamic = (!isParserInserted() && elementDocument->contentSecurityPolicy()->allowDynamic());

        request.setContentSecurityPolicyNonce(m_element->fastGetAttribute(HTMLNames::nonceAttr));

        if (scriptPassesCSPDynamic) {
            UseCounter::count(elementDocument->frame(), UseCounter::ScriptPassesCSPDynamic);
            request.setContentSecurityCheck(DoNotCheckContentSecurityPolicy);
        }
        request.setDefer(defer);

        String integrityAttr = m_element->fastGetAttribute(HTMLNames::integrityAttr);
        if (!integrityAttr.isEmpty()) {
            IntegrityMetadataSet metadataSet;
            SubresourceIntegrity::parseIntegrityAttribute(integrityAttr, metadataSet, elementDocument);
            request.setIntegrityMetadata(metadataSet);
        }

        m_resource = ScriptResource::fetch(request, elementDocument->fetcher());

        m_isExternalScript = true;
    }

    if (m_resource)
        return true;

    dispatchErrorEvent();
    return false;
}
예제 #27
0
void Notification::show() 
{
    // prevent double-showing
    if (m_state == Idle && m_notificationCenter->client()) {
#if ENABLE(NOTIFICATIONS)
        if (!downcast<Document>(*scriptExecutionContext()).page())
            return;
        if (NotificationController::from(downcast<Document>(*scriptExecutionContext()).page())->client()->checkPermission(scriptExecutionContext()) != NotificationClient::PermissionAllowed) {
            dispatchErrorEvent();
            return;
        }
#endif
        if (m_notificationCenter->client()->show(this)) {
            m_state = Showing;
            setPendingActivity(this);
        }
    }
}
예제 #28
0
void ScriptLoader::finishLoading(Document* contextDocument, ScriptLoader::FinishType type)
{
    ASSERT(!m_willBeParserExecuted);

    if (!contextDocument)
        return;

    if (type == FinishWithErrorOrCancel) {
        dispatchErrorEvent();
        contextDocument->scriptRunner()->notifyScriptLoadError(this, m_willExecuteInOrder ? ScriptRunner::IN_ORDER_EXECUTION : ScriptRunner::ASYNC_EXECUTION);
        return;
    }
    if (m_willExecuteInOrder)
        contextDocument->scriptRunner()->notifyScriptReady(this, ScriptRunner::IN_ORDER_EXECUTION);
    else
        contextDocument->scriptRunner()->notifyScriptReady(this, ScriptRunner::ASYNC_EXECUTION);

    m_resource = 0;
}
예제 #29
0
bool ScriptLoader::fetchScript(const String& sourceUrl, FetchRequest::DeferOption defer)
{
    ASSERT(m_element);

    RefPtrWillBeRawPtr<Document> elementDocument(m_element->document());
    if (!m_element->inDocument() || m_element->document() != elementDocument)
        return false;

    ASSERT(!m_resource);
    if (!stripLeadingAndTrailingHTMLSpaces(sourceUrl).isEmpty()) {
        FetchRequest request(ResourceRequest(elementDocument->completeURL(sourceUrl)), m_element->localName());

        CrossOriginAttributeValue crossOrigin = crossOriginAttributeValue(m_element->fastGetAttribute(HTMLNames::crossoriginAttr));
        if (crossOrigin != CrossOriginAttributeNotSet)
            request.setCrossOriginAccessControl(elementDocument->securityOrigin(), crossOrigin);
        request.setCharset(scriptCharset());

        bool scriptPassesCSP = elementDocument->contentSecurityPolicy()->allowScriptWithNonce(m_element->fastGetAttribute(HTMLNames::nonceAttr));
        if (scriptPassesCSP)
            request.setContentSecurityCheck(DoNotCheckContentSecurityPolicy);
        request.setDefer(defer);

        String integrityAttr = m_element->fastGetAttribute(HTMLNames::integrityAttr);
        IntegrityMetadataSet metadataSet;
        if (!integrityAttr.isEmpty()) {
            SubresourceIntegrity::parseIntegrityAttribute(integrityAttr, metadataSet, elementDocument.get());
            request.setIntegrityMetadata(metadataSet);
        }

        m_resource = ScriptResource::fetch(request, elementDocument->fetcher());
        if (m_resource && !integrityAttr.isEmpty())
            m_resource->setIntegrityMetadata(metadataSet);

        m_isExternalScript = true;
    }

    if (m_resource)
        return true;

    dispatchErrorEvent();
    return false;
}
예제 #30
0
void ScriptExecutionContext::reportException(const String& errorMessage, int lineNumber, int columnNumber, const String& sourceURL, JSC::Exception* exception, RefPtr<ScriptCallStack>&& callStack, CachedScript* cachedScript)
{
    if (m_inDispatchErrorEvent) {
        if (!m_pendingExceptions)
            m_pendingExceptions = std::make_unique<Vector<std::unique_ptr<PendingException>>>();
        m_pendingExceptions->append(std::make_unique<PendingException>(errorMessage, lineNumber, columnNumber, sourceURL, callStack.copyRef()));
        return;
    }

    // First report the original exception and only then all the nested ones.
    if (!dispatchErrorEvent(errorMessage, lineNumber, columnNumber, sourceURL, exception, cachedScript))
        logExceptionToConsole(errorMessage, sourceURL, lineNumber, columnNumber, callStack.copyRef());

    if (!m_pendingExceptions)
        return;

    std::unique_ptr<Vector<std::unique_ptr<PendingException>>> pendingExceptions = WTFMove(m_pendingExceptions);
    for (auto& exception : *pendingExceptions)
        logExceptionToConsole(exception->m_errorMessage, exception->m_sourceURL, exception->m_lineNumber, exception->m_columnNumber, exception->m_callStack.copyRef());
}