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

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

Issue 1048963002: Fix incorrect creation of duplicate navigation entries for repeated page load failures. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@committype3
Patch Set: works Created 5 years, 8 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 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/browser/frame_host/navigation_controller_impl.h" 5 #include "content/browser/frame_host/navigation_controller_impl.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/command_line.h" 8 #include "base/command_line.h"
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/metrics/histogram.h" 10 #include "base/metrics/histogram.h"
(...skipping 778 matching lines...) Expand 10 before | Expand all | Expand 10 after
789 details->previous_entry_index = -1; 789 details->previous_entry_index = -1;
790 } 790 }
791 791
792 // If we have a pending entry at this point, it should have a SiteInstance. 792 // If we have a pending entry at this point, it should have a SiteInstance.
793 // Restored entries start out with a null SiteInstance, but we should have 793 // Restored entries start out with a null SiteInstance, but we should have
794 // assigned one in NavigateToPendingEntry. 794 // assigned one in NavigateToPendingEntry.
795 DCHECK(pending_entry_index_ == -1 || pending_entry_->site_instance()); 795 DCHECK(pending_entry_index_ == -1 || pending_entry_->site_instance());
796 796
797 // If we are doing a cross-site reload, we need to replace the existing 797 // If we are doing a cross-site reload, we need to replace the existing
798 // navigation entry, not add another entry to the history. This has the side 798 // navigation entry, not add another entry to the history. This has the side
799 // effect of removing forward browsing history, if such existed. 799 // effect of removing forward browsing history, if such existed. Or if we are
800 // Or if we are doing a cross-site redirect navigation, 800 // doing a cross-site redirect navigation, we will do a similar thing.
801 // we will do a similar thing. 801 if (params.url_is_unreachable) {
Charlie Reis 2015/04/03 20:59:46 Should this be params.url_is_unreachable && failed
Avi (use Gerrit) 2015/04/06 19:38:16 I'm trying to come up with a scenario in which the
Charlie Reis 2015/04/06 20:48:10 The multiple frames thing is a different issue, an
Avi (use Gerrit) 2015/04/06 21:30:14 Yeah, I got it. The pending entry isn't guaranteed
802 details->did_replace_entry = 802 details->did_replace_entry = failed_pending_entry_.get() &&
803 pending_entry_ && pending_entry_->should_replace_entry(); 803 failed_pending_entry_->should_replace_entry();
804 } else {
805 details->did_replace_entry = pending_entry_ &&
806 pending_entry_->should_replace_entry();
807 }
804 808
805 // Do navigation-type specific actions. These will make and commit an entry. 809 // Do navigation-type specific actions. These will make and commit an entry.
806 details->type = ClassifyNavigation(rfh, params); 810 details->type = ClassifyNavigation(rfh, params);
807 811
808 // is_in_page must be computed before the entry gets committed. 812 // is_in_page must be computed before the entry gets committed.
809 details->is_in_page = AreURLsInPageNavigation(rfh->GetLastCommittedURL(), 813 details->is_in_page = AreURLsInPageNavigation(rfh->GetLastCommittedURL(),
810 params.url, params.was_within_same_page, rfh); 814 params.url, params.was_within_same_page, rfh);
811 815
812 switch (details->type) { 816 switch (details->type) {
813 case NAVIGATION_TYPE_NEW_PAGE: 817 case NAVIGATION_TYPE_NEW_PAGE:
(...skipping 937 matching lines...) Expand 10 before | Expand all | Expand 10 after
1751 RestoreType type) { 1755 RestoreType type) {
1752 DCHECK(selected_index >= 0 && selected_index < GetEntryCount()); 1756 DCHECK(selected_index >= 0 && selected_index < GetEntryCount());
1753 ConfigureEntriesForRestore(&entries_, type); 1757 ConfigureEntriesForRestore(&entries_, type);
1754 1758
1755 SetMaxRestoredPageID(static_cast<int32>(GetEntryCount())); 1759 SetMaxRestoredPageID(static_cast<int32>(GetEntryCount()));
1756 1760
1757 last_committed_entry_index_ = selected_index; 1761 last_committed_entry_index_ = selected_index;
1758 } 1762 }
1759 1763
1760 void NavigationControllerImpl::DiscardNonCommittedEntriesInternal() { 1764 void NavigationControllerImpl::DiscardNonCommittedEntriesInternal() {
1761 DiscardPendingEntry(); 1765 DiscardPendingEntry(false);
1762 DiscardTransientEntry(); 1766 DiscardTransientEntry();
1763 } 1767 }
1764 1768
1765 void NavigationControllerImpl::DiscardPendingEntry() { 1769 void NavigationControllerImpl::DiscardPendingEntry(bool was_failure) {
1766 // It is not safe to call DiscardPendingEntry while NavigateToEntry is in 1770 // It is not safe to call DiscardPendingEntry while NavigateToEntry is in
1767 // progress, since this will cause a use-after-free. (We only allow this 1771 // progress, since this will cause a use-after-free. (We only allow this
1768 // when the tab is being destroyed for shutdown, since it won't return to 1772 // when the tab is being destroyed for shutdown, since it won't return to
1769 // NavigateToEntry in that case.) http://crbug.com/347742. 1773 // NavigateToEntry in that case.) http://crbug.com/347742.
1770 CHECK(!in_navigate_to_pending_entry_ || delegate_->IsBeingDestroyed()); 1774 CHECK(!in_navigate_to_pending_entry_ || delegate_->IsBeingDestroyed());
1771 1775
1772 if (pending_entry_index_ == -1) 1776 if (pending_entry_index_ == -1) {
1773 delete pending_entry_; 1777 if (was_failure)
1778 failed_pending_entry_.reset(pending_entry_);
1779 else
1780 delete pending_entry_;
1781 }
1782
1774 pending_entry_ = NULL; 1783 pending_entry_ = NULL;
1775 pending_entry_index_ = -1; 1784 pending_entry_index_ = -1;
1785 if (!was_failure)
1786 failed_pending_entry_.reset();
Charlie Reis 2015/04/03 20:59:46 You've confirmed this gets cleared after the error
Avi (use Gerrit) 2015/04/06 19:38:16 Yes, this gets cleared by the DiscardNonCommittedE
1776 } 1787 }
1777 1788
1778 void NavigationControllerImpl::DiscardTransientEntry() { 1789 void NavigationControllerImpl::DiscardTransientEntry() {
1779 if (transient_entry_index_ == -1) 1790 if (transient_entry_index_ == -1)
1780 return; 1791 return;
1781 entries_.erase(entries_.begin() + transient_entry_index_); 1792 entries_.erase(entries_.begin() + transient_entry_index_);
1782 if (last_committed_entry_index_ > transient_entry_index_) 1793 if (last_committed_entry_index_ > transient_entry_index_)
1783 last_committed_entry_index_--; 1794 last_committed_entry_index_--;
1784 transient_entry_index_ = -1; 1795 transient_entry_index_ = -1;
1785 } 1796 }
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
1830 } 1841 }
1831 } 1842 }
1832 } 1843 }
1833 1844
1834 void NavigationControllerImpl::SetGetTimestampCallbackForTest( 1845 void NavigationControllerImpl::SetGetTimestampCallbackForTest(
1835 const base::Callback<base::Time()>& get_timestamp_callback) { 1846 const base::Callback<base::Time()>& get_timestamp_callback) {
1836 get_timestamp_callback_ = get_timestamp_callback; 1847 get_timestamp_callback_ = get_timestamp_callback;
1837 } 1848 }
1838 1849
1839 } // namespace content 1850 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698