Commit d1bf4b96 authored by jialiul's avatar jialiul Committed by Commit bot

Address 2 crashes in download attribution code.

crbug.com/676675
Out of memory crash caused by memory alloc inside vector::push_back().
Since vector grows its internal buffer following some kind of geometric
progression, it makes more sense to keep pointers inside the vector
instead of actual objects.  Therefore, change the
vector<ReferrerChainEntry> into vector<unique_ptr<ReferrerChainEntry>>.
This will help with the memory allocation inside push_back() function.

crbug.com/679252
Add additional check on the return of FindNavigationEvent() function to
make suer it is valid.

BUG=676675,679252

Review-Url: https://codereview.chromium.org/2624463003
Cr-Commit-Position: refs/heads/master@{#442780}
parent 37240b4f
......@@ -1834,7 +1834,7 @@ void DownloadProtectionService::AddReferrerChainToClientDownloadRequest(
UMA_HISTOGRAM_BOOLEAN(
"SafeBrowsing.ReferrerHasInvalidTabID.DownloadAttribution",
download_tab_id == -1);
std::vector<ReferrerChainEntry> attribution_chain;
SafeBrowsingNavigationObserverManager::ReferrerChain attribution_chain;
SafeBrowsingNavigationObserverManager::AttributionResult result =
navigation_observer_manager_->IdentifyReferrerChainForDownload(
download_url,
......@@ -1847,8 +1847,8 @@ void DownloadProtectionService::AddReferrerChainToClientDownloadRequest(
UMA_HISTOGRAM_ENUMERATION(
"SafeBrowsing.ReferrerAttributionResult.DownloadAttribution", result,
SafeBrowsingNavigationObserverManager::ATTRIBUTION_FAILURE_TYPE_MAX);
for (auto entry : attribution_chain)
out_request->add_referrer_chain()->Swap(&entry);
for (auto& entry : attribution_chain)
out_request->add_referrer_chain()->Swap(entry.get());
}
void DownloadProtectionService::AddReferrerChainToPPAPIClientDownloadRequest(
......@@ -1865,7 +1865,7 @@ void DownloadProtectionService::AddReferrerChainToPPAPIClientDownloadRequest(
UMA_HISTOGRAM_BOOLEAN(
"SafeBrowsing.ReferrerHasInvalidTabID.DownloadAttribution",
tab_id == -1);
std::vector<ReferrerChainEntry> attribution_chain;
SafeBrowsingNavigationObserverManager::ReferrerChain attribution_chain;
SafeBrowsingNavigationObserverManager::AttributionResult result =
navigation_observer_manager_->IdentifyReferrerChainForPPAPIDownload(
initiating_frame_url,
......@@ -1879,8 +1879,8 @@ void DownloadProtectionService::AddReferrerChainToPPAPIClientDownloadRequest(
UMA_HISTOGRAM_ENUMERATION(
"SafeBrowsing.ReferrerAttributionResult.PPAPIDownloadAttribution", result,
SafeBrowsingNavigationObserverManager::ATTRIBUTION_FAILURE_TYPE_MAX);
for (auto entry : attribution_chain)
out_request->add_referrer_chain()->Swap(&entry);
for (auto& entry : attribution_chain)
out_request->add_referrer_chain()->Swap(entry.get());
}
} // namespace safe_browsing
......@@ -33,6 +33,8 @@ using content::DownloadItem;
namespace safe_browsing {
typedef SafeBrowsingNavigationObserverManager::ReferrerChain ReferrerChain;
const char kSingleFrameTestURL[] =
"/safe_browsing/download_protection/navigation_observer/"
"navigation_observer_tests.html";
......@@ -234,24 +236,25 @@ class SBNavigationObserverBrowserTest : public InProcessBrowserTest {
const GURL& expected_referrer_url,
const GURL& expected_referrer_main_frame_url,
bool expected_is_retargeting,
ReferrerChainEntry actual_entry) {
EXPECT_EQ(expected_url.spec(), actual_entry.url());
EXPECT_EQ(expected_type, actual_entry.type());
ReferrerChainEntry* actual_entry) {
EXPECT_EQ(expected_url.spec(), actual_entry->url());
EXPECT_EQ(expected_type, actual_entry->type());
if (expected_ip_address.empty()) {
ASSERT_EQ(0, actual_entry.ip_addresses_size());
ASSERT_EQ(0, actual_entry->ip_addresses_size());
} else {
ASSERT_EQ(1, actual_entry.ip_addresses_size());
EXPECT_EQ(expected_ip_address, actual_entry.ip_addresses(0));
ASSERT_EQ(1, actual_entry->ip_addresses_size());
EXPECT_EQ(expected_ip_address, actual_entry->ip_addresses(0));
}
EXPECT_EQ(expected_referrer_url.spec(), actual_entry.referrer_url());
EXPECT_EQ(expected_referrer_url.spec(), actual_entry->referrer_url());
EXPECT_EQ(expected_referrer_main_frame_url.spec(),
actual_entry.referrer_main_frame_url());
EXPECT_EQ(expected_is_retargeting, actual_entry.is_retargeting());
actual_entry->referrer_main_frame_url());
EXPECT_EQ(expected_is_retargeting, actual_entry->is_retargeting());
}
std::vector<ReferrerChainEntry> IdentifyReferrerChainForDownload(
DownloadItem* download) {
std::vector<ReferrerChainEntry> referrer_chain;
// Identify referrer chain of a DownloadItem and populate |referrer_chain|.
void IdentifyReferrerChainForDownload(
DownloadItem* download,
ReferrerChain* referrer_chain) {
int download_tab_id =
SessionTabHelper::IdForTab(download->GetWebContents());
// IdentifyReferrerChain should return SUCCESS(1), SUCCESS_LANDING_PAGE(2),
......@@ -259,15 +262,15 @@ class SBNavigationObserverBrowserTest : public InProcessBrowserTest {
EXPECT_LE(observer_manager_->IdentifyReferrerChainForDownload(
download->GetURL(), download_tab_id,
2, // kDownloadAttributionUserGestureLimit
&referrer_chain),
referrer_chain),
SafeBrowsingNavigationObserverManager::SUCCESS_LANDING_REFERRER);
return referrer_chain;
}
std::vector<ReferrerChainEntry> IdentifyReferrerChainForPPAPIDownload(
// Identify referrer chain of a PPAPI download and populate |referrer_chain|.
void IdentifyReferrerChainForPPAPIDownload(
const GURL& initiating_frame_url,
content::WebContents* web_contents) {
std::vector<ReferrerChainEntry> referrer_chain;
content::WebContents* web_contents,
ReferrerChain* referrer_chain) {
int tab_id = SessionTabHelper::IdForTab(web_contents);
bool has_user_gesture = observer_manager_->HasUserGesture(web_contents);
observer_manager_->OnUserGestureConsumed(web_contents, base::Time::Now());
......@@ -276,9 +279,8 @@ class SBNavigationObserverBrowserTest : public InProcessBrowserTest {
tab_id,
has_user_gesture,
2, // kDownloadAttributionUserGestureLimit)
&referrer_chain),
referrer_chain),
SafeBrowsingNavigationObserverManager::SUCCESS_LANDING_REFERRER);
return referrer_chain;
}
void VerifyHostToIpMap() {
......@@ -346,7 +348,8 @@ IN_PROC_BROWSER_TEST_F(SBNavigationObserverBrowserTest, TypeInURLDownload) {
nav_map->at(download_url).at(0));
VerifyHostToIpMap();
auto referrer_chain = IdentifyReferrerChainForDownload(GetDownload());
ReferrerChain referrer_chain;
IdentifyReferrerChainForDownload(GetDownload(), &referrer_chain);
ASSERT_EQ(1U, referrer_chain.size());
VerifyReferrerChainEntry(download_url, // url
ReferrerChainEntry::DOWNLOAD_URL, // type
......@@ -354,7 +357,7 @@ IN_PROC_BROWSER_TEST_F(SBNavigationObserverBrowserTest, TypeInURLDownload) {
GURL(), // referrer_url
GURL(), // referrer_main_frame_url
false, // is_retargeting
referrer_chain[0]);
referrer_chain[0].get());
}
// Click on a link and start download on the same page.
IN_PROC_BROWSER_TEST_F(SBNavigationObserverBrowserTest, DirectDownload) {
......@@ -385,7 +388,8 @@ IN_PROC_BROWSER_TEST_F(SBNavigationObserverBrowserTest, DirectDownload) {
nav_map->at(download_url).at(0));
VerifyHostToIpMap();
auto referrer_chain = IdentifyReferrerChainForDownload(GetDownload());
ReferrerChain referrer_chain;
IdentifyReferrerChainForDownload(GetDownload(), &referrer_chain);
ASSERT_EQ(2U, referrer_chain.size());
VerifyReferrerChainEntry(download_url, // url
ReferrerChainEntry::DOWNLOAD_URL, // type
......@@ -393,14 +397,14 @@ IN_PROC_BROWSER_TEST_F(SBNavigationObserverBrowserTest, DirectDownload) {
initial_url, // referrer_url
initial_url, // referrer_main_frame_url
false, // is_retargeting
referrer_chain[0]);
referrer_chain[0].get());
VerifyReferrerChainEntry(initial_url, // url
ReferrerChainEntry::LANDING_PAGE, // type
test_server_ip, // ip_address
GURL(), // referrer_url
GURL(), // referrer_main_frame_url
false, // is_retargeting
referrer_chain[1]);
referrer_chain[1].get());
}
// Click on a link with rel="noreferrer" attribute, and start download on the
......@@ -434,7 +438,8 @@ IN_PROC_BROWSER_TEST_F(SBNavigationObserverBrowserTest,
nav_map->at(download_url).at(0));
VerifyHostToIpMap();
auto referrer_chain = IdentifyReferrerChainForDownload(GetDownload());
ReferrerChain referrer_chain;
IdentifyReferrerChainForDownload(GetDownload(), &referrer_chain);
ASSERT_EQ(2U, referrer_chain.size());
VerifyReferrerChainEntry(download_url, // url
ReferrerChainEntry::DOWNLOAD_URL, // type
......@@ -442,14 +447,14 @@ IN_PROC_BROWSER_TEST_F(SBNavigationObserverBrowserTest,
initial_url, // referrer_url
initial_url, // referrer_main_frame_url
false, // is_retargeting
referrer_chain[0]);
referrer_chain[0].get());
VerifyReferrerChainEntry(initial_url, // url
ReferrerChainEntry::LANDING_PAGE, // type
test_server_ip, // ip_address
GURL(), // referrer_url
GURL(), // referrer_main_frame_url
false, // is_retargeting
referrer_chain[1]);
referrer_chain[1].get());
}
// Click on a link with rel="noreferrer" attribute, and start download in a
......@@ -497,7 +502,8 @@ IN_PROC_BROWSER_TEST_F(SBNavigationObserverBrowserTest,
nav_map->at(download_url).at(1));
VerifyHostToIpMap();
auto referrer_chain = IdentifyReferrerChainForDownload(GetDownload());
ReferrerChain referrer_chain;
IdentifyReferrerChainForDownload(GetDownload(), &referrer_chain);
ASSERT_EQ(2U, referrer_chain.size());
VerifyReferrerChainEntry(download_url, // url
ReferrerChainEntry::DOWNLOAD_URL, // type
......@@ -505,14 +511,14 @@ IN_PROC_BROWSER_TEST_F(SBNavigationObserverBrowserTest,
initial_url, // referrer_url
initial_url, // referrer_main_frame_url
true, // is_retargeting
referrer_chain[0]);
referrer_chain[0].get());
VerifyReferrerChainEntry(initial_url, // url
ReferrerChainEntry::LANDING_PAGE, // type
test_server_ip, // ip_address
GURL(), // referrer_url
GURL(), // referrer_main_frame_url
false, // is_retargeting
referrer_chain[1]);
referrer_chain[1].get());
}
// Click on a link which navigates to a page then redirects to a download using
......@@ -528,7 +534,7 @@ IN_PROC_BROWSER_TEST_F(SBNavigationObserverBrowserTest,
ASSERT_TRUE(nav_map);
// Since unlike server redirects client redirects commit and then generate a
// second navigation, our observer records two NavigationEvents for this test.
ASSERT_EQ(std::size_t(3), nav_map->size());
ASSERT_EQ(3U, nav_map->size());
ASSERT_EQ(1U, nav_map->at(redirect_url).size());
ASSERT_EQ(1U, nav_map->at(download_url).size());
ASSERT_EQ(1U, nav_map->at(initial_url).size());
......@@ -558,29 +564,30 @@ IN_PROC_BROWSER_TEST_F(SBNavigationObserverBrowserTest,
nav_map->at(download_url).at(0));
VerifyHostToIpMap();
auto referrer_chain = IdentifyReferrerChainForDownload(GetDownload());
ASSERT_EQ(std::size_t(3), referrer_chain.size());
ReferrerChain referrer_chain;
IdentifyReferrerChainForDownload(GetDownload(), &referrer_chain);
ASSERT_EQ(3U, referrer_chain.size());
VerifyReferrerChainEntry(download_url, // url
ReferrerChainEntry::DOWNLOAD_URL, // type
test_server_ip, // ip_address
redirect_url, // referrer_url
redirect_url, // referrer_main_frame_url
false, // is_retargeting
referrer_chain[0]);
referrer_chain[0].get());
VerifyReferrerChainEntry(redirect_url, // url
ReferrerChainEntry::CLIENT_REDIRECT, // type
test_server_ip, // ip_address
initial_url, // referrer_url
initial_url, // referrer_main_frame_url
false, // is_retargeting
referrer_chain[1]);
referrer_chain[1].get());
VerifyReferrerChainEntry(initial_url, // url
ReferrerChainEntry::LANDING_PAGE, // type
test_server_ip, // ip_address
GURL(), // referrer_url
GURL(), // referrer_main_frame_url
false, // is_retargeting
referrer_chain[2]);
referrer_chain[2].get());
}
// Click on a link which navigates to a page then redirects to a download using
......@@ -594,7 +601,7 @@ IN_PROC_BROWSER_TEST_F(SBNavigationObserverBrowserTest,
std::string test_server_ip(embedded_test_server()->host_port_pair().host());
auto nav_map = navigation_map();
ASSERT_TRUE(nav_map);
ASSERT_EQ(std::size_t(3), nav_map->size());
ASSERT_EQ(3U, nav_map->size());
ASSERT_EQ(2U, nav_map->at(redirect_url).size());
ASSERT_EQ(1U, nav_map->at(download_url).size());
ASSERT_EQ(1U, nav_map->at(initial_url).size());
......@@ -635,29 +642,30 @@ IN_PROC_BROWSER_TEST_F(SBNavigationObserverBrowserTest,
nav_map->at(download_url).at(0));
VerifyHostToIpMap();
auto referrer_chain = IdentifyReferrerChainForDownload(GetDownload());
ASSERT_EQ(std::size_t(3), referrer_chain.size());
ReferrerChain referrer_chain;
IdentifyReferrerChainForDownload(GetDownload(), &referrer_chain);
ASSERT_EQ(3U, referrer_chain.size());
VerifyReferrerChainEntry(download_url, // url
ReferrerChainEntry::DOWNLOAD_URL, // type
test_server_ip, // ip_address
redirect_url, // referrer_url
redirect_url, // referrer_main_frame_url
false, // is_retargeting
referrer_chain[0]);
referrer_chain[0].get());
VerifyReferrerChainEntry(redirect_url, // url
ReferrerChainEntry::CLIENT_REDIRECT, // type
test_server_ip, // ip_address
initial_url, // referrer_url
initial_url, // referrer_main_frame_url
true, // is_retargeting
referrer_chain[1]);
referrer_chain[1].get());
VerifyReferrerChainEntry(initial_url, // url
ReferrerChainEntry::LANDING_PAGE, // type
test_server_ip, // ip_address
GURL(), // referrer_url
GURL(), // referrer_main_frame_url
false, // is_retargeting
referrer_chain[2]);
referrer_chain[2].get());
}
// Click on a link which redirects twice before reaching download using
......@@ -674,7 +682,7 @@ IN_PROC_BROWSER_TEST_F(SBNavigationObserverBrowserTest,
std::string test_server_ip(embedded_test_server()->host_port_pair().host());
auto nav_map = navigation_map();
ASSERT_TRUE(nav_map);
ASSERT_EQ(std::size_t(4), nav_map->size());
ASSERT_EQ(4U, nav_map->size());
ASSERT_EQ(1U, nav_map->at(first_redirect_url).size());
ASSERT_EQ(1U, nav_map->at(second_redirect_url).size());
ASSERT_EQ(1U, nav_map->at(download_url).size());
......@@ -713,36 +721,37 @@ IN_PROC_BROWSER_TEST_F(SBNavigationObserverBrowserTest,
nav_map->at(download_url).at(0));
VerifyHostToIpMap();
auto referrer_chain = IdentifyReferrerChainForDownload(GetDownload());
ASSERT_EQ(std::size_t(4), referrer_chain.size());
ReferrerChain referrer_chain;
IdentifyReferrerChainForDownload(GetDownload(), &referrer_chain);
ASSERT_EQ(4U, referrer_chain.size());
VerifyReferrerChainEntry(download_url, // url
ReferrerChainEntry::DOWNLOAD_URL, // type
test_server_ip, // ip_address
second_redirect_url, // referrer_url
second_redirect_url, // referrer_main_frame_url
false, // is_retargeting
referrer_chain[0]);
referrer_chain[0].get());
VerifyReferrerChainEntry(second_redirect_url, // url
ReferrerChainEntry::CLIENT_REDIRECT, // type
test_server_ip, // ip_address
first_redirect_url, // referrer_url
first_redirect_url, // referrer_main_frame_url
false, // is_retargeting
referrer_chain[1]);
referrer_chain[1].get());
VerifyReferrerChainEntry(first_redirect_url, // url
ReferrerChainEntry::CLIENT_REDIRECT, // type
test_server_ip, // ip_address
initial_url, // referrer_url
initial_url, // referrer_main_frame_url
false, // is_retargeting
referrer_chain[2]);
referrer_chain[2].get());
VerifyReferrerChainEntry(initial_url, // url
ReferrerChainEntry::LANDING_PAGE, // type
test_server_ip, // ip_address
GURL(), // referrer_url
GURL(), // referrer_main_frame_url
false, // is_retargeting
referrer_chain[3]);
referrer_chain[3].get());
}
// Click on a link which redirects to download using window.location.
......@@ -775,7 +784,8 @@ IN_PROC_BROWSER_TEST_F(SBNavigationObserverBrowserTest,
false, // has_server_redirect
nav_map->at(download_url).at(0));
auto referrer_chain = IdentifyReferrerChainForDownload(GetDownload());
ReferrerChain referrer_chain;
IdentifyReferrerChainForDownload(GetDownload(), &referrer_chain);
ASSERT_EQ(2U, referrer_chain.size());
VerifyReferrerChainEntry(download_url, // url
ReferrerChainEntry::DOWNLOAD_URL, // type
......@@ -783,14 +793,14 @@ IN_PROC_BROWSER_TEST_F(SBNavigationObserverBrowserTest,
initial_url, // referrer_url
initial_url, // referrer_main_frame_url
false, // is_retargeting
referrer_chain[0]);
referrer_chain[0].get());
VerifyReferrerChainEntry(initial_url, // url
ReferrerChainEntry::LANDING_PAGE, // type
test_server_ip, // ip_address
GURL(), // referrer_url
GURL(), // referrer_main_frame_url
false, // is_retargeting
referrer_chain[1]);
referrer_chain[1].get());
}
// Click on a link which redirects twice until it reaches download using a
......@@ -804,7 +814,7 @@ IN_PROC_BROWSER_TEST_F(SBNavigationObserverBrowserTest, MixRedirects) {
std::string test_server_ip(embedded_test_server()->host_port_pair().host());
auto nav_map = navigation_map();
ASSERT_TRUE(nav_map);
ASSERT_EQ(std::size_t(3), nav_map->size());
ASSERT_EQ(3U, nav_map->size());
ASSERT_EQ(1U, nav_map->at(redirect_url).size());
ASSERT_EQ(1U, nav_map->at(download_url).size());
ASSERT_EQ(1U, nav_map->at(initial_url).size());
......@@ -834,29 +844,30 @@ IN_PROC_BROWSER_TEST_F(SBNavigationObserverBrowserTest, MixRedirects) {
nav_map->at(download_url).at(0));
VerifyHostToIpMap();
auto referrer_chain = IdentifyReferrerChainForDownload(GetDownload());
ASSERT_EQ(std::size_t(3), referrer_chain.size());
ReferrerChain referrer_chain;
IdentifyReferrerChainForDownload(GetDownload(), &referrer_chain);
ASSERT_EQ(3U, referrer_chain.size());
VerifyReferrerChainEntry(download_url, // url
ReferrerChainEntry::DOWNLOAD_URL, // type
test_server_ip, // ip_address
redirect_url, // referrer_url
redirect_url, // referrer_main_frame_url
false, // is_retargeting
referrer_chain[0]);
referrer_chain[0].get());
VerifyReferrerChainEntry(redirect_url, // url
ReferrerChainEntry::CLIENT_REDIRECT, // type
test_server_ip, // ip_address
initial_url, // referrer_url
initial_url, // referrer_main_frame_url
false, // is_retargeting
referrer_chain[1]);
referrer_chain[1].get());
VerifyReferrerChainEntry(initial_url, // url
ReferrerChainEntry::LANDING_PAGE, // type
test_server_ip, // ip_address
GURL(), // referrer_url
GURL(), // referrer_main_frame_url
false, // is_retargeting
referrer_chain[2]);
referrer_chain[2].get());
}
// Use javascript to open download in a new tab.
......@@ -868,7 +879,7 @@ IN_PROC_BROWSER_TEST_F(SBNavigationObserverBrowserTest, NewTabDownload) {
std::string test_server_ip(embedded_test_server()->host_port_pair().host());
auto nav_map = navigation_map();
ASSERT_TRUE(nav_map);
ASSERT_EQ(std::size_t(3), nav_map->size());
ASSERT_EQ(3U, nav_map->size());
ASSERT_EQ(2U, nav_map->at(blank_url).size());
ASSERT_EQ(1U, nav_map->at(download_url).size());
ASSERT_EQ(1U, nav_map->at(initial_url).size());
......@@ -913,29 +924,30 @@ IN_PROC_BROWSER_TEST_F(SBNavigationObserverBrowserTest, NewTabDownload) {
nav_map->at(download_url).at(0).target_tab_id);
VerifyHostToIpMap();
auto referrer_chain = IdentifyReferrerChainForDownload(GetDownload());
ASSERT_EQ(std::size_t(3), referrer_chain.size());
ReferrerChain referrer_chain;
IdentifyReferrerChainForDownload(GetDownload(), &referrer_chain);
ASSERT_EQ(3U, referrer_chain.size());
VerifyReferrerChainEntry(download_url, // url
ReferrerChainEntry::DOWNLOAD_URL, // type
test_server_ip, // ip_address
blank_url, // referrer_url
blank_url, // referrer_main_frame_url
false, // is_retargeting
referrer_chain[0]);
referrer_chain[0].get());
VerifyReferrerChainEntry(blank_url, // url
ReferrerChainEntry::CLIENT_REDIRECT, // type
"", // ip_address
initial_url, // referrer_url
initial_url, // referrer_main_frame_url
true, // is_retargeting
referrer_chain[1]);
referrer_chain[1].get());
VerifyReferrerChainEntry(initial_url, // url
ReferrerChainEntry::LANDING_PAGE, // type
test_server_ip, // ip_address
GURL(), // referrer_url
GURL(), // referrer_main_frame_url
false, // is_retargeting
referrer_chain[2]);
referrer_chain[2].get());
}
// Use javascript to open download in a new tab and download has a data url.
......@@ -948,7 +960,7 @@ IN_PROC_BROWSER_TEST_F(SBNavigationObserverBrowserTest,
std::string test_server_ip(embedded_test_server()->host_port_pair().host());
auto nav_map = navigation_map();
ASSERT_TRUE(nav_map);
ASSERT_EQ(std::size_t(3), nav_map->size());
ASSERT_EQ(3U, nav_map->size());
ASSERT_EQ(2U, nav_map->at(blank_url).size());
ASSERT_EQ(1U, nav_map->at(download_url).size());
ASSERT_EQ(1U, nav_map->at(initial_url).size());
......@@ -994,29 +1006,30 @@ IN_PROC_BROWSER_TEST_F(SBNavigationObserverBrowserTest,
nav_map->at(download_url).at(0).target_tab_id);
VerifyHostToIpMap();
auto referrer_chain = IdentifyReferrerChainForDownload(GetDownload());
ASSERT_EQ(std::size_t(3), referrer_chain.size());
ReferrerChain referrer_chain;
IdentifyReferrerChainForDownload(GetDownload(), &referrer_chain);
ASSERT_EQ(3U, referrer_chain.size());
VerifyReferrerChainEntry(download_url, // url
ReferrerChainEntry::DOWNLOAD_URL, // type
"", // ip_address
blank_url, // referrer_url
blank_url, // referrer_main_frame_url
false, // is_retargeting
referrer_chain[0]);
referrer_chain[0].get());
VerifyReferrerChainEntry(blank_url, // url
ReferrerChainEntry::CLIENT_REDIRECT, // type
"", // ip_address
initial_url, // referrer_url
initial_url, // referrer_main_frame_url
true, // is_retargeting
referrer_chain[1]);
referrer_chain[1].get());
VerifyReferrerChainEntry(initial_url, // url
ReferrerChainEntry::LANDING_PAGE, // type
test_server_ip, // ip_address
GURL(), // referrer_url
GURL(), // referrer_main_frame_url
false, // is_retargeting
referrer_chain[2]);
referrer_chain[2].get());
}
// TODO(jialiul): Need to figure out why this test is failing on Windows and
......@@ -1055,7 +1068,8 @@ IN_PROC_BROWSER_TEST_F(SBNavigationObserverBrowserTest,
nav_map->at(download_url).at(0));
VerifyHostToIpMap();
auto referrer_chain = IdentifyReferrerChainForDownload(GetDownload());
ReferrerChain referrer_chain;
IdentifyReferrerChainForDownload(GetDownload(), &referrer_chain);
ASSERT_EQ(2U, referrer_chain.size());
VerifyReferrerChainEntry(download_url, // url
ReferrerChainEntry::DOWNLOAD_URL, // type
......@@ -1063,14 +1077,14 @@ IN_PROC_BROWSER_TEST_F(SBNavigationObserverBrowserTest,
initial_url, // referrer_url
initial_url, // referrer_main_frame_url
false, // is_retargeting
referrer_chain[0]);
referrer_chain[0].get());
VerifyReferrerChainEntry(initial_url, // url
ReferrerChainEntry::LANDING_PAGE, // type
test_server_ip, // ip_address
GURL(), // referrer_url
GURL(), // referrer_main_frame_url
false, // is_retargeting
referrer_chain[1]);
referrer_chain[1].get());
}
// Click a link in a subframe and start download.
......@@ -1090,7 +1104,7 @@ IN_PROC_BROWSER_TEST_F(SBNavigationObserverBrowserTest,
std::string test_server_ip(embedded_test_server()->host_port_pair().host());
auto nav_map = navigation_map();
ASSERT_TRUE(nav_map);
ASSERT_EQ(std::size_t(5), nav_map->size());
ASSERT_EQ(5U, nav_map->size());
ASSERT_EQ(1U, nav_map->at(multi_frame_test_url).size());
ASSERT_EQ(1U, nav_map->at(iframe_url).size());
ASSERT_EQ(1U, nav_map->at(iframe_retargeting_url).size());
......@@ -1138,7 +1152,8 @@ IN_PROC_BROWSER_TEST_F(SBNavigationObserverBrowserTest,
nav_map->at(download_url).at(0));
VerifyHostToIpMap();
auto referrer_chain = IdentifyReferrerChainForDownload(GetDownload());
ReferrerChain referrer_chain;
IdentifyReferrerChainForDownload(GetDownload(), &referrer_chain);
ASSERT_EQ(4U, referrer_chain.size());
VerifyReferrerChainEntry(download_url, // url
ReferrerChainEntry::DOWNLOAD_URL, // type
......@@ -1146,28 +1161,28 @@ IN_PROC_BROWSER_TEST_F(SBNavigationObserverBrowserTest,
iframe_url, // referrer_url
multi_frame_test_url, // referrer_main_frame_url
false, // is_retargeting
referrer_chain[0]);
referrer_chain[0].get());
VerifyReferrerChainEntry(iframe_url, // url
ReferrerChainEntry::LANDING_PAGE, // type
test_server_ip, // ip_address
GURL(), // referrer_url
multi_frame_test_url, // referrer_main_frame_url
false, // is_retargeting
referrer_chain[1]);
referrer_chain[1].get());
VerifyReferrerChainEntry(multi_frame_test_url, // url
ReferrerChainEntry::CLIENT_REDIRECT, // type
test_server_ip, // ip_address
initial_url, // referrer_url
initial_url, // referrer_main_frame_url
false, // is_retargeting
referrer_chain[2]);
referrer_chain[2].get());
VerifyReferrerChainEntry(initial_url, // url
ReferrerChainEntry::LANDING_REFERRER, // type
test_server_ip, // ip_address
GURL(), // referrer_url
GURL(), // referrer_main_frame_url
false, // is_retargeting
referrer_chain[3]);
referrer_chain[3].get());
}
// Click a link in a subframe and open download in a new tab.
......@@ -1253,7 +1268,8 @@ IN_PROC_BROWSER_TEST_F(SBNavigationObserverBrowserTest,
nav_map->at(download_url).at(0));
VerifyHostToIpMap();
auto referrer_chain = IdentifyReferrerChainForDownload(GetDownload());
ReferrerChain referrer_chain;
IdentifyReferrerChainForDownload(GetDownload(), &referrer_chain);
EXPECT_EQ(5U, referrer_chain.size());
VerifyReferrerChainEntry(download_url, // url
ReferrerChainEntry::DOWNLOAD_URL, // type
......@@ -1261,35 +1277,35 @@ IN_PROC_BROWSER_TEST_F(SBNavigationObserverBrowserTest,
blank_url, // referrer_url
blank_url, // referrer_main_frame_url
false, // is_retargeting
referrer_chain[0]);
referrer_chain[0].get());
VerifyReferrerChainEntry(blank_url, // url
ReferrerChainEntry::CLIENT_REDIRECT, // type
"", // ip_address
iframe_retargeting_url, // referrer_url
multi_frame_test_url, // referrer_main_frame_url
true, // is_retargeting
referrer_chain[1]);
referrer_chain[1].get());
VerifyReferrerChainEntry(iframe_retargeting_url, // url
ReferrerChainEntry::LANDING_PAGE, // type
test_server_ip, // ip_address
GURL(), // referrer_url
multi_frame_test_url, // referrer_main_frame_url
false, // is_retargeting
referrer_chain[2]);
referrer_chain[2].get());
VerifyReferrerChainEntry(multi_frame_test_url, // url
ReferrerChainEntry::CLIENT_REDIRECT, // type
test_server_ip, // ip_address
initial_url, // referrer_url
initial_url, // referrer_main_frame_url
false, // is_retargeting
referrer_chain[3]);
referrer_chain[3].get());
VerifyReferrerChainEntry(initial_url, // url
ReferrerChainEntry::LANDING_REFERRER, // type
test_server_ip, // ip_address
GURL(), // referrer_url
GURL(), // referrer_main_frame_url
false, // is_retargeting
referrer_chain[4]);
referrer_chain[4].get());
}
// Click a link which redirects to the landing page, and then click on the
......@@ -1304,7 +1320,7 @@ IN_PROC_BROWSER_TEST_F(SBNavigationObserverBrowserTest, CompleteReferrerChain) {
std::string test_server_ip(embedded_test_server()->host_port_pair().host());
auto nav_map = navigation_map();
ASSERT_TRUE(nav_map);
ASSERT_EQ(std::size_t(4), nav_map->size());
ASSERT_EQ(4U, nav_map->size());
ASSERT_EQ(1U, nav_map->at(redirect_url).size());
ASSERT_EQ(1U, nav_map->at(landing_url).size());
ASSERT_EQ(1U, nav_map->at(download_url).size());
......@@ -1343,29 +1359,30 @@ IN_PROC_BROWSER_TEST_F(SBNavigationObserverBrowserTest, CompleteReferrerChain) {
nav_map->at(download_url).at(0));
VerifyHostToIpMap();
auto referrer_chain = IdentifyReferrerChainForDownload(GetDownload());
EXPECT_EQ(std::size_t(4), referrer_chain.size());
ReferrerChain referrer_chain;
IdentifyReferrerChainForDownload(GetDownload(), &referrer_chain);
EXPECT_EQ(4U, referrer_chain.size());
VerifyReferrerChainEntry(download_url, // url
ReferrerChainEntry::DOWNLOAD_URL, // type
test_server_ip, // ip_address
landing_url, // referrer_url
landing_url, // referrer_main_frame_url
false, // is_retargeting
referrer_chain[0]);
referrer_chain[0].get());
VerifyReferrerChainEntry(landing_url, // url
ReferrerChainEntry::LANDING_PAGE, // type
test_server_ip, // ip_address
redirect_url, // referrer_url
redirect_url, // referrer_main_frame_url
false, // is_retargeting
referrer_chain[1]);
referrer_chain[1].get());
VerifyReferrerChainEntry(redirect_url, // url
ReferrerChainEntry::CLIENT_REDIRECT, // type
test_server_ip, // ip_address
initial_url, // referrer_url
initial_url, // referrer_main_frame_url
false, // is_retargeting
referrer_chain[2]);
referrer_chain[2].get());
VerifyReferrerChainEntry(
initial_url, // url
ReferrerChainEntry::LANDING_REFERRER, // type
......@@ -1373,7 +1390,7 @@ IN_PROC_BROWSER_TEST_F(SBNavigationObserverBrowserTest, CompleteReferrerChain) {
GURL(), // referrer_url is empty since this beyonds 2 clicks.
GURL(), // referrer_main_frame_url is empty for the same reason.
false, // is_retargeting
referrer_chain[3]);
referrer_chain[3].get());
}
// Click three links before reaching download.
......@@ -1394,7 +1411,7 @@ IN_PROC_BROWSER_TEST_F(SBNavigationObserverBrowserTest,
std::string test_server_ip(embedded_test_server()->host_port_pair().host());
auto nav_map = navigation_map();
ASSERT_TRUE(nav_map);
ASSERT_EQ(std::size_t(5), nav_map->size());
ASSERT_EQ(5U, nav_map->size());
ASSERT_EQ(1U, nav_map->at(initial_url).size());
ASSERT_EQ(1U, nav_map->at(page_before_landing_referrer_url).size());
ASSERT_EQ(1U, nav_map->at(landing_referrer_url).size());
......@@ -1442,22 +1459,23 @@ IN_PROC_BROWSER_TEST_F(SBNavigationObserverBrowserTest,
nav_map->at(download_url).at(0));
VerifyHostToIpMap();
auto referrer_chain = IdentifyReferrerChainForDownload(GetDownload());
EXPECT_EQ(std::size_t(3), referrer_chain.size());
ReferrerChain referrer_chain;
IdentifyReferrerChainForDownload(GetDownload(), &referrer_chain);
EXPECT_EQ(3U, referrer_chain.size());
VerifyReferrerChainEntry(download_url, // url
ReferrerChainEntry::DOWNLOAD_URL, // type
test_server_ip, // ip_address
landing_url, // referrer_url
landing_url, // referrer_main_frame_url
false, // is_retargeting
referrer_chain[0]);
referrer_chain[0].get());
VerifyReferrerChainEntry(landing_url, // url
ReferrerChainEntry::LANDING_PAGE, // type
test_server_ip, // ip_address
landing_referrer_url, // referrer_url
landing_referrer_url, // referrer_main_frame_url
false, // is_retargeting
referrer_chain[1]);
referrer_chain[1].get());
VerifyReferrerChainEntry(
landing_referrer_url, // url
ReferrerChainEntry::LANDING_REFERRER, // type
......@@ -1465,7 +1483,7 @@ IN_PROC_BROWSER_TEST_F(SBNavigationObserverBrowserTest,
GURL(), // referrer_url is empty since this beyonds 2 clicks.
GURL(), // referrer_main_frame_url is empty for the same reason.
false, // is_retargeting
referrer_chain[2]);
referrer_chain[2].get());
// page_before_landing_referrer_url is not in referrer chain.
}
......@@ -1482,7 +1500,7 @@ IN_PROC_BROWSER_TEST_F(SBNavigationObserverBrowserTest,
SimulateUserGesture();
auto nav_map = navigation_map();
ASSERT_TRUE(nav_map);
ASSERT_EQ(std::size_t(3), nav_map->size());
ASSERT_EQ(3U, nav_map->size());
ASSERT_EQ(1U, nav_map->at(redirect_url).size());
ASSERT_EQ(1U, nav_map->at(landing_url).size());
ASSERT_EQ(1U, nav_map->at(initial_url).size());
......@@ -1512,24 +1530,26 @@ IN_PROC_BROWSER_TEST_F(SBNavigationObserverBrowserTest,
nav_map->at(landing_url).at(0));
VerifyHostToIpMap();
auto referrer_chain = IdentifyReferrerChainForPPAPIDownload(
landing_url, browser()->tab_strip_model()->GetActiveWebContents());
EXPECT_EQ(std::size_t(3), referrer_chain.size());
ReferrerChain referrer_chain;
IdentifyReferrerChainForPPAPIDownload(
landing_url,
browser()->tab_strip_model()->GetActiveWebContents(),
&referrer_chain);
EXPECT_EQ(3U, referrer_chain.size());
VerifyReferrerChainEntry(landing_url, // url
ReferrerChainEntry::LANDING_PAGE, // type
test_server_ip, // ip_address
redirect_url, // referrer_url
redirect_url, // referrer_main_frame_url
false, // is_retargeting
referrer_chain[0]);
referrer_chain[0].get());
VerifyReferrerChainEntry(redirect_url, // url
ReferrerChainEntry::CLIENT_REDIRECT, // type
test_server_ip, // ip_address
initial_url, // referrer_url
initial_url, // referrer_main_frame_url
false, // is_retargeting
referrer_chain[1]);
referrer_chain[1].get());
VerifyReferrerChainEntry(
initial_url, // url
ReferrerChainEntry::LANDING_REFERRER, // type
......@@ -1537,7 +1557,7 @@ IN_PROC_BROWSER_TEST_F(SBNavigationObserverBrowserTest,
GURL(), // referrer_url is empty since this beyonds 2 clicks.
GURL(), // referrer_main_frame_url is empty for the same reason.
false, // is_retargeting
referrer_chain[2]);
referrer_chain[2].get());
}
// Click a link which redirects to a page that triggers PPAPI download without
......@@ -1552,7 +1572,7 @@ IN_PROC_BROWSER_TEST_F(SBNavigationObserverBrowserTest,
auto nav_map = navigation_map();
ASSERT_TRUE(nav_map);
ASSERT_EQ(std::size_t(3), nav_map->size());
ASSERT_EQ(3U, nav_map->size());
ASSERT_EQ(1U, nav_map->at(redirect_url).size());
ASSERT_EQ(1U, nav_map->at(hosting_url).size());
ASSERT_EQ(1U, nav_map->at(landing_url).size());
......@@ -1582,31 +1602,33 @@ IN_PROC_BROWSER_TEST_F(SBNavigationObserverBrowserTest,
nav_map->at(hosting_url).at(0));
VerifyHostToIpMap();
auto referrer_chain = IdentifyReferrerChainForPPAPIDownload(
hosting_url, browser()->tab_strip_model()->GetActiveWebContents());
EXPECT_EQ(std::size_t(3), referrer_chain.size());
ReferrerChain referrer_chain;
IdentifyReferrerChainForPPAPIDownload(
hosting_url,
browser()->tab_strip_model()->GetActiveWebContents(),
&referrer_chain);
EXPECT_EQ(3U, referrer_chain.size());
VerifyReferrerChainEntry(hosting_url, // url
ReferrerChainEntry::CLIENT_REDIRECT, // type
test_server_ip, // ip_address
redirect_url, // referrer_url
redirect_url, // referrer_main_frame_url
false, // is_retargeting
referrer_chain[0]);
referrer_chain[0].get());
VerifyReferrerChainEntry(redirect_url, // url
ReferrerChainEntry::CLIENT_REDIRECT, // type
test_server_ip, // ip_address
landing_url, // referrer_url
landing_url, // referrer_main_frame_url
false, // is_retargeting
referrer_chain[1]);
referrer_chain[1].get());
VerifyReferrerChainEntry(landing_url, // url
ReferrerChainEntry::LANDING_PAGE, // type
test_server_ip, // ip_address
GURL(), // no more referrer before landing_url
GURL(),
false, // is_retargeting
referrer_chain[2]);
referrer_chain[2].get());
}
// Server-side redirect.
......@@ -1639,7 +1661,8 @@ IN_PROC_BROWSER_TEST_F(SBNavigationObserverBrowserTest, ServerRedirect) {
true, // has_server_redirect
nav_map->at(download_url).at(0));
auto referrer_chain = IdentifyReferrerChainForDownload(GetDownload());
ReferrerChain referrer_chain;
IdentifyReferrerChainForDownload(GetDownload(), &referrer_chain);
ASSERT_EQ(1U, referrer_chain.size());
VerifyReferrerChainEntry(download_url, // url
ReferrerChainEntry::DOWNLOAD_URL, // type
......@@ -1647,7 +1670,7 @@ IN_PROC_BROWSER_TEST_F(SBNavigationObserverBrowserTest, ServerRedirect) {
GURL(), // referrer_url
GURL(), // referrer_main_frame_url
false, // is_retargeting
referrer_chain[0]);
referrer_chain[0].get());
}
// Retargeting immediately followed by server-side redirect.
......@@ -1690,7 +1713,8 @@ IN_PROC_BROWSER_TEST_F(SBNavigationObserverBrowserTest,
true, // has_server_redirect
nav_map->at(download_url).at(0));
auto referrer_chain = IdentifyReferrerChainForDownload(GetDownload());
ReferrerChain referrer_chain;
IdentifyReferrerChainForDownload(GetDownload(), &referrer_chain);
ASSERT_EQ(2U, referrer_chain.size());
VerifyReferrerChainEntry(download_url, // url
ReferrerChainEntry::DOWNLOAD_URL, // type
......@@ -1698,14 +1722,14 @@ IN_PROC_BROWSER_TEST_F(SBNavigationObserverBrowserTest,
initial_url, // referrer_url
initial_url, // referrer_main_frame_url
true, // is_retargeting
referrer_chain[0]);
referrer_chain[0].get());
VerifyReferrerChainEntry(initial_url, // url
ReferrerChainEntry::LANDING_PAGE, // type
test_server_ip, // ip_address
GURL(), // referrer_url
GURL(), // referrer_main_frame_url
false, // is_retargeting
referrer_chain[1]);
referrer_chain[1].get());
}
// host_to_ip_map_ size should increase by one after a new navigation.
......
......@@ -194,7 +194,7 @@ SafeBrowsingNavigationObserverManager::IdentifyReferrerChainForDownload(
const GURL& target_url,
int target_tab_id,
int user_gesture_count_limit,
std::vector<ReferrerChainEntry>* out_referrer_chain) {
ReferrerChain* out_referrer_chain) {
if (!target_url.is_valid())
return INVALID_URL;
......@@ -225,7 +225,7 @@ SafeBrowsingNavigationObserverManager::IdentifyReferrerChainForPPAPIDownload(
int tab_id,
bool has_user_gesture,
int user_gesture_count_limit,
std::vector<ReferrerChainEntry>* out_referrer_chain) {
ReferrerChain* out_referrer_chain) {
if (!initiating_frame_url.is_valid())
return INVALID_URL;
......@@ -397,7 +397,6 @@ NavigationEvent* SafeBrowsingNavigationObserverManager::FindNavigationEvent(
// the vector in reverse order to get the latest match.
for (auto rit = it->second.rbegin(); rit != it->second.rend(); ++rit) {
// If tab id is not valid, we only compare url, otherwise we compare both.
if (rit->destination_url == search_url)
if (rit->destination_url == search_url &&
(target_tab_id == -1 || rit->target_tab_id == target_tab_id)) {
// If both source_url and source_main_frame_url are empty, and this
......@@ -413,6 +412,8 @@ NavigationEvent* SafeBrowsingNavigationObserverManager::FindNavigationEvent(
FindNavigationEvent(rit->original_request_url,
GURL(),
rit->target_tab_id);
if (!retargeting_nav_event)
return nullptr;
// Adjust retargeting navigation event's attributes.
retargeting_nav_event->has_server_redirect = true;
retargeting_nav_event->destination_url = search_url;
......@@ -429,28 +430,29 @@ NavigationEvent* SafeBrowsingNavigationObserverManager::FindNavigationEvent(
}
void SafeBrowsingNavigationObserverManager::AddToReferrerChain(
std::vector<ReferrerChainEntry>* referrer_chain,
ReferrerChain* referrer_chain,
NavigationEvent* nav_event,
ReferrerChainEntry::URLType type) {
ReferrerChainEntry referrer_chain_entry;
referrer_chain_entry.set_url(nav_event->destination_url.spec());
referrer_chain_entry.set_type(type);
std::unique_ptr<ReferrerChainEntry> referrer_chain_entry =
base::MakeUnique<ReferrerChainEntry>();
referrer_chain_entry->set_url(nav_event->destination_url.spec());
referrer_chain_entry->set_type(type);
auto ip_it = host_to_ip_map_.find(nav_event->destination_url.host());
if (ip_it != host_to_ip_map_.end()) {
for (ResolvedIPAddress entry : ip_it->second) {
referrer_chain_entry.add_ip_addresses(entry.ip);
referrer_chain_entry->add_ip_addresses(entry.ip);
}
}
// Since we only track navigation to landing referrer, we will not log the
// referrer of the landing referrer page.
if (type != ReferrerChainEntry::LANDING_REFERRER) {
referrer_chain_entry.set_referrer_url(nav_event->source_url.spec());
referrer_chain_entry.set_referrer_main_frame_url(
referrer_chain_entry->set_referrer_url(nav_event->source_url.spec());
referrer_chain_entry->set_referrer_main_frame_url(
nav_event->source_main_frame_url.spec());
}
referrer_chain_entry.set_is_retargeting(nav_event->source_tab_id !=
referrer_chain_entry->set_is_retargeting(nav_event->source_tab_id !=
nav_event->target_tab_id);
referrer_chain_entry.set_navigation_time_msec(
referrer_chain_entry->set_navigation_time_msec(
nav_event->last_updated.ToJavaTime());
referrer_chain->push_back(std::move(referrer_chain_entry));
}
......@@ -459,7 +461,7 @@ void SafeBrowsingNavigationObserverManager::GetRemainingReferrerChain(
NavigationEvent* last_nav_event_traced,
int current_user_gesture_count,
int user_gesture_count_limit,
std::vector<ReferrerChainEntry>* out_referrer_chain,
ReferrerChain* out_referrer_chain,
SafeBrowsingNavigationObserverManager::AttributionResult* out_result) {
while (current_user_gesture_count < user_gesture_count_limit) {
......
......@@ -32,6 +32,7 @@ class SafeBrowsingNavigationObserverManager
public base::RefCountedThreadSafe<SafeBrowsingNavigationObserverManager> {
public:
static const base::Feature kDownloadAttribution;
typedef std::vector<std::unique_ptr<ReferrerChainEntry>> ReferrerChain;
// For UMA histogram counting. Do NOT change order.
enum AttributionResult {
......@@ -90,7 +91,7 @@ class SafeBrowsingNavigationObserverManager
const GURL& target_url,
int target_tab_id, // -1 if tab id is not valid
int user_gesture_count_limit,
std::vector<ReferrerChainEntry>* out_referrer_chain);
ReferrerChain* out_referrer_chain);
// Based on the |initiating_frame_url| and its associated |tab_id|, trace back
// the observed NavigationEvents in navigation_map_ to identify the sequence
......@@ -105,7 +106,7 @@ class SafeBrowsingNavigationObserverManager
int tab_id,
bool has_user_gesture,
int user_gesture_count_limit,
std::vector<ReferrerChainEntry>* out_referrer_chain);
ReferrerChain* out_referrer_chain);
private:
friend class base::RefCountedThreadSafe<
......@@ -180,19 +181,18 @@ class SafeBrowsingNavigationObserverManager
const GURL& target_main_frame_url,
int target_tab_id);
void AddToReferrerChain(std::vector<ReferrerChainEntry>* referrer_chain,
void AddToReferrerChain(ReferrerChain* referrer_chain,
NavigationEvent* nav_event,
ReferrerChainEntry::URLType type);
// Helper function to get the remaining referrer chain when we've already
// traced back |current_user_gesture_count| number of user gestures.
// This function modifies the |out_referrer_chain| and |out_result|.
void GetRemainingReferrerChain(
NavigationEvent* last_nav_event_traced,
int current_user_gesture_count,
int user_gesture_count_limit,
std::vector<ReferrerChainEntry>* out_referrer_chain,
AttributionResult* out_result);
void GetRemainingReferrerChain(NavigationEvent* last_nav_event_traced,
int current_user_gesture_count,
int user_gesture_count_limit,
ReferrerChain* out_referrer_chain,
AttributionResult* out_result);
// navigation_map_ keeps track of all the observed navigations. This map is
// keyed on the resolved request url. In other words, in case of server
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment