Commit e4182b17 authored by Devlin Cronin's avatar Devlin Cronin Committed by Commit Bot

[Extensions] Gracefully handle cookies with super late expiration dates

On 32-bit machines, cookies with expiration dates beyond the year 2037
are stored with the expiration time as base::Time::Max(). When
converting to a double, this will return infinity(). infinity() cannot
be serialized in JSON, which can lead to a crash.

Instead, gracefully handle this case by setting the cookie to expire at
std::numeric_limits<double>::max(). Add a regression test for the same.

Bug: 848221
Change-Id: Id1bae19f785d864bf6d926f360a31f485d6dd574
Reviewed-on: https://chromium-review.googlesource.com/1105122Reviewed-by: default avatarMike West <mkwst@chromium.org>
Commit-Queue: Devlin <rdevlin.cronin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#569309}
parent 80a1b16c
......@@ -8,6 +8,7 @@
#include <stddef.h>
#include <limits>
#include <utility>
#include <vector>
......@@ -94,8 +95,12 @@ Cookie CreateCookie(const net::CanonicalCookie& canonical_cookie,
cookie.session = !canonical_cookie.IsPersistent();
if (canonical_cookie.IsPersistent()) {
cookie.expiration_date.reset(
new double(canonical_cookie.ExpiryDate().ToDoubleT()));
double expiration_date = canonical_cookie.ExpiryDate().ToDoubleT();
if (canonical_cookie.ExpiryDate().is_max() ||
!std::isfinite(expiration_date)) {
expiration_date = std::numeric_limits<double>::max();
}
cookie.expiration_date = std::make_unique<double>(expiration_date);
}
cookie.store_id = store_id;
......
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/extensions/api/cookies/cookies_helpers.h"
#include <limits>
#include <memory>
#include "net/cookies/canonical_cookie.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace extensions {
// Tests that cookies with an expiration date too far in the future to represent
// with base::Time serialize gracefully.
// Regression test for https://crbug.com/848221.
TEST(CookiesHelperUnittest, CookieConversionWithInfiniteExpirationDate) {
// Set a cookie to expire at base::Time::Max(). This can happen when the
// cookie is set to expire farther in the future than we can accurately
// represent with base::Time(). Note that, in practice, this is really only
// applicable on 32-bit machines, but we can fake it a bit for cross-platform
// testing by just setting the expiration date directly.
const base::Time kExpirationDate = base::Time::Max();
net::CanonicalCookie cookie("cookiename", "cookievalue", "example.com", "/",
base::Time::Now(), kExpirationDate, base::Time(),
false, false, net::CookieSameSite::DEFAULT_MODE,
net::COOKIE_PRIORITY_DEFAULT);
// Serialize the cookie to JSON. We need to gracefully handle the infinite
// expiration date, which should be converted to the maximum value.
api::cookies::Cookie serialized_cookie =
cookies_helpers::CreateCookie(cookie, "1");
std::unique_ptr<base::Value> value_cookie = serialized_cookie.ToValue();
ASSERT_TRUE(value_cookie);
base::Value* expiration_time =
value_cookie->FindKeyOfType("expirationDate", base::Value::Type::DOUBLE);
ASSERT_TRUE(expiration_time);
EXPECT_EQ(std::numeric_limits<double>::max(), expiration_time->GetDouble());
}
} // namespace extensions
......@@ -3379,6 +3379,7 @@ test("unit_tests") {
"../browser/extensions/api/chrome_extensions_api_client_unittest.cc",
"../browser/extensions/api/content_settings/content_settings_store_unittest.cc",
"../browser/extensions/api/content_settings/content_settings_unittest.cc",
"../browser/extensions/api/cookies/cookies_helpers_unittest.cc",
"../browser/extensions/api/cookies/cookies_unittest.cc",
"../browser/extensions/api/cryptotoken_private/cryptotoken_private_api_unittest.cc",
"../browser/extensions/api/declarative/rules_registry_service_unittest.cc",
......
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