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 27 matching lines...) Expand all Loading... | |
| 38 * decision by deleting the provisions above and replace them with the notice | 38 * decision by deleting the provisions above and replace them with the notice |
| 39 * and other provisions required by the GPL or the LGPL. If you do not delete | 39 * and other provisions required by the GPL or the LGPL. If you do not delete |
| 40 * the provisions above, a recipient may use your version of this file under | 40 * the provisions above, a recipient may use your version of this file under |
| 41 * the terms of any one of the MPL, the GPL or the LGPL. | 41 * the terms of any one of the MPL, the GPL or the LGPL. |
| 42 * | 42 * |
| 43 * ***** END LICENSE BLOCK ***** */ | 43 * ***** END LICENSE BLOCK ***** */ |
| 44 | 44 |
| 45 #include "net/cookies/parsed_cookie.h" | 45 #include "net/cookies/parsed_cookie.h" |
| 46 | 46 |
| 47 #include "base/logging.h" | 47 #include "base/logging.h" |
| 48 #include "base/metrics/histogram.h" | |
| 48 #include "base/string_util.h" | 49 #include "base/string_util.h" |
| 49 | 50 |
| 50 namespace { | 51 namespace { |
| 51 | 52 |
| 52 const char kPathTokenName[] = "path"; | 53 const char kPathTokenName[] = "path"; |
| 53 const char kDomainTokenName[] = "domain"; | 54 const char kDomainTokenName[] = "domain"; |
| 54 const char kExpiresTokenName[] = "expires"; | 55 const char kExpiresTokenName[] = "expires"; |
| 55 const char kMaxAgeTokenName[] = "max-age"; | 56 const char kMaxAgeTokenName[] = "max-age"; |
| 56 const char kSecureTokenName[] = "secure"; | 57 const char kSecureTokenName[] = "secure"; |
| 57 const char kHttpOnlyTokenName[] = "httponly"; | 58 const char kHttpOnlyTokenName[] = "httponly"; |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 175 bool ParsedCookie::IsValid() const { | 176 bool ParsedCookie::IsValid() const { |
| 176 return !pairs_.empty(); | 177 return !pairs_.empty(); |
| 177 } | 178 } |
| 178 | 179 |
| 179 CookiePriority ParsedCookie::Priority() const { | 180 CookiePriority ParsedCookie::Priority() const { |
| 180 return (priority_index_ == 0) ? COOKIE_PRIORITY_DEFAULT : | 181 return (priority_index_ == 0) ? COOKIE_PRIORITY_DEFAULT : |
| 181 StringToCookiePriority(pairs_[priority_index_].second); | 182 StringToCookiePriority(pairs_[priority_index_].second); |
| 182 } | 183 } |
| 183 | 184 |
| 184 bool ParsedCookie::SetName(const std::string& name) { | 185 bool ParsedCookie::SetName(const std::string& name) { |
| 185 if (!IsValidToken(name)) | 186 if (!IsValidToken(name)) { |
| 187 UMA_HISTOGRAM_BOOLEAN("Cookies.SetNameInvalidToken", true); | |
| 186 return false; | 188 return false; |
| 189 } | |
| 187 if (pairs_.empty()) | 190 if (pairs_.empty()) |
| 188 pairs_.push_back(std::make_pair("", "")); | 191 pairs_.push_back(std::make_pair("", "")); |
| 189 pairs_[0].first = name; | 192 pairs_[0].first = name; |
| 193 UMA_HISTOGRAM_BOOLEAN("Cookies.SetNameInvalidToken", false); | |
| 190 return true; | 194 return true; |
| 191 } | 195 } |
| 192 | 196 |
| 193 bool ParsedCookie::SetValue(const std::string& value) { | 197 bool ParsedCookie::SetValue(const std::string& value) { |
| 194 if (!IsValidCookieValue(value)) | 198 if (!IsValidCookieValue(value)) { |
| 199 UMA_HISTOGRAM_BOOLEAN("Cookies.SetValueInvalidCookieValue", true); | |
| 195 return false; | 200 return false; |
| 201 } | |
| 196 if (pairs_.empty()) | 202 if (pairs_.empty()) |
| 197 pairs_.push_back(std::make_pair("", "")); | 203 pairs_.push_back(std::make_pair("", "")); |
| 198 pairs_[0].second = value; | 204 pairs_[0].second = value; |
| 205 UMA_HISTOGRAM_BOOLEAN("Cookies.SetValueInvalidCookieValue", false); | |
| 199 return true; | 206 return true; |
| 200 } | 207 } |
| 201 | 208 |
| 202 bool ParsedCookie::SetPath(const std::string& path) { | 209 bool ParsedCookie::SetPath(const std::string& path) { |
| 203 return SetString(&path_index_, kPathTokenName, path); | 210 return SetString(&path_index_, kPathTokenName, path); |
| 204 } | 211 } |
| 205 | 212 |
| 206 bool ParsedCookie::SetDomain(const std::string& domain) { | 213 bool ParsedCookie::SetDomain(const std::string& domain) { |
| 207 return SetString(&domain_index_, kDomainTokenName, domain); | 214 return SetString(&domain_index_, kDomainTokenName, domain); |
| 208 } | 215 } |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 330 std::string::const_iterator it = value.begin(); | 337 std::string::const_iterator it = value.begin(); |
| 331 std::string::const_iterator end = FindFirstTerminator(value); | 338 std::string::const_iterator end = FindFirstTerminator(value); |
| 332 | 339 |
| 333 std::string::const_iterator value_start, value_end; | 340 std::string::const_iterator value_start, value_end; |
| 334 ParseValue(&it, end, &value_start, &value_end); | 341 ParseValue(&it, end, &value_start, &value_end); |
| 335 return std::string(value_start, value_end); | 342 return std::string(value_start, value_end); |
| 336 } | 343 } |
| 337 | 344 |
| 338 // Parse all token/value pairs and populate pairs_. | 345 // Parse all token/value pairs and populate pairs_. |
| 339 void ParsedCookie::ParseTokenValuePairs(const std::string& cookie_line) { | 346 void ParsedCookie::ParseTokenValuePairs(const std::string& cookie_line) { |
| 347 bool parsed_invalid_control_char = false; | |
| 348 bool parsed_invalid_token = false; | |
| 349 | |
| 340 pairs_.clear(); | 350 pairs_.clear(); |
| 341 | 351 |
| 342 // Ok, here we go. We should be expecting to be starting somewhere | 352 // Ok, here we go. We should be expecting to be starting somewhere |
| 343 // before the cookie line, not including any header name... | 353 // before the cookie line, not including any header name... |
| 344 std::string::const_iterator start = cookie_line.begin(); | 354 std::string::const_iterator start = cookie_line.begin(); |
| 345 std::string::const_iterator it = start; | 355 std::string::const_iterator it = start; |
| 346 | 356 |
| 347 // TODO(erikwright): Make sure we're stripping \r\n in the network code. | 357 // TODO(erikwright): Make sure we're stripping \r\n in the network code. |
| 348 // Then we can log any unexpected terminators. | 358 // Then we can log any unexpected terminators. |
| 349 std::string::const_iterator end = FindFirstTerminator(cookie_line); | 359 std::string::const_iterator end = FindFirstTerminator(cookie_line); |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 377 pair.first = std::string(token_start, token_end); | 387 pair.first = std::string(token_start, token_end); |
| 378 ++it; // Skip past the '='. | 388 ++it; // Skip past the '='. |
| 379 } | 389 } |
| 380 | 390 |
| 381 // OK, now try to parse a value. | 391 // OK, now try to parse a value. |
| 382 std::string::const_iterator value_start, value_end; | 392 std::string::const_iterator value_start, value_end; |
| 383 ParseValue(&it, end, &value_start, &value_end); | 393 ParseValue(&it, end, &value_start, &value_end); |
| 384 // OK, we're finished with a Token/Value. | 394 // OK, we're finished with a Token/Value. |
| 385 pair.second = std::string(value_start, value_end); | 395 pair.second = std::string(value_start, value_end); |
| 386 | 396 |
| 397 if (!IsValidCookieAttributeValue(pair.second)) | |
| 398 parsed_invalid_control_char = true; | |
| 399 if (!IsValidToken(pair.second)) | |
| 400 parsed_invalid_token = true; | |
| 401 | |
| 387 // From RFC2109: "Attributes (names) (attr) are case-insensitive." | 402 // From RFC2109: "Attributes (names) (attr) are case-insensitive." |
| 388 if (pair_num != 0) | 403 if (pair_num != 0) |
| 389 StringToLowerASCII(&pair.first); | 404 StringToLowerASCII(&pair.first); |
| 390 pairs_.push_back(pair); | 405 pairs_.push_back(pair); |
| 391 | 406 |
| 392 // We've processed a token/value pair, we're either at the end of | 407 // We've processed a token/value pair, we're either at the end of |
| 393 // the string or a ValueSeparator like ';', which we want to skip. | 408 // the string or a ValueSeparator like ';', which we want to skip. |
| 394 if (it != end) | 409 if (it != end) |
| 395 ++it; | 410 ++it; |
| 396 } | 411 } |
| 412 | |
| 413 UMA_HISTOGRAM_BOOLEAN("Cookies.ParsedInvalidControlCharacter", | |
| 414 parsed_invalid_control_char); | |
|
erikwright (departed)
2013/05/27 19:19:41
indentation (align with ")
jww
2013/05/28 17:14:05
Done.
| |
| 415 UMA_HISTOGRAM_BOOLEAN("Cookies.ParsedInvalidToken", parsed_invalid_token); | |
| 397 } | 416 } |
| 398 | 417 |
| 399 void ParsedCookie::SetupAttributes() { | 418 void ParsedCookie::SetupAttributes() { |
| 400 // We skip over the first token/value, the user supplied one. | 419 // We skip over the first token/value, the user supplied one. |
| 401 for (size_t i = 1; i < pairs_.size(); ++i) { | 420 for (size_t i = 1; i < pairs_.size(); ++i) { |
| 402 if (pairs_[i].first == kPathTokenName) { | 421 if (pairs_[i].first == kPathTokenName) { |
| 403 path_index_ = i; | 422 path_index_ = i; |
| 404 } else if (pairs_[i].first == kDomainTokenName) { | 423 } else if (pairs_[i].first == kDomainTokenName) { |
| 405 domain_index_ = i; | 424 domain_index_ = i; |
| 406 } else if (pairs_[i].first == kExpiresTokenName) { | 425 } else if (pairs_[i].first == kExpiresTokenName) { |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 437 ClearAttributePair(*index); | 456 ClearAttributePair(*index); |
| 438 return true; | 457 return true; |
| 439 } else { | 458 } else { |
| 440 return SetAttributePair(index, key, std::string()); | 459 return SetAttributePair(index, key, std::string()); |
| 441 } | 460 } |
| 442 } | 461 } |
| 443 | 462 |
| 444 bool ParsedCookie::SetAttributePair(size_t* index, | 463 bool ParsedCookie::SetAttributePair(size_t* index, |
| 445 const std::string& key, | 464 const std::string& key, |
| 446 const std::string& value) { | 465 const std::string& value) { |
| 447 if (!IsValidToken(key) || !IsValidCookieAttributeValue(value)) | 466 if (!IsValidToken(key) || !IsValidCookieAttributeValue(value)) { |
| 467 UMA_HISTOGRAM_BOOLEAN("Cookies.SetAttributePairInvalidChars", true); | |
| 448 return false; | 468 return false; |
| 469 } | |
| 470 UMA_HISTOGRAM_BOOLEAN("Cookies.SetAttributePairInvalidChars", false); | |
| 449 if (!IsValid()) | 471 if (!IsValid()) |
| 450 return false; | 472 return false; |
| 451 if (*index) { | 473 if (*index) { |
| 452 pairs_[*index].second = value; | 474 pairs_[*index].second = value; |
| 453 } else { | 475 } else { |
| 454 pairs_.push_back(std::make_pair(key, value)); | 476 pairs_.push_back(std::make_pair(key, value)); |
| 455 *index = pairs_.size() - 1; | 477 *index = pairs_.size() - 1; |
| 456 } | 478 } |
| 457 return true; | 479 return true; |
| 458 } | 480 } |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 470 for (size_t i = 0; i < arraysize(indexes); ++i) { | 492 for (size_t i = 0; i < arraysize(indexes); ++i) { |
| 471 if (*indexes[i] == index) | 493 if (*indexes[i] == index) |
| 472 *indexes[i] = 0; | 494 *indexes[i] = 0; |
| 473 else if (*indexes[i] > index) | 495 else if (*indexes[i] > index) |
| 474 --*indexes[i]; | 496 --*indexes[i]; |
| 475 } | 497 } |
| 476 pairs_.erase(pairs_.begin() + index); | 498 pairs_.erase(pairs_.begin() + index); |
| 477 } | 499 } |
| 478 | 500 |
| 479 } // namespace | 501 } // namespace |
| OLD | NEW |