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 bool did_parse_token = ParseToken(&it, end, &token_start, &token_end); |
371 break; | 379 if (!did_parse_token) { |
380 // Allow first token to be treated as empty-key if unparsable | |
381 if (pair_num != 0) | |
382 break; | |
372 | 383 |
373 if (it == end || *it != '=') { | 384 // If parsing failed, start the value parsing at the very beginning. |
385 token_start = start; | |
386 } | |
387 | |
388 if (!did_parse_token || it == end || *it != '=') { | |
mmenke
2016/08/17 16:23:17
Hrm..!did_parse_token isn't needed here...Though s
jww
2016/08/17 16:57:08
I believe it is needed. The prior if-block only br
mmenke
2016/08/17 17:56:33
Right, but then it == end. The check for whether
jww
2016/08/17 18:19:18
Ah, great point! I'll actually simplify some of th
| |
374 // We have a token-value, we didn't have any token name. | 389 // We have a token-value, we didn't have any token name. |
375 if (pair_num == 0) { | 390 if (pair_num == 0) { |
376 // For the first time around, we want to treat single values | 391 // For the first time around, we want to treat single values |
377 // as a value with an empty name. (Mozilla bug 169091). | 392 // as a value with an empty name. (Mozilla bug 169091). |
378 // IE seems to also have this behavior, ex "AAA", and "AAA=10" will | 393 // 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". | 394 // set 2 different cookies, and setting "BBB" will then replace "AAA". |
380 pair.first = ""; | 395 pair.first = ""; |
381 // Rewind to the beginning of what we thought was the token name, | 396 // Rewind to the beginning of what we thought was the token name, |
382 // and let it get parsed as a value. | 397 // and let it get parsed as a value. |
383 it = token_start; | 398 it = token_start; |
(...skipping 30 matching lines...) Expand all Loading... | |
414 pairs_.push_back(pair); | 429 pairs_.push_back(pair); |
415 | 430 |
416 // We've processed a token/value pair, we're either at the end of | 431 // 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. | 432 // the string or a ValueSeparator like ';', which we want to skip. |
418 if (it != end) | 433 if (it != end) |
419 ++it; | 434 ++it; |
420 } | 435 } |
421 } | 436 } |
422 | 437 |
423 void ParsedCookie::SetupAttributes() { | 438 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. | 439 // We skip over the first token/value, the user supplied one. |
431 for (size_t i = 1; i < pairs_.size(); ++i) { | 440 for (size_t i = 1; i < pairs_.size(); ++i) { |
432 if (pairs_[i].first == kPathTokenName) { | 441 if (pairs_[i].first == kPathTokenName) { |
433 path_index_ = i; | 442 path_index_ = i; |
434 } else if (pairs_[i].first == kDomainTokenName) { | 443 } else if (pairs_[i].first == kDomainTokenName && pairs_[i].second != "") { |
435 domain_index_ = i; | 444 domain_index_ = i; |
436 } else if (pairs_[i].first == kExpiresTokenName) { | 445 } else if (pairs_[i].first == kExpiresTokenName) { |
437 expires_index_ = i; | 446 expires_index_ = i; |
438 } else if (pairs_[i].first == kMaxAgeTokenName) { | 447 } else if (pairs_[i].first == kMaxAgeTokenName) { |
439 maxage_index_ = i; | 448 maxage_index_ = i; |
440 } else if (pairs_[i].first == kSecureTokenName) { | 449 } else if (pairs_[i].first == kSecureTokenName) { |
441 secure_index_ = i; | 450 secure_index_ = i; |
442 } else if (pairs_[i].first == kHttpOnlyTokenName) { | 451 } else if (pairs_[i].first == kHttpOnlyTokenName) { |
443 httponly_index_ = i; | 452 httponly_index_ = i; |
444 } else if (pairs_[i].first == kSameSiteTokenName) { | 453 } else if (pairs_[i].first == kSameSiteTokenName) { |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
504 --*indexes[i]; | 513 --*indexes[i]; |
505 } | 514 } |
506 pairs_.erase(pairs_.begin() + index); | 515 pairs_.erase(pairs_.begin() + index); |
507 } | 516 } |
508 | 517 |
509 bool ParsedCookie::IsSameSiteAttributeValid() const { | 518 bool ParsedCookie::IsSameSiteAttributeValid() const { |
510 return same_site_index_ == 0 || SameSite() != CookieSameSite::DEFAULT_MODE; | 519 return same_site_index_ == 0 || SameSite() != CookieSameSite::DEFAULT_MODE; |
511 } | 520 } |
512 | 521 |
513 } // namespace | 522 } // namespace |
OLD | NEW |