Commit 2896ec3f authored by Maks Orlovich's avatar Maks Orlovich Committed by Commit Bot

CookieMonster::DeleteCanonicalCookie: use the proper key

Creation time is no longer unique (not that it ever was);
(domain,path,key) is (as it's long been).

Bug: 826322
Change-Id: I433fe3ceffd2b2cfeb5c27c7af0033d69e76301c
Reviewed-on: https://chromium-review.googlesource.com/984514Reviewed-by: default avatarMatt Menke <mmenke@chromium.org>
Reviewed-by: default avatarVictor Costan <pwnall@chromium.org>
Commit-Queue: Maks Orlovich <morlovich@chromium.org>
Cr-Commit-Position: refs/heads/master@{#548762}
parent 95fa24b1
......@@ -810,8 +810,14 @@ void CookieMonster::DeleteCanonicalCookie(const CanonicalCookie& cookie,
uint32_t result = 0u;
for (CookieMapItPair its = cookies_.equal_range(GetKey(cookie.Domain()));
its.first != its.second; ++its.first) {
// The creation date acts as the unique index...
if (its.first->second->CreationDate() == cookie.CreationDate()) {
const std::unique_ptr<CanonicalCookie>& candidate = its.first->second;
// Historically, this has refused modification if the cookie has changed
// value in between the CanonicalCookie object was returned by a getter
// and when this ran. The later parts of the conditional (everything but
// the equivalence check) attempt to preserve this behavior.
if (candidate->IsEquivalent(cookie) &&
candidate->CreationDate() == cookie.CreationDate() &&
candidate->Value() == cookie.Value()) {
InternalDeleteCookie(its.first, true, DELETE_COOKIE_EXPLICIT);
result = 1u;
break;
......
......@@ -19,6 +19,7 @@
#include "base/metrics/histogram_samples.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
#include "base/strings/strcat.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_piece.h"
#include "base/strings/string_split.h"
......@@ -3107,6 +3108,47 @@ TEST_F(CookieMonsterTest, SetCanonicalCookieDoesNotBlockForLoadAll) {
}
}
TEST_F(CookieMonsterTest, DeleteDuplicateCTime) {
const char* const kNames[] = {"A", "B", "C"};
const size_t kNum = arraysize(kNames);
// Tests that DeleteCanonicalCookie properly distinguishes different cookies
// (e.g. different name or path) with identical ctime on same domain.
// This gets tested a few times with different deletion target, to make sure
// that the implementation doesn't just happen to pick the right one because
// of implementation details.
for (size_t run = 0; run < kNum; ++run) {
CookieMonster cm(nullptr);
Time now = Time::Now();
GURL url("http://www.example.com");
for (size_t i = 0; i < kNum; ++i) {
std::string cookie_string =
base::StrCat({kNames[i], "=", base::NumberToString(i)});
EXPECT_TRUE(SetCookieWithCreationTime(&cm, url, cookie_string, now));
}
// Delete the run'th cookie.
CookieList all_cookies =
GetAllCookiesForURLWithOptions(&cm, url, CookieOptions());
ASSERT_EQ(all_cookies.size(), kNum);
for (size_t i = 0; i < kNum; ++i) {
const CanonicalCookie& cookie = all_cookies[i];
if (cookie.Name() == kNames[run]) {
EXPECT_TRUE(DeleteCanonicalCookie(&cm, cookie));
}
}
// Check that the right cookie got removed.
all_cookies = GetAllCookiesForURLWithOptions(&cm, url, CookieOptions());
ASSERT_EQ(all_cookies.size(), kNum - 1);
for (size_t i = 0; i < kNum - 1; ++i) {
const CanonicalCookie& cookie = all_cookies[i];
EXPECT_NE(cookie.Name(), kNames[run]);
}
}
}
class CookieMonsterNotificationTest : public CookieMonsterTest {
public:
CookieMonsterNotificationTest()
......
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