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

Side by Side Diff: net/base/cookie_monster.cc

Issue 17045: CookieMonster edge-case parsing improvements and tests. (Closed)
Patch Set: Typo Created 11 years, 11 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
« no previous file with comments | « net/base/cookie_monster.h ('k') | net/base/cookie_monster_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2006-2008 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 886 matching lines...) Expand 10 before | Expand all | Expand 10 after
897 for (; *it != end && CharIsA(**it, chars); --(*it)); 897 for (; *it != end && CharIsA(**it, chars); --(*it));
898 return *it == end; 898 return *it == end;
899 } 899 }
900 900
901 // Parse all token/value pairs and populate pairs_. 901 // Parse all token/value pairs and populate pairs_.
902 void CookieMonster::ParsedCookie::ParseTokenValuePairs( 902 void CookieMonster::ParsedCookie::ParseTokenValuePairs(
903 const std::string& cookie_line) { 903 const std::string& cookie_line) {
904 static const char kTerminator[] = "\n\r\0"; 904 static const char kTerminator[] = "\n\r\0";
905 static const int kTerminatorLen = sizeof(kTerminator) - 1; 905 static const int kTerminatorLen = sizeof(kTerminator) - 1;
906 static const char kWhitespace[] = " \t"; 906 static const char kWhitespace[] = " \t";
907 static const char kQuoteTerminator[] = "\"";
908 static const char kValueSeparator[] = ";"; 907 static const char kValueSeparator[] = ";";
909 static const char kTokenSeparator[] = ";="; 908 static const char kTokenSeparator[] = ";=";
910 909
911 pairs_.clear(); 910 pairs_.clear();
912 911
913 // Ok, here we go. We should be expecting to be starting somewhere 912 // Ok, here we go. We should be expecting to be starting somewhere
914 // before the cookie line, not including any header name... 913 // before the cookie line, not including any header name...
915 std::string::const_iterator start = cookie_line.begin(); 914 std::string::const_iterator start = cookie_line.begin();
916 std::string::const_iterator end = cookie_line.end(); 915 std::string::const_iterator end = cookie_line.end();
917 std::string::const_iterator it = start; 916 std::string::const_iterator it = start;
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
980 } 979 }
981 980
982 // OK, now try to parse a value. 981 // OK, now try to parse a value.
983 std::string::const_iterator value_start, value_end; 982 std::string::const_iterator value_start, value_end;
984 983
985 // Seek past any whitespace that might in-between the token and value. 984 // Seek past any whitespace that might in-between the token and value.
986 SeekPast(&it, end, kWhitespace); 985 SeekPast(&it, end, kWhitespace);
987 // value_start should point at the first character of the value. 986 // value_start should point at the first character of the value.
988 value_start = it; 987 value_start = it;
989 988
990 // The value is double quoted, process <quoted-string>. 989 // It is unclear exactly how quoted string values should be handled.
991 if (it != end && *it == '"') { 990 // Major browsers do different things, for example, Firefox supports
992 // Skip over the first double quote, and parse until 991 // semicolons embedded in a quoted value, while IE does not. Looking at
993 // a terminating double quote or the end. 992 // the specs, RFC 2109 and 2965 allow for a quoted-string as the value.
994 for (++it; it != end && !CharIsA(*it, kQuoteTerminator); ++it) { 993 // However, these specs were apparently written after browsers had
995 // Allow an escaped \" in a double quoted string. 994 // implemented cookies, and they seem very distant from the reality of
996 if (*it == '\\') { 995 // what is actually implemented and used on the web. The original spec
997 ++it; 996 // from Netscape is possibly what is closest to the cookies used today.
998 if (it == end) 997 // This spec didn't have explicit support for double quoted strings, and
999 break; 998 // states that ; is not allowed as part of a value. We had originally
1000 } 999 // implement the Firefox behavior (A="B;C"; -> A="B;C";). However, since
1001 } 1000 // there is no standard that makes sense, we decided to follow the behavior
1001 // of IE and Safari, which is closer to the original Netscape proposal.
1002 // This means that A="B;C" -> A="B;. This also makes the code much simpler
1003 // and reduces the possibility for invalid cookies, where other browsers
1004 // like Opera currently reject those invalid cookies (ex A="B" "C";).
1002 1005
1003 SeekTo(&it, end, kValueSeparator); 1006 // Just look for ';' to terminate ('=' allowed).
1004 // We could seek to the end, that's ok. 1007 // We can hit the end, maybe they didn't terminate.
1005 value_end = it; 1008 SeekTo(&it, end, kValueSeparator);
1006 } else {
1007 // The value is non-quoted, process <token-value>.
1008 // Just look for ';' to terminate ('=' allowed).
1009 // We can hit the end, maybe they didn't terminate.
1010 SeekTo(&it, end, kValueSeparator);
1011 1009
1012 // Ignore any whitespace between the value and the value separator 1010 // Will be pointed at the ; seperator or the end.
1013 if (it != value_start) { // Could have an empty value 1011 value_end = it;
1014 --it;
1015 SeekBackPast(&it, value_start, kWhitespace);
1016 ++it;
1017 }
1018 1012
1019 value_end = it; 1013 // Ignore any unwanted whitespace after the value.
1014 if (value_end != value_start) { // Could have an empty value
1015 --value_end;
1016 SeekBackPast(&value_end, value_start, kWhitespace);
1017 ++value_end;
1020 } 1018 }
1021 1019
1022 // OK, we're finished with a Token/Value. 1020 // OK, we're finished with a Token/Value.
1023 pair.second = std::string(value_start, value_end); 1021 pair.second = std::string(value_start, value_end);
1024 // From RFC2109: "Attributes (names) (attr) are case-insensitive." 1022 // From RFC2109: "Attributes (names) (attr) are case-insensitive."
1025 if (pair_num != 0) 1023 if (pair_num != 0)
1026 StringToLowerASCII(&pair.first); 1024 StringToLowerASCII(&pair.first);
1027 pairs_.push_back(pair); 1025 pairs_.push_back(pair);
1028 1026
1029 // We've processed a token/value pair, we're either at the end of 1027 // We've processed a token/value pair, we're either at the end of
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
1111 } 1109 }
1112 1110
1113 std::string CookieMonster::CanonicalCookie::DebugString() const { 1111 std::string CookieMonster::CanonicalCookie::DebugString() const {
1114 return StringPrintf("name: %s value: %s path: %s creation: %llu", 1112 return StringPrintf("name: %s value: %s path: %s creation: %llu",
1115 name_.c_str(), value_.c_str(), path_.c_str(), 1113 name_.c_str(), value_.c_str(), path_.c_str(),
1116 creation_date_.ToTimeT()); 1114 creation_date_.ToTimeT());
1117 } 1115 }
1118 1116
1119 } // namespace 1117 } // namespace
1120 1118
OLDNEW
« no previous file with comments | « net/base/cookie_monster.h ('k') | net/base/cookie_monster_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698