| Index: net/cookies/parsed_cookie.cc
|
| diff --git a/net/cookies/parsed_cookie.cc b/net/cookies/parsed_cookie.cc
|
| index 2175692f534a0ff8c4db3a65f898858a47da8a10..0be70e1565fec6579c369ef13c5dc3d0dd83b4f5 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,12 +363,26 @@ 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))
|
| - break;
|
| + if (!ParseToken(&it, end, &token_start, &token_end)) {
|
| + // Allow first token to be treated as empty-key if unparsable
|
| + if (pair_num != 0)
|
| + break;
|
| +
|
| + // If parsing failed, start the value parsing at the very beginning.
|
| + token_start = start;
|
| + }
|
|
|
| if (it == end || *it != '=') {
|
| // We have a token-value, we didn't have any token name.
|
| @@ -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;
|
|
|