Index: content/browser/frame_host/render_frame_host_manager_browsertest.cc |
diff --git a/content/browser/frame_host/render_frame_host_manager_browsertest.cc b/content/browser/frame_host/render_frame_host_manager_browsertest.cc |
index 9f6afe7d49c3d3c06e49058371152ddd905970e6..652dd91e0cd8625dca936634d95054a1c0e73bce 100644 |
--- a/content/browser/frame_host/render_frame_host_manager_browsertest.cc |
+++ b/content/browser/frame_host/render_frame_host_manager_browsertest.cc |
@@ -3166,38 +3166,42 @@ IN_PROC_BROWSER_TEST_F(RenderFrameHostManagerTest, CoReferencingFrames) { |
IN_PROC_BROWSER_TEST_F(RenderFrameHostManagerTest, |
SelfReferencingFragmentFrames) { |
StartEmbeddedServer(); |
- GURL url( |
- embedded_test_server()->GetURL("a.com", "/page_with_iframe.html#123")); |
+ GURL url(embedded_test_server()->GetURL("a.com", "/title1.html#123")); |
EXPECT_TRUE(NavigateToURL(shell(), url)); |
WebContentsImpl* web_contents = |
static_cast<WebContentsImpl*>(shell()->web_contents()); |
FrameTreeNode* root = web_contents->GetFrameTree()->root(); |
- FrameTreeNode* child = root->child_at(0); |
- // ExecuteScript is used here and once more below because it is important to |
- // use renderer-initiated navigations since browser-initiated navigations are |
- // bypassed in the self-referencing navigation check. |
- TestFrameNavigationObserver observer1(child); |
- EXPECT_TRUE( |
- ExecuteScript(child, "location.href = '" + url.spec() + "456" + "';")); |
- observer1.Wait(); |
+ GURL url2(url.spec() + "456"); |
+ const char kSetupIframe[] = |
+ "var f = document.createElement('iframe');" |
+ "f.src = '%s';" |
+ "document.body.appendChild(f);"; |
+ { |
+ TestNavigationManager manager(web_contents, url2); |
+ std::string script = base::StringPrintf(kSetupIframe, url2.spec().c_str()); |
+ EXPECT_TRUE(ExecuteScript(root, script)); |
+ manager.WaitForNavigationFinished(); |
+ } |
- FrameTreeNode* grandchild = child->child_at(0); |
- GURL expected_url(embedded_test_server()->GetURL("a.com", "/title1.html")); |
- EXPECT_EQ(expected_url, grandchild->current_url()); |
+ FrameTreeNode* child = root->child_at(0); |
+ EXPECT_TRUE(WaitForLoadStop(web_contents)); |
+ EXPECT_EQ(url2, child->current_url()); |
// This navigation should be blocked. |
- GURL blocked_url(embedded_test_server()->GetURL( |
- "a.com", "/page_with_iframe.html#123456789")); |
- TestNavigationManager manager(web_contents, blocked_url); |
- EXPECT_TRUE(ExecuteScript(grandchild, |
- "location.href = '" + blocked_url.spec() + "';")); |
- // Wait for WillStartRequest and verify that the request is aborted before |
- // starting it. |
- EXPECT_FALSE(manager.WaitForRequestStart()); |
- WaitForLoadStop(web_contents); |
+ GURL url3(url2.spec() + "789"); |
+ { |
+ TestNavigationManager manager(web_contents, url3); |
+ std::string script = base::StringPrintf(kSetupIframe, url3.spec().c_str()); |
+ EXPECT_TRUE(ExecuteScript(child, script)); |
+ |
+ // Wait for WillStartRequest and verify that the request is aborted before |
+ // starting it. |
+ EXPECT_FALSE(manager.WaitForRequestStart()); |
+ WaitForLoadStop(web_contents); |
+ } |
// The FrameTree contains two successful instances of the url plus an |
// unsuccessfully-navigated third instance with a blank URL. |
@@ -3208,8 +3212,8 @@ IN_PROC_BROWSER_TEST_F(RenderFrameHostManagerTest, |
"Where A = http://a.com/", |
FrameTreeVisualizer().DepictFrameTree(root)); |
- // The URL of the grandchild has not changed. |
- EXPECT_EQ(expected_url, grandchild->current_url()); |
+ EXPECT_EQ(GURL(), child->child_at(0)->current_url()); |
+ EXPECT_FALSE(child->child_at(0)->has_committed_real_load()); |
} |
// Ensure that loading a page with a meta refresh iframe does not cause an |
@@ -3280,4 +3284,53 @@ IN_PROC_BROWSER_TEST_F(RenderFrameHostManagerTest, |
EXPECT_EQ(child->current_url(), first_url); |
} |
+// Ensures that POST requests bypass self-referential URL checks. See |
+// https://crbug.com/710008. |
+IN_PROC_BROWSER_TEST_F(RenderFrameHostManagerTest, |
+ SelfReferencingFramesWithPOST) { |
+ StartEmbeddedServer(); |
+ GURL url(embedded_test_server()->GetURL("a.com", "/page_with_iframe.html")); |
+ EXPECT_TRUE(NavigateToURL(shell(), url)); |
+ |
+ WebContentsImpl* web_contents = |
+ static_cast<WebContentsImpl*>(shell()->web_contents()); |
+ |
+ FrameTreeNode* root = web_contents->GetFrameTree()->root(); |
+ FrameTreeNode* child = root->child_at(0); |
+ |
+ GURL child_url(embedded_test_server()->GetURL("a.com", "/title1.html")); |
+ EXPECT_EQ(url, root->current_url()); |
+ EXPECT_EQ(child_url, child->current_url()); |
+ |
+ // Navigate the child frame to the same URL as parent via POST. |
+ std::string script = |
+ "var f = document.createElement('form');\n" |
+ "f.method = 'POST';\n" |
+ "f.action = '/page_with_iframe.html';\n" |
+ "document.body.appendChild(f);\n" |
+ "f.submit();"; |
+ { |
+ TestFrameNavigationObserver observer(child); |
+ EXPECT_TRUE(ExecuteScript(child, script)); |
+ observer.Wait(); |
+ } |
+ |
+ FrameTreeNode* grandchild = child->child_at(0); |
+ EXPECT_EQ(url, child->current_url()); |
+ EXPECT_EQ(child_url, grandchild->current_url()); |
+ |
+ // Now navigate the grandchild to the same URL as its two ancestors. This |
+ // should be allowed since it uses POST; it was blocked prior to |
+ // fixing https://crbug.com/710008. |
+ { |
+ TestFrameNavigationObserver observer(grandchild); |
+ EXPECT_TRUE(ExecuteScript(grandchild, script)); |
+ observer.Wait(); |
+ } |
+ |
+ EXPECT_EQ(url, grandchild->current_url()); |
+ ASSERT_EQ(1U, grandchild->child_count()); |
+ EXPECT_EQ(child_url, grandchild->child_at(0)->current_url()); |
+} |
+ |
} // namespace content |