summaryrefslogtreecommitdiffstats
path: root/chromium/third_party/WebKit/Source/core/dom/ScriptLoader.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/third_party/WebKit/Source/core/dom/ScriptLoader.cpp')
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/ScriptLoader.cpp80
1 files changed, 33 insertions, 47 deletions
diff --git a/chromium/third_party/WebKit/Source/core/dom/ScriptLoader.cpp b/chromium/third_party/WebKit/Source/core/dom/ScriptLoader.cpp
index eaa0e45da91..e5b9a3be4bb 100644
--- a/chromium/third_party/WebKit/Source/core/dom/ScriptLoader.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/ScriptLoader.cpp
@@ -24,10 +24,10 @@
#include "config.h"
#include "core/dom/ScriptLoader.h"
-#include "HTMLNames.h"
-#include "SVGNames.h"
#include "bindings/v8/ScriptController.h"
#include "bindings/v8/ScriptSourceCode.h"
+#include "core/HTMLNames.h"
+#include "core/SVGNames.h"
#include "core/dom/Document.h"
#include "core/events/Event.h"
#include "core/dom/IgnoreDestructiveWriteCountIncrementer.h"
@@ -38,11 +38,11 @@
#include "core/fetch/FetchRequest.h"
#include "core/fetch/ResourceFetcher.h"
#include "core/fetch/ScriptResource.h"
-#include "core/html/HTMLImport.h"
#include "core/html/HTMLScriptElement.h"
+#include "core/html/imports/HTMLImport.h"
#include "core/html/parser/HTMLParserIdioms.h"
-#include "core/frame/ContentSecurityPolicy.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
+#include "core/frame/csp/ContentSecurityPolicy.h"
#include "core/svg/SVGScriptElement.h"
#include "platform/MIMETypeRegistry.h"
#include "platform/weborigin/SecurityOrigin.h"
@@ -65,7 +65,6 @@ ScriptLoader::ScriptLoader(Element* element, bool parserInserted, bool alreadySt
, m_willExecuteWhenDocumentFinishedParsing(false)
, m_forceAsync(!parserInserted)
, m_willExecuteInOrder(false)
- , m_isPotentiallyCORSEnabled(false)
{
ASSERT(m_element);
if (parserInserted && element->document().scriptableDocumentParser() && !element->document().isInDocumentWrite())
@@ -116,7 +115,6 @@ static bool isLegacySupportedJavaScriptLanguage(const String& language)
DEFINE_STATIC_LOCAL(LanguageSet, languages, ());
if (languages.isEmpty()) {
languages.add("javascript");
- languages.add("javascript");
languages.add("javascript1.0");
languages.add("javascript1.1");
languages.add("javascript1.2");
@@ -159,7 +157,7 @@ bool ScriptLoader::isScriptTypeSupported(LegacyTypeSupport supportLegacyTypes) c
type = "text/" + language.lower();
if (MIMETypeRegistry::isSupportedJavaScriptMIMEType(type) || isLegacySupportedJavaScriptLanguage(language))
return true;
- } else if (MIMETypeRegistry::isSupportedJavaScriptMIMEType(type.stripWhiteSpace().lower()) || (supportLegacyTypes == AllowLegacyTypeInTypeAttribute && isLegacySupportedJavaScriptLanguage(type))) {
+ } else if (MIMETypeRegistry::isSupportedJavaScriptMIMEType(type.stripWhiteSpace()) || (supportLegacyTypes == AllowLegacyTypeInTypeAttribute && isLegacySupportedJavaScriptLanguage(type))) {
return true;
}
@@ -227,7 +225,7 @@ bool ScriptLoader::prepareScript(const TextPosition& scriptStartPosition, Legacy
m_willBeParserExecuted = true;
} else if (client->hasSourceAttribute() && m_parserInserted && !client->asyncAttributeValue()) {
m_willBeParserExecuted = true;
- } else if (!client->hasSourceAttribute() && m_parserInserted && !elementDocument.haveStylesheetsAndImportsLoaded()) {
+ } else if (!client->hasSourceAttribute() && m_parserInserted && !elementDocument.isRenderingReady()) {
m_willBeParserExecuted = true;
m_readyToBeParserExecuted = true;
} else if (client->hasSourceAttribute() && !client->asyncAttributeValue() && !m_forceAsync) {
@@ -241,8 +239,7 @@ bool ScriptLoader::prepareScript(const TextPosition& scriptStartPosition, Legacy
// Reset line numbering for nested writes.
TextPosition position = elementDocument.isInDocumentWrite() ? TextPosition() : scriptStartPosition;
KURL scriptURL = (!elementDocument.isInDocumentWrite() && m_parserInserted) ? elementDocument.url() : KURL();
- if (!executePotentiallyCrossOriginScript(ScriptSourceCode(scriptContent(), scriptURL, position)))
- return false;
+ executeScript(ScriptSourceCode(scriptContent(), scriptURL, position));
}
return true;
@@ -252,9 +249,7 @@ bool ScriptLoader::fetchScript(const String& sourceUrl)
{
ASSERT(m_element);
- RefPtr<Document> elementDocument(m_element->document());
- if (!m_element->dispatchBeforeLoadEvent(sourceUrl))
- return false;
+ RefPtrWillBeRawPtr<Document> elementDocument(m_element->document());
if (!m_element->inDocument() || m_element->document() != elementDocument)
return false;
@@ -262,12 +257,9 @@ bool ScriptLoader::fetchScript(const String& sourceUrl)
if (!stripLeadingAndTrailingHTMLSpaces(sourceUrl).isEmpty()) {
FetchRequest request(ResourceRequest(elementDocument->completeURL(sourceUrl)), m_element->localName());
- String crossOriginMode = m_element->fastGetAttribute(HTMLNames::crossoriginAttr);
- if (!crossOriginMode.isNull()) {
- StoredCredentials allowCredentials = equalIgnoringCase(crossOriginMode, "use-credentials") ? AllowStoredCredentials : DoNotAllowStoredCredentials;
- request.setCrossOriginAccessControl(elementDocument->securityOrigin(), allowCredentials);
- m_isPotentiallyCORSEnabled = true;
- }
+ AtomicString crossOriginMode = m_element->fastGetAttribute(HTMLNames::crossoriginAttr);
+ if (!crossOriginMode.isNull())
+ request.setCrossOriginAccessControl(elementDocument->securityOrigin(), crossOriginMode);
request.setCharset(scriptCharset());
bool isValidScriptNonce = elementDocument->contentSecurityPolicy()->allowScriptNonce(m_element->fastGetAttribute(HTMLNames::nonceAttr));
@@ -287,12 +279,14 @@ bool ScriptLoader::fetchScript(const String& sourceUrl)
bool isHTMLScriptLoader(Element* element)
{
- return element->hasTagName(HTMLNames::scriptTag);
+ ASSERT(element);
+ return isHTMLScriptElement(*element);
}
bool isSVGScriptLoader(Element* element)
{
- return element->hasTagName(SVGNames::scriptTag);
+ ASSERT(element);
+ return isSVGScriptElement(*element);
}
void ScriptLoader::executeScript(const ScriptSourceCode& sourceCode)
@@ -302,31 +296,37 @@ void ScriptLoader::executeScript(const ScriptSourceCode& sourceCode)
if (sourceCode.isEmpty())
return;
- RefPtr<Document> elementDocument(m_element->document());
- RefPtr<Document> contextDocument = elementDocument->contextDocument().get();
+ RefPtrWillBeRawPtr<Document> elementDocument(m_element->document());
+ RefPtrWillBeRawPtr<Document> contextDocument = elementDocument->contextDocument().get();
if (!contextDocument)
return;
- Frame* frame = contextDocument->frame();
+ LocalFrame* frame = contextDocument->frame();
bool shouldBypassMainWorldContentSecurityPolicy = (frame && frame->script().shouldBypassMainWorldContentSecurityPolicy()) || elementDocument->contentSecurityPolicy()->allowScriptNonce(m_element->fastGetAttribute(HTMLNames::nonceAttr)) || elementDocument->contentSecurityPolicy()->allowScriptHash(sourceCode.source());
if (!m_isExternalScript && (!shouldBypassMainWorldContentSecurityPolicy && !elementDocument->contentSecurityPolicy()->allowInlineScript(elementDocument->url(), m_startLineNumber)))
return;
- if (m_isExternalScript && m_resource && !m_resource->mimeTypeAllowedByNosniff()) {
- contextDocument->addConsoleMessage(SecurityMessageSource, ErrorMessageLevel, "Refused to execute script from '" + m_resource->url().elidedString() + "' because its MIME type ('" + m_resource->mimeType() + "') is not executable, and strict MIME type checking is enabled.");
- return;
+ if (m_isExternalScript) {
+ ScriptResource* resource = m_resource ? m_resource.get() : sourceCode.resource();
+ if (resource && !resource->mimeTypeAllowedByNosniff()) {
+ contextDocument->addConsoleMessage(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 (frame) {
- IgnoreDestructiveWriteCountIncrementer ignoreDesctructiveWriteCountIncrementer(m_isExternalScript ? contextDocument.get() : 0);
+ 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 (sourceCode.resource() && sourceCode.resource()->passesAccessControlCheck(m_element->document().securityOrigin()))
+ if (!m_isExternalScript || (sourceCode.resource() && sourceCode.resource()->passesAccessControlCheck(m_element->document().securityOrigin())))
corsCheck = SharableCrossOrigin;
// Create a script from the script element node, using the script
@@ -363,24 +363,12 @@ void ScriptLoader::execute(ScriptResource* resource)
resource->removeClient(this);
}
-bool ScriptLoader::executePotentiallyCrossOriginScript(const ScriptSourceCode& sourceCode)
-{
- if (sourceCode.resource()
- && isPotentiallyCORSEnabled()
- && !m_element->document().fetcher()->canAccess(sourceCode.resource(), PotentiallyCORSEnabled)) {
- dispatchErrorEvent();
- return false;
- }
- executeScript(sourceCode);
- return true;
-}
-
void ScriptLoader::notifyFinished(Resource* resource)
{
ASSERT(!m_willBeParserExecuted);
- RefPtr<Document> elementDocument(m_element->document());
- RefPtr<Document> contextDocument = elementDocument->contextDocument().get();
+ RefPtrWillBeRawPtr<Document> elementDocument(m_element->document());
+ RefPtrWillBeRawPtr<Document> contextDocument = elementDocument->contextDocument().get();
if (!contextDocument)
return;
@@ -391,13 +379,11 @@ void ScriptLoader::notifyFinished(Resource* resource)
ASSERT_UNUSED(resource, resource == m_resource);
if (!m_resource)
return;
- CORSEnabled corsEnabled = isPotentiallyCORSEnabled() ? PotentiallyCORSEnabled : NotCORSEnabled;
- if (!elementDocument->fetcher()->canAccess(m_resource.get(), corsEnabled)) {
+ 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