OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // Portions of this code based on Mozilla: | 5 // Portions of this code based on Mozilla: |
6 // (netwerk/cookie/src/nsCookieService.cpp) | 6 // (netwerk/cookie/src/nsCookieService.cpp) |
7 /* ***** BEGIN LICENSE BLOCK ***** | 7 /* ***** BEGIN LICENSE BLOCK ***** |
8 * Version: MPL 1.1/GPL 2.0/LGPL 2.1 | 8 * Version: MPL 1.1/GPL 2.0/LGPL 2.1 |
9 * | 9 * |
10 * The contents of this file are subject to the Mozilla Public License Version | 10 * The contents of this file are subject to the Mozilla Public License Version |
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
188 : StringToCookieSameSite(pairs_[same_site_index_].second); | 188 : StringToCookieSameSite(pairs_[same_site_index_].second); |
189 } | 189 } |
190 | 190 |
191 CookiePriority ParsedCookie::Priority() const { | 191 CookiePriority ParsedCookie::Priority() const { |
192 return (priority_index_ == 0) | 192 return (priority_index_ == 0) |
193 ? COOKIE_PRIORITY_DEFAULT | 193 ? COOKIE_PRIORITY_DEFAULT |
194 : StringToCookiePriority(pairs_[priority_index_].second); | 194 : StringToCookiePriority(pairs_[priority_index_].second); |
195 } | 195 } |
196 | 196 |
197 bool ParsedCookie::SetName(const std::string& name) { | 197 bool ParsedCookie::SetName(const std::string& name) { |
198 if (!IsValidToken(name)) | 198 if (!name.empty() && !IsValidToken(name)) |
199 return false; | 199 return false; |
200 if (pairs_.empty()) | 200 if (pairs_.empty()) |
201 pairs_.push_back(std::make_pair("", "")); | 201 pairs_.push_back(std::make_pair("", "")); |
202 pairs_[0].first = name; | 202 pairs_[0].first = name; |
203 return true; | 203 return true; |
204 } | 204 } |
205 | 205 |
206 bool ParsedCookie::SetValue(const std::string& value) { | 206 bool ParsedCookie::SetValue(const std::string& value) { |
207 if (!IsValidCookieValue(value)) | 207 if (!IsValidCookieValue(value)) |
208 return false; | 208 return false; |
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
356 | 356 |
357 // Ok, here we go. We should be expecting to be starting somewhere | 357 // Ok, here we go. We should be expecting to be starting somewhere |
358 // before the cookie line, not including any header name... | 358 // before the cookie line, not including any header name... |
359 std::string::const_iterator start = cookie_line.begin(); | 359 std::string::const_iterator start = cookie_line.begin(); |
360 std::string::const_iterator it = start; | 360 std::string::const_iterator it = start; |
361 | 361 |
362 // TODO(erikwright): Make sure we're stripping \r\n in the network code. | 362 // TODO(erikwright): Make sure we're stripping \r\n in the network code. |
363 // Then we can log any unexpected terminators. | 363 // Then we can log any unexpected terminators. |
364 std::string::const_iterator end = FindFirstTerminator(cookie_line); | 364 std::string::const_iterator end = FindFirstTerminator(cookie_line); |
365 | 365 |
| 366 // For an empty |cookie_line|, add an empty-key with an empty value, which |
| 367 // has the effect of clearing any prior setting of the empty-key. This is done |
| 368 // to match the behavior of other browsers. See https://crbug.com/601786. |
| 369 if (it == end) { |
| 370 pairs_.push_back(TokenValuePair("", "")); |
| 371 return; |
| 372 } |
| 373 |
366 for (int pair_num = 0; pair_num < kMaxPairs && it != end; ++pair_num) { | 374 for (int pair_num = 0; pair_num < kMaxPairs && it != end; ++pair_num) { |
367 TokenValuePair pair; | 375 TokenValuePair pair; |
368 | 376 |
369 std::string::const_iterator token_start, token_end; | 377 std::string::const_iterator token_start, token_end; |
370 if (!ParseToken(&it, end, &token_start, &token_end)) | 378 if (!ParseToken(&it, end, &token_start, &token_end)) { |
371 break; | 379 // Allow first token to be treated as empty-key if unparsable |
| 380 if (pair_num != 0) |
| 381 break; |
| 382 |
| 383 // If parsing failed, start the value parsing at the very beginning. |
| 384 token_start = start; |
| 385 } |
372 | 386 |
373 if (it == end || *it != '=') { | 387 if (it == end || *it != '=') { |
374 // We have a token-value, we didn't have any token name. | 388 // We have a token-value, we didn't have any token name. |
375 if (pair_num == 0) { | 389 if (pair_num == 0) { |
376 // For the first time around, we want to treat single values | 390 // For the first time around, we want to treat single values |
377 // as a value with an empty name. (Mozilla bug 169091). | 391 // as a value with an empty name. (Mozilla bug 169091). |
378 // IE seems to also have this behavior, ex "AAA", and "AAA=10" will | 392 // IE seems to also have this behavior, ex "AAA", and "AAA=10" will |
379 // set 2 different cookies, and setting "BBB" will then replace "AAA". | 393 // set 2 different cookies, and setting "BBB" will then replace "AAA". |
380 pair.first = ""; | 394 pair.first = ""; |
381 // Rewind to the beginning of what we thought was the token name, | 395 // Rewind to the beginning of what we thought was the token name, |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
414 pairs_.push_back(pair); | 428 pairs_.push_back(pair); |
415 | 429 |
416 // We've processed a token/value pair, we're either at the end of | 430 // We've processed a token/value pair, we're either at the end of |
417 // the string or a ValueSeparator like ';', which we want to skip. | 431 // the string or a ValueSeparator like ';', which we want to skip. |
418 if (it != end) | 432 if (it != end) |
419 ++it; | 433 ++it; |
420 } | 434 } |
421 } | 435 } |
422 | 436 |
423 void ParsedCookie::SetupAttributes() { | 437 void ParsedCookie::SetupAttributes() { |
424 // Ignore Set-Cookie directive where name and value are both empty. | |
425 if (pairs_[0].first.empty() && pairs_[0].second.empty()) { | |
426 pairs_.clear(); | |
427 return; | |
428 } | |
429 | |
430 // We skip over the first token/value, the user supplied one. | 438 // We skip over the first token/value, the user supplied one. |
431 for (size_t i = 1; i < pairs_.size(); ++i) { | 439 for (size_t i = 1; i < pairs_.size(); ++i) { |
432 if (pairs_[i].first == kPathTokenName) { | 440 if (pairs_[i].first == kPathTokenName) { |
433 path_index_ = i; | 441 path_index_ = i; |
434 } else if (pairs_[i].first == kDomainTokenName) { | 442 } else if (pairs_[i].first == kDomainTokenName && pairs_[i].second != "") { |
435 domain_index_ = i; | 443 domain_index_ = i; |
436 } else if (pairs_[i].first == kExpiresTokenName) { | 444 } else if (pairs_[i].first == kExpiresTokenName) { |
437 expires_index_ = i; | 445 expires_index_ = i; |
438 } else if (pairs_[i].first == kMaxAgeTokenName) { | 446 } else if (pairs_[i].first == kMaxAgeTokenName) { |
439 maxage_index_ = i; | 447 maxage_index_ = i; |
440 } else if (pairs_[i].first == kSecureTokenName) { | 448 } else if (pairs_[i].first == kSecureTokenName) { |
441 secure_index_ = i; | 449 secure_index_ = i; |
442 } else if (pairs_[i].first == kHttpOnlyTokenName) { | 450 } else if (pairs_[i].first == kHttpOnlyTokenName) { |
443 httponly_index_ = i; | 451 httponly_index_ = i; |
444 } else if (pairs_[i].first == kSameSiteTokenName) { | 452 } else if (pairs_[i].first == kSameSiteTokenName) { |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
504 --*indexes[i]; | 512 --*indexes[i]; |
505 } | 513 } |
506 pairs_.erase(pairs_.begin() + index); | 514 pairs_.erase(pairs_.begin() + index); |
507 } | 515 } |
508 | 516 |
509 bool ParsedCookie::IsSameSiteAttributeValid() const { | 517 bool ParsedCookie::IsSameSiteAttributeValid() const { |
510 return same_site_index_ == 0 || SameSite() != CookieSameSite::DEFAULT_MODE; | 518 return same_site_index_ == 0 || SameSite() != CookieSameSite::DEFAULT_MODE; |
511 } | 519 } |
512 | 520 |
513 } // namespace | 521 } // namespace |
OLD | NEW |