Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(64)

Side by Side Diff: net/cookies/parsed_cookie.cc

Issue 2246613003: Update cookie value and attribute setting behavior to match other UAs (Closed) Base URL: https://chromium.googlesource.com/chromium/src@master
Patch Set: Updated ParsedCookie unittests Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698