| Index: content/browser/frame_host/navigator_impl.cc
|
| diff --git a/content/browser/frame_host/navigator_impl.cc b/content/browser/frame_host/navigator_impl.cc
|
| index 70fcb63429bc7ea5c499e74a128beea25ddb096c..e218d8745318b3c685ae0df9bd5af67f36357969 100644
|
| --- a/content/browser/frame_host/navigator_impl.cc
|
| +++ b/content/browser/frame_host/navigator_impl.cc
|
| @@ -245,7 +245,7 @@ void NavigatorImpl::DidFailProvisionalLoadWithError(
|
| }
|
|
|
| // Discard the pending navigation entry if needed.
|
| - DiscardPendingEntryOnFailureIfNeeded(render_frame_host->navigation_handle());
|
| + DiscardPendingEntryIfNeeded(render_frame_host->navigation_handle());
|
|
|
| if (delegate_) {
|
| delegate_->DidFailProvisionalLoadWithError(
|
| @@ -951,7 +951,7 @@ void NavigatorImpl::FailedNavigation(FrameTreeNode* frame_tree_node,
|
| NavigationRequest* navigation_request = frame_tree_node->navigation_request();
|
| DCHECK(navigation_request);
|
|
|
| - DiscardPendingEntryOnFailureIfNeeded(navigation_request->navigation_handle());
|
| + DiscardPendingEntryIfNeeded(navigation_request->navigation_handle());
|
|
|
| // If the request was canceled by the user do not show an error page.
|
| if (error_code == net::ERR_ABORTED) {
|
| @@ -1009,6 +1009,46 @@ NavigationHandleImpl* NavigatorImpl::GetNavigationHandleForFrameHost(
|
| return render_frame_host->navigation_handle();
|
| }
|
|
|
| +void NavigatorImpl::DiscardPendingEntryIfNeeded(NavigationHandleImpl* handle) {
|
| + // Racy conditions can cause a fail message to arrive after its corresponding
|
| + // pending entry has been replaced by another navigation. If
|
| + // |DiscardPendingEntry| is called in this case, then the completely valid
|
| + // entry for the new navigation would be discarded. See crbug.com/513742. To
|
| + // catch this case, the current pending entry is compared against the current
|
| + // navigation handle's entry id, which should correspond to the failed load.
|
| + NavigationEntry* pending_entry = controller_->GetPendingEntry();
|
| + bool pending_matches_fail_msg =
|
| + handle && pending_entry &&
|
| + handle->pending_nav_entry_id() == pending_entry->GetUniqueID();
|
| + if (!pending_matches_fail_msg)
|
| + return;
|
| +
|
| + // We usually clear the pending entry when it fails, so that an arbitrary URL
|
| + // isn't left visible above a committed page. This must be enforced when the
|
| + // pending entry isn't visible (e.g., renderer-initiated navigations) to
|
| + // prevent URL spoofs for in-page navigations that don't go through
|
| + // DidStartProvisionalLoadForFrame.
|
| + //
|
| + // However, we do preserve the pending entry in some cases, such as on the
|
| + // initial navigation of an unmodified blank tab. We also allow the delegate
|
| + // to say when it's safe to leave aborted URLs in the omnibox, to let the
|
| + // user edit the URL and try again. This may be useful in cases that the
|
| + // committed page cannot be attacker-controlled. In these cases, we still
|
| + // allow the view to clear the pending entry and typed URL if the user
|
| + // requests (e.g., hitting Escape with focus in the address bar).
|
| + //
|
| + // Note: don't touch the transient entry, since an interstitial may exist.
|
| + bool should_preserve_entry = controller_->IsUnmodifiedBlankTab() ||
|
| + delegate_->ShouldPreserveAbortedURLs();
|
| + if (pending_entry != controller_->GetVisibleEntry() ||
|
| + !should_preserve_entry) {
|
| + controller_->DiscardPendingEntry(true);
|
| +
|
| + // Also force the UI to refresh.
|
| + controller_->delegate()->NotifyNavigationStateChanged(INVALIDATE_TYPE_URL);
|
| + }
|
| +}
|
| +
|
| // PlzNavigate
|
| void NavigatorImpl::RequestNavigation(FrameTreeNode* frame_tree_node,
|
| const GURL& dest_url,
|
| @@ -1169,45 +1209,4 @@ void NavigatorImpl::DidStartMainFrameNavigation(
|
| }
|
| }
|
|
|
| -void NavigatorImpl::DiscardPendingEntryOnFailureIfNeeded(
|
| - NavigationHandleImpl* handle) {
|
| - // Racy conditions can cause a fail message to arrive after its corresponding
|
| - // pending entry has been replaced by another navigation. If
|
| - // |DiscardPendingEntry| is called in this case, then the completely valid
|
| - // entry for the new navigation would be discarded. See crbug.com/513742. To
|
| - // catch this case, the current pending entry is compared against the current
|
| - // navigation handle's entry id, which should correspond to the failed load.
|
| - NavigationEntry* pending_entry = controller_->GetPendingEntry();
|
| - bool pending_matches_fail_msg =
|
| - handle && pending_entry &&
|
| - handle->pending_nav_entry_id() == pending_entry->GetUniqueID();
|
| - if (!pending_matches_fail_msg)
|
| - return;
|
| -
|
| - // We usually clear the pending entry when it fails, so that an arbitrary URL
|
| - // isn't left visible above a committed page. This must be enforced when the
|
| - // pending entry isn't visible (e.g., renderer-initiated navigations) to
|
| - // prevent URL spoofs for in-page navigations that don't go through
|
| - // DidStartProvisionalLoadForFrame.
|
| - //
|
| - // However, we do preserve the pending entry in some cases, such as on the
|
| - // initial navigation of an unmodified blank tab. We also allow the delegate
|
| - // to say when it's safe to leave aborted URLs in the omnibox, to let the
|
| - // user edit the URL and try again. This may be useful in cases that the
|
| - // committed page cannot be attacker-controlled. In these cases, we still
|
| - // allow the view to clear the pending entry and typed URL if the user
|
| - // requests (e.g., hitting Escape with focus in the address bar).
|
| - //
|
| - // Note: don't touch the transient entry, since an interstitial may exist.
|
| - bool should_preserve_entry = controller_->IsUnmodifiedBlankTab() ||
|
| - delegate_->ShouldPreserveAbortedURLs();
|
| - if (pending_entry != controller_->GetVisibleEntry() ||
|
| - !should_preserve_entry) {
|
| - controller_->DiscardPendingEntry(true);
|
| -
|
| - // Also force the UI to refresh.
|
| - controller_->delegate()->NotifyNavigationStateChanged(INVALIDATE_TYPE_URL);
|
| - }
|
| -}
|
| -
|
| } // namespace content
|
|
|