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

Side by Side Diff: content/browser/tab_contents/navigation_controller.cc

Issue 6709056: Avoid corrupting the pending_entry when an unexpected navigation commits. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Clear pending entry Created 9 years, 9 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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/tab_contents/navigation_controller.h" 5 #include "content/browser/tab_contents/navigation_controller.h"
6 6
7 #include "base/file_util.h" 7 #include "base/file_util.h"
8 #include "base/logging.h" 8 #include "base/logging.h"
9 #include "base/string_util.h" 9 #include "base/string_util.h"
10 #include "base/time.h" 10 #include "base/time.h"
(...skipping 484 matching lines...) Expand 10 before | Expand all | Expand 10 after
495 495
496 // Save the previous state before we clobber it. 496 // Save the previous state before we clobber it.
497 if (GetLastCommittedEntry()) { 497 if (GetLastCommittedEntry()) {
498 details->previous_url = GetLastCommittedEntry()->url(); 498 details->previous_url = GetLastCommittedEntry()->url();
499 details->previous_entry_index = last_committed_entry_index(); 499 details->previous_entry_index = last_committed_entry_index();
500 } else { 500 } else {
501 details->previous_url = GURL(); 501 details->previous_url = GURL();
502 details->previous_entry_index = -1; 502 details->previous_entry_index = -1;
503 } 503 }
504 504
505 // Assign the current site instance to any pending entry, so we can find it 505 // The pending_entry has no SiteInstance when we are restoring an entry. We
506 // later by calling GetEntryIndexWithPageID. We only care about this if the 506 // must fill it in here so we can find the entry later by calling
507 // pending entry is an existing navigation and not a new one (or else we 507 // GetEntryIndexWithPageID. In all other cases, the SiteInstance should be
508 // wouldn't care about finding it with GetEntryIndexWithPageID). 508 // assigned already and we shouldn't change it.
509 // 509 if (pending_entry_index_ >= 0 && !pending_entry_->site_instance()) {
brettw 2011/03/22 05:39:18 Is there a unit test covering this case?
Charlie Reis 2011/03/22 17:04:32 Yes: NavigationControllerTest.RestoreNavigate chec
510 // TODO(brettw) this seems slightly bogus as we don't really know if the 510 DCHECK(pending_entry_->restore_type() != NavigationEntry::RESTORE_NONE);
511 // pending entry is what this navigation is for. There is a similar TODO
512 // w.r.t. the pending entry in RendererDidNavigateToNewPage.
513 if (pending_entry_index_ >= 0) {
514 pending_entry_->set_site_instance(tab_contents_->GetSiteInstance()); 511 pending_entry_->set_site_instance(tab_contents_->GetSiteInstance());
515 pending_entry_->set_restore_type(NavigationEntry::RESTORE_NONE); 512 pending_entry_->set_restore_type(NavigationEntry::RESTORE_NONE);
516 } 513 }
517 514
518 // is_in_page must be computed before the entry gets committed. 515 // is_in_page must be computed before the entry gets committed.
519 details->is_in_page = IsURLInPageNavigation(params.url); 516 details->is_in_page = IsURLInPageNavigation(params.url);
520 517
521 // Do navigation-type specific actions. These will make and commit an entry. 518 // Do navigation-type specific actions. These will make and commit an entry.
522 details->type = ClassifyNavigation(params); 519 details->type = ClassifyNavigation(params);
523 520
(...skipping 24 matching lines...) Expand all
548 default: 545 default:
549 NOTREACHED(); 546 NOTREACHED();
550 } 547 }
551 548
552 // All committed entries should have nonempty content state so WebKit doesn't 549 // All committed entries should have nonempty content state so WebKit doesn't
553 // get confused when we go back to them (see the function for details). 550 // get confused when we go back to them (see the function for details).
554 DCHECK(!params.content_state.empty()); 551 DCHECK(!params.content_state.empty());
555 NavigationEntry* active_entry = GetActiveEntry(); 552 NavigationEntry* active_entry = GetActiveEntry();
556 active_entry->set_content_state(params.content_state); 553 active_entry->set_content_state(params.content_state);
557 554
555 // The active entry's SiteInstance should match our SiteInstance.
556 DCHECK(active_entry->site_instance() == tab_contents_->GetSiteInstance());
557
558 // WebKit doesn't set the "auto" transition on meta refreshes properly (bug 558 // WebKit doesn't set the "auto" transition on meta refreshes properly (bug
559 // 1051891) so we manually set it for redirects which we normally treat as 559 // 1051891) so we manually set it for redirects which we normally treat as
560 // "non-user-gestures" where we want to update stuff after navigations. 560 // "non-user-gestures" where we want to update stuff after navigations.
561 // 561 //
562 // Note that the redirect check also checks for a pending entry to 562 // Note that the redirect check also checks for a pending entry to
563 // differentiate real redirects from browser initiated navigations to a 563 // differentiate real redirects from browser initiated navigations to a
564 // redirected entry. This happens when you hit back to go to a page that was 564 // redirected entry. This happens when you hit back to go to a page that was
565 // the destination of a redirect, we don't want to treat it as a redirect 565 // the destination of a redirect, we don't want to treat it as a redirect
566 // even though that's what its transition will be. See bug 1117048. 566 // even though that's what its transition will be. See bug 1117048.
567 // 567 //
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
692 entries->push_back(entry); 692 entries->push_back(entry);
693 } 693 }
694 } 694 }
695 695
696 void NavigationController::RendererDidNavigateToNewPage( 696 void NavigationController::RendererDidNavigateToNewPage(
697 const ViewHostMsg_FrameNavigate_Params& params, bool* did_replace_entry) { 697 const ViewHostMsg_FrameNavigate_Params& params, bool* did_replace_entry) {
698 NavigationEntry* new_entry; 698 NavigationEntry* new_entry;
699 if (pending_entry_) { 699 if (pending_entry_) {
700 // TODO(brettw) this assumes that the pending entry is appropriate for the 700 // TODO(brettw) this assumes that the pending entry is appropriate for the
701 // new page that was just loaded. I don't think this is necessarily the 701 // new page that was just loaded. I don't think this is necessarily the
702 // case! We should have some more tracking to know for sure. This goes along 702 // case! We should have some more tracking to know for sure.
703 // with a similar TODO at the top of RendererDidNavigate where we blindly
704 // set the site instance on the pending entry.
705 new_entry = new NavigationEntry(*pending_entry_); 703 new_entry = new NavigationEntry(*pending_entry_);
706 704
707 // Don't use the page type from the pending entry. Some interstitial page 705 // Don't use the page type from the pending entry. Some interstitial page
708 // may have set the type to interstitial. Once we commit, however, the page 706 // may have set the type to interstitial. Once we commit, however, the page
709 // type must always be normal. 707 // type must always be normal.
710 new_entry->set_page_type(NORMAL_PAGE); 708 new_entry->set_page_type(NORMAL_PAGE);
711 } else { 709 } else {
712 new_entry = new NavigationEntry; 710 new_entry = new NavigationEntry;
713 } 711 }
714 712
(...skipping 30 matching lines...) Expand all
745 if (entry->update_virtual_url_with_url()) 743 if (entry->update_virtual_url_with_url())
746 UpdateVirtualURLToURL(entry, params.url); 744 UpdateVirtualURLToURL(entry, params.url);
747 DCHECK(entry->site_instance() == NULL || 745 DCHECK(entry->site_instance() == NULL ||
748 entry->site_instance() == tab_contents_->GetSiteInstance()); 746 entry->site_instance() == tab_contents_->GetSiteInstance());
749 entry->set_site_instance(tab_contents_->GetSiteInstance()); 747 entry->set_site_instance(tab_contents_->GetSiteInstance());
750 748
751 entry->set_has_post_data(params.is_post); 749 entry->set_has_post_data(params.is_post);
752 750
753 // The entry we found in the list might be pending if the user hit 751 // The entry we found in the list might be pending if the user hit
754 // back/forward/reload. This load should commit it (since it's already in the 752 // back/forward/reload. This load should commit it (since it's already in the
755 // list, we can just discard the pending pointer). 753 // list, we can just discard the pending pointer). We should also discard the
754 // pending entry if it corresponds to a different navigation, since that one
755 // is now likely canceled.
brettw 2011/03/22 05:39:18 Can you add here that it may not be cancelled, but
Charlie Reis 2011/03/22 17:04:32 Done.
756 // 756 //
757 // Note that we need to use the "internal" version since we don't want to 757 // Note that we need to use the "internal" version since we don't want to
758 // actually change any other state, just kill the pointer. 758 // actually change any other state, just kill the pointer.
759 if (entry == pending_entry_) 759 if (pending_entry_)
760 DiscardNonCommittedEntriesInternal(); 760 DiscardNonCommittedEntriesInternal();
761 761
762 // If a transient entry was removed, the indices might have changed, so we 762 // If a transient entry was removed, the indices might have changed, so we
763 // have to query the entry index again. 763 // have to query the entry index again.
764 last_committed_entry_index_ = 764 last_committed_entry_index_ =
765 GetEntryIndexWithPageID(tab_contents_->GetSiteInstance(), params.page_id); 765 GetEntryIndexWithPageID(tab_contents_->GetSiteInstance(), params.page_id);
766 } 766 }
767 767
768 void NavigationController::RendererDidNavigateToSamePage( 768 void NavigationController::RendererDidNavigateToSamePage(
769 const ViewHostMsg_FrameNavigate_Params& params) { 769 const ViewHostMsg_FrameNavigate_Params& params) {
(...skipping 414 matching lines...) Expand 10 before | Expand all | Expand 10 after
1184 size_t insert_index = 0; 1184 size_t insert_index = 0;
1185 for (int i = 0; i < max_index; i++) { 1185 for (int i = 0; i < max_index; i++) {
1186 // When cloning a tab, copy all entries except interstitial pages 1186 // When cloning a tab, copy all entries except interstitial pages
1187 if (source.entries_[i].get()->page_type() != INTERSTITIAL_PAGE) { 1187 if (source.entries_[i].get()->page_type() != INTERSTITIAL_PAGE) {
1188 entries_.insert(entries_.begin() + insert_index++, 1188 entries_.insert(entries_.begin() + insert_index++,
1189 linked_ptr<NavigationEntry>( 1189 linked_ptr<NavigationEntry>(
1190 new NavigationEntry(*source.entries_[i]))); 1190 new NavigationEntry(*source.entries_[i])));
1191 } 1191 }
1192 } 1192 }
1193 } 1193 }
OLDNEW
« no previous file with comments | « chrome/browser/tab_contents/web_contents_unittest.cc ('k') | content/browser/tab_contents/navigation_controller_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698