Chromium Code Reviews| Index: content/browser/frame_host/navigation_handle_impl.cc |
| diff --git a/content/browser/frame_host/navigation_handle_impl.cc b/content/browser/frame_host/navigation_handle_impl.cc |
| index 30536bd306c76c4da490f9ea142210612c907d0c..4b92a9b1107b9afc578ff5c6a2facad8e730de06 100644 |
| --- a/content/browser/frame_host/navigation_handle_impl.cc |
| +++ b/content/browser/frame_host/navigation_handle_impl.cc |
| @@ -52,6 +52,15 @@ void NotifyAbandonedTransferNavigation(const GlobalRequestID& id) { |
| rdh->CancelRequest(id.child_id, id.request_id); |
| } |
| +// This is a helper method used in IsSelfReferentialURL. It checks if two |
| +// URLs are identical when the URL fragments are removed. |
| +bool EqualIgnoringFragmentIdentifier(const GURL& url1, const GURL& url2) { |
| + url::Replacements<char> replacements; |
| + replacements.ClearRef(); |
| + return (url1.ReplaceComponents(replacements) == |
| + url2.ReplaceComponents(replacements)); |
| +} |
| + |
| } // namespace |
| // static |
| @@ -445,6 +454,12 @@ void NavigationHandleImpl::WillStartRequest( |
| state_ = WILL_SEND_REQUEST; |
| complete_callback_ = callback; |
| + if (IsSelfReferentialURL()) { |
| + state_ = CANCELING; |
| + RunCompleteCallback(NavigationThrottle::CANCEL); |
| + return; |
| + } |
| + |
| RegisterNavigationThrottles(); |
| if (IsBrowserSideNavigationEnabled()) |
| @@ -482,6 +497,12 @@ void NavigationHandleImpl::WillRedirectRequest( |
| state_ = WILL_REDIRECT_REQUEST; |
| complete_callback_ = callback; |
| + if (IsSelfReferentialURL()) { |
| + state_ = CANCELING; |
| + RunCompleteCallback(NavigationThrottle::CANCEL); |
| + return; |
| + } |
| + |
| // Notify each throttle of the request. |
| NavigationThrottle::ThrottleCheckResult result = CheckWillRedirectRequest(); |
| @@ -812,4 +833,32 @@ void NavigationHandleImpl::RegisterNavigationThrottles() { |
| std::make_move_iterator(throttles_to_register.end())); |
| } |
| +bool NavigationHandleImpl::IsSelfReferentialURL() { |
| + // about: URLs should be exempted since they are reserved for other purposes |
| + // and cannot be the source of infinite recursion. See |
| + // https://crbug.com/341858 . |
| + if (url_.SchemeIs("about")) { |
|
alexmos
2017/01/19 23:45:53
nit: { not needed
davidsac (gone - try alexmos)
2017/01/24 01:16:38
Done.
|
| + return false; |
| + } |
| + |
| + // Browser-triggered navigations should be exempted. |
| + if (!is_renderer_initiated_) { |
|
alexmos
2017/01/19 23:45:53
nit: { not needed
davidsac (gone - try alexmos)
2017/01/24 01:16:38
Done.
|
| + return false; |
| + } |
| + |
| + // We allow one level of self-reference because some sites depend on that, |
| + // but we don't allow more than one. |
| + bool found_self_reference = false; |
| + for (const FrameTreeNode* node = frame_tree_node_->parent(); node; |
| + node = node->parent()) { |
| + if (EqualIgnoringFragmentIdentifier(node->current_url(), url_)) { |
| + if (found_self_reference) { |
|
alexmos
2017/01/19 23:45:53
nit: { not needed
davidsac (gone - try alexmos)
2017/01/24 01:16:38
Done.
|
| + return true; |
| + } |
| + found_self_reference = true; |
| + } |
| + } |
| + return false; |
| +} |
| + |
| } // namespace content |