Index: Source/WebCore/loader/FrameLoader.cpp |
=================================================================== |
--- Source/WebCore/loader/FrameLoader.cpp (revision 112895) |
+++ Source/WebCore/loader/FrameLoader.cpp (working copy) |
@@ -293,7 +293,7 @@ |
// FIXME: Find a good spot for these. |
ASSERT(submission->data()); |
ASSERT(submission->state()); |
- ASSERT(submission->state()->sourceFrame() == m_frame); |
+ ASSERT(!submission->state()->sourceDocument()->frame() || submission->state()->sourceDocument()->frame() == m_frame); |
if (!m_frame->page()) |
return; |
@@ -312,7 +312,7 @@ |
} |
Frame* targetFrame = m_frame->tree()->find(submission->target()); |
- if (!shouldAllowNavigation(targetFrame)) |
+ if (!submission->state()->sourceDocument()->canNavigate(targetFrame)) |
return; |
if (!targetFrame) { |
if (!DOMWindow::allowPopUp(m_frame) && !ScriptController::processingUserGesture()) |
@@ -1170,7 +1170,9 @@ |
// FIXME: It's possible this targetFrame will not be the same frame that was targeted by the actual |
// load if frame names have changed. |
- Frame* sourceFrame = formState ? formState->sourceFrame() : m_frame; |
+ Frame* sourceFrame = formState ? formState->sourceDocument()->frame() : m_frame; |
+ if (!sourceFrame) |
+ sourceFrame = m_frame; |
Frame* targetFrame = sourceFrame->loader()->findFrameForNavigation(request.frameName()); |
if (targetFrame && targetFrame != sourceFrame) { |
if (Page* page = targetFrame->page()) |
@@ -1496,86 +1498,6 @@ |
loadWithDocumentLoader(loader.get(), endToEndReload ? FrameLoadTypeReloadFromOrigin : FrameLoadTypeReload, 0); |
} |
-static bool canAccessAncestor(const SecurityOrigin* activeSecurityOrigin, Frame* targetFrame) |
-{ |
- // targetFrame can be NULL when we're trying to navigate a top-level frame |
- // that has a NULL opener. |
- if (!targetFrame) |
- return false; |
- |
- const bool isLocalActiveOrigin = activeSecurityOrigin->isLocal(); |
- for (Frame* ancestorFrame = targetFrame; ancestorFrame; ancestorFrame = ancestorFrame->tree()->parent()) { |
- Document* ancestorDocument = ancestorFrame->document(); |
- if (!ancestorDocument) |
- return true; |
- |
- const SecurityOrigin* ancestorSecurityOrigin = ancestorDocument->securityOrigin(); |
- if (activeSecurityOrigin->canAccess(ancestorSecurityOrigin)) |
- return true; |
- |
- // Allow file URL descendant navigation even when allowFileAccessFromFileURLs is false. |
- if (isLocalActiveOrigin && ancestorSecurityOrigin->isLocal()) |
- return true; |
- } |
- |
- return false; |
-} |
- |
-bool FrameLoader::shouldAllowNavigation(Frame* targetFrame) const |
-{ |
- // The navigation change is safe if the active frame is: |
- // - in the same security origin as the target or one of the target's |
- // ancestors. |
- // |
- // Or the target frame is: |
- // - a top-level frame in the frame hierarchy and the active frame can |
- // navigate the target frame's opener per above or it is the opener of |
- // the target frame. |
- |
- if (!targetFrame) |
- return true; |
- |
- // Performance optimization. |
- if (m_frame == targetFrame) |
- return true; |
- |
- // Let a frame navigate the top-level window that contains it. This is |
- // important to allow because it lets a site "frame-bust" (escape from a |
- // frame created by another web site). |
- if (!isDocumentSandboxed(m_frame, SandboxTopNavigation) && targetFrame == m_frame->tree()->top()) |
- return true; |
- |
- // A sandboxed frame can only navigate itself and its descendants. |
- if (isDocumentSandboxed(m_frame, SandboxNavigation) && !targetFrame->tree()->isDescendantOf(m_frame)) |
- return false; |
- |
- // Let a frame navigate its opener if the opener is a top-level window. |
- if (!targetFrame->tree()->parent() && m_frame->loader()->opener() == targetFrame) |
- return true; |
- |
- Document* activeDocument = m_frame->document(); |
- ASSERT(activeDocument); |
- const SecurityOrigin* activeSecurityOrigin = activeDocument->securityOrigin(); |
- |
- // For top-level windows, check the opener. |
- if (!targetFrame->tree()->parent() && canAccessAncestor(activeSecurityOrigin, targetFrame->loader()->opener())) |
- return true; |
- |
- // In general, check the frame's ancestors. |
- if (canAccessAncestor(activeSecurityOrigin, targetFrame)) |
- return true; |
- |
- Document* targetDocument = targetFrame->document(); |
- // FIXME: this error message should contain more specifics of why the navigation change is not allowed. |
- String message = "Unsafe JavaScript attempt to initiate a navigation change for frame with URL " + |
- targetDocument->url().string() + " from frame with URL " + activeDocument->url().string() + ".\n"; |
- |
- // FIXME: should we print to the console of the activeFrame as well? |
- targetFrame->domWindow()->printErrorMessage(message); |
- |
- return false; |
-} |
- |
void FrameLoader::stopAllLoaders(ClearProvisionalItemPolicy clearProvisionalItemPolicy) |
{ |
ASSERT(!m_frame->document() || !m_frame->document()->inPageCache()); |
@@ -3054,7 +2976,10 @@ |
Frame* FrameLoader::findFrameForNavigation(const AtomicString& name) |
{ |
Frame* frame = m_frame->tree()->find(name); |
- if (!shouldAllowNavigation(frame)) |
+ // FIXME: We calling canNavigate on the Document that's requesting the |
+ // navigation, not based on the document that happens to be displayed in |
+ // this Frame. |
+ if (!m_frame->document()->canNavigate(frame)) |
return 0; |
return frame; |
} |
@@ -3317,7 +3242,7 @@ |
if (!request.frameName().isEmpty() && request.frameName() != "_blank") { |
Frame* frame = lookupFrame->tree()->find(request.frameName()); |
- if (frame && openerFrame->loader()->shouldAllowNavigation(frame)) { |
+ if (frame && openerFrame->document()->canNavigate(frame)) { |
if (Page* page = frame->page()) |
page->chrome()->focus(); |
created = false; |