| Index: net/cookies/cookie_monster.cc
|
| diff --git a/net/cookies/cookie_monster.cc b/net/cookies/cookie_monster.cc
|
| index 94d76d59f5a494477e2b5b688b2918c6f35f321f..b01599923ef13e75072f8c9479366916605f4d96 100644
|
| --- a/net/cookies/cookie_monster.cc
|
| +++ b/net/cookies/cookie_monster.cc
|
| @@ -222,14 +222,12 @@ struct CookieSignature {
|
| };
|
|
|
| // For a CookieItVector iterator range [|it_begin|, |it_end|),
|
| -// sorts the first |num_sort| + 1 elements by LastAccessDate().
|
| -// The + 1 element exists so for any interval of length <= |num_sort| starting
|
| -// from |cookies_its_begin|, a LastAccessDate() bound can be found.
|
| +// sorts the first |num_sort| elements by LastAccessDate().
|
| void SortLeastRecentlyAccessed(CookieMonster::CookieItVector::iterator it_begin,
|
| CookieMonster::CookieItVector::iterator it_end,
|
| size_t num_sort) {
|
| - DCHECK_LT(static_cast<int>(num_sort), it_end - it_begin);
|
| - std::partial_sort(it_begin, it_begin + num_sort + 1, it_end, LRACookieSorter);
|
| + DCHECK_LE(static_cast<int>(num_sort), it_end - it_begin);
|
| + std::partial_sort(it_begin, it_begin + num_sort, it_end, LRACookieSorter);
|
| }
|
|
|
| // Given a single cookie vector |cookie_its|, pushs all of the secure cookies in
|
| @@ -2022,18 +2020,44 @@ size_t CookieMonster::GarbageCollect(const Time& current,
|
| SplitCookieVectorIntoSecureAndNonSecure(cookie_its, &secure_cookie_its,
|
| &non_secure_cookie_its);
|
| size_t non_secure_purge_goal =
|
| - std::min<size_t>(purge_goal, non_secure_cookie_its.size() - 1);
|
| + std::min<size_t>(purge_goal, non_secure_cookie_its.size());
|
|
|
| + base::Time earliest_non_secure_access_time;
|
| size_t just_deleted = GarbageCollectLeastRecentlyAccessed(
|
| - current, safe_date, non_secure_purge_goal, non_secure_cookie_its);
|
| + current, safe_date, non_secure_purge_goal, non_secure_cookie_its,
|
| + &earliest_non_secure_access_time);
|
| num_deleted += just_deleted;
|
|
|
| - if (just_deleted < purge_goal && secure_cookie_its.size() > 0) {
|
| - size_t secure_purge_goal = std::min<size_t>(
|
| - purge_goal - just_deleted, secure_cookie_its.size() - 1);
|
| + if (secure_cookie_its.size() == 0) {
|
| + // This case is unlikely, but should still update
|
| + // |earliest_access_time_| if only have non-secure cookies.
|
| + earliest_access_time_ = earliest_non_secure_access_time;
|
| + // Garbage collection can't delete all cookies.
|
| + DCHECK(!earliest_access_time_.is_null());
|
| + } else if (just_deleted < purge_goal) {
|
| + size_t secure_purge_goal = std::min<size_t>(purge_goal - just_deleted,
|
| + secure_cookie_its.size());
|
| + base::Time earliest_secure_access_time;
|
| num_deleted += GarbageCollectLeastRecentlyAccessed(
|
| - current, safe_date, secure_purge_goal, secure_cookie_its);
|
| + current, safe_date, secure_purge_goal, secure_cookie_its,
|
| + &earliest_secure_access_time);
|
| +
|
| + if (!earliest_non_secure_access_time.is_null() &&
|
| + earliest_non_secure_access_time < earliest_secure_access_time) {
|
| + earliest_access_time_ = earliest_non_secure_access_time;
|
| + } else {
|
| + earliest_access_time_ = earliest_secure_access_time;
|
| + }
|
| +
|
| + // Garbage collection can't delete all cookies.
|
| + DCHECK(!earliest_access_time_.is_null());
|
| }
|
| +
|
| + // If there are secure cookies, but deleting non-secure cookies was enough
|
| + // to meet the purge goal, secure cookies are never examined, so
|
| + // |earliest_access_time_| can't be determined. Leaving it alone will mean
|
| + // it's no later than the real earliest last access time, so this won't
|
| + // lead to any problems.
|
| }
|
| }
|
|
|
| @@ -2132,13 +2156,17 @@ size_t CookieMonster::GarbageCollectLeastRecentlyAccessed(
|
| const base::Time& current,
|
| const base::Time& safe_date,
|
| size_t purge_goal,
|
| - CookieItVector cookie_its) {
|
| + CookieItVector cookie_its,
|
| + base::Time* earliest_time) {
|
| + DCHECK_LE(purge_goal, cookie_its.size());
|
| DCHECK(thread_checker_.CalledOnValidThread());
|
|
|
| - // Sorts up to *and including* |cookie_its[purge_goal]|, so
|
| - // |earliest_access_time| will be properly assigned even if
|
| + // Sorts up to *and including* |cookie_its[purge_goal]| (if it exists), so
|
| + // |earliest_time| will be properly assigned even if
|
| // |global_purge_it| == |cookie_its.begin() + purge_goal|.
|
| - SortLeastRecentlyAccessed(cookie_its.begin(), cookie_its.end(), purge_goal);
|
| + SortLeastRecentlyAccessed(
|
| + cookie_its.begin(), cookie_its.end(),
|
| + cookie_its.size() < purge_goal ? purge_goal + 1 : purge_goal);
|
| // Find boundary to cookies older than safe_date.
|
| CookieItVector::iterator global_purge_it = LowerBoundAccessDate(
|
| cookie_its.begin(), cookie_its.begin() + purge_goal, safe_date);
|
| @@ -2146,8 +2174,8 @@ size_t CookieMonster::GarbageCollectLeastRecentlyAccessed(
|
| size_t num_deleted =
|
| GarbageCollectDeleteRange(current, DELETE_COOKIE_EVICTED_GLOBAL,
|
| cookie_its.begin(), global_purge_it);
|
| - // Set access day to the oldest cookie that wasn't deleted.
|
| - earliest_access_time_ = (*global_purge_it)->second->LastAccessDate();
|
| + if (global_purge_it != cookie_its.end())
|
| + *earliest_time = (*global_purge_it)->second->LastAccessDate();
|
| return num_deleted;
|
| }
|
|
|
|
|