summaryrefslogtreecommitdiff
path: root/chromium/net/cookies
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2017-03-08 10:28:10 +0100
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2017-03-20 13:40:30 +0000
commite733310db58160074f574c429d48f8308c0afe17 (patch)
treef8aef4b7e62a69928dbcf880620eece20f98c6df /chromium/net/cookies
parent2f583e4aec1ae3a86fa047829c96b310dc12ecdf (diff)
downloadqtwebengine-chromium-e733310db58160074f574c429d48f8308c0afe17.tar.gz
BASELINE: Update Chromium to 56.0.2924.122
Change-Id: I4e04de8f47e47e501c46ed934c76a431c6337ced Reviewed-by: Michael BrĂ¼ning <michael.bruning@qt.io>
Diffstat (limited to 'chromium/net/cookies')
-rw-r--r--chromium/net/cookies/canonical_cookie.cc3
-rw-r--r--chromium/net/cookies/canonical_cookie.h2
-rw-r--r--chromium/net/cookies/cookie_monster.cc101
-rw-r--r--chromium/net/cookies/cookie_monster.h33
-rw-r--r--chromium/net/cookies/cookie_monster_perftest.cc4
-rw-r--r--chromium/net/cookies/cookie_monster_store_test.cc53
-rw-r--r--chromium/net/cookies/cookie_monster_store_test.h29
-rw-r--r--chromium/net/cookies/cookie_monster_unittest.cc47
-rw-r--r--chromium/net/cookies/cookie_util.cc85
-rw-r--r--chromium/net/cookies/cookie_util.h9
-rw-r--r--chromium/net/cookies/cookie_util_unittest.cc186
11 files changed, 321 insertions, 231 deletions
diff --git a/chromium/net/cookies/canonical_cookie.cc b/chromium/net/cookies/canonical_cookie.cc
index bbabbb771a4..de2fbbe6c65 100644
--- a/chromium/net/cookies/canonical_cookie.cc
+++ b/chromium/net/cookies/canonical_cookie.cc
@@ -157,7 +157,8 @@ Time CanonicalCookie::CanonExpiration(const ParsedCookie& pc,
// Try the Expires attribute.
if (pc.HasExpires() && !pc.Expires().empty()) {
// Adjust for clock skew between server and host.
- base::Time parsed_expiry = cookie_util::ParseCookieTime(pc.Expires());
+ base::Time parsed_expiry =
+ cookie_util::ParseCookieExpirationTime(pc.Expires());
if (!parsed_expiry.is_null())
return parsed_expiry + (current - server_time);
}
diff --git a/chromium/net/cookies/canonical_cookie.h b/chromium/net/cookies/canonical_cookie.h
index 4102299e425..2ef9131e1a6 100644
--- a/chromium/net/cookies/canonical_cookie.h
+++ b/chromium/net/cookies/canonical_cookie.h
@@ -139,6 +139,8 @@ class NET_EXPORT CanonicalCookie {
std::string DebugString() const;
static std::string CanonPath(const GURL& url, const ParsedCookie& pc);
+
+ // Returns a "null" time if expiration was unspecified or invalid.
static base::Time CanonExpiration(const ParsedCookie& pc,
const base::Time& current,
const base::Time& server_time);
diff --git a/chromium/net/cookies/cookie_monster.cc b/chromium/net/cookies/cookie_monster.cc
index 9925dbc1b97..b656d83e6c0 100644
--- a/chromium/net/cookies/cookie_monster.cc
+++ b/chromium/net/cookies/cookie_monster.cc
@@ -1006,7 +1006,7 @@ CookieMonster::AddCallbackForCookie(const GURL& gurl,
std::pair<GURL, std::string> key(gurl, name);
if (hook_map_.count(key) == 0)
- hook_map_[key] = make_linked_ptr(new CookieChangedCallbackList());
+ hook_map_[key] = base::MakeUnique<CookieChangedCallbackList>();
return hook_map_[key]->Add(
base::Bind(&RunAsync, base::ThreadTaskRunnerHandle::Get(), callback));
}
@@ -1094,15 +1094,14 @@ CookieList CookieMonster::GetAllCookies() {
// sorter as elsewhere, then copy the result out.
std::vector<CanonicalCookie*> cookie_ptrs;
cookie_ptrs.reserve(cookies_.size());
- for (CookieMap::iterator it = cookies_.begin(); it != cookies_.end(); ++it)
- cookie_ptrs.push_back(it->second);
+ for (const auto& cookie : cookies_)
+ cookie_ptrs.push_back(cookie.second.get());
std::sort(cookie_ptrs.begin(), cookie_ptrs.end(), CookieSorter);
CookieList cookie_list;
cookie_list.reserve(cookie_ptrs.size());
- for (std::vector<CanonicalCookie*>::const_iterator it = cookie_ptrs.begin();
- it != cookie_ptrs.end(); ++it)
- cookie_list.push_back(**it);
+ for (const auto& cookie_ptr : cookie_ptrs)
+ cookie_list.push_back(*cookie_ptr);
return cookie_list;
}
@@ -1135,7 +1134,7 @@ int CookieMonster::DeleteAllCreatedBetween(const Time& delete_begin,
int num_deleted = 0;
for (CookieMap::iterator it = cookies_.begin(); it != cookies_.end();) {
CookieMap::iterator curit = it;
- CanonicalCookie* cc = curit->second;
+ CanonicalCookie* cc = curit->second.get();
++it;
if (cc->CreationDate() >= delete_begin &&
@@ -1156,7 +1155,7 @@ int CookieMonster::DeleteAllCreatedBetweenWithPredicate(
int num_deleted = 0;
for (CookieMap::iterator it = cookies_.begin(); it != cookies_.end();) {
CookieMap::iterator curit = it;
- CanonicalCookie* cc = curit->second;
+ CanonicalCookie* cc = curit->second.get();
++it;
if (cc->CreationDate() >= delete_begin &&
@@ -1230,7 +1229,7 @@ void CookieMonster::DeleteCookie(const GURL& url,
for (CookieMap::iterator it = cookies_.begin(); it != cookies_.end();) {
CookieMap::iterator curit = it;
++it;
- if (matching_cookies.find(curit->second) != matching_cookies.end()) {
+ if (matching_cookies.find(curit->second.get()) != matching_cookies.end()) {
InternalDeleteCookie(curit, true, DELETE_COOKIE_EXPLICIT);
}
}
@@ -1274,7 +1273,7 @@ int CookieMonster::DeleteSessionCookies() {
int num_deleted = 0;
for (CookieMap::iterator it = cookies_.begin(); it != cookies_.end();) {
CookieMap::iterator curit = it;
- CanonicalCookie* cc = curit->second;
+ CanonicalCookie* cc = curit->second.get();
++it;
if (!cc->IsPersistent()) {
@@ -1332,21 +1331,23 @@ bool CookieMonster::ShouldFetchAllCookiesWhenFetchingAnyCookie() {
return fetch_strategy_ == kAlwaysFetch;
}
-void CookieMonster::OnLoaded(TimeTicks beginning_time,
- const std::vector<CanonicalCookie*>& cookies) {
+void CookieMonster::OnLoaded(
+ TimeTicks beginning_time,
+ std::vector<std::unique_ptr<CanonicalCookie>> cookies) {
DCHECK(thread_checker_.CalledOnValidThread());
- StoreLoadedCookies(cookies);
+ StoreLoadedCookies(std::move(cookies));
histogram_time_blocked_on_load_->AddTime(TimeTicks::Now() - beginning_time);
// Invoke the task queue of cookie request.
InvokeQueue();
}
-void CookieMonster::OnKeyLoaded(const std::string& key,
- const std::vector<CanonicalCookie*>& cookies) {
+void CookieMonster::OnKeyLoaded(
+ const std::string& key,
+ std::vector<std::unique_ptr<CanonicalCookie>> cookies) {
DCHECK(thread_checker_.CalledOnValidThread());
- StoreLoadedCookies(cookies);
+ StoreLoadedCookies(std::move(cookies));
auto tasks_pending_for_key = tasks_pending_for_key_.find(key);
@@ -1372,7 +1373,7 @@ void CookieMonster::OnKeyLoaded(const std::string& key,
}
void CookieMonster::StoreLoadedCookies(
- const std::vector<CanonicalCookie*>& cookies) {
+ std::vector<std::unique_ptr<CanonicalCookie>> cookies) {
DCHECK(thread_checker_.CalledOnValidThread());
// TODO(erikwright): Remove ScopedTracker below once crbug.com/457528 is
@@ -1385,20 +1386,20 @@ void CookieMonster::StoreLoadedCookies(
// removed, and sync'd.
CookieItVector cookies_with_control_chars;
- for (std::vector<CanonicalCookie*>::const_iterator it = cookies.begin();
- it != cookies.end(); ++it) {
- int64_t cookie_creation_time = (*it)->CreationDate().ToInternalValue();
+ for (auto& cookie : cookies) {
+ int64_t cookie_creation_time = cookie->CreationDate().ToInternalValue();
if (creation_times_.insert(cookie_creation_time).second) {
- CookieMap::iterator inserted =
- InternalInsertCookie(GetKey((*it)->Domain()), *it, GURL(), false);
- const Time cookie_access_time((*it)->LastAccessDate());
+ CanonicalCookie* cookie_ptr = cookie.get();
+ CookieMap::iterator inserted = InternalInsertCookie(
+ GetKey(cookie_ptr->Domain()), std::move(cookie), GURL(), false);
+ const Time cookie_access_time(cookie_ptr->LastAccessDate());
if (earliest_access_time_.is_null() ||
cookie_access_time < earliest_access_time_)
earliest_access_time_ = cookie_access_time;
- if (ContainsControlCharacter((*it)->Name()) ||
- ContainsControlCharacter((*it)->Value())) {
+ if (ContainsControlCharacter(cookie_ptr->Name()) ||
+ ContainsControlCharacter(cookie_ptr->Value())) {
cookies_with_control_chars.push_back(inserted);
}
} else {
@@ -1406,11 +1407,8 @@ void CookieMonster::StoreLoadedCookies(
"Found cookies with duplicate creation "
"times in backing store: "
"{name='%s', domain='%s', path='%s'}",
- (*it)->Name().c_str(), (*it)->Domain().c_str(),
- (*it)->Path().c_str());
- // We've been given ownership of the cookie and are throwing it
- // away; reclaim the space.
- delete (*it);
+ cookie->Name().c_str(), cookie->Domain().c_str(),
+ cookie->Path().c_str());
}
}
@@ -1498,7 +1496,7 @@ void CookieMonster::TrimDuplicateCookiesForKey(const std::string& key,
// the equivalence map.
for (CookieMap::iterator it = begin; it != end; ++it) {
DCHECK_EQ(key, it->first);
- CanonicalCookie* cookie = it->second;
+ CanonicalCookie* cookie = it->second.get();
CookieSignature signature(cookie->Name(), cookie->Domain(), cookie->Path());
CookieSet& set = equivalent_cookies[signature];
@@ -1582,7 +1580,7 @@ void CookieMonster::FindCookiesForKey(const std::string& key,
for (CookieMapItPair its = cookies_.equal_range(key);
its.first != its.second;) {
CookieMap::iterator curit = its.first;
- CanonicalCookie* cc = curit->second;
+ CanonicalCookie* cc = curit->second.get();
++its.first;
// If the cookie is expired, delete it.
@@ -1623,7 +1621,7 @@ bool CookieMonster::DeleteAnyEquivalentCookie(const std::string& key,
for (CookieMapItPair its = cookies_.equal_range(key);
its.first != its.second;) {
CookieMap::iterator curit = its.first;
- CanonicalCookie* cc = curit->second;
+ CanonicalCookie* cc = curit->second.get();
++its.first;
// If strict secure cookies is being enforced, then the equivalency
@@ -1674,25 +1672,28 @@ bool CookieMonster::DeleteAnyEquivalentCookie(const std::string& key,
CookieMonster::CookieMap::iterator CookieMonster::InternalInsertCookie(
const std::string& key,
- CanonicalCookie* cc,
+ std::unique_ptr<CanonicalCookie> cc,
const GURL& source_url,
bool sync_to_store) {
DCHECK(thread_checker_.CalledOnValidThread());
+ CanonicalCookie* cc_ptr = cc.get();
- if ((cc->IsPersistent() || persist_session_cookies_) && store_.get() &&
+ if ((cc_ptr->IsPersistent() || persist_session_cookies_) && store_.get() &&
sync_to_store)
- store_->AddCookie(*cc);
+ store_->AddCookie(*cc_ptr);
CookieMap::iterator inserted =
- cookies_.insert(CookieMap::value_type(key, cc));
- if (delegate_.get())
- delegate_->OnCookieChanged(*cc, false, CookieStore::ChangeCause::INSERTED);
+ cookies_.insert(CookieMap::value_type(key, std::move(cc)));
+ if (delegate_.get()) {
+ delegate_->OnCookieChanged(*cc_ptr, false,
+ CookieStore::ChangeCause::INSERTED);
+ }
// See InitializeHistograms() for details.
- int32_t type_sample = cc->SameSite() != CookieSameSite::NO_RESTRICTION
+ int32_t type_sample = cc_ptr->SameSite() != CookieSameSite::NO_RESTRICTION
? 1 << COOKIE_TYPE_SAME_SITE
: 0;
- type_sample |= cc->IsHttpOnly() ? 1 << COOKIE_TYPE_HTTPONLY : 0;
- type_sample |= cc->IsSecure() ? 1 << COOKIE_TYPE_SECURE : 0;
+ type_sample |= cc_ptr->IsHttpOnly() ? 1 << COOKIE_TYPE_HTTPONLY : 0;
+ type_sample |= cc_ptr->IsSecure() ? 1 << COOKIE_TYPE_SECURE : 0;
histogram_cookie_type_->Add(type_sample);
// Histogram the type of scheme used on URLs that set cookies. This
@@ -1704,18 +1705,19 @@ CookieMonster::CookieMap::iterator CookieMonster::InternalInsertCookie(
CookieSource cookie_source_sample;
if (source_url.SchemeIsCryptographic()) {
cookie_source_sample =
- cc->IsSecure() ? COOKIE_SOURCE_SECURE_COOKIE_CRYPTOGRAPHIC_SCHEME
- : COOKIE_SOURCE_NONSECURE_COOKIE_CRYPTOGRAPHIC_SCHEME;
+ cc_ptr->IsSecure()
+ ? COOKIE_SOURCE_SECURE_COOKIE_CRYPTOGRAPHIC_SCHEME
+ : COOKIE_SOURCE_NONSECURE_COOKIE_CRYPTOGRAPHIC_SCHEME;
} else {
cookie_source_sample =
- cc->IsSecure()
+ cc_ptr->IsSecure()
? COOKIE_SOURCE_SECURE_COOKIE_NONCRYPTOGRAPHIC_SCHEME
: COOKIE_SOURCE_NONSECURE_COOKIE_NONCRYPTOGRAPHIC_SCHEME;
}
histogram_cookie_source_scheme_->Add(cookie_source_sample);
}
- RunCookieChangedCallbacks(*cc, CookieStore::ChangeCause::INSERTED);
+ RunCookieChangedCallbacks(*cc_ptr, CookieStore::ChangeCause::INSERTED);
return inserted;
}
@@ -1782,7 +1784,7 @@ bool CookieMonster::SetCanonicalCookie(std::unique_ptr<CanonicalCookie> cc,
(cc->ExpiryDate() - creation_time).InMinutes());
}
- InternalInsertCookie(key, cc.release(), source_url, true);
+ InternalInsertCookie(key, std::move(cc), source_url, true);
} else {
VLOG(kVlogSetCookies) << "SetCookie() not storing already expired cookie.";
}
@@ -1847,7 +1849,7 @@ void CookieMonster::InternalDeleteCookie(CookieMap::iterator it,
if (deletion_cause != DELETE_COOKIE_DONT_RECORD)
histogram_cookie_deletion_cause_->Add(deletion_cause);
- CanonicalCookie* cc = it->second;
+ CanonicalCookie* cc = it->second.get();
VLOG(kVlogSetCookies) << "InternalDeleteCookie()"
<< ", cause:" << deletion_cause
<< ", cc: " << cc->DebugString();
@@ -1860,7 +1862,6 @@ void CookieMonster::InternalDeleteCookie(CookieMap::iterator it,
delegate_->OnCookieChanged(*cc, true, mapping.cause);
RunCookieChangedCallbacks(*cc, mapping.cause);
cookies_.erase(it);
- delete cc;
}
// Domain expiry behavior is unchanged by key/expiry scheme (the
@@ -2045,7 +2046,7 @@ size_t CookieMonster::PurgeLeastRecentMatches(CookieItVector* cookies,
size_t current = 0u;
while ((removed < purge_goal && current < cookies->size()) &&
cookies_count_possibly_to_be_deleted > 0) {
- const CanonicalCookie* current_cookie = cookies->at(current)->second;
+ const CanonicalCookie* current_cookie = cookies->at(current)->second.get();
// Only delete the current cookie if the priority is equal to
// the current level.
if (IsCookieEligibleForEviction(priority, protect_secure_cookies,
diff --git a/chromium/net/cookies/cookie_monster.h b/chromium/net/cookies/cookie_monster.h
index 087099c92b3..8dea3d32903 100644
--- a/chromium/net/cookies/cookie_monster.h
+++ b/chromium/net/cookies/cookie_monster.h
@@ -50,7 +50,7 @@ class CookieMonsterDelegate;
// backing store. Otherwise, callbacks may be invoked immediately.
//
// A cookie task is either pending loading of the entire cookie store, or
-// loading of cookies for a specfic domain key(eTLD+1). In the former case, the
+// loading of cookies for a specific domain key(eTLD+1). In the former case, the
// cookie task will be queued in tasks_pending_ while PersistentCookieStore
// chain loads the cookie store on DB thread. In the latter case, the cookie
// task will be queued in tasks_pending_for_key_ while PermanentCookieStore
@@ -97,10 +97,11 @@ class NET_EXPORT CookieMonster : public CookieStore {
// for the hashing might not overcome the O(log(1000)) for querying
// a multimap. Also, multimap is standard, another reason to use it.
// TODO(rdsmith): This benchmark should be re-done now that we're allowing
- // subtantially more entries in the map.
- typedef std::multimap<std::string, CanonicalCookie*> CookieMap;
- typedef std::pair<CookieMap::iterator, CookieMap::iterator> CookieMapItPair;
- typedef std::vector<CookieMap::iterator> CookieItVector;
+ // substantially more entries in the map.
+ using CookieMap =
+ std::multimap<std::string, std::unique_ptr<CanonicalCookie>>;
+ using CookieMapItPair = std::pair<CookieMap::iterator, CookieMap::iterator>;
+ using CookieItVector = std::vector<CookieMap::iterator>;
// Cookie garbage collection thresholds. Based off of the Mozilla defaults.
// When the number of cookies gets to k{Domain,}MaxCookies
@@ -243,7 +244,7 @@ class NET_EXPORT CookieMonster : public CookieStore {
CookieMonsterTest,
TestCookieDeleteAllCreatedBetweenTimestampsWithPredicate);
- // For gargage collection constants.
+ // For garbage collection constants.
FRIEND_TEST_ALL_PREFIXES(CookieMonsterTest, TestHostGarbageCollection);
FRIEND_TEST_ALL_PREFIXES(CookieMonsterTest, TestTotalGarbageCollection);
FRIEND_TEST_ALL_PREFIXES(CookieMonsterTest, GarbageCollectionTriggers);
@@ -451,7 +452,7 @@ class NET_EXPORT CookieMonster : public CookieStore {
// was invoked and is used for reporting histogram_time_blocked_on_load_.
// See PersistentCookieStore::Load for details on the contents of cookies.
void OnLoaded(base::TimeTicks beginning_time,
- const std::vector<CanonicalCookie*>& cookies);
+ std::vector<std::unique_ptr<CanonicalCookie>> cookies);
// Stores cookies loaded from the backing store and invokes the deferred
// task(s) pending loading of cookies associated with the domain key
@@ -459,10 +460,11 @@ class NET_EXPORT CookieMonster : public CookieStore {
// loaded from DB. See PersistentCookieStore::Load for details on the contents
// of cookies.
void OnKeyLoaded(const std::string& key,
- const std::vector<CanonicalCookie*>& cookies);
+ std::vector<std::unique_ptr<CanonicalCookie>> cookies);
// Stores the loaded cookies.
- void StoreLoadedCookies(const std::vector<CanonicalCookie*>& cookies);
+ void StoreLoadedCookies(
+ std::vector<std::unique_ptr<CanonicalCookie>> cookies);
// Invokes deferred calls.
void InvokeQueue();
@@ -505,10 +507,10 @@ class NET_EXPORT CookieMonster : public CookieStore {
bool already_expired,
bool enforce_strict_secure);
- // Takes ownership of *cc. Returns an iterator that points to the inserted
+ // Inserts |cc| into cookies_. Returns an iterator that points to the inserted
// cookie in cookies_. Guarantee: all iterators to cookies_ remain valid.
CookieMap::iterator InternalInsertCookie(const std::string& key,
- CanonicalCookie* cc,
+ std::unique_ptr<CanonicalCookie> cc,
const GURL& source_url,
bool sync_to_store);
@@ -536,7 +538,7 @@ class NET_EXPORT CookieMonster : public CookieStore {
// |deletion_cause| argument is used for collecting statistics and choosing
// the correct CookieStore::ChangeCause for OnCookieChanged
// notifications. Guarantee: All iterators to cookies_ except to the
- // deleted entry remain vaild.
+ // deleted entry remain valid.
void InternalDeleteCookie(CookieMap::iterator it,
bool sync_to_store,
DeletionCause deletion_cause);
@@ -714,8 +716,9 @@ class NET_EXPORT CookieMonster : public CookieStore {
bool persist_session_cookies_;
- typedef std::map<std::pair<GURL, std::string>,
- linked_ptr<CookieChangedCallbackList>> CookieChangedHookMap;
+ using CookieChangedHookMap =
+ std::map<std::pair<GURL, std::string>,
+ std::unique_ptr<CookieChangedCallbackList>>;
CookieChangedHookMap hook_map_;
base::ThreadChecker thread_checker_;
@@ -754,7 +757,7 @@ typedef base::RefCountedThreadSafe<CookieMonster::PersistentCookieStore>
class NET_EXPORT CookieMonster::PersistentCookieStore
: public RefcountedPersistentCookieStore {
public:
- typedef base::Callback<void(const std::vector<CanonicalCookie*>&)>
+ typedef base::Callback<void(std::vector<std::unique_ptr<CanonicalCookie>>)>
LoadedCallback;
// TODO(erikchen): Depending on the results of the cookie monster Finch
diff --git a/chromium/net/cookies/cookie_monster_perftest.cc b/chromium/net/cookies/cookie_monster_perftest.cc
index 983f5ee2e54..eb9ce7b9435 100644
--- a/chromium/net/cookies/cookie_monster_perftest.cc
+++ b/chromium/net/cookies/cookie_monster_perftest.cc
@@ -282,7 +282,7 @@ TEST_F(CookieMonsterTest, TestDomainLine) {
TEST_F(CookieMonsterTest, TestImport) {
scoped_refptr<MockPersistentCookieStore> store(new MockPersistentCookieStore);
- std::vector<CanonicalCookie*> initial_cookies;
+ std::vector<std::unique_ptr<CanonicalCookie>> initial_cookies;
GetCookiesCallback getCookiesCallback;
// We want to setup a fairly large backing store, with 300 domains of 50
@@ -300,7 +300,7 @@ TEST_F(CookieMonsterTest, TestImport) {
}
}
- store->SetLoadExpectation(true, initial_cookies);
+ store->SetLoadExpectation(true, std::move(initial_cookies));
std::unique_ptr<CookieMonster> cm(new CookieMonster(store.get(), nullptr));
diff --git a/chromium/net/cookies/cookie_monster_store_test.cc b/chromium/net/cookies/cookie_monster_store_test.cc
index 7a8af87c47e..1375134a16c 100644
--- a/chromium/net/cookies/cookie_monster_store_test.cc
+++ b/chromium/net/cookies/cookie_monster_store_test.cc
@@ -19,14 +19,6 @@
namespace net {
-LoadedCallbackTask::LoadedCallbackTask(LoadedCallback loaded_callback,
- std::vector<CanonicalCookie*> cookies)
- : loaded_callback_(loaded_callback), cookies_(cookies) {
-}
-
-LoadedCallbackTask::~LoadedCallbackTask() {
-}
-
CookieStoreCommand::CookieStoreCommand(
Type type,
const CookieMonster::PersistentCookieStore::LoadedCallback& loaded_callback,
@@ -46,9 +38,9 @@ MockPersistentCookieStore::MockPersistentCookieStore()
void MockPersistentCookieStore::SetLoadExpectation(
bool return_value,
- const std::vector<CanonicalCookie*>& result) {
+ std::vector<std::unique_ptr<CanonicalCookie>> result) {
load_return_value_ = return_value;
- load_result_ = result;
+ load_result_.swap(result);
}
void MockPersistentCookieStore::Load(const LoadedCallback& loaded_callback) {
@@ -57,15 +49,13 @@ void MockPersistentCookieStore::Load(const LoadedCallback& loaded_callback) {
CookieStoreCommand(CookieStoreCommand::LOAD, loaded_callback, ""));
return;
}
- std::vector<CanonicalCookie*> out_cookies;
+ std::vector<std::unique_ptr<CanonicalCookie>> out_cookies;
if (load_return_value_) {
- out_cookies = load_result_;
+ out_cookies.swap(load_result_);
loaded_ = true;
}
base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE,
- base::Bind(&LoadedCallbackTask::Run,
- new LoadedCallbackTask(loaded_callback, out_cookies)));
+ FROM_HERE, base::Bind(loaded_callback, base::Passed(&out_cookies)));
}
void MockPersistentCookieStore::LoadCookiesForKey(
@@ -79,11 +69,9 @@ void MockPersistentCookieStore::LoadCookiesForKey(
if (!loaded_) {
Load(loaded_callback);
} else {
+ std::vector<std::unique_ptr<CanonicalCookie>> empty_cookies;
base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE,
- base::Bind(&LoadedCallbackTask::Run,
- new LoadedCallbackTask(loaded_callback,
- std::vector<CanonicalCookie*>())));
+ FROM_HERE, base::Bind(loaded_callback, base::Passed(&empty_cookies)));
}
}
@@ -137,9 +125,9 @@ std::unique_ptr<CanonicalCookie> BuildCanonicalCookie(
// functions. Would be nice to export them, and re-use here.
EXPECT_FALSE(pc.HasMaxAge());
EXPECT_TRUE(pc.HasPath());
- base::Time cookie_expires = pc.HasExpires()
- ? cookie_util::ParseCookieTime(pc.Expires())
- : base::Time();
+ base::Time cookie_expires =
+ pc.HasExpires() ? cookie_util::ParseCookieExpirationTime(pc.Expires())
+ : base::Time();
std::string cookie_path = pc.Path();
return CanonicalCookie::Create(url, pc.Name(), pc.Value(), url.host(),
@@ -151,11 +139,11 @@ std::unique_ptr<CanonicalCookie> BuildCanonicalCookie(
void AddCookieToList(const GURL& url,
const std::string& cookie_line,
const base::Time& creation_time,
- std::vector<CanonicalCookie*>* out_list) {
+ std::vector<std::unique_ptr<CanonicalCookie>>* out_list) {
std::unique_ptr<CanonicalCookie> cookie(
BuildCanonicalCookie(url, cookie_line, creation_time));
- out_list->push_back(cookie.release());
+ out_list->push_back(std::move(cookie));
}
MockSimplePersistentCookieStore::MockSimplePersistentCookieStore()
@@ -164,16 +152,13 @@ MockSimplePersistentCookieStore::MockSimplePersistentCookieStore()
void MockSimplePersistentCookieStore::Load(
const LoadedCallback& loaded_callback) {
- std::vector<CanonicalCookie*> out_cookies;
+ std::vector<std::unique_ptr<CanonicalCookie>> out_cookies;
- for (CanonicalCookieMap::const_iterator it = cookies_.begin();
- it != cookies_.end(); it++)
- out_cookies.push_back(new CanonicalCookie(it->second));
+ for (auto it = cookies_.begin(); it != cookies_.end(); it++)
+ out_cookies.push_back(base::MakeUnique<CanonicalCookie>(it->second));
base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE,
- base::Bind(&LoadedCallbackTask::Run,
- new LoadedCallbackTask(loaded_callback, out_cookies)));
+ FROM_HERE, base::Bind(loaded_callback, base::Passed(&out_cookies)));
loaded_ = true;
}
@@ -183,11 +168,9 @@ void MockSimplePersistentCookieStore::LoadCookiesForKey(
if (!loaded_) {
Load(loaded_callback);
} else {
+ std::vector<std::unique_ptr<CanonicalCookie>> empty_cookies;
base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE,
- base::Bind(&LoadedCallbackTask::Run,
- new LoadedCallbackTask(loaded_callback,
- std::vector<CanonicalCookie*>())));
+ FROM_HERE, base::Bind(loaded_callback, base::Passed(&empty_cookies)));
}
}
diff --git a/chromium/net/cookies/cookie_monster_store_test.h b/chromium/net/cookies/cookie_monster_store_test.h
index 835ec6d0520..29b063fd1aa 100644
--- a/chromium/net/cookies/cookie_monster_store_test.h
+++ b/chromium/net/cookies/cookie_monster_store_test.h
@@ -30,29 +30,6 @@ class Time;
namespace net {
-// Wrapper class for posting a loaded callback. Since the Callback class is not
-// reference counted, we cannot post a callback to the message loop directly,
-// instead we post a LoadedCallbackTask.
-class LoadedCallbackTask
- : public base::RefCountedThreadSafe<LoadedCallbackTask> {
- public:
- typedef CookieMonster::PersistentCookieStore::LoadedCallback LoadedCallback;
-
- LoadedCallbackTask(LoadedCallback loaded_callback,
- std::vector<CanonicalCookie*> cookies);
-
- void Run() { loaded_callback_.Run(cookies_); }
-
- private:
- friend class base::RefCountedThreadSafe<LoadedCallbackTask>;
- ~LoadedCallbackTask();
-
- LoadedCallback loaded_callback_;
- std::vector<CanonicalCookie*> cookies_;
-
- DISALLOW_COPY_AND_ASSIGN(LoadedCallbackTask);
-}; // Wrapper class LoadedCallbackTask
-
// Describes a call to one of the 5 functions of PersistentCookieStore.
struct CookieStoreCommand {
enum Type {
@@ -107,7 +84,7 @@ class MockPersistentCookieStore : public CookieMonster::PersistentCookieStore {
}
void SetLoadExpectation(bool return_value,
- const std::vector<CanonicalCookie*>& result);
+ std::vector<std::unique_ptr<CanonicalCookie>> result);
const CommandList& commands() const { return commands_; }
@@ -136,7 +113,7 @@ class MockPersistentCookieStore : public CookieMonster::PersistentCookieStore {
// Deferred result to use when Load() is called.
bool load_return_value_;
- std::vector<CanonicalCookie*> load_result_;
+ std::vector<std::unique_ptr<CanonicalCookie>> load_result_;
// Indicates if the store has been fully loaded to avoid returning duplicate
// cookies.
bool loaded_;
@@ -177,7 +154,7 @@ std::unique_ptr<CanonicalCookie> BuildCanonicalCookie(
void AddCookieToList(const GURL& url,
const std::string& cookie_line,
const base::Time& creation_time,
- std::vector<CanonicalCookie*>* out_list);
+ std::vector<std::unique_ptr<CanonicalCookie>>* out_list);
// Just act like a backing database. Keep cookie information from
// Add/Update/Delete and regurgitate it when Load is called.
diff --git a/chromium/net/cookies/cookie_monster_unittest.cc b/chromium/net/cookies/cookie_monster_unittest.cc
index 9414fe11d4c..2c5ae97212b 100644
--- a/chromium/net/cookies/cookie_monster_unittest.cc
+++ b/chromium/net/cookies/cookie_monster_unittest.cc
@@ -974,11 +974,11 @@ class DeferredCookieTaskTest : public CookieMonsterTest {
// and PersistentCookieStore::Load completion callback.
void CompleteLoading() {
while (!loaded_for_key_callbacks_.empty()) {
- loaded_for_key_callbacks_.front().Run(loaded_cookies_);
+ loaded_for_key_callbacks_.front().Run(std::move(loaded_cookies_));
loaded_cookies_.clear();
loaded_for_key_callbacks_.pop();
}
- loaded_callback_.Run(loaded_cookies_);
+ loaded_callback_.Run(std::move(loaded_cookies_));
}
// Performs the provided action, expecting it to cause a call to
@@ -1027,7 +1027,7 @@ class DeferredCookieTaskTest : public CookieMonsterTest {
testing::InSequence in_sequence_;
// Holds cookies to be returned from PersistentCookieStore::Load or
// PersistentCookieStore::LoadCookiesForKey.
- std::vector<CanonicalCookie*> loaded_cookies_;
+ std::vector<std::unique_ptr<CanonicalCookie>> loaded_cookies_;
// Stores the callback passed from the CookieMonster to the
// PersistentCookieStore::Load
CookieMonster::PersistentCookieStore::LoadedCallback loaded_callback_;
@@ -1310,7 +1310,7 @@ TEST_F(DeferredCookieTaskTest,
}
TEST_F(DeferredCookieTaskTest, DeferredDeleteCanonicalCookie) {
- std::vector<CanonicalCookie*> cookies;
+ std::vector<std::unique_ptr<CanonicalCookie>> cookies;
std::unique_ptr<CanonicalCookie> cookie = BuildCanonicalCookie(
http_www_google_.url(), "X=1; path=/", base::Time::Now());
@@ -1789,7 +1789,7 @@ TEST_F(CookieMonsterTest, DontImportDuplicateCookies) {
// be careful not to have any duplicate creation times at all (as it's a
// violation of a CookieMonster invariant) even if Time::Now() doesn't
// move between calls.
- std::vector<CanonicalCookie*> initial_cookies;
+ std::vector<std::unique_ptr<CanonicalCookie>> initial_cookies;
// Insert 4 cookies with name "X" on path "/", with varying creation
// dates. We expect only the most recent one to be preserved following
@@ -1830,7 +1830,7 @@ TEST_F(CookieMonsterTest, DontImportDuplicateCookies) {
Time::Now() + TimeDelta::FromDays(10), &initial_cookies);
// Inject our initial cookies into the mock PersistentCookieStore.
- store->SetLoadExpectation(true, initial_cookies);
+ store->SetLoadExpectation(true, std::move(initial_cookies));
std::unique_ptr<CookieMonster> cm(new CookieMonster(store.get(), nullptr));
@@ -1866,7 +1866,7 @@ TEST_F(CookieMonsterTest, DontImportDuplicateCreationTimes) {
// four with the earlier time as creation times. We should only get
// two cookies remaining, but which two (other than that there should
// be one from each set) will be random.
- std::vector<CanonicalCookie*> initial_cookies;
+ std::vector<std::unique_ptr<CanonicalCookie>> initial_cookies;
AddCookieToList(GURL("http://www.google.com"), "X=1; path=/", now,
&initial_cookies);
AddCookieToList(GURL("http://www.google.com"), "X=2; path=/", now,
@@ -1886,7 +1886,7 @@ TEST_F(CookieMonsterTest, DontImportDuplicateCreationTimes) {
&initial_cookies);
// Inject our initial cookies into the mock PersistentCookieStore.
- store->SetLoadExpectation(true, initial_cookies);
+ store->SetLoadExpectation(true, std::move(initial_cookies));
std::unique_ptr<CookieMonster> cm(new CookieMonster(store.get(), nullptr));
@@ -2301,7 +2301,8 @@ TEST_F(CookieMonsterTest, WhileLoadingLoadCompletesBeforeKeyLoadCompletes) {
store->commands()[1].type);
// The main load completes first (With no cookies).
- store->commands()[0].loaded_callback.Run(std::vector<CanonicalCookie*>());
+ store->commands()[0].loaded_callback.Run(
+ std::vector<std::unique_ptr<CanonicalCookie>>());
// The tasks should run in order, and the get should see the cookies.
@@ -2313,7 +2314,8 @@ TEST_F(CookieMonsterTest, WhileLoadingLoadCompletesBeforeKeyLoadCompletes) {
// The loaded for key event completes late, with not cookies (Since they
// were already loaded).
- store->commands()[1].loaded_callback.Run(std::vector<CanonicalCookie*>());
+ store->commands()[1].loaded_callback.Run(
+ std::vector<std::unique_ptr<CanonicalCookie>>());
// The just set cookie should still be in the store.
GetCookieListCallback get_cookie_list_callback2;
@@ -2348,14 +2350,13 @@ TEST_F(CookieMonsterTest, WhileLoadingDeleteAllGetForURL) {
ASSERT_EQ(1u, store->commands().size());
ASSERT_EQ(CookieStoreCommand::LOAD, store->commands()[0].type);
- std::vector<CanonicalCookie*> cookies;
+ std::vector<std::unique_ptr<CanonicalCookie>> cookies;
// When passed to the CookieMonster, it takes ownership of the pointed to
// cookies.
cookies.push_back(
- CanonicalCookie::Create(kUrl, "a=b", base::Time(), CookieOptions())
- .release());
+ CanonicalCookie::Create(kUrl, "a=b", base::Time(), CookieOptions()));
ASSERT_TRUE(cookies[0]);
- store->commands()[0].loaded_callback.Run(cookies);
+ store->commands()[0].loaded_callback.Run(std::move(cookies));
delete_callback.WaitUntilDone();
EXPECT_EQ(1, delete_callback.result());
@@ -2396,7 +2397,8 @@ TEST_F(CookieMonsterTest, WhileLoadingGetAllSetGetAll) {
ASSERT_EQ(CookieStoreCommand::LOAD, store->commands()[0].type);
// The load completes (With no cookies).
- store->commands()[0].loaded_callback.Run(std::vector<CanonicalCookie*>());
+ store->commands()[0].loaded_callback.Run(
+ std::vector<std::unique_ptr<CanonicalCookie>>());
get_cookie_list_callback1.WaitUntilDone();
EXPECT_EQ(0u, get_cookie_list_callback1.cookies().size());
@@ -2448,7 +2450,8 @@ TEST_F(CookieMonsterTest, CheckOrderOfCookieTaskQueueWhenLoadingCompletes) {
ASSERT_EQ(CookieStoreCommand::LOAD, store->commands()[0].type);
// The load completes.
- store->commands()[0].loaded_callback.Run(std::vector<CanonicalCookie*>());
+ store->commands()[0].loaded_callback.Run(
+ std::vector<std::unique_ptr<CanonicalCookie>>());
// The get cookies call should see no cookies set.
get_cookie_list_callback1.WaitUntilDone();
@@ -2474,11 +2477,9 @@ class FlushablePersistentStore : public CookieMonster::PersistentCookieStore {
FlushablePersistentStore() : flush_count_(0) {}
void Load(const LoadedCallback& loaded_callback) override {
- std::vector<CanonicalCookie*> out_cookies;
+ std::vector<std::unique_ptr<CanonicalCookie>> out_cookies;
base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE,
- base::Bind(&LoadedCallbackTask::Run,
- new LoadedCallbackTask(loaded_callback, out_cookies)));
+ FROM_HERE, base::Bind(loaded_callback, base::Passed(&out_cookies)));
}
void LoadCookiesForKey(const std::string& key,
@@ -2881,7 +2882,7 @@ TEST_F(CookieMonsterTest, ControlCharacterPurge) {
scoped_refptr<MockPersistentCookieStore> store(new MockPersistentCookieStore);
- std::vector<CanonicalCookie*> initial_cookies;
+ std::vector<std::unique_ptr<CanonicalCookie>> initial_cookies;
AddCookieToList(url, "foo=bar; path=" + path, now1, &initial_cookies);
@@ -2893,12 +2894,12 @@ TEST_F(CookieMonsterTest, ControlCharacterPurge) {
"boo",
domain, path, now2, later, false, false, CookieSameSite::DEFAULT_MODE,
false, COOKIE_PRIORITY_DEFAULT);
- initial_cookies.push_back(cc.release());
+ initial_cookies.push_back(std::move(cc));
AddCookieToList(url, "hello=world; path=" + path, now3, &initial_cookies);
// Inject our initial cookies into the mock PersistentCookieStore.
- store->SetLoadExpectation(true, initial_cookies);
+ store->SetLoadExpectation(true, std::move(initial_cookies));
std::unique_ptr<CookieMonster> cm(new CookieMonster(store.get(), nullptr));
diff --git a/chromium/net/cookies/cookie_util.cc b/chromium/net/cookies/cookie_util.cc
index 210b8d479af..a1b274b39b0 100644
--- a/chromium/net/cookies/cookie_util.cc
+++ b/chromium/net/cookies/cookie_util.cc
@@ -18,6 +18,77 @@
namespace net {
namespace cookie_util {
+namespace {
+
+base::Time MinNonNullTime() {
+ return base::Time::FromInternalValue(1);
+}
+
+// Tries to assemble a base::Time given a base::Time::Exploded representing a
+// UTC calendar date.
+//
+// If the date falls outside of the range supported internally by
+// FromUTCExploded() on the current platform, then the result is:
+//
+// * Time(1) if it's below the range FromUTCExploded() supports.
+// * Time::Max() if it's above the range FromUTCExploded() supports.
+bool SaturatedTimeFromUTCExploded(const base::Time::Exploded& exploded,
+ base::Time* out) {
+ // Try to calculate the base::Time in the normal fashion.
+ if (base::Time::FromUTCExploded(exploded, out)) {
+ // Don't return Time(0) on success.
+ if (out->is_null())
+ *out = MinNonNullTime();
+ return true;
+ }
+
+ // base::Time::FromUTCExploded() has platform-specific limits:
+ //
+ // * Windows: Years 1601 - 30827
+ // * 32-bit POSIX: Years 1970 - 2038
+ //
+ // Work around this by returning min/max valid times for times outside those
+ // ranges when imploding the time is doomed to fail.
+ //
+ // Note that the following implementation is NOT perfect. It will accept
+ // some invalid calendar dates in the out-of-range case.
+ if (!exploded.HasValidValues())
+ return false;
+#if defined(OS_POSIX) && !defined(OS_MACOSX)
+ // Allow dates prior to unix epoch (which fail on non-Mac/iOS POSIX).
+ if (exploded.year < 1970) {
+ *out = MinNonNullTime();
+ return true;
+ }
+
+ // On 32-bit non-Mac/iOS POSIX systems, the time_t value that FromExploded()
+ // returns overflows in the middle of year 2038. In that case, return
+ // Time::Max().
+ if (sizeof(time_t) == 4u && exploded.year >= 2038) {
+ *out = base::Time::Max();
+ return true;
+ }
+#endif // defined(OS_POSIX) && !defined(OS_MACOSX)
+
+#if defined(OS_WIN)
+ // Allow dates prior to Windows epoch.
+ if (exploded.year < 1601) {
+ *out = MinNonNullTime();
+ return true;
+ }
+
+ // Allow dates after the Windows epoch.
+ if (exploded.year >= 30827) {
+ *out = base::Time::Max();
+ return true;
+ }
+#endif // defined(OS_WIN)
+
+ return false;
+}
+
+} // namespace
+
bool DomainIsHostOnly(const std::string& domain_string) {
return (domain_string.empty() || domain_string[0] != '.');
}
@@ -103,7 +174,7 @@ bool GetCookieDomainWithString(const GURL& url,
// - The time must be of the format hh:mm:ss.
// An average cookie expiration will look something like this:
// Sat, 15-Apr-17 21:01:22 GMT
-base::Time ParseCookieTime(const std::string& time_string) {
+base::Time ParseCookieExpirationTime(const std::string& time_string) {
static const char* const kMonths[] = {
"jan", "feb", "mar", "apr", "may", "jun",
"jul", "aug", "sep", "oct", "nov", "dec" };
@@ -200,13 +271,11 @@ base::Time ParseCookieTime(const std::string& time_string) {
if (exploded.year >= 0 && exploded.year <= 68)
exploded.year += 2000;
- // If our values are within their correct ranges, we got our time.
- if (exploded.day_of_month >= 1 && exploded.day_of_month <= 31 &&
- exploded.month >= 1 && exploded.month <= 12 &&
- exploded.year >= 1601 && exploded.year <= 30827 &&
- exploded.hour <= 23 && exploded.minute <= 59 && exploded.second <= 59) {
- return base::Time::FromUTCExploded(exploded);
- }
+ // Note that clipping the date if it is outside of a platform-specific range
+ // is permitted by: https://tools.ietf.org/html/rfc6265#section-5.2.1
+ base::Time result;
+ if (SaturatedTimeFromUTCExploded(exploded, &result))
+ return result;
// One of our values was out of expected range. For well-formed input,
// the following check would be reasonable:
diff --git a/chromium/net/cookies/cookie_util.h b/chromium/net/cookies/cookie_util.h
index 0bf1452af86..60e5f661cd4 100644
--- a/chromium/net/cookies/cookie_util.h
+++ b/chromium/net/cookies/cookie_util.h
@@ -37,8 +37,13 @@ NET_EXPORT bool GetCookieDomainWithString(const GURL& url,
// i.e. it doesn't begin with a leading '.' character.
NET_EXPORT bool DomainIsHostOnly(const std::string& domain_string);
-// Parses the string with the cookie time (very forgivingly).
-NET_EXPORT base::Time ParseCookieTime(const std::string& time_string);
+// Parses the string with the cookie expiration time (very forgivingly).
+// Returns the "null" time on failure.
+//
+// If the expiration date is below or above the platform-specific range
+// supported by Time::FromUTCExplodeded(), then this will return Time(1) or
+// Time::Max(), respectively.
+NET_EXPORT base::Time ParseCookieExpirationTime(const std::string& time_string);
// Convenience for converting a cookie origin (domain and https pair) to a URL.
NET_EXPORT GURL CookieOriginToURL(const std::string& domain, bool is_https);
diff --git a/chromium/net/cookies/cookie_util_unittest.cc b/chromium/net/cookies/cookie_util_unittest.cc
index 5414be1e4dd..8ca3acafe43 100644
--- a/chromium/net/cookies/cookie_util_unittest.cc
+++ b/chromium/net/cookies/cookie_util_unittest.cc
@@ -63,79 +63,81 @@ TEST(CookieUtilTest, TestCookieDateParsing) {
const bool valid;
const time_t epoch;
} tests[] = {
- { "Sat, 15-Apr-17 21:01:22 GMT", true, 1492290082 },
- { "Thu, 19-Apr-2007 16:00:00 GMT", true, 1176998400 },
- { "Wed, 25 Apr 2007 21:02:13 GMT", true, 1177534933 },
- { "Thu, 19/Apr\\2007 16:00:00 GMT", true, 1176998400 },
- { "Fri, 1 Jan 2010 01:01:50 GMT", true, 1262307710 },
- { "Wednesday, 1-Jan-2003 00:00:00 GMT", true, 1041379200 },
- { ", 1-Jan-2003 00:00:00 GMT", true, 1041379200 },
- { " 1-Jan-2003 00:00:00 GMT", true, 1041379200 },
- { "1-Jan-2003 00:00:00 GMT", true, 1041379200 },
- { "Wed,18-Apr-07 22:50:12 GMT", true, 1176936612 },
- { "WillyWonka , 18-Apr-07 22:50:12 GMT", true, 1176936612 },
- { "WillyWonka , 18-Apr-07 22:50:12", true, 1176936612 },
- { "WillyWonka , 18-apr-07 22:50:12", true, 1176936612 },
- { "Mon, 18-Apr-1977 22:50:13 GMT", true, 230251813 },
- { "Mon, 18-Apr-77 22:50:13 GMT", true, 230251813 },
- // If the cookie came in with the expiration quoted (which in terms of
- // the RFC you shouldn't do), we will get string quoted. Bug 1261605.
- { "\"Sat, 15-Apr-17\\\"21:01:22\\\"GMT\"", true, 1492290082 },
- // Test with full month names and partial names.
- { "Partyday, 18- April-07 22:50:12", true, 1176936612 },
- { "Partyday, 18 - Apri-07 22:50:12", true, 1176936612 },
- { "Wednes, 1-Januar-2003 00:00:00 GMT", true, 1041379200 },
- // Test that we always take GMT even with other time zones or bogus
- // values. The RFC says everything should be GMT, and in the worst case
- // we are 24 hours off because of zone issues.
- { "Sat, 15-Apr-17 21:01:22", true, 1492290082 },
- { "Sat, 15-Apr-17 21:01:22 GMT-2", true, 1492290082 },
- { "Sat, 15-Apr-17 21:01:22 GMT BLAH", true, 1492290082 },
- { "Sat, 15-Apr-17 21:01:22 GMT-0400", true, 1492290082 },
- { "Sat, 15-Apr-17 21:01:22 GMT-0400 (EDT)",true, 1492290082 },
- { "Sat, 15-Apr-17 21:01:22 DST", true, 1492290082 },
- { "Sat, 15-Apr-17 21:01:22 -0400", true, 1492290082 },
- { "Sat, 15-Apr-17 21:01:22 (hello there)", true, 1492290082 },
- // Test that if we encounter multiple : fields, that we take the first
- // that correctly parses.
- { "Sat, 15-Apr-17 21:01:22 11:22:33", true, 1492290082 },
- { "Sat, 15-Apr-17 ::00 21:01:22", true, 1492290082 },
- { "Sat, 15-Apr-17 boink:z 21:01:22", true, 1492290082 },
- // We take the first, which in this case is invalid.
- { "Sat, 15-Apr-17 91:22:33 21:01:22", false, 0 },
- // amazon.com formats their cookie expiration like this.
- { "Thu Apr 18 22:50:12 2007 GMT", true, 1176936612 },
- // Test that hh:mm:ss can occur anywhere.
- { "22:50:12 Thu Apr 18 2007 GMT", true, 1176936612 },
- { "Thu 22:50:12 Apr 18 2007 GMT", true, 1176936612 },
- { "Thu Apr 22:50:12 18 2007 GMT", true, 1176936612 },
- { "Thu Apr 18 22:50:12 2007 GMT", true, 1176936612 },
- { "Thu Apr 18 2007 22:50:12 GMT", true, 1176936612 },
- { "Thu Apr 18 2007 GMT 22:50:12", true, 1176936612 },
- // Test that the day and year can be anywhere if they are unambigious.
- { "Sat, 15-Apr-17 21:01:22 GMT", true, 1492290082 },
- { "15-Sat, Apr-17 21:01:22 GMT", true, 1492290082 },
- { "15-Sat, Apr 21:01:22 GMT 17", true, 1492290082 },
- { "15-Sat, Apr 21:01:22 GMT 2017", true, 1492290082 },
- { "15 Apr 21:01:22 2017", true, 1492290082 },
- { "15 17 Apr 21:01:22", true, 1492290082 },
- { "Apr 15 17 21:01:22", true, 1492290082 },
- { "Apr 15 21:01:22 17", true, 1492290082 },
- { "2017 April 15 21:01:22", true, 1492290082 },
- { "15 April 2017 21:01:22", true, 1492290082 },
- // Some invalid dates
- { "98 April 17 21:01:22", false, 0 },
- { "Thu, 012-Aug-2008 20:49:07 GMT", false, 0 },
- { "Thu, 12-Aug-31841 20:49:07 GMT", false, 0 },
- { "Thu, 12-Aug-9999999999 20:49:07 GMT", false, 0 },
- { "Thu, 999999999999-Aug-2007 20:49:07 GMT", false, 0 },
- { "Thu, 12-Aug-2007 20:61:99999999999 GMT", false, 0 },
- { "IAintNoDateFool", false, 0 },
+ {"Sat, 15-Apr-17 21:01:22 GMT", true, 1492290082},
+ {"Thu, 19-Apr-2007 16:00:00 GMT", true, 1176998400},
+ {"Wed, 25 Apr 2007 21:02:13 GMT", true, 1177534933},
+ {"Thu, 19/Apr\\2007 16:00:00 GMT", true, 1176998400},
+ {"Fri, 1 Jan 2010 01:01:50 GMT", true, 1262307710},
+ {"Wednesday, 1-Jan-2003 00:00:00 GMT", true, 1041379200},
+ {", 1-Jan-2003 00:00:00 GMT", true, 1041379200},
+ {" 1-Jan-2003 00:00:00 GMT", true, 1041379200},
+ {"1-Jan-2003 00:00:00 GMT", true, 1041379200},
+ {"Wed,18-Apr-07 22:50:12 GMT", true, 1176936612},
+ {"WillyWonka , 18-Apr-07 22:50:12 GMT", true, 1176936612},
+ {"WillyWonka , 18-Apr-07 22:50:12", true, 1176936612},
+ {"WillyWonka , 18-apr-07 22:50:12", true, 1176936612},
+ {"Mon, 18-Apr-1977 22:50:13 GMT", true, 230251813},
+ {"Mon, 18-Apr-77 22:50:13 GMT", true, 230251813},
+ // If the cookie came in with the expiration quoted (which in terms of
+ // the RFC you shouldn't do), we will get string quoted. Bug 1261605.
+ {"\"Sat, 15-Apr-17\\\"21:01:22\\\"GMT\"", true, 1492290082},
+ // Test with full month names and partial names.
+ {"Partyday, 18- April-07 22:50:12", true, 1176936612},
+ {"Partyday, 18 - Apri-07 22:50:12", true, 1176936612},
+ {"Wednes, 1-Januar-2003 00:00:00 GMT", true, 1041379200},
+ // Test that we always take GMT even with other time zones or bogus
+ // values. The RFC says everything should be GMT, and in the worst case
+ // we are 24 hours off because of zone issues.
+ {"Sat, 15-Apr-17 21:01:22", true, 1492290082},
+ {"Sat, 15-Apr-17 21:01:22 GMT-2", true, 1492290082},
+ {"Sat, 15-Apr-17 21:01:22 GMT BLAH", true, 1492290082},
+ {"Sat, 15-Apr-17 21:01:22 GMT-0400", true, 1492290082},
+ {"Sat, 15-Apr-17 21:01:22 GMT-0400 (EDT)", true, 1492290082},
+ {"Sat, 15-Apr-17 21:01:22 DST", true, 1492290082},
+ {"Sat, 15-Apr-17 21:01:22 -0400", true, 1492290082},
+ {"Sat, 15-Apr-17 21:01:22 (hello there)", true, 1492290082},
+ // Test that if we encounter multiple : fields, that we take the first
+ // that correctly parses.
+ {"Sat, 15-Apr-17 21:01:22 11:22:33", true, 1492290082},
+ {"Sat, 15-Apr-17 ::00 21:01:22", true, 1492290082},
+ {"Sat, 15-Apr-17 boink:z 21:01:22", true, 1492290082},
+ // We take the first, which in this case is invalid.
+ {"Sat, 15-Apr-17 91:22:33 21:01:22", false, 0},
+ // amazon.com formats their cookie expiration like this.
+ {"Thu Apr 18 22:50:12 2007 GMT", true, 1176936612},
+ // Test that hh:mm:ss can occur anywhere.
+ {"22:50:12 Thu Apr 18 2007 GMT", true, 1176936612},
+ {"Thu 22:50:12 Apr 18 2007 GMT", true, 1176936612},
+ {"Thu Apr 22:50:12 18 2007 GMT", true, 1176936612},
+ {"Thu Apr 18 22:50:12 2007 GMT", true, 1176936612},
+ {"Thu Apr 18 2007 22:50:12 GMT", true, 1176936612},
+ {"Thu Apr 18 2007 GMT 22:50:12", true, 1176936612},
+ // Test that the day and year can be anywhere if they are unambigious.
+ {"Sat, 15-Apr-17 21:01:22 GMT", true, 1492290082},
+ {"15-Sat, Apr-17 21:01:22 GMT", true, 1492290082},
+ {"15-Sat, Apr 21:01:22 GMT 17", true, 1492290082},
+ {"15-Sat, Apr 21:01:22 GMT 2017", true, 1492290082},
+ {"15 Apr 21:01:22 2017", true, 1492290082},
+ {"15 17 Apr 21:01:22", true, 1492290082},
+ {"Apr 15 17 21:01:22", true, 1492290082},
+ {"Apr 15 21:01:22 17", true, 1492290082},
+ {"2017 April 15 21:01:22", true, 1492290082},
+ {"15 April 2017 21:01:22", true, 1492290082},
+ // Some invalid dates
+ {"98 April 17 21:01:22", false, 0},
+ {"Thu, 012-Aug-2008 20:49:07 GMT", false, 0},
+ {"Thu, 12-Aug-9999999999 20:49:07 GMT", false, 0},
+ {"Thu, 999999999999-Aug-2007 20:49:07 GMT", false, 0},
+ {"Thu, 12-Aug-2007 20:61:99999999999 GMT", false, 0},
+ {"IAintNoDateFool", false, 0},
+ {"1600 April 33 21:01:22", false, 0},
+ {"1970 April 33 21:01:22", false, 0},
+ {"Thu, 33-Aug-31841 20:49:07 GMT", false, 0},
};
base::Time parsed_time;
for (size_t i = 0; i < arraysize(tests); ++i) {
- parsed_time = cookie_util::ParseCookieTime(tests[i].str);
+ parsed_time = cookie_util::ParseCookieExpirationTime(tests[i].str);
if (!tests[i].valid) {
EXPECT_TRUE(parsed_time.is_null()) << tests[i].str;
continue;
@@ -145,6 +147,52 @@ TEST(CookieUtilTest, TestCookieDateParsing) {
}
}
+// Tests parsing dates that are beyond 2038. 32-bit (non-Mac) POSIX systems are
+// incapable of doing this, however the expectation is for cookie parsing to
+// succeed anyway (and return the minimum value Time::FromUTCExploded() can
+// parse on the current platform). Also checks a date outside the limit on
+// Windows, which is year 30827.
+TEST(CookieUtilTest, ParseCookieExpirationTimeBeyond2038) {
+ const char* kTests[] = {
+ "Thu, 12-Aug-31841 20:49:07 GMT", "2039 April 15 21:01:22",
+ "2039 April 15 21:01:22", "2038 April 15 21:01:22",
+ };
+
+ for (const auto& test : kTests) {
+ base::Time parsed_time = cookie_util::ParseCookieExpirationTime(test);
+ EXPECT_FALSE(parsed_time.is_null());
+
+ // It should either have an exact value, or be base::Time::Max(). For
+ // simplicity just check that it is greater than an arbitray date.
+ base::Time almost_jan_2038 =
+ base::Time::UnixEpoch() + base::TimeDelta::FromDays(365 * 68);
+ EXPECT_LT(almost_jan_2038, parsed_time);
+ }
+}
+
+// Tests parsing dates that are prior to (or around) 1970. Non-Mac POSIX systems
+// are incapable of doing this, however the expectation is for cookie parsing to
+// succeed anyway (and return a minimal base::Time).
+TEST(CookieUtilTest, ParseCookieExpirationTimeBefore1970) {
+ const char* kTests[] = {
+ // The unix epoch.
+ "1970 Jan 1 00:00:00",
+ // The windows epoch.
+ "1601 Jan 1 00:00:00",
+ // Other dates.
+ "1969 March 3 21:01:22", "1600 April 15 21:01:22",
+ };
+
+ for (const auto& test : kTests) {
+ base::Time parsed_time = cookie_util::ParseCookieExpirationTime(test);
+ EXPECT_FALSE(parsed_time.is_null());
+
+ // It should either have an exact value, or should be base::Time(1)
+ // For simplicity just check that it is less than the unix epoch.
+ EXPECT_LE(parsed_time, base::Time::UnixEpoch());
+ }
+}
+
TEST(CookieUtilTest, TestRequestCookieParsing) {
std::vector<RequestCookieParsingTest> tests;