Index: net/cookies/parsed_cookie.cc |
diff --git a/net/cookies/parsed_cookie.cc b/net/cookies/parsed_cookie.cc |
index 2175692f534a0ff8c4db3a65f898858a47da8a10..31e58601b9bd1bcd5d001c41bad9151457daae34 100644 |
--- a/net/cookies/parsed_cookie.cc |
+++ b/net/cookies/parsed_cookie.cc |
@@ -195,7 +195,7 @@ CookiePriority ParsedCookie::Priority() const { |
} |
bool ParsedCookie::SetName(const std::string& name) { |
- if (!IsValidToken(name)) |
+ if (!name.empty() && !IsValidToken(name)) |
return false; |
if (pairs_.empty()) |
pairs_.push_back(std::make_pair("", "")); |
@@ -363,14 +363,24 @@ void ParsedCookie::ParseTokenValuePairs(const std::string& cookie_line) { |
// Then we can log any unexpected terminators. |
std::string::const_iterator end = FindFirstTerminator(cookie_line); |
+ // For an empty |cookie_line|, add an empty-key with an empty value, which |
+ // has the effect of clearing any prior setting of the empty-key. This is done |
+ // to match the behavior of other browsers. See https://crbug.com/601786. |
+ if (it == end) { |
+ pairs_.push_back(TokenValuePair("", "")); |
+ return; |
+ } |
+ |
for (int pair_num = 0; pair_num < kMaxPairs && it != end; ++pair_num) { |
TokenValuePair pair; |
std::string::const_iterator token_start, token_end; |
- if (!ParseToken(&it, end, &token_start, &token_end)) |
+ bool did_parse_token = ParseToken(&it, end, &token_start, &token_end); |
+ // Allow first token to be treated as empty-key if unparsable |
+ if (!did_parse_token && pair_num != 0) |
break; |
- if (it == end || *it != '=') { |
+ if (!did_parse_token || it == end || *it != '=') { |
// We have a token-value, we didn't have any token name. |
if (pair_num == 0) { |
// For the first time around, we want to treat single values |
@@ -379,8 +389,12 @@ void ParsedCookie::ParseTokenValuePairs(const std::string& cookie_line) { |
// set 2 different cookies, and setting "BBB" will then replace "AAA". |
pair.first = ""; |
// Rewind to the beginning of what we thought was the token name, |
- // and let it get parsed as a value. |
- it = token_start; |
+ // and let it get parsed as a value. If parsing failed, start the value |
+ // parsing at the very beginning. |
+ if (did_parse_token) |
+ it = token_start; |
+ else |
+ it = start; |
mmenke
2016/08/16 15:06:47
nit: Use braces in else/if.
Also, another option
jww
2016/08/16 18:18:17
Did both.
|
} else { |
// Any not-first attribute we want to treat a value as a |
// name with an empty value... This is so something like |
@@ -421,17 +435,11 @@ void ParsedCookie::ParseTokenValuePairs(const std::string& cookie_line) { |
} |
void ParsedCookie::SetupAttributes() { |
- // Ignore Set-Cookie directive where name and value are both empty. |
- if (pairs_[0].first.empty() && pairs_[0].second.empty()) { |
- pairs_.clear(); |
- return; |
- } |
- |
// We skip over the first token/value, the user supplied one. |
for (size_t i = 1; i < pairs_.size(); ++i) { |
if (pairs_[i].first == kPathTokenName) { |
path_index_ = i; |
- } else if (pairs_[i].first == kDomainTokenName) { |
+ } else if (pairs_[i].first == kDomainTokenName && pairs_[i].second != "") { |
domain_index_ = i; |
} else if (pairs_[i].first == kExpiresTokenName) { |
expires_index_ = i; |