예제 #1
0
void ScriptElement::executeScript(const ScriptSourceCode& sourceCode)
{
    ASSERT(m_alreadyStarted);

    if (sourceCode.isEmpty())
        return;

    if (!m_element->document()->contentSecurityPolicy()->allowScriptNonce(m_element->fastGetAttribute(HTMLNames::nonceAttr), m_element->document()->url(), m_startLineNumber))
        return;

    if (!m_isExternalScript && !m_element->document()->contentSecurityPolicy()->allowInlineScript(m_element->document()->url(), m_startLineNumber))
        return;

#if ENABLE(NOSNIFF)
    if (m_isExternalScript && m_cachedScript && !m_cachedScript->mimeTypeAllowedByNosniff()) {
        m_element->document()->addConsoleMessage(SecurityMessageSource, ErrorMessageLevel, "Refused to execute script from '" + m_cachedScript->url().elidedString() + "' because its MIME type ('" + m_cachedScript->mimeType() + "') is not executable, and strict MIME type checking is enabled.");
        return;
    }
#endif

    RefPtr<Document> document = m_element->document();
    ASSERT(document);
    if (Frame* frame = document->frame()) {
        {
            IgnoreDestructiveWriteCountIncrementer ignoreDesctructiveWriteCountIncrementer(m_isExternalScript ? document.get() : 0);
            // Create a script from the script element node, using the script
            // block's source and the script block's type.
            // Note: This is where the script is compiled and actually executed.
            frame->script()->evaluate(sourceCode);
        }
    }
}
예제 #2
0
void ScriptLoader::executeScript(const ScriptSourceCode& sourceCode, double* compilationFinishTime)
{
    ASSERT(m_alreadyStarted);

    if (sourceCode.isEmpty())
        return;

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

    LocalFrame* frame = contextDocument->frame();

    const ContentSecurityPolicy* csp = elementDocument->contentSecurityPolicy();
    bool shouldBypassMainWorldCSP = (frame && frame->script().shouldBypassMainWorldCSP())
        || csp->allowScriptWithNonce(m_element->fastGetAttribute(HTMLNames::nonceAttr))
        || csp->allowScriptWithHash(sourceCode.source());

    if (!m_isExternalScript && (!shouldBypassMainWorldCSP && !csp->allowInlineScript(elementDocument->url(), m_startLineNumber)))
        return;

    if (m_isExternalScript) {
        ScriptResource* resource = m_resource ? m_resource.get() : sourceCode.resource();
        if (resource && !resource->mimeTypeAllowedByNosniff()) {
            contextDocument->addConsoleMessage(ConsoleMessage::create(SecurityMessageSource, ErrorMessageLevel, "Refused to execute script from '" + resource->url().elidedString() + "' because its MIME type ('" + resource->mimeType() + "') is not executable, and strict MIME type checking is enabled."));
            return;
        }

        if (!SubresourceIntegrity::CheckSubresourceIntegrity(*m_element, sourceCode.source(), sourceCode.resource()->url(), sourceCode.resource()->mimeType()))
            return;
    }

    // FIXME: Can this be moved earlier in the function?
    // Why are we ever attempting to execute scripts without a frame?
    if (!frame)
        return;

    const bool isImportedScript = contextDocument != elementDocument;
    // http://www.whatwg.org/specs/web-apps/current-work/#execute-the-script-block step 2.3
    // with additional support for HTML imports.
    IgnoreDestructiveWriteCountIncrementer ignoreDestructiveWriteCountIncrementer(m_isExternalScript || isImportedScript ? contextDocument.get() : 0);

    if (isHTMLScriptLoader(m_element))
        contextDocument->pushCurrentScript(toHTMLScriptElement(m_element));

    AccessControlStatus corsCheck = NotSharableCrossOrigin;
    if (!m_isExternalScript || (sourceCode.resource() && sourceCode.resource()->passesAccessControlCheck(&m_element->document(), m_element->document().securityOrigin())))
        corsCheck = SharableCrossOrigin;

    // Create a script from the script element node, using the script
    // block's source and the script block's type.
    // Note: This is where the script is compiled and actually executed.
    frame->script().executeScriptInMainWorld(sourceCode, corsCheck, compilationFinishTime);

    if (isHTMLScriptLoader(m_element)) {
        ASSERT(contextDocument->currentScript() == m_element);
        contextDocument->popCurrentScript();
    }
}