Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(947)

Side by Side Diff: content/renderer/render_frame_impl.cc

Issue 2454233002: Fix history nav to a script-injected about:blank frame. (Closed)
Patch Set: Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/renderer/render_frame_impl.h" 5 #include "content/renderer/render_frame_impl.h"
6 6
7 #include <map> 7 #include <map>
8 #include <string> 8 #include <string>
9 #include <utility> 9 #include <utility>
10 #include <vector> 10 #include <vector>
(...skipping 4959 matching lines...) Expand 10 before | Expand all | Expand 10 after
4970 if (is_content_initiated && IsTopLevelNavigation(frame_) && 4970 if (is_content_initiated && IsTopLevelNavigation(frame_) &&
4971 render_view_->renderer_preferences_ 4971 render_view_->renderer_preferences_
4972 .browser_handles_all_top_level_requests) { 4972 .browser_handles_all_top_level_requests) {
4973 OpenURL(url, IsHttpPost(info.urlRequest), 4973 OpenURL(url, IsHttpPost(info.urlRequest),
4974 GetRequestBodyForWebURLRequest(info.urlRequest), referrer, 4974 GetRequestBodyForWebURLRequest(info.urlRequest), referrer,
4975 info.defaultPolicy, info.replacesCurrentHistoryItem, false); 4975 info.defaultPolicy, info.replacesCurrentHistoryItem, false);
4976 return blink::WebNavigationPolicyIgnore; // Suppress the load here. 4976 return blink::WebNavigationPolicyIgnore; // Suppress the load here.
4977 } 4977 }
4978 4978
4979 // In OOPIF-enabled modes, back/forward navigations in newly created subframes 4979 // In OOPIF-enabled modes, back/forward navigations in newly created subframes
4980 // should be sent to the browser if there is a matching FrameNavigationEntry. 4980 // should be sent to the browser if there is a matching FrameNavigationEntry,
4981 // If this frame isn't on the list of unique names that have history items, 4981 // and if it isn't just staying at about:blank. If this frame isn't in the
4982 // fall back to loading the default url. (We remove each name as we encounter 4982 // map of unique names that have history items, or if it's staying at the
4983 // it, because it will only be used once as the frame is created.) 4983 // initial about:blank URL, fall back to loading the default url. (We remove
4984 // each name as we encounter it, because it will only be used once as the
4985 // frame is created.)
4984 if (SiteIsolationPolicy::UseSubframeNavigationEntries() && 4986 if (SiteIsolationPolicy::UseSubframeNavigationEntries() &&
4985 info.isHistoryNavigationInNewChildFrame && is_content_initiated && 4987 info.isHistoryNavigationInNewChildFrame && is_content_initiated &&
4986 frame_->parent() && 4988 frame_->parent()) {
4987 RenderFrameImpl::FromWebFrame(frame_->parent()) 4989 // Check whether the browser has a history item for this frame that isn't
4988 ->history_subframe_unique_names_.erase( 4990 // just staying at the initial about:blank document.
4989 frame_->uniqueName().utf8()) > 0) { 4991 bool should_ask_browser = false;
4990 // Don't do this if |info| also says it is a client redirect, in which case 4992 RenderFrameImpl* parent = RenderFrameImpl::FromWebFrame(frame_->parent());
4991 // JavaScript on the page is trying to interrupt the history navigation. 4993 const auto& iter = parent->history_subframe_unique_names_.find(
4992 if (!info.isClientRedirect) { 4994 frame_->uniqueName().utf8());
4993 OpenURL(url, IsHttpPost(info.urlRequest), 4995 if (iter != parent->history_subframe_unique_names_.end()) {
4994 GetRequestBodyForWebURLRequest(info.urlRequest), referrer, 4996 bool history_item_is_about_blank = iter->second;
4995 info.defaultPolicy, info.replacesCurrentHistoryItem, true); 4997 should_ask_browser =
4996 // Suppress the load in Blink but mark the frame as loading. 4998 !history_item_is_about_blank || url != GURL(url::kAboutBlankURL);
4997 return blink::WebNavigationPolicyHandledByClient; 4999 parent->history_subframe_unique_names_.erase(frame_->uniqueName().utf8());
4998 } else { 5000 }
4999 // Client redirects during an initial history load should attempt to 5001
5000 // cancel the history navigation. They will create a provisional document 5002 if (should_ask_browser) {
5001 // loader, causing the history load to be ignored in NavigateInternal, and 5003 // Don't do this if |info| also says it is a client redirect, in which
5002 // this IPC will try to cancel any cross-process history load. 5004 // case JavaScript on the page is trying to interrupt the history
5003 Send(new FrameHostMsg_CancelInitialHistoryLoad(routing_id_)); 5005 // navigation.
5006 if (!info.isClientRedirect) {
5007 OpenURL(url, IsHttpPost(info.urlRequest),
5008 GetRequestBodyForWebURLRequest(info.urlRequest), referrer,
5009 info.defaultPolicy, info.replacesCurrentHistoryItem, true);
5010 // Suppress the load in Blink but mark the frame as loading.
5011 return blink::WebNavigationPolicyHandledByClient;
5012 } else {
5013 // Client redirects during an initial history load should attempt to
5014 // cancel the history navigation. They will create a provisional
5015 // document loader, causing the history load to be ignored in
5016 // NavigateInternal, and this IPC will try to cancel any cross-process
5017 // history load.
5018 Send(new FrameHostMsg_CancelInitialHistoryLoad(routing_id_));
5019 }
5004 } 5020 }
5005 } 5021 }
5006 5022
5007 // Use the frame's original request's URL rather than the document's URL for 5023 // Use the frame's original request's URL rather than the document's URL for
5008 // subsequent checks. For a popup, the document's URL may become the opener 5024 // subsequent checks. For a popup, the document's URL may become the opener
5009 // window's URL if the opener has called document.write(). 5025 // window's URL if the opener has called document.write().
5010 // See http://crbug.com/93517. 5026 // See http://crbug.com/93517.
5011 GURL old_url(frame_->dataSource()->request().url()); 5027 GURL old_url(frame_->dataSource()->request().url());
5012 5028
5013 // Detect when we're crossing a permission-based boundary (e.g. into or out of 5029 // Detect when we're crossing a permission-based boundary (e.g. into or out of
(...skipping 566 matching lines...) Expand 10 before | Expand all | Expand 10 after
5580 item_for_history_navigation.documentSequenceNumber()) { 5596 item_for_history_navigation.documentSequenceNumber()) {
5581 history_load_type = blink::WebHistoryDifferentDocumentLoad; 5597 history_load_type = blink::WebHistoryDifferentDocumentLoad;
5582 NOTREACHED(); 5598 NOTREACHED();
5583 } 5599 }
5584 } 5600 }
5585 5601
5586 // If this navigation is to a history item for a new child frame, we may 5602 // If this navigation is to a history item for a new child frame, we may
5587 // want to ignore it in some cases. If a Javascript navigation (i.e., 5603 // want to ignore it in some cases. If a Javascript navigation (i.e.,
5588 // client redirect) interrupted it and has either been scheduled, 5604 // client redirect) interrupted it and has either been scheduled,
5589 // started loading, or has committed, we should ignore the history item. 5605 // started loading, or has committed, we should ignore the history item.
5590 // Similarly, if the history item just says to stay on about:blank,
5591 // don't load it again, which might clobber injected content.
5592 bool interrupted_by_client_redirect = 5606 bool interrupted_by_client_redirect =
5593 frame_->isNavigationScheduledWithin(0) || 5607 frame_->isNavigationScheduledWithin(0) ||
5594 frame_->provisionalDataSource() || 5608 frame_->provisionalDataSource() ||
5595 !current_history_item_.isNull(); 5609 !current_history_item_.isNull();
5596 bool staying_at_about_blank =
5597 current_history_item_.isNull() &&
5598 item_for_history_navigation.urlString() == url::kAboutBlankURL;
5599 if (staying_at_about_blank) {
5600 // TODO(creis): We should avoid the need to go to the browser and back
5601 // when loading about:blank as a history item, which we can do by
5602 // sending a subtree of same-process history items when navigating a
5603 // frame back/forward (see https://crbug.com/639842).
5604 //
5605 // Until then, we need to fake a DidStopLoading, since there's no easy
5606 // way to generate a commit for the initial empty document at this
5607 // point in time.
5608 //
5609 // Note that the stopLoading call may run script which might delete
5610 // this frame, so return immediately if this frame is no longer valid.
5611 base::WeakPtr<RenderFrameImpl> weak_this = weak_factory_.GetWeakPtr();
5612 frame_->stopLoading();
5613 if (!weak_this)
5614 return;
5615 }
5616 if (request_params.is_history_navigation_in_new_child && 5610 if (request_params.is_history_navigation_in_new_child &&
5617 (interrupted_by_client_redirect || staying_at_about_blank)) { 5611 interrupted_by_client_redirect) {
5618 should_load_request = false; 5612 should_load_request = false;
5619 has_history_navigation_in_frame = false; 5613 has_history_navigation_in_frame = false;
5620 } 5614 }
5621 5615
5622 // Generate the request for the load from the HistoryItem. 5616 // Generate the request for the load from the HistoryItem.
5623 // PlzNavigate: use the data sent by the browser for the url and the 5617 // PlzNavigate: use the data sent by the browser for the url and the
5624 // HTTP state. The restoration of user state such as scroll position 5618 // HTTP state. The restoration of user state such as scroll position
5625 // will be done based on the history item during the load. 5619 // will be done based on the history item during the load.
5626 if (!browser_side_navigation && should_load_request) { 5620 if (!browser_side_navigation && should_load_request) {
5627 request = frame_->requestFromHistoryItem(item_for_history_navigation, 5621 request = frame_->requestFromHistoryItem(item_for_history_navigation,
(...skipping 771 matching lines...) Expand 10 before | Expand all | Expand 10 after
6399 // event target. Potentially a Pepper plugin will receive the event. 6393 // event target. Potentially a Pepper plugin will receive the event.
6400 // In order to tell whether a plugin gets the last mouse event and which it 6394 // In order to tell whether a plugin gets the last mouse event and which it
6401 // is, we set |pepper_last_mouse_event_target_| to null here. If a plugin gets 6395 // is, we set |pepper_last_mouse_event_target_| to null here. If a plugin gets
6402 // the event, it will notify us via DidReceiveMouseEvent() and set itself as 6396 // the event, it will notify us via DidReceiveMouseEvent() and set itself as
6403 // |pepper_last_mouse_event_target_|. 6397 // |pepper_last_mouse_event_target_|.
6404 pepper_last_mouse_event_target_ = nullptr; 6398 pepper_last_mouse_event_target_ = nullptr;
6405 #endif 6399 #endif
6406 } 6400 }
6407 6401
6408 } // namespace content 6402 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698