| Index: third_party/WebKit/Source/core/dom/PendingScript.cpp
|
| diff --git a/third_party/WebKit/Source/core/dom/PendingScript.cpp b/third_party/WebKit/Source/core/dom/PendingScript.cpp
|
| index e9cd5ab012ca4d19f1cfbdbfd6a9001076ccb32c..20c822632920b32bb2a86bca59a8d52bf4b4d691 100644
|
| --- a/third_party/WebKit/Source/core/dom/PendingScript.cpp
|
| +++ b/third_party/WebKit/Source/core/dom/PendingScript.cpp
|
| @@ -25,79 +25,37 @@
|
|
|
| #include "core/dom/PendingScript.h"
|
|
|
| -#include "bindings/core/v8/ScriptSourceCode.h"
|
| -#include "bindings/core/v8/ScriptState.h"
|
| -#include "bindings/core/v8/V8Binding.h"
|
| -#include "core/dom/ClassicScript.h"
|
| -#include "core/dom/Document.h"
|
| #include "core/dom/ScriptElementBase.h"
|
| -#include "core/dom/TaskRunnerHelper.h"
|
| -#include "core/frame/LocalFrame.h"
|
| -#include "core/frame/SubresourceIntegrity.h"
|
| -#include "platform/SharedBuffer.h"
|
| #include "wtf/CurrentTime.h"
|
|
|
| namespace blink {
|
|
|
| -PendingScript* PendingScript::create(ScriptElementBase* element,
|
| - ScriptResource* resource) {
|
| - return new PendingScript(element, resource, TextPosition());
|
| -}
|
| -
|
| -PendingScript* PendingScript::create(ScriptElementBase* element,
|
| - const TextPosition& startingPosition) {
|
| - return new PendingScript(element, nullptr, startingPosition);
|
| -}
|
| -
|
| -PendingScript* PendingScript::createForTesting(ScriptResource* resource) {
|
| - return new PendingScript(nullptr, resource, TextPosition(), true);
|
| -}
|
| -
|
| PendingScript::PendingScript(ScriptElementBase* element,
|
| - ScriptResource* resource,
|
| - const TextPosition& startingPosition,
|
| - bool isForTesting)
|
| + const TextPosition& startingPosition)
|
| : m_watchingForLoad(false),
|
| m_element(element),
|
| m_startingPosition(startingPosition),
|
| - m_integrityFailure(false),
|
| m_parserBlockingLoadStartTime(0),
|
| - m_client(nullptr),
|
| - m_isForTesting(isForTesting) {
|
| - checkState();
|
| - setResource(resource);
|
| - MemoryCoordinator::instance().registerClient(this);
|
| -}
|
| + m_client(nullptr) {}
|
|
|
| PendingScript::~PendingScript() {}
|
|
|
| -NOINLINE void PendingScript::checkState() const {
|
| - // TODO(hiroshige): Turn these CHECK()s into DCHECK() before going to beta.
|
| - CHECK(m_isForTesting || m_element);
|
| - CHECK(resource() || !m_streamer);
|
| - CHECK(!m_streamer || m_streamer->resource() == resource());
|
| -}
|
| -
|
| void PendingScript::dispose() {
|
| stopWatchingForLoad();
|
| - DCHECK(!m_client);
|
| - DCHECK(!m_watchingForLoad);
|
| + DCHECK(!client());
|
| + DCHECK(!isWatchingForLoad());
|
|
|
| - MemoryCoordinator::instance().unregisterClient(this);
|
| - setResource(nullptr);
|
| m_startingPosition = TextPosition::belowRangePosition();
|
| - m_integrityFailure = false;
|
| m_parserBlockingLoadStartTime = 0;
|
| - if (m_streamer)
|
| - m_streamer->cancel();
|
| - m_streamer = nullptr;
|
| +
|
| + disposeInternal();
|
| m_element = nullptr;
|
| }
|
|
|
| void PendingScript::watchForLoad(PendingScriptClient* client) {
|
| checkState();
|
|
|
| - DCHECK(!m_watchingForLoad);
|
| + DCHECK(!isWatchingForLoad());
|
| // addClient() will call streamingFinished() if the load is complete. Callers
|
| // who do not expect to be re-entered from this call should not call
|
| // watchForLoad for a PendingScript which isReady. We also need to set
|
| @@ -110,10 +68,10 @@ void PendingScript::watchForLoad(PendingScriptClient* client) {
|
| }
|
|
|
| void PendingScript::stopWatchingForLoad() {
|
| - if (!m_watchingForLoad)
|
| + if (!isWatchingForLoad())
|
| return;
|
| checkState();
|
| - DCHECK(resource());
|
| + DCHECK(isExternal());
|
| m_client = nullptr;
|
| m_watchingForLoad = false;
|
| }
|
| @@ -126,172 +84,14 @@ ScriptElementBase* PendingScript::element() const {
|
| return m_element.get();
|
| }
|
|
|
| -void PendingScript::streamingFinished() {
|
| - checkState();
|
| - DCHECK(resource());
|
| - if (m_client)
|
| - m_client->pendingScriptFinished(this);
|
| -}
|
| -
|
| void PendingScript::markParserBlockingLoadStartTime() {
|
| DCHECK_EQ(m_parserBlockingLoadStartTime, 0.0);
|
| m_parserBlockingLoadStartTime = monotonicallyIncreasingTime();
|
| }
|
|
|
| -// Returns true if SRI check passed.
|
| -static bool checkScriptResourceIntegrity(Resource* resource,
|
| - ScriptElementBase* element) {
|
| - DCHECK_EQ(resource->getType(), Resource::Script);
|
| - ScriptResource* scriptResource = toScriptResource(resource);
|
| - String integrityAttr = element->integrityAttributeValue();
|
| -
|
| - // It is possible to get back a script resource with integrity metadata
|
| - // for a request with an empty integrity attribute. In that case, the
|
| - // integrity check should be skipped, so this check ensures that the
|
| - // integrity attribute isn't empty in addition to checking if the
|
| - // resource has empty integrity metadata.
|
| - if (integrityAttr.isEmpty() || scriptResource->integrityMetadata().isEmpty())
|
| - return true;
|
| -
|
| - switch (scriptResource->integrityDisposition()) {
|
| - case ResourceIntegrityDisposition::Passed:
|
| - return true;
|
| -
|
| - case ResourceIntegrityDisposition::Failed:
|
| - // TODO(jww): This should probably also generate a console
|
| - // message identical to the one produced by
|
| - // CheckSubresourceIntegrity below. See https://crbug.com/585267.
|
| - return false;
|
| -
|
| - case ResourceIntegrityDisposition::NotChecked: {
|
| - if (!resource->resourceBuffer())
|
| - return true;
|
| -
|
| - bool passed = SubresourceIntegrity::CheckSubresourceIntegrity(
|
| - scriptResource->integrityMetadata(), element->document(),
|
| - resource->resourceBuffer()->data(),
|
| - resource->resourceBuffer()->size(), resource->url(), *resource);
|
| - scriptResource->setIntegrityDisposition(
|
| - passed ? ResourceIntegrityDisposition::Passed
|
| - : ResourceIntegrityDisposition::Failed);
|
| - return passed;
|
| - }
|
| - }
|
| -
|
| - NOTREACHED();
|
| - return true;
|
| -}
|
| -
|
| -void PendingScript::notifyFinished(Resource* resource) {
|
| - // The following SRI checks need to be here because, unfortunately, fetches
|
| - // are not done purely according to the Fetch spec. In particular,
|
| - // different requests for the same resource do not have different
|
| - // responses; the memory cache can (and will) return the exact same
|
| - // Resource object.
|
| - //
|
| - // For different requests, the same Resource object will be returned and
|
| - // will not be associated with the particular request. Therefore, when the
|
| - // body of the response comes in, there's no way to validate the integrity
|
| - // of the Resource object against a particular request (since there may be
|
| - // several pending requests all tied to the identical object, and the
|
| - // actual requests are not stored).
|
| - //
|
| - // In order to simulate the correct behavior, Blink explicitly does the SRI
|
| - // checks here, when a PendingScript tied to a particular request is
|
| - // finished (and in the case of a StyleSheet, at the point of execution),
|
| - // while having proper Fetch checks in the fetch module for use in the
|
| - // fetch JavaScript API. In a future world where the ResourceFetcher uses
|
| - // the Fetch algorithm, this should be fixed by having separate Response
|
| - // objects (perhaps attached to identical Resource objects) per request.
|
| - //
|
| - // See https://crbug.com/500701 for more information.
|
| - checkState();
|
| - if (m_element) {
|
| - m_integrityFailure = !checkScriptResourceIntegrity(resource, m_element);
|
| - }
|
| -
|
| - // If script streaming is in use, the client will be notified in
|
| - // streamingFinished.
|
| - if (m_streamer)
|
| - m_streamer->notifyFinished(resource);
|
| - else if (m_client)
|
| - m_client->pendingScriptFinished(this);
|
| -}
|
| -
|
| -void PendingScript::notifyAppendData(ScriptResource* resource) {
|
| - if (m_streamer)
|
| - m_streamer->notifyAppendData(resource);
|
| -}
|
| -
|
| DEFINE_TRACE(PendingScript) {
|
| visitor->trace(m_element);
|
| - visitor->trace(m_streamer);
|
| visitor->trace(m_client);
|
| - ResourceOwner<ScriptResource>::trace(visitor);
|
| - MemoryCoordinatorClient::trace(visitor);
|
| -}
|
| -
|
| -ClassicScript* PendingScript::getSource(const KURL& documentURL,
|
| - bool& errorOccurred) const {
|
| - checkState();
|
| -
|
| - errorOccurred = this->errorOccurred();
|
| - if (resource()) {
|
| - DCHECK(resource()->isLoaded());
|
| - if (m_streamer && !m_streamer->streamingSuppressed())
|
| - return ClassicScript::create(ScriptSourceCode(m_streamer, resource()));
|
| - return ClassicScript::create(ScriptSourceCode(resource()));
|
| - }
|
| -
|
| - return ClassicScript::create(ScriptSourceCode(
|
| - m_element->textContent(), documentURL, startingPosition()));
|
| -}
|
| -
|
| -void PendingScript::setStreamer(ScriptStreamer* streamer) {
|
| - DCHECK(!m_streamer);
|
| - DCHECK(!m_watchingForLoad);
|
| - m_streamer = streamer;
|
| - checkState();
|
| -}
|
| -
|
| -bool PendingScript::isReady() const {
|
| - checkState();
|
| - if (resource()) {
|
| - return resource()->isLoaded() && (!m_streamer || m_streamer->isFinished());
|
| - }
|
| -
|
| - return true;
|
| -}
|
| -
|
| -bool PendingScript::errorOccurred() const {
|
| - checkState();
|
| - if (resource())
|
| - return resource()->errorOccurred() || m_integrityFailure;
|
| -
|
| - return false;
|
| -}
|
| -
|
| -void PendingScript::onPurgeMemory() {
|
| - checkState();
|
| - if (!m_streamer)
|
| - return;
|
| - m_streamer->cancel();
|
| - m_streamer = nullptr;
|
| -}
|
| -
|
| -void PendingScript::startStreamingIfPossible(
|
| - Document* document,
|
| - ScriptStreamer::Type streamerType) {
|
| - if (!document->frame())
|
| - return;
|
| -
|
| - ScriptState* scriptState = toScriptStateForMainWorld(document->frame());
|
| - if (!scriptState)
|
| - return;
|
| -
|
| - ScriptStreamer::startStreaming(
|
| - this, streamerType, document->frame()->settings(), scriptState,
|
| - TaskRunnerHelper::get(TaskType::Networking, document));
|
| }
|
|
|
| } // namespace blink
|
|
|