Chromium Code Reviews| 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 345 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("", "")); | |
|
mmenke
2016/08/15 21:11:03
Maybe add an early return? Doesn't make a differe
jww
2016/08/16 02:24:23
Early return sgtm. Done.
| |
| 371 | |
| 366 for (int pair_num = 0; pair_num < kMaxPairs && it != end; ++pair_num) { | 372 for (int pair_num = 0; pair_num < kMaxPairs && it != end; ++pair_num) { |
| 367 TokenValuePair pair; | 373 TokenValuePair pair; |
| 368 | 374 |
| 369 std::string::const_iterator token_start, token_end; | 375 std::string::const_iterator token_start, token_end; |
| 370 if (!ParseToken(&it, end, &token_start, &token_end)) | 376 bool did_parse_token = ParseToken(&it, end, &token_start, &token_end); |
| 377 if (!did_parse_token && pair_num != 0) | |
|
mmenke
2016/08/15 21:11:03
Think this is worth a comment (Just "Allow first t
mmenke
2016/08/15 21:11:03
What about if other tokens are empty? Do other br
jww
2016/08/16 02:24:23
Comment added.
For tokens other than the first, I
mmenke
2016/08/16 15:06:47
Ahh...The "break;" was concerning me. I had assum
| |
| 371 break; | 378 break; |
| 372 | 379 |
| 373 if (it == end || *it != '=') { | 380 if (!did_parse_token || it == end || *it != '=') { |
| 374 // We have a token-value, we didn't have any token name. | 381 // We have a token-value, we didn't have any token name. |
| 375 if (pair_num == 0) { | 382 if (pair_num == 0) { |
| 376 // For the first time around, we want to treat single values | 383 // For the first time around, we want to treat single values |
| 377 // as a value with an empty name. (Mozilla bug 169091). | 384 // as a value with an empty name. (Mozilla bug 169091). |
| 378 // IE seems to also have this behavior, ex "AAA", and "AAA=10" will | 385 // 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". | 386 // set 2 different cookies, and setting "BBB" will then replace "AAA". |
| 380 pair.first = ""; | 387 pair.first = ""; |
| 381 // Rewind to the beginning of what we thought was the token name, | 388 // Rewind to the beginning of what we thought was the token name, |
| 382 // and let it get parsed as a value. | 389 // and let it get parsed as a value. |
| 383 it = token_start; | 390 it = did_parse_token ? token_start : start; |
|
mmenke
2016/08/15 21:11:03
Having this extra logic seems a little ugly.
I'd
jww
2016/08/16 02:24:23
I agree that this is ugly, but from looking at thi
| |
| 384 } else { | 391 } else { |
| 385 // Any not-first attribute we want to treat a value as a | 392 // Any not-first attribute we want to treat a value as a |
| 386 // name with an empty value... This is so something like | 393 // name with an empty value... This is so something like |
| 387 // "secure;" will get parsed as a Token name, and not a value. | 394 // "secure;" will get parsed as a Token name, and not a value. |
| 388 pair.first = std::string(token_start, token_end); | 395 pair.first = std::string(token_start, token_end); |
| 389 } | 396 } |
| 390 } else { | 397 } else { |
| 391 // We have a TOKEN=VALUE. | 398 // We have a TOKEN=VALUE. |
| 392 pair.first = std::string(token_start, token_end); | 399 pair.first = std::string(token_start, token_end); |
| 393 ++it; // Skip past the '='. | 400 ++it; // Skip past the '='. |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 414 pairs_.push_back(pair); | 421 pairs_.push_back(pair); |
| 415 | 422 |
| 416 // We've processed a token/value pair, we're either at the end of | 423 // 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. | 424 // the string or a ValueSeparator like ';', which we want to skip. |
| 418 if (it != end) | 425 if (it != end) |
| 419 ++it; | 426 ++it; |
| 420 } | 427 } |
| 421 } | 428 } |
| 422 | 429 |
| 423 void ParsedCookie::SetupAttributes() { | 430 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. | 431 // We skip over the first token/value, the user supplied one. |
| 431 for (size_t i = 1; i < pairs_.size(); ++i) { | 432 for (size_t i = 1; i < pairs_.size(); ++i) { |
| 432 if (pairs_[i].first == kPathTokenName) { | 433 if (pairs_[i].first == kPathTokenName) { |
| 433 path_index_ = i; | 434 path_index_ = i; |
| 434 } else if (pairs_[i].first == kDomainTokenName) { | 435 } else if (pairs_[i].first == kDomainTokenName && pairs_[i].second != "") { |
|
mmenke
2016/08/15 21:11:03
Here's something weird:
For all the other tokens,
jww
2016/08/16 02:24:23
This wouldn't match the other UAs, unfortunately,
mmenke
2016/08/16 15:06:47
Sorry, should have been clearer. Looking at this
| |
| 435 domain_index_ = i; | 436 domain_index_ = i; |
| 436 } else if (pairs_[i].first == kExpiresTokenName) { | 437 } else if (pairs_[i].first == kExpiresTokenName) { |
| 437 expires_index_ = i; | 438 expires_index_ = i; |
| 438 } else if (pairs_[i].first == kMaxAgeTokenName) { | 439 } else if (pairs_[i].first == kMaxAgeTokenName) { |
| 439 maxage_index_ = i; | 440 maxage_index_ = i; |
| 440 } else if (pairs_[i].first == kSecureTokenName) { | 441 } else if (pairs_[i].first == kSecureTokenName) { |
| 441 secure_index_ = i; | 442 secure_index_ = i; |
| 442 } else if (pairs_[i].first == kHttpOnlyTokenName) { | 443 } else if (pairs_[i].first == kHttpOnlyTokenName) { |
| 443 httponly_index_ = i; | 444 httponly_index_ = i; |
| 444 } else if (pairs_[i].first == kSameSiteTokenName) { | 445 } else if (pairs_[i].first == kSameSiteTokenName) { |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 504 --*indexes[i]; | 505 --*indexes[i]; |
| 505 } | 506 } |
| 506 pairs_.erase(pairs_.begin() + index); | 507 pairs_.erase(pairs_.begin() + index); |
| 507 } | 508 } |
| 508 | 509 |
| 509 bool ParsedCookie::IsSameSiteAttributeValid() const { | 510 bool ParsedCookie::IsSameSiteAttributeValid() const { |
| 510 return same_site_index_ == 0 || SameSite() != CookieSameSite::DEFAULT_MODE; | 511 return same_site_index_ == 0 || SameSite() != CookieSameSite::DEFAULT_MODE; |
| 511 } | 512 } |
| 512 | 513 |
| 513 } // namespace | 514 } // namespace |
| OLD | NEW |