diff --git a/toolkit/components/places/src/History.cpp b/toolkit/components/places/src/History.cpp index 2979722d898c..375ebbde2f0a 100644 --- a/toolkit/components/places/src/History.cpp +++ b/toolkit/components/places/src/History.cpp @@ -1212,12 +1212,27 @@ History::RegisterVisitedCallback(nsIURI* aURI, // Links wanting to know about this URI. Therefore, we should query the // database now. nsresult rv = VisitedQuery::Start(aURI); + + // In IPC builds, we are passed a NULL Link from + // ContentParent::RecvStartVisitedQuery. Since we won't be adding a NULL + // entry to our list of observers, and the code after this point assumes + // that aLink is non-NULL, we will need to return now. if (NS_FAILED(rv) || !aLink) { // Remove our array from the hashtable so we don't keep it around. mObservers.RemoveEntry(aURI); return rv; } } +#ifdef MOZ_IPC + // In IPC builds, we are passed a NULL Link from + // ContentParent::RecvStartVisitedQuery. All of our code after this point + // assumes aLink is non-NULL, so we have to return now. + else if (!aLink) { + NS_ASSERTION(XRE_GetProcessType() == GeckoProcessType_Default, + "We should only ever get a null Link in the default process!"); + return NS_OK; + } +#endif // Sanity check that Links are not registered more than once for a given URI. // This will not catch a case where it is registered for two different URIs. diff --git a/toolkit/components/places/tests/cpp/test_IHistory.cpp b/toolkit/components/places/tests/cpp/test_IHistory.cpp index a8b506b14f1d..d417063042a8 100644 --- a/toolkit/components/places/tests/cpp/test_IHistory.cpp +++ b/toolkit/components/places/tests/cpp/test_IHistory.cpp @@ -550,6 +550,34 @@ test_visituri_transition_embed() run_next_test(); } +//////////////////////////////////////////////////////////////////////////////// +//// IPC-only Tests + +#ifdef MOZ_IPC +void +test_two_null_links_same_uri() +{ + // Tests that we do not crash when we have had two NULL Links passed to + // RegisterVisitedCallback and then the visit occurs (bug 607469). This only + // happens in IPC builds. + nsCOMPtr testURI(new_test_uri()); + + nsCOMPtr history(do_get_IHistory()); + nsresult rv = history->RegisterVisitedCallback(testURI, NULL); + do_check_success(rv); + rv = history->RegisterVisitedCallback(testURI, NULL); + do_check_success(rv); + + rv = history->VisitURI(testURI, NULL, mozilla::IHistory::TOP_LEVEL); + do_check_success(rv); + + nsCOMPtr finisher = new VisitURIObserver(); + finisher->WaitForNotification(); + + run_next_test(); +} +#endif // MOZ_IPC + //////////////////////////////////////////////////////////////////////////////// //// Test Harness @@ -571,6 +599,11 @@ Test gTests[] = { TEST(test_visituri_creates_visit), TEST(test_visituri_transition_typed), TEST(test_visituri_transition_embed), + + // The rest of these tests are tests that are only run in IPC builds. +#ifdef MOZ_IPC + TEST(test_two_null_links_same_uri), +#endif // MOZ_IPC }; const char* file = __FILE__;