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

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

Issue 23503084: Remove control character cookie UMA stats. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 3 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 | Annotate | Revision Log
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 27 matching lines...) Expand all
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"
49 #include "base/strings/string_util.h" 48 #include "base/strings/string_util.h"
50 49
51 // TODO(jww): We are collecting several UMA statistics in this file, and they
52 // relate to http://crbug.com/238041. We are measuring stats related to control
53 // characters in cookies because, currently, we allow control characters in a
54 // variety of scenarios where various RFCs theoretically disallow them. These
55 // control characters have the potential to cause problems with certain web
56 // servers that reject HTTP requests that contain cookies with control
57 // characters. We are measuring whether disallowing such cookies would have a
58 // notable impact on our users. We want to collect these stats through 1 stable
59 // release, so these UMA stats should remain at least through the M29
60 // branch-point.
61
62 namespace { 50 namespace {
63 51
64 const char kPathTokenName[] = "path"; 52 const char kPathTokenName[] = "path";
65 const char kDomainTokenName[] = "domain"; 53 const char kDomainTokenName[] = "domain";
66 const char kExpiresTokenName[] = "expires"; 54 const char kExpiresTokenName[] = "expires";
67 const char kMaxAgeTokenName[] = "max-age"; 55 const char kMaxAgeTokenName[] = "max-age";
68 const char kSecureTokenName[] = "secure"; 56 const char kSecureTokenName[] = "secure";
69 const char kHttpOnlyTokenName[] = "httponly"; 57 const char kHttpOnlyTokenName[] = "httponly";
70 const char kPriorityTokenName[] = "priority"; 58 const char kPriorityTokenName[] = "priority";
71 59
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
191 bool ParsedCookie::IsValid() const { 179 bool ParsedCookie::IsValid() const {
192 return !pairs_.empty(); 180 return !pairs_.empty();
193 } 181 }
194 182
195 CookiePriority ParsedCookie::Priority() const { 183 CookiePriority ParsedCookie::Priority() const {
196 return (priority_index_ == 0) ? COOKIE_PRIORITY_DEFAULT : 184 return (priority_index_ == 0) ? COOKIE_PRIORITY_DEFAULT :
197 StringToCookiePriority(pairs_[priority_index_].second); 185 StringToCookiePriority(pairs_[priority_index_].second);
198 } 186 }
199 187
200 bool ParsedCookie::SetName(const std::string& name) { 188 bool ParsedCookie::SetName(const std::string& name) {
201 bool valid_token = IsValidToken(name); 189 if (!IsValidToken(name))
202 UMA_HISTOGRAM_BOOLEAN("Cookie.SetNameVaildity", valid_token);
203 if (!valid_token)
204 return false; 190 return false;
205 if (pairs_.empty()) 191 if (pairs_.empty())
206 pairs_.push_back(std::make_pair("", "")); 192 pairs_.push_back(std::make_pair("", ""));
207 pairs_[0].first = name; 193 pairs_[0].first = name;
208 return true; 194 return true;
209 } 195 }
210 196
211 bool ParsedCookie::SetValue(const std::string& value) { 197 bool ParsedCookie::SetValue(const std::string& value) {
212 bool valid_cookie_value = IsValidCookieValue(value); 198 if (!IsValidCookieValue(value))
213 UMA_HISTOGRAM_BOOLEAN("Cookie.SetValueCookieValueValidity",
214 valid_cookie_value);
215 if (!valid_cookie_value)
216 return false; 199 return false;
217 if (pairs_.empty()) 200 if (pairs_.empty())
218 pairs_.push_back(std::make_pair("", "")); 201 pairs_.push_back(std::make_pair("", ""));
219 pairs_[0].second = value; 202 pairs_[0].second = value;
220 return true; 203 return true;
221 } 204 }
222 205
223 bool ParsedCookie::SetPath(const std::string& path) { 206 bool ParsedCookie::SetPath(const std::string& path) {
224 return SetString(&path_index_, kPathTokenName, path); 207 return SetString(&path_index_, kPathTokenName, path);
225 } 208 }
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
351 std::string::const_iterator it = value.begin(); 334 std::string::const_iterator it = value.begin();
352 std::string::const_iterator end = FindFirstTerminator(value); 335 std::string::const_iterator end = FindFirstTerminator(value);
353 336
354 std::string::const_iterator value_start, value_end; 337 std::string::const_iterator value_start, value_end;
355 ParseValue(&it, end, &value_start, &value_end); 338 ParseValue(&it, end, &value_start, &value_end);
356 return std::string(value_start, value_end); 339 return std::string(value_start, value_end);
357 } 340 }
358 341
359 // Parse all token/value pairs and populate pairs_. 342 // Parse all token/value pairs and populate pairs_.
360 void ParsedCookie::ParseTokenValuePairs(const std::string& cookie_line) { 343 void ParsedCookie::ParseTokenValuePairs(const std::string& cookie_line) {
361 enum ParsedCookieStatus {
362 PARSED_COOKIE_STATUS_NOTHING = 0x0,
363 PARSED_COOKIE_STATUS_CONTROL_CHAR = 0x1,
364 PARSED_COOKIE_STATUS_INVALID = 0x2,
365 PARSED_COOKIE_STATUS_BOTH =
366 PARSED_COOKIE_STATUS_CONTROL_CHAR | PARSED_COOKIE_STATUS_INVALID
367 };
368 int parsed_cookie_status = PARSED_COOKIE_STATUS_NOTHING;
369
370 pairs_.clear(); 344 pairs_.clear();
371 345
372 // Ok, here we go. We should be expecting to be starting somewhere 346 // Ok, here we go. We should be expecting to be starting somewhere
373 // before the cookie line, not including any header name... 347 // before the cookie line, not including any header name...
374 std::string::const_iterator start = cookie_line.begin(); 348 std::string::const_iterator start = cookie_line.begin();
375 std::string::const_iterator it = start; 349 std::string::const_iterator it = start;
376 350
377 // TODO(erikwright): Make sure we're stripping \r\n in the network code. 351 // TODO(erikwright): Make sure we're stripping \r\n in the network code.
378 // Then we can log any unexpected terminators. 352 // Then we can log any unexpected terminators.
379 std::string::const_iterator end = FindFirstTerminator(cookie_line); 353 std::string::const_iterator end = FindFirstTerminator(cookie_line);
(...skipping 28 matching lines...) Expand all
408 ++it; // Skip past the '='. 382 ++it; // Skip past the '='.
409 } 383 }
410 384
411 // OK, now try to parse a value. 385 // OK, now try to parse a value.
412 std::string::const_iterator value_start, value_end; 386 std::string::const_iterator value_start, value_end;
413 ParseValue(&it, end, &value_start, &value_end); 387 ParseValue(&it, end, &value_start, &value_end);
414 388
415 // OK, we're finished with a Token/Value. 389 // OK, we're finished with a Token/Value.
416 pair.second = std::string(value_start, value_end); 390 pair.second = std::string(value_start, value_end);
417 391
418 if (!IsValidCookieAttributeValue(pair.second))
419 parsed_cookie_status |= PARSED_COOKIE_STATUS_CONTROL_CHAR;
420 if (!IsValidToken(pair.second))
421 parsed_cookie_status |= PARSED_COOKIE_STATUS_INVALID;
422
423 // From RFC2109: "Attributes (names) (attr) are case-insensitive." 392 // From RFC2109: "Attributes (names) (attr) are case-insensitive."
424 if (pair_num != 0) 393 if (pair_num != 0)
425 StringToLowerASCII(&pair.first); 394 StringToLowerASCII(&pair.first);
426 // Ignore Set-Cookie directives contaning control characters. See 395 // Ignore Set-Cookie directives contaning control characters. See
427 // http://crbug.com/238041. 396 // http://crbug.com/238041.
428 if (!IsValidCookieAttributeValue(pair.first) || 397 if (!IsValidCookieAttributeValue(pair.first) ||
429 !IsValidCookieAttributeValue(pair.second)) { 398 !IsValidCookieAttributeValue(pair.second)) {
430 pairs_.clear(); 399 pairs_.clear();
431 break; 400 break;
432 } 401 }
433 402
434 pairs_.push_back(pair); 403 pairs_.push_back(pair);
435 404
436 // We've processed a token/value pair, we're either at the end of 405 // We've processed a token/value pair, we're either at the end of
437 // the string or a ValueSeparator like ';', which we want to skip. 406 // the string or a ValueSeparator like ';', which we want to skip.
438 if (it != end) 407 if (it != end)
439 ++it; 408 ++it;
440 } 409 }
441
442 UMA_HISTOGRAM_ENUMERATION("Cookie.ParsedCookieStatus", parsed_cookie_status,
443 PARSED_COOKIE_STATUS_BOTH + 1);
444 } 410 }
445 411
446 void ParsedCookie::SetupAttributes() { 412 void ParsedCookie::SetupAttributes() {
447 // We skip over the first token/value, the user supplied one. 413 // We skip over the first token/value, the user supplied one.
448 for (size_t i = 1; i < pairs_.size(); ++i) { 414 for (size_t i = 1; i < pairs_.size(); ++i) {
449 if (pairs_[i].first == kPathTokenName) { 415 if (pairs_[i].first == kPathTokenName) {
450 path_index_ = i; 416 path_index_ = i;
451 } else if (pairs_[i].first == kDomainTokenName) { 417 } else if (pairs_[i].first == kDomainTokenName) {
452 domain_index_ = i; 418 domain_index_ = i;
453 } else if (pairs_[i].first == kExpiresTokenName) { 419 } else if (pairs_[i].first == kExpiresTokenName) {
(...skipping 30 matching lines...) Expand all
484 ClearAttributePair(*index); 450 ClearAttributePair(*index);
485 return true; 451 return true;
486 } else { 452 } else {
487 return SetAttributePair(index, key, std::string()); 453 return SetAttributePair(index, key, std::string());
488 } 454 }
489 } 455 }
490 456
491 bool ParsedCookie::SetAttributePair(size_t* index, 457 bool ParsedCookie::SetAttributePair(size_t* index,
492 const std::string& key, 458 const std::string& key,
493 const std::string& value) { 459 const std::string& value) {
494 bool valid_attribute_pair = IsValidToken(key) && 460 if (!(IsValidToken(key) && IsValidCookieAttributeValue(value)))
495 IsValidCookieAttributeValue(value);
496 UMA_HISTOGRAM_BOOLEAN("Cookie.SetAttributePairCharsValidity",
497 valid_attribute_pair);
498 if (!valid_attribute_pair)
499 return false; 461 return false;
500 if (!IsValid()) 462 if (!IsValid())
501 return false; 463 return false;
502 if (*index) { 464 if (*index) {
503 pairs_[*index].second = value; 465 pairs_[*index].second = value;
504 } else { 466 } else {
505 pairs_.push_back(std::make_pair(key, value)); 467 pairs_.push_back(std::make_pair(key, value));
506 *index = pairs_.size() - 1; 468 *index = pairs_.size() - 1;
507 } 469 }
508 return true; 470 return true;
(...skipping 12 matching lines...) Expand all
521 for (size_t i = 0; i < arraysize(indexes); ++i) { 483 for (size_t i = 0; i < arraysize(indexes); ++i) {
522 if (*indexes[i] == index) 484 if (*indexes[i] == index)
523 *indexes[i] = 0; 485 *indexes[i] = 0;
524 else if (*indexes[i] > index) 486 else if (*indexes[i] > index)
525 --*indexes[i]; 487 --*indexes[i];
526 } 488 }
527 pairs_.erase(pairs_.begin() + index); 489 pairs_.erase(pairs_.begin() + index);
528 } 490 }
529 491
530 } // namespace 492 } // namespace
OLDNEW
« no previous file with comments | « no previous file | tools/metrics/histograms/histograms.xml » ('j') | tools/metrics/histograms/histograms.xml » ('J')

Powered by Google App Engine
This is Rietveld 408576698