Commit bf471e5a authored by Nate Chapin's avatar Nate Chapin Committed by Commit Bot

Make DocumentInit take a DocumentLoader instead of a LocalFrame

This better communicates the responsible party for security checks.
You can definitely know which LocalFrame is associated with a
DocumentLoader, but a LocalFrame may be associated with multiple
DocumentLoaders.

Also, remove some dead code and inline a couple of methods.

Change-Id: I563a4259981bd61fd5a19b154cdd59f2aed46d24
Reviewed-on: https://chromium-review.googlesource.com/1159604
Commit-Queue: Nate Chapin <japhet@chromium.org>
Reviewed-by: default avatarDaniel Cheng <dcheng@chromium.org>
Cr-Commit-Position: refs/heads/master@{#580972}
parent f76159f4
...@@ -40,10 +40,11 @@ ...@@ -40,10 +40,11 @@
namespace blink { namespace blink {
// FIXME: Broken with OOPI. // FIXME: Broken with OOPI.
static Document* ParentDocument(LocalFrame* frame) { static Document* ParentDocument(DocumentLoader* loader) {
DCHECK(frame); DCHECK(loader);
DCHECK(loader->GetFrame());
Element* owner_element = frame->DeprecatedLocalOwner(); Element* owner_element = loader->GetFrame()->DeprecatedLocalOwner();
if (!owner_element) if (!owner_element)
return nullptr; return nullptr;
return &owner_element->GetDocument(); return &owner_element->GetDocument();
...@@ -71,33 +72,37 @@ DocumentInit::DocumentInit(const DocumentInit&) = default; ...@@ -71,33 +72,37 @@ DocumentInit::DocumentInit(const DocumentInit&) = default;
DocumentInit::~DocumentInit() = default; DocumentInit::~DocumentInit() = default;
bool DocumentInit::ShouldSetURL() const { bool DocumentInit::ShouldSetURL() const {
LocalFrame* frame = FrameForSecurityContext(); DocumentLoader* loader = MasterDocumentLoader();
return (frame && frame->Tree().Parent()) || !url_.IsEmpty(); return (loader && loader->GetFrame()->Tree().Parent()) || !url_.IsEmpty();
} }
bool DocumentInit::ShouldTreatURLAsSrcdocDocument() const { bool DocumentInit::ShouldTreatURLAsSrcdocDocument() const {
return parent_document_ && return parent_document_ &&
frame_->Loader().ShouldTreatURLAsSrcdocDocument(url_); document_loader_->GetFrame()->Loader().ShouldTreatURLAsSrcdocDocument(
} url_);
}
LocalFrame* DocumentInit::FrameForSecurityContext() const {
if (frame_) DocumentLoader* DocumentInit::MasterDocumentLoader() const {
return frame_; if (document_loader_)
if (imports_controller_) return document_loader_;
return imports_controller_->Master()->GetFrame(); if (imports_controller_) {
return imports_controller_->Master()
->GetFrame()
->Loader()
.GetDocumentLoader();
}
return nullptr; return nullptr;
} }
SandboxFlags DocumentInit::GetSandboxFlags() const { SandboxFlags DocumentInit::GetSandboxFlags() const {
DCHECK(FrameForSecurityContext()); DCHECK(MasterDocumentLoader());
FrameLoader* loader = &FrameForSecurityContext()->Loader(); DocumentLoader* loader = MasterDocumentLoader();
SandboxFlags flags = loader->EffectiveSandboxFlags(); SandboxFlags flags = loader->GetFrame()->Loader().EffectiveSandboxFlags();
// If the load was blocked by CSP, force the Document's origin to be unique, // If the load was blocked by CSP, force the Document's origin to be unique,
// so that the blocked document appears to be a normal cross-origin document's // so that the blocked document appears to be a normal cross-origin document's
// load per CSP spec: https://www.w3.org/TR/CSP3/#directive-frame-ancestors. // load per CSP spec: https://www.w3.org/TR/CSP3/#directive-frame-ancestors.
if (loader->GetDocumentLoader() && if (loader->WasBlockedAfterCSP()) {
loader->GetDocumentLoader()->WasBlockedAfterCSP()) {
flags |= kSandboxOrigin; flags |= kSandboxOrigin;
} }
...@@ -105,48 +110,50 @@ SandboxFlags DocumentInit::GetSandboxFlags() const { ...@@ -105,48 +110,50 @@ SandboxFlags DocumentInit::GetSandboxFlags() const {
} }
WebInsecureRequestPolicy DocumentInit::GetInsecureRequestPolicy() const { WebInsecureRequestPolicy DocumentInit::GetInsecureRequestPolicy() const {
DCHECK(FrameForSecurityContext()); DCHECK(MasterDocumentLoader());
return FrameForSecurityContext()->Loader().GetInsecureRequestPolicy(); Frame* parent_frame = MasterDocumentLoader()->GetFrame()->Tree().Parent();
if (!parent_frame)
return kLeaveInsecureRequestsAlone;
return parent_frame->GetSecurityContext()->GetInsecureRequestPolicy();
} }
SecurityContext::InsecureNavigationsSet* SecurityContext::InsecureNavigationsSet*
DocumentInit::InsecureNavigationsToUpgrade() const { DocumentInit::InsecureNavigationsToUpgrade() const {
DCHECK(FrameForSecurityContext()); DCHECK(MasterDocumentLoader());
return FrameForSecurityContext()->Loader().InsecureNavigationsToUpgrade(); Frame* parent_frame = MasterDocumentLoader()->GetFrame()->Tree().Parent();
if (!parent_frame)
return nullptr;
return parent_frame->GetSecurityContext()->InsecureNavigationsToUpgrade();
} }
bool DocumentInit::IsHostedInReservedIPRange() const { bool DocumentInit::IsHostedInReservedIPRange() const {
if (LocalFrame* frame = FrameForSecurityContext()) { if (DocumentLoader* loader = MasterDocumentLoader()) {
if (DocumentLoader* loader = if (!loader->GetResponse().RemoteIPAddress().IsEmpty()) {
frame->Loader().GetProvisionalDocumentLoader() return NetworkUtils::IsReservedIPAddress(
? frame->Loader().GetProvisionalDocumentLoader() loader->GetResponse().RemoteIPAddress());
: frame->Loader().GetDocumentLoader()) {
if (!loader->GetResponse().RemoteIPAddress().IsEmpty())
return NetworkUtils::IsReservedIPAddress(
loader->GetResponse().RemoteIPAddress());
} }
} }
return false; return false;
} }
Settings* DocumentInit::GetSettings() const { Settings* DocumentInit::GetSettings() const {
DCHECK(FrameForSecurityContext()); DCHECK(MasterDocumentLoader());
return FrameForSecurityContext()->GetSettings(); return MasterDocumentLoader()->GetFrame()->GetSettings();
} }
KURL DocumentInit::ParentBaseURL() const { DocumentInit& DocumentInit::WithDocumentLoader(DocumentLoader* loader) {
return parent_document_->BaseURL(); DCHECK(!document_loader_);
}
DocumentInit& DocumentInit::WithFrame(LocalFrame* frame) {
DCHECK(!frame_);
DCHECK(!imports_controller_); DCHECK(!imports_controller_);
frame_ = frame; document_loader_ = loader;
if (frame_) if (document_loader_)
parent_document_ = ParentDocument(frame_); parent_document_ = ParentDocument(document_loader_);
return *this; return *this;
} }
LocalFrame* DocumentInit::GetFrame() const {
return document_loader_ ? document_loader_->GetFrame() : nullptr;
}
DocumentInit& DocumentInit::WithContextDocument(Document* context_document) { DocumentInit& DocumentInit::WithContextDocument(Document* context_document) {
DCHECK(!context_document_); DCHECK(!context_document_);
context_document_ = context_document; context_document_ = context_document;
......
...@@ -41,6 +41,7 @@ ...@@ -41,6 +41,7 @@
namespace blink { namespace blink {
class Document; class Document;
class DocumentLoader;
class LocalFrame; class LocalFrame;
class HTMLImportsController; class HTMLImportsController;
class Settings; class Settings;
...@@ -56,7 +57,7 @@ class CORE_EXPORT DocumentInit final { ...@@ -56,7 +57,7 @@ class CORE_EXPORT DocumentInit final {
// Example: // Example:
// //
// DocumentInit init = DocumentInit::Create() // DocumentInit init = DocumentInit::Create()
// .WithFrame(frame) // .WithDocumentLoader(loader)
// .WithContextDocument(context_document) // .WithContextDocument(context_document)
// .WithURL(url); // .WithURL(url);
// Document* document = Document::Create(init); // Document* document = Document::Create(init);
...@@ -70,21 +71,18 @@ class CORE_EXPORT DocumentInit final { ...@@ -70,21 +71,18 @@ class CORE_EXPORT DocumentInit final {
return imports_controller_; return imports_controller_;
} }
bool HasSecurityContext() const { return FrameForSecurityContext(); } bool HasSecurityContext() const { return MasterDocumentLoader(); }
bool ShouldTreatURLAsSrcdocDocument() const; bool ShouldTreatURLAsSrcdocDocument() const;
bool ShouldSetURL() const; bool ShouldSetURL() const;
bool IsSeamlessAllowedFor(Document* child) const;
SandboxFlags GetSandboxFlags() const; SandboxFlags GetSandboxFlags() const;
bool IsHostedInReservedIPRange() const; bool IsHostedInReservedIPRange() const;
WebInsecureRequestPolicy GetInsecureRequestPolicy() const; WebInsecureRequestPolicy GetInsecureRequestPolicy() const;
SecurityContext::InsecureNavigationsSet* InsecureNavigationsToUpgrade() const; SecurityContext::InsecureNavigationsSet* InsecureNavigationsToUpgrade() const;
KURL ParentBaseURL() const;
LocalFrame* OwnerFrame() const;
Settings* GetSettings() const; Settings* GetSettings() const;
DocumentInit& WithFrame(LocalFrame*); DocumentInit& WithDocumentLoader(DocumentLoader*);
LocalFrame* GetFrame() const { return frame_; } LocalFrame* GetFrame() const;
// Used by the DOMImplementation and DOMParser to pass their parent Document // Used by the DOMImplementation and DOMParser to pass their parent Document
// so that the created Document will return the Document when the // so that the created Document will return the Document when the
...@@ -106,9 +104,13 @@ class CORE_EXPORT DocumentInit final { ...@@ -106,9 +104,13 @@ class CORE_EXPORT DocumentInit final {
private: private:
DocumentInit(HTMLImportsController*); DocumentInit(HTMLImportsController*);
LocalFrame* FrameForSecurityContext() const; // For a Document associated directly with a frame, this will be the
// DocumentLoader driving the commit. For an import, XSLT-generated
// document, etc., it will be the DocumentLoader that drove the commit
// of its owning Document.
DocumentLoader* MasterDocumentLoader() const;
Member<LocalFrame> frame_; Member<DocumentLoader> document_loader_;
Member<Document> parent_document_; Member<Document> parent_document_;
Member<HTMLImportsController> imports_controller_; Member<HTMLImportsController> imports_controller_;
......
...@@ -1378,7 +1378,9 @@ void LocalFrame::ForceSynchronousDocumentInstall( ...@@ -1378,7 +1378,9 @@ void LocalFrame::ForceSynchronousDocumentInstall(
GetDocument()->Shutdown(); GetDocument()->Shutdown();
DomWindow()->InstallNewDocument( DomWindow()->InstallNewDocument(
mime_type, DocumentInit::Create().WithFrame(this), false); mime_type,
DocumentInit::Create().WithDocumentLoader(loader_.GetDocumentLoader()),
false);
loader_.StateMachine()->AdvanceTo( loader_.StateMachine()->AdvanceTo(
FrameLoaderStateMachine::kCommittedFirstRealLoad); FrameLoaderStateMachine::kCommittedFirstRealLoad);
......
...@@ -105,7 +105,8 @@ void ImageDocumentTest::CreateDocumentWithoutLoadingImage(int view_width, ...@@ -105,7 +105,8 @@ void ImageDocumentTest::CreateDocumentWithoutLoadingImage(int view_width,
LocalFrame& frame = dummy_page_holder_->GetFrame(); LocalFrame& frame = dummy_page_holder_->GetFrame();
frame.GetDocument()->Shutdown(); frame.GetDocument()->Shutdown();
DocumentInit init = DocumentInit::Create().WithFrame(&frame); DocumentInit init = DocumentInit::Create().WithDocumentLoader(
frame.Loader().GetDocumentLoader());
frame.DomWindow()->InstallNewDocument("image/jpeg", init, false); frame.DomWindow()->InstallNewDocument("image/jpeg", init, false);
} }
......
...@@ -1091,7 +1091,7 @@ void DocumentLoader::InstallNewDocument( ...@@ -1091,7 +1091,7 @@ void DocumentLoader::InstallNewDocument(
Document* document = frame_->DomWindow()->InstallNewDocument( Document* document = frame_->DomWindow()->InstallNewDocument(
mime_type, mime_type,
DocumentInit::Create() DocumentInit::Create()
.WithFrame(frame_) .WithDocumentLoader(this)
.WithURL(url) .WithURL(url)
.WithOwnerDocument(owner_document) .WithOwnerDocument(owner_document)
.WithNewRegistrationContext(), .WithNewRegistrationContext(),
......
...@@ -1601,24 +1601,6 @@ SandboxFlags FrameLoader::EffectiveSandboxFlags() const { ...@@ -1601,24 +1601,6 @@ SandboxFlags FrameLoader::EffectiveSandboxFlags() const {
return flags; return flags;
} }
WebInsecureRequestPolicy FrameLoader::GetInsecureRequestPolicy() const {
Frame* parent_frame = frame_->Tree().Parent();
if (!parent_frame)
return kLeaveInsecureRequestsAlone;
return parent_frame->GetSecurityContext()->GetInsecureRequestPolicy();
}
SecurityContext::InsecureNavigationsSet*
FrameLoader::InsecureNavigationsToUpgrade() const {
DCHECK(frame_);
Frame* parent_frame = frame_->Tree().Parent();
if (!parent_frame)
return nullptr;
return parent_frame->GetSecurityContext()->InsecureNavigationsToUpgrade();
}
void FrameLoader::ModifyRequestForCSP(ResourceRequest& resource_request, void FrameLoader::ModifyRequestForCSP(ResourceRequest& resource_request,
Document* origin_document) const { Document* origin_document) const {
if (RuntimeEnabledFeatures::EmbedderCSPEnforcementEnabled() && if (RuntimeEnabledFeatures::EmbedderCSPEnforcementEnabled() &&
......
...@@ -165,8 +165,6 @@ class CORE_EXPORT FrameLoader final { ...@@ -165,8 +165,6 @@ class CORE_EXPORT FrameLoader final {
void ForceSandboxFlags(SandboxFlags flags) { forced_sandbox_flags_ |= flags; } void ForceSandboxFlags(SandboxFlags flags) { forced_sandbox_flags_ |= flags; }
SandboxFlags EffectiveSandboxFlags() const; SandboxFlags EffectiveSandboxFlags() const;
WebInsecureRequestPolicy GetInsecureRequestPolicy() const;
SecurityContext::InsecureNavigationsSet* InsecureNavigationsToUpgrade() const;
void ModifyRequestForCSP(ResourceRequest&, Document*) const; void ModifyRequestForCSP(ResourceRequest&, Document*) const;
Frame* Opener(); Frame* Opener();
......
...@@ -144,7 +144,8 @@ TEST_F(WindowPerformanceTest, NavigateAway) { ...@@ -144,7 +144,8 @@ TEST_F(WindowPerformanceTest, NavigateAway) {
EXPECT_TRUE(ObservingLongTasks()); EXPECT_TRUE(ObservingLongTasks());
// Simulate navigation commit. // Simulate navigation commit.
DocumentInit init = DocumentInit::Create().WithFrame(GetFrame()); DocumentInit init = DocumentInit::Create().WithDocumentLoader(
GetFrame()->Loader().GetDocumentLoader());
GetDocument()->Shutdown(); GetDocument()->Shutdown();
GetFrame()->SetDOMWindow(LocalDOMWindow::Create(*GetFrame())); GetFrame()->SetDOMWindow(LocalDOMWindow::Create(*GetFrame()));
GetFrame()->DomWindow()->InstallNewDocument(AtomicString(), init, false); GetFrame()->DomWindow()->InstallNewDocument(AtomicString(), init, false);
...@@ -178,7 +179,7 @@ TEST(PerformanceLifetimeTest, SurviveContextSwitch) { ...@@ -178,7 +179,7 @@ TEST(PerformanceLifetimeTest, SurviveContextSwitch) {
page_holder->GetDocument().Shutdown(); page_holder->GetDocument().Shutdown();
page_holder->GetFrame().DomWindow()->InstallNewDocument( page_holder->GetFrame().DomWindow()->InstallNewDocument(
AtomicString(), AtomicString(),
DocumentInit::Create().WithFrame(&page_holder->GetFrame()), false); DocumentInit::Create().WithDocumentLoader(document_loader), false);
EXPECT_EQ(perf, DOMWindowPerformance::performance( EXPECT_EQ(perf, DOMWindowPerformance::performance(
*page_holder->GetFrame().DomWindow())); *page_holder->GetFrame().DomWindow()));
......
...@@ -70,7 +70,11 @@ Document* XSLTProcessor::CreateDocumentFromSource( ...@@ -70,7 +70,11 @@ Document* XSLTProcessor::CreateDocumentFromSource(
if (owner_document == source_node) if (owner_document == source_node)
url = owner_document->Url(); url = owner_document->Url();
DocumentInit init = DocumentInit::Create().WithFrame(frame).WithURL(url); DocumentInit init =
DocumentInit::Create()
.WithDocumentLoader(frame ? frame->Loader().GetDocumentLoader()
: nullptr)
.WithURL(url);
String document_source = source_string; String document_source = source_string;
bool force_xhtml = source_mime_type == "text/plain"; bool force_xhtml = source_mime_type == "text/plain";
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment