| Index: net/cookies/canonical_cookie.cc
|
| diff --git a/net/cookies/canonical_cookie.cc b/net/cookies/canonical_cookie.cc
|
| index 6c81a55dc7df1d768618d9d76b338a0b0fd79974..8e3158af6ee26347e24153fe8a4398e272a32eaf 100644
|
| --- a/net/cookies/canonical_cookie.cc
|
| +++ b/net/cookies/canonical_cookie.cc
|
| @@ -50,10 +50,12 @@
|
| #include "base/metrics/histogram_macros.h"
|
| #include "base/strings/string_util.h"
|
| #include "base/strings/stringprintf.h"
|
| +#include "net/base/url_util.h"
|
| #include "net/cookies/cookie_util.h"
|
| #include "net/cookies/parsed_cookie.h"
|
| #include "url/gurl.h"
|
| #include "url/url_canon.h"
|
| +#include "url/url_util.h"
|
|
|
| using base::Time;
|
| using base::TimeDelta;
|
| @@ -228,21 +230,22 @@ std::unique_ptr<CanonicalCookie> CanonicalCookie::Create(
|
| creation_time,
|
| server_time);
|
|
|
| - CookiePrefix prefix = CanonicalCookie::GetCookiePrefix(parsed_cookie.Name());
|
| - bool is_cookie_valid =
|
| - CanonicalCookie::IsCookiePrefixValid(prefix, url, parsed_cookie);
|
| - CanonicalCookie::RecordCookiePrefixMetrics(prefix, is_cookie_valid);
|
| + CookiePrefix prefix = GetCookiePrefix(parsed_cookie.Name());
|
| + bool is_cookie_valid = IsCookiePrefixValid(prefix, url, parsed_cookie);
|
| + RecordCookiePrefixMetrics(prefix, is_cookie_valid);
|
| if (!is_cookie_valid) {
|
| VLOG(kVlogSetCookies)
|
| << "Create() failed because the cookie violated prefix rules.";
|
| return nullptr;
|
| }
|
|
|
| - return base::WrapUnique(new CanonicalCookie(
|
| + std::unique_ptr<CanonicalCookie> cc(base::MakeUnique<CanonicalCookie>(
|
| parsed_cookie.Name(), parsed_cookie.Value(), cookie_domain, cookie_path,
|
| creation_time, cookie_expires, creation_time, parsed_cookie.IsSecure(),
|
| parsed_cookie.IsHttpOnly(), parsed_cookie.SameSite(),
|
| parsed_cookie.Priority()));
|
| + DCHECK(cc->IsCanonical());
|
| + return cc;
|
| }
|
|
|
| bool CanonicalCookie::IsEquivalentForSecureCookieMatching(
|
| @@ -399,6 +402,51 @@ bool CanonicalCookie::FullCompare(const CanonicalCookie& other) const {
|
| return Priority() < other.Priority();
|
| }
|
|
|
| +bool CanonicalCookie::IsCanonical() const {
|
| + // Not checking domain against ParsedCookie as it may have come purely
|
| + // from the URL.
|
| + if (ParsedCookie::ParseTokenString(name_) != name_ ||
|
| + ParsedCookie::ParseValueString(value_) != value_ ||
|
| + ParsedCookie::ParseValueString(path_) != path_ ||
|
| + !ParsedCookie::IsValidCookieAttributeValue(name_) ||
|
| + !ParsedCookie::IsValidCookieAttributeValue(value_) ||
|
| + !ParsedCookie::IsValidCookieAttributeValue(path_)) {
|
| + return false;
|
| + }
|
| +
|
| + if (!last_access_date_.is_null() && creation_date_.is_null())
|
| + return false;
|
| +
|
| + url::CanonHostInfo canon_host_info;
|
| + std::string canonical_domain(CanonicalizeHost(domain_, &canon_host_info));
|
| + // TODO(rdsmith): This specifically allows for empty domains. The spec
|
| + // suggests this is invalid (if a domain attribute is empty, the cookie's
|
| + // domain is set to the canonicalized request host; see
|
| + // https://tools.ietf.org/html/rfc6265#section-5.3). However, it is
|
| + // needed for Chrome extension cookies.
|
| + // See http://crbug.com/730633 for more information.
|
| + if (canonical_domain != domain_)
|
| + return false;
|
| +
|
| + if (path_.empty() || path_[0] != '/')
|
| + return false;
|
| +
|
| + switch (GetCookiePrefix(name_)) {
|
| + case COOKIE_PREFIX_HOST:
|
| + if (!secure_ || path_ != "/" || domain_.empty() || domain_[0] == '.')
|
| + return false;
|
| + break;
|
| + case COOKIE_PREFIX_SECURE:
|
| + if (!secure_)
|
| + return false;
|
| + break;
|
| + default:
|
| + break;
|
| + }
|
| +
|
| + return true;
|
| +}
|
| +
|
| // static
|
| CanonicalCookie::CookiePrefix CanonicalCookie::GetCookiePrefix(
|
| const std::string& name) {
|
|
|