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

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: Add comment. 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 476 matching lines...) Expand 10 before | Expand all | Expand 10 after
487 487
488 // Save the previous state before we clobber it. 488 // Save the previous state before we clobber it.
489 if (GetLastCommittedEntry()) { 489 if (GetLastCommittedEntry()) {
490 details->previous_url = GetLastCommittedEntry()->url(); 490 details->previous_url = GetLastCommittedEntry()->url();
491 details->previous_entry_index = last_committed_entry_index(); 491 details->previous_entry_index = last_committed_entry_index();
492 } else { 492 } else {
493 details->previous_url = GURL(); 493 details->previous_url = GURL();
494 details->previous_entry_index = -1; 494 details->previous_entry_index = -1;
495 } 495 }
496 496
497 // Assign the current site instance to any pending entry, so we can find it 497 // The pending_entry has no SiteInstance when we are restoring an entry. We
498 // later by calling GetEntryIndexWithPageID. We only care about this if the 498 // must fill it in here so we can find the entry later by calling
499 // pending entry is an existing navigation and not a new one (or else we 499 // GetEntryIndexWithPageID. In all other cases, the SiteInstance should be
500 // wouldn't care about finding it with GetEntryIndexWithPageID). 500 // assigned already and we shouldn't change it.
501 // 501 if (pending_entry_index_ >= 0 && !pending_entry_->site_instance()) {
502 // TODO(brettw) this seems slightly bogus as we don't really know if the 502 DCHECK(pending_entry_->restore_type() != NavigationEntry::RESTORE_NONE);
503 // pending entry is what this navigation is for. There is a similar TODO
504 // w.r.t. the pending entry in RendererDidNavigateToNewPage.
505 if (pending_entry_index_ >= 0) {
506 pending_entry_->set_site_instance(tab_contents_->GetSiteInstance()); 503 pending_entry_->set_site_instance(tab_contents_->GetSiteInstance());
507 pending_entry_->set_restore_type(NavigationEntry::RESTORE_NONE); 504 pending_entry_->set_restore_type(NavigationEntry::RESTORE_NONE);
508 } 505 }
509 506
510 // is_in_page must be computed before the entry gets committed. 507 // is_in_page must be computed before the entry gets committed.
511 details->is_in_page = IsURLInPageNavigation(params.url); 508 details->is_in_page = IsURLInPageNavigation(params.url);
512 509
513 // Do navigation-type specific actions. These will make and commit an entry. 510 // Do navigation-type specific actions. These will make and commit an entry.
514 details->type = ClassifyNavigation(params); 511 details->type = ClassifyNavigation(params);
515 512
(...skipping 24 matching lines...) Expand all
540 default: 537 default:
541 NOTREACHED(); 538 NOTREACHED();
542 } 539 }
543 540
544 // All committed entries should have nonempty content state so WebKit doesn't 541 // All committed entries should have nonempty content state so WebKit doesn't
545 // get confused when we go back to them (see the function for details). 542 // get confused when we go back to them (see the function for details).
546 DCHECK(!params.content_state.empty()); 543 DCHECK(!params.content_state.empty());
547 NavigationEntry* active_entry = GetActiveEntry(); 544 NavigationEntry* active_entry = GetActiveEntry();
548 active_entry->set_content_state(params.content_state); 545 active_entry->set_content_state(params.content_state);
549 546
547 // The active entry's SiteInstance should match our SiteInstance.
548 DCHECK(active_entry->site_instance() == tab_contents_->GetSiteInstance());
549
550 // WebKit doesn't set the "auto" transition on meta refreshes properly (bug 550 // WebKit doesn't set the "auto" transition on meta refreshes properly (bug
551 // 1051891) so we manually set it for redirects which we normally treat as 551 // 1051891) so we manually set it for redirects which we normally treat as
552 // "non-user-gestures" where we want to update stuff after navigations. 552 // "non-user-gestures" where we want to update stuff after navigations.
553 // 553 //
554 // Note that the redirect check also checks for a pending entry to 554 // Note that the redirect check also checks for a pending entry to
555 // differentiate real redirects from browser initiated navigations to a 555 // differentiate real redirects from browser initiated navigations to a
556 // redirected entry. This happens when you hit back to go to a page that was 556 // redirected entry. This happens when you hit back to go to a page that was
557 // the destination of a redirect, we don't want to treat it as a redirect 557 // the destination of a redirect, we don't want to treat it as a redirect
558 // even though that's what its transition will be. See bug 1117048. 558 // even though that's what its transition will be. See bug 1117048.
559 // 559 //
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
684 entries->push_back(entry); 684 entries->push_back(entry);
685 } 685 }
686 } 686 }
687 687
688 void NavigationController::RendererDidNavigateToNewPage( 688 void NavigationController::RendererDidNavigateToNewPage(
689 const ViewHostMsg_FrameNavigate_Params& params, bool* did_replace_entry) { 689 const ViewHostMsg_FrameNavigate_Params& params, bool* did_replace_entry) {
690 NavigationEntry* new_entry; 690 NavigationEntry* new_entry;
691 if (pending_entry_) { 691 if (pending_entry_) {
692 // TODO(brettw) this assumes that the pending entry is appropriate for the 692 // TODO(brettw) this assumes that the pending entry is appropriate for the
693 // new page that was just loaded. I don't think this is necessarily the 693 // new page that was just loaded. I don't think this is necessarily the
694 // case! We should have some more tracking to know for sure. This goes along 694 // case! We should have some more tracking to know for sure.
695 // with a similar TODO at the top of RendererDidNavigate where we blindly
696 // set the site instance on the pending entry.
697 new_entry = new NavigationEntry(*pending_entry_); 695 new_entry = new NavigationEntry(*pending_entry_);
698 696
699 // Don't use the page type from the pending entry. Some interstitial page 697 // Don't use the page type from the pending entry. Some interstitial page
700 // may have set the type to interstitial. Once we commit, however, the page 698 // may have set the type to interstitial. Once we commit, however, the page
701 // type must always be normal. 699 // type must always be normal.
702 new_entry->set_page_type(NORMAL_PAGE); 700 new_entry->set_page_type(NORMAL_PAGE);
703 } else { 701 } else {
704 new_entry = new NavigationEntry; 702 new_entry = new NavigationEntry;
705 } 703 }
706 704
(...skipping 30 matching lines...) Expand all
737 if (entry->update_virtual_url_with_url()) 735 if (entry->update_virtual_url_with_url())
738 UpdateVirtualURLToURL(entry, params.url); 736 UpdateVirtualURLToURL(entry, params.url);
739 DCHECK(entry->site_instance() == NULL || 737 DCHECK(entry->site_instance() == NULL ||
740 entry->site_instance() == tab_contents_->GetSiteInstance()); 738 entry->site_instance() == tab_contents_->GetSiteInstance());
741 entry->set_site_instance(tab_contents_->GetSiteInstance()); 739 entry->set_site_instance(tab_contents_->GetSiteInstance());
742 740
743 entry->set_has_post_data(params.is_post); 741 entry->set_has_post_data(params.is_post);
744 742
745 // The entry we found in the list might be pending if the user hit 743 // The entry we found in the list might be pending if the user hit
746 // back/forward/reload. This load should commit it (since it's already in the 744 // back/forward/reload. This load should commit it (since it's already in the
747 // list, we can just discard the pending pointer). 745 // list, we can just discard the pending pointer). We should also discard the
746 // pending entry if it corresponds to a different navigation, since that one
747 // is now likely canceled. If it is not canceled, we will treat it as a new
748 // navigation when it arrives, which is also ok.
748 // 749 //
749 // Note that we need to use the "internal" version since we don't want to 750 // Note that we need to use the "internal" version since we don't want to
750 // actually change any other state, just kill the pointer. 751 // actually change any other state, just kill the pointer.
751 if (entry == pending_entry_) 752 if (pending_entry_)
752 DiscardNonCommittedEntriesInternal(); 753 DiscardNonCommittedEntriesInternal();
753 754
754 // If a transient entry was removed, the indices might have changed, so we 755 // If a transient entry was removed, the indices might have changed, so we
755 // have to query the entry index again. 756 // have to query the entry index again.
756 last_committed_entry_index_ = 757 last_committed_entry_index_ =
757 GetEntryIndexWithPageID(tab_contents_->GetSiteInstance(), params.page_id); 758 GetEntryIndexWithPageID(tab_contents_->GetSiteInstance(), params.page_id);
758 } 759 }
759 760
760 void NavigationController::RendererDidNavigateToSamePage( 761 void NavigationController::RendererDidNavigateToSamePage(
761 const ViewHostMsg_FrameNavigate_Params& params) { 762 const ViewHostMsg_FrameNavigate_Params& params) {
(...skipping 444 matching lines...) Expand 10 before | Expand all | Expand 10 after
1206 size_t insert_index = 0; 1207 size_t insert_index = 0;
1207 for (int i = 0; i < max_index; i++) { 1208 for (int i = 0; i < max_index; i++) {
1208 // When cloning a tab, copy all entries except interstitial pages 1209 // When cloning a tab, copy all entries except interstitial pages
1209 if (source.entries_[i].get()->page_type() != INTERSTITIAL_PAGE) { 1210 if (source.entries_[i].get()->page_type() != INTERSTITIAL_PAGE) {
1210 entries_.insert(entries_.begin() + insert_index++, 1211 entries_.insert(entries_.begin() + insert_index++,
1211 linked_ptr<NavigationEntry>( 1212 linked_ptr<NavigationEntry>(
1212 new NavigationEntry(*source.entries_[i]))); 1213 new NavigationEntry(*source.entries_[i])));
1213 } 1214 }
1214 } 1215 }
1215 } 1216 }
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