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

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

Issue 2528813002: Fix Self-Referencing OOPIF Infinite Loop (Closed)
Patch Set: make EqualIgnoringFragmentIdentifier more efficient Created 3 years, 10 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 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
47 NavigationThrottle::ThrottleCheckResult result) { 47 NavigationThrottle::ThrottleCheckResult result) {
48 *to_update = result; 48 *to_update = result;
49 } 49 }
50 50
51 void NotifyAbandonedTransferNavigation(const GlobalRequestID& id) { 51 void NotifyAbandonedTransferNavigation(const GlobalRequestID& id) {
52 DCHECK_CURRENTLY_ON(BrowserThread::IO); 52 DCHECK_CURRENTLY_ON(BrowserThread::IO);
53 if (ResourceDispatcherHostImpl* rdh = ResourceDispatcherHostImpl::Get()) 53 if (ResourceDispatcherHostImpl* rdh = ResourceDispatcherHostImpl::Get())
54 rdh->CancelRequest(id.child_id, id.request_id); 54 rdh->CancelRequest(id.child_id, id.request_id);
55 } 55 }
56 56
57 // This is a helper method used in IsSelfReferentialURL. It checks if two
58 // URLs are identical when the URL fragments are removed.
59 bool EqualIgnoringFragmentIdentifier(const GURL& a, const GURL& b) {
nasko 2017/02/07 19:51:20 This is actually being implemented in GURL itself
davidsac (gone - try alexmos) 2017/02/10 18:44:26 Acknowledged.
60 // Compute the length of each URL without its ref. Note that the reference
61 // begin (if it exists) points to the character *after* the '#', so we need
62 // to subtract one.
63 int aLength = a.spec().length();
64 if (a.parsed_for_possibly_invalid_spec().ref.len >= 0)
65 aLength = a.parsed_for_possibly_invalid_spec().ref.begin - 1;
66
67 int bLength = b.spec().length();
68 if (b.parsed_for_possibly_invalid_spec().ref.len >= 0)
69 bLength = b.parsed_for_possibly_invalid_spec().ref.begin - 1;
70
71 if (aLength != bLength)
72 return false;
73
74 const std::string& aString = a.spec();
75 const std::string& bString = b.spec();
76 // FIXME: Abstraction this into a function in WTFString.h.
77 for (int i = 0; i < aLength; ++i) {
78 if (aString[i] != bString[i])
79 return false;
80 }
81 return true;
82 }
83
57 } // namespace 84 } // namespace
58 85
59 // static 86 // static
60 std::unique_ptr<NavigationHandleImpl> NavigationHandleImpl::Create( 87 std::unique_ptr<NavigationHandleImpl> NavigationHandleImpl::Create(
61 const GURL& url, 88 const GURL& url,
62 const std::vector<GURL>& redirect_chain, 89 const std::vector<GURL>& redirect_chain,
63 FrameTreeNode* frame_tree_node, 90 FrameTreeNode* frame_tree_node,
64 bool is_renderer_initiated, 91 bool is_renderer_initiated,
65 bool is_same_page, 92 bool is_same_page,
66 const base::TimeTicks& navigation_start, 93 const base::TimeTicks& navigation_start,
(...skipping 433 matching lines...) Expand 10 before | Expand all | Expand 10 after
500 Referrer(redirect_chain_[0], sanitized_referrer.policy); 527 Referrer(redirect_chain_[0], sanitized_referrer.policy);
501 } else { 528 } else {
502 sanitized_referrer_ = sanitized_referrer; 529 sanitized_referrer_ = sanitized_referrer;
503 } 530 }
504 is_external_protocol_ = is_external_protocol; 531 is_external_protocol_ = is_external_protocol;
505 request_context_type_ = request_context_type; 532 request_context_type_ = request_context_type;
506 mixed_content_context_type_ = mixed_content_context_type; 533 mixed_content_context_type_ = mixed_content_context_type;
507 state_ = WILL_SEND_REQUEST; 534 state_ = WILL_SEND_REQUEST;
508 complete_callback_ = callback; 535 complete_callback_ = callback;
509 536
537 if (IsSelfReferentialURL()) {
538 state_ = CANCELING;
539 RunCompleteCallback(NavigationThrottle::CANCEL);
540 return;
541 }
542
510 RegisterNavigationThrottles(); 543 RegisterNavigationThrottles();
511 544
512 if (IsBrowserSideNavigationEnabled()) 545 if (IsBrowserSideNavigationEnabled())
513 navigation_ui_data_ = GetDelegate()->GetNavigationUIData(this); 546 navigation_ui_data_ = GetDelegate()->GetNavigationUIData(this);
514 547
515 // Notify each throttle of the request. 548 // Notify each throttle of the request.
516 NavigationThrottle::ThrottleCheckResult result = CheckWillStartRequest(); 549 NavigationThrottle::ThrottleCheckResult result = CheckWillStartRequest();
517 550
518 // If the navigation is not deferred, run the callback. 551 // If the navigation is not deferred, run the callback.
519 if (result != NavigationThrottle::DEFER) 552 if (result != NavigationThrottle::DEFER)
(...skipping 22 matching lines...) Expand all
542 response_headers_ = response_headers; 575 response_headers_ = response_headers;
543 connection_info_ = connection_info; 576 connection_info_ = connection_info;
544 was_redirected_ = true; 577 was_redirected_ = true;
545 redirect_chain_.push_back(new_url); 578 redirect_chain_.push_back(new_url);
546 if (new_method != "POST") 579 if (new_method != "POST")
547 resource_request_body_ = nullptr; 580 resource_request_body_ = nullptr;
548 581
549 state_ = WILL_REDIRECT_REQUEST; 582 state_ = WILL_REDIRECT_REQUEST;
550 complete_callback_ = callback; 583 complete_callback_ = callback;
551 584
585 if (IsSelfReferentialURL()) {
586 state_ = CANCELING;
587 RunCompleteCallback(NavigationThrottle::CANCEL);
588 return;
589 }
590
552 // Notify each throttle of the request. 591 // Notify each throttle of the request.
553 NavigationThrottle::ThrottleCheckResult result = CheckWillRedirectRequest(); 592 NavigationThrottle::ThrottleCheckResult result = CheckWillRedirectRequest();
554 593
555 // If the navigation is not deferred, run the callback. 594 // If the navigation is not deferred, run the callback.
556 if (result != NavigationThrottle::DEFER) 595 if (result != NavigationThrottle::DEFER)
557 RunCompleteCallback(result); 596 RunCompleteCallback(result);
558 } 597 }
559 598
560 void NavigationHandleImpl::WillProcessResponse( 599 void NavigationHandleImpl::WillProcessResponse(
561 RenderFrameHostImpl* render_frame_host, 600 RenderFrameHostImpl* render_frame_host,
(...skipping 316 matching lines...) Expand 10 before | Expand all | Expand 10 after
878 std::unique_ptr<content::NavigationThrottle> ancestor_throttle = 917 std::unique_ptr<content::NavigationThrottle> ancestor_throttle =
879 content::AncestorThrottle::MaybeCreateThrottleFor(this); 918 content::AncestorThrottle::MaybeCreateThrottleFor(this);
880 if (ancestor_throttle) 919 if (ancestor_throttle)
881 throttles_.push_back(std::move(ancestor_throttle)); 920 throttles_.push_back(std::move(ancestor_throttle));
882 921
883 throttles_.insert(throttles_.begin(), 922 throttles_.insert(throttles_.begin(),
884 std::make_move_iterator(throttles_to_register.begin()), 923 std::make_move_iterator(throttles_to_register.begin()),
885 std::make_move_iterator(throttles_to_register.end())); 924 std::make_move_iterator(throttles_to_register.end()));
886 } 925 }
887 926
927 bool NavigationHandleImpl::IsSelfReferentialURL() {
928 // about: URLs should be exempted since they are reserved for other purposes
929 // and cannot be the source of infinite recursion. See
930 // https://crbug.com/341858 .
931 if (url_.SchemeIs("about"))
932 return false;
933
934 // Browser-triggered navigations should be exempted.
935 if (!is_renderer_initiated_)
936 return false;
937
938 // We allow one level of self-reference because some sites depend on that,
939 // but we don't allow more than one.
940 bool found_self_reference = false;
941 for (const FrameTreeNode* node = frame_tree_node_->parent(); node;
942 node = node->parent()) {
943 if (EqualIgnoringFragmentIdentifier(node->current_url(), url_)) {
944 if (found_self_reference)
945 return true;
946 found_self_reference = true;
947 }
948 }
949 return false;
950 }
951
888 } // namespace content 952 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698