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); } } }
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(); } }