OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |