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

Side by Side Diff: content/browser/frame_host/navigation_handle_impl.cc

Issue 2528813002: Fix Self-Referencing OOPIF Infinite Loop (Closed)
Patch Set: commented and cleaned up tests Created 3 years, 11 months 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 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 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/browser/frame_host/navigation_handle_impl.h" 5 #include "content/browser/frame_host/navigation_handle_impl.h"
6 6
7 #include <iterator> 7 #include <iterator>
8 8
9 #include "base/debug/dump_without_crashing.h" 9 #include "base/debug/dump_without_crashing.h"
10 #include "base/logging.h" 10 #include "base/logging.h"
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
45 NavigationThrottle::ThrottleCheckResult result) { 45 NavigationThrottle::ThrottleCheckResult result) {
46 *to_update = result; 46 *to_update = result;
47 } 47 }
48 48
49 void NotifyAbandonedTransferNavigation(const GlobalRequestID& id) { 49 void NotifyAbandonedTransferNavigation(const GlobalRequestID& id) {
50 DCHECK_CURRENTLY_ON(BrowserThread::IO); 50 DCHECK_CURRENTLY_ON(BrowserThread::IO);
51 if (ResourceDispatcherHostImpl* rdh = ResourceDispatcherHostImpl::Get()) 51 if (ResourceDispatcherHostImpl* rdh = ResourceDispatcherHostImpl::Get())
52 rdh->CancelRequest(id.child_id, id.request_id); 52 rdh->CancelRequest(id.child_id, id.request_id);
53 } 53 }
54 54
55 // This is a helper method used in IsSelfReferentialURL. It checks if two
56 // URLs are identical when the URL fragments are removed.
57 bool EqualIgnoringFragmentIdentifier(const GURL& url1, const GURL& url2) {
58 url::Replacements<char> replacements;
59 replacements.ClearRef();
60 return (url1.ReplaceComponents(replacements) ==
61 url2.ReplaceComponents(replacements));
dcheng 2017/01/28 01:51:44 We (or more precisely, csharrison@) has gone to a
davidsac (gone - try alexmos) 2017/02/10 18:44:26 Done.
62 }
63
55 } // namespace 64 } // namespace
56 65
57 // static 66 // static
58 std::unique_ptr<NavigationHandleImpl> NavigationHandleImpl::Create( 67 std::unique_ptr<NavigationHandleImpl> NavigationHandleImpl::Create(
59 const GURL& url, 68 const GURL& url,
60 FrameTreeNode* frame_tree_node, 69 FrameTreeNode* frame_tree_node,
61 bool is_renderer_initiated, 70 bool is_renderer_initiated,
62 bool is_same_page, 71 bool is_same_page,
63 const base::TimeTicks& navigation_start, 72 const base::TimeTicks& navigation_start,
64 int pending_nav_entry_id, 73 int pending_nav_entry_id,
(...skipping 373 matching lines...) Expand 10 before | Expand all | Expand 10 after
438 resource_request_body_ = resource_request_body; 447 resource_request_body_ = resource_request_body;
439 sanitized_referrer_ = sanitized_referrer; 448 sanitized_referrer_ = sanitized_referrer;
440 has_user_gesture_ = has_user_gesture; 449 has_user_gesture_ = has_user_gesture;
441 transition_ = transition; 450 transition_ = transition;
442 is_external_protocol_ = is_external_protocol; 451 is_external_protocol_ = is_external_protocol;
443 request_context_type_ = request_context_type; 452 request_context_type_ = request_context_type;
444 mixed_content_context_type_ = mixed_content_context_type; 453 mixed_content_context_type_ = mixed_content_context_type;
445 state_ = WILL_SEND_REQUEST; 454 state_ = WILL_SEND_REQUEST;
446 complete_callback_ = callback; 455 complete_callback_ = callback;
447 456
457 if (IsSelfReferentialURL()) {
458 state_ = CANCELING;
459 RunCompleteCallback(NavigationThrottle::CANCEL);
460 return;
461 }
462
448 RegisterNavigationThrottles(); 463 RegisterNavigationThrottles();
449 464
450 if (IsBrowserSideNavigationEnabled()) 465 if (IsBrowserSideNavigationEnabled())
451 navigation_ui_data_ = GetDelegate()->GetNavigationUIData(this); 466 navigation_ui_data_ = GetDelegate()->GetNavigationUIData(this);
452 467
453 // Notify each throttle of the request. 468 // Notify each throttle of the request.
454 NavigationThrottle::ThrottleCheckResult result = CheckWillStartRequest(); 469 NavigationThrottle::ThrottleCheckResult result = CheckWillStartRequest();
455 470
456 // If the navigation is not deferred, run the callback. 471 // If the navigation is not deferred, run the callback.
457 if (result != NavigationThrottle::DEFER) 472 if (result != NavigationThrottle::DEFER)
(...skipping 17 matching lines...) Expand all
475 response_headers_ = response_headers; 490 response_headers_ = response_headers;
476 connection_info_ = connection_info; 491 connection_info_ = connection_info;
477 was_redirected_ = true; 492 was_redirected_ = true;
478 redirect_chain_.push_back(new_url); 493 redirect_chain_.push_back(new_url);
479 if (new_method != "POST") 494 if (new_method != "POST")
480 resource_request_body_ = nullptr; 495 resource_request_body_ = nullptr;
481 496
482 state_ = WILL_REDIRECT_REQUEST; 497 state_ = WILL_REDIRECT_REQUEST;
483 complete_callback_ = callback; 498 complete_callback_ = callback;
484 499
500 if (IsSelfReferentialURL()) {
501 state_ = CANCELING;
502 RunCompleteCallback(NavigationThrottle::CANCEL);
503 return;
504 }
505
485 // Notify each throttle of the request. 506 // Notify each throttle of the request.
486 NavigationThrottle::ThrottleCheckResult result = CheckWillRedirectRequest(); 507 NavigationThrottle::ThrottleCheckResult result = CheckWillRedirectRequest();
487 508
488 // If the navigation is not deferred, run the callback. 509 // If the navigation is not deferred, run the callback.
489 if (result != NavigationThrottle::DEFER) 510 if (result != NavigationThrottle::DEFER)
490 RunCompleteCallback(result); 511 RunCompleteCallback(result);
491 } 512 }
492 513
493 void NavigationHandleImpl::WillProcessResponse( 514 void NavigationHandleImpl::WillProcessResponse(
494 RenderFrameHostImpl* render_frame_host, 515 RenderFrameHostImpl* render_frame_host,
(...skipping 310 matching lines...) Expand 10 before | Expand all | Expand 10 after
805 std::unique_ptr<content::NavigationThrottle> ancestor_throttle = 826 std::unique_ptr<content::NavigationThrottle> ancestor_throttle =
806 content::AncestorThrottle::MaybeCreateThrottleFor(this); 827 content::AncestorThrottle::MaybeCreateThrottleFor(this);
807 if (ancestor_throttle) 828 if (ancestor_throttle)
808 throttles_.push_back(std::move(ancestor_throttle)); 829 throttles_.push_back(std::move(ancestor_throttle));
809 830
810 throttles_.insert(throttles_.begin(), 831 throttles_.insert(throttles_.begin(),
811 std::make_move_iterator(throttles_to_register.begin()), 832 std::make_move_iterator(throttles_to_register.begin()),
812 std::make_move_iterator(throttles_to_register.end())); 833 std::make_move_iterator(throttles_to_register.end()));
813 } 834 }
814 835
836 bool NavigationHandleImpl::IsSelfReferentialURL() {
837 // about: URLs should be exempted since they are reserved for other purposes
838 // and cannot be the source of infinite recursion. See
839 // https://crbug.com/341858 .
840 if (url_.SchemeIs("about"))
841 return false;
842
843 // Browser-triggered navigations should be exempted.
844 if (!is_renderer_initiated_)
845 return false;
846
847 // We allow one level of self-reference because some sites depend on that,
848 // but we don't allow more than one.
849 bool found_self_reference = false;
850 for (const FrameTreeNode* node = frame_tree_node_->parent(); node;
851 node = node->parent()) {
852 if (EqualIgnoringFragmentIdentifier(node->current_url(), url_)) {
853 if (found_self_reference)
854 return true;
855 found_self_reference = true;
856 }
857 }
858 return false;
859 }
860
815 } // namespace content 861 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698