blob: 7d55dd9e9d211ed9f25e50388cf8c9e20c14dfff [file] [log] [blame]
[email protected]b0d7aa362012-02-03 18:19:151// 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
3// found in the LICENSE file.
4
[email protected]184799df2014-07-22 16:03:245#include <string>
6#include <utility>
[email protected]184799df2014-07-22 16:03:247
payal.pandey47e20fdf52015-04-24 12:38:348#include "base/strings/string_split.h"
[email protected]63ee33bd2012-03-15 09:29:589#include "net/cookies/cookie_util.h"
[email protected]b0d7aa362012-02-03 18:19:1510#include "testing/gtest/include/gtest/gtest.h"
11
ttuttle859dc7a2015-04-23 19:42:2912namespace net {
13
[email protected]184799df2014-07-22 16:03:2414namespace {
15
16struct RequestCookieParsingTest {
17 std::string str;
payal.pandey47e20fdf52015-04-24 12:38:3418 base::StringPairs parsed;
[email protected]184799df2014-07-22 16:03:2419};
20
ttuttle859dc7a2015-04-23 19:42:2921cookie_util::ParsedRequestCookies MakeParsedRequestCookies(
payal.pandey47e20fdf52015-04-24 12:38:3422 const base::StringPairs& data) {
ttuttle859dc7a2015-04-23 19:42:2923 cookie_util::ParsedRequestCookies parsed;
[email protected]184799df2014-07-22 16:03:2424 for (size_t i = 0; i < data.size(); i++) {
25 parsed.push_back(std::make_pair(base::StringPiece(data[i].first),
26 base::StringPiece(data[i].second)));
27 }
28 return parsed;
29}
30
payal.pandey47e20fdf52015-04-24 12:38:3431void CheckParse(const std::string& str,
32 const base::StringPairs& parsed_expected) {
ttuttle859dc7a2015-04-23 19:42:2933 cookie_util::ParsedRequestCookies parsed;
34 cookie_util::ParseRequestCookieLine(str, &parsed);
[email protected]184799df2014-07-22 16:03:2435 EXPECT_EQ(MakeParsedRequestCookies(parsed_expected), parsed);
36}
37
payal.pandey47e20fdf52015-04-24 12:38:3438void CheckSerialize(const base::StringPairs& parsed,
39 const std::string& str_expected) {
ttuttle859dc7a2015-04-23 19:42:2940 cookie_util::ParsedRequestCookies prc = MakeParsedRequestCookies(parsed);
41 EXPECT_EQ(str_expected, cookie_util::SerializeRequestCookieLine(prc));
[email protected]184799df2014-07-22 16:03:2442}
43
[email protected]b0d7aa362012-02-03 18:19:1544TEST(CookieUtilTest, TestDomainIsHostOnly) {
45 const struct {
46 const char* str;
47 const bool is_host_only;
rdsmithe4815982017-06-09 17:48:5348 } tests[] = {{"", true}, {"www.foo.com", true}, {".foo.com", false}};
[email protected]b0d7aa362012-02-03 18:19:1549
viettrungluue4a8b882014-10-16 06:17:3850 for (size_t i = 0; i < arraysize(tests); ++i) {
[email protected]b0d7aa362012-02-03 18:19:1551 EXPECT_EQ(tests[i].is_host_only,
ttuttle859dc7a2015-04-23 19:42:2952 cookie_util::DomainIsHostOnly(tests[i].str));
[email protected]b0d7aa362012-02-03 18:19:1553 }
54}
[email protected]5b9bc352012-07-18 13:13:3455
56TEST(CookieUtilTest, TestCookieDateParsing) {
57 const struct {
58 const char* str;
59 const bool valid;
60 const time_t epoch;
61 } tests[] = {
mmenkeb6e73772016-10-20 18:40:3262 {"Sat, 15-Apr-17 21:01:22 GMT", true, 1492290082},
63 {"Thu, 19-Apr-2007 16:00:00 GMT", true, 1176998400},
64 {"Wed, 25 Apr 2007 21:02:13 GMT", true, 1177534933},
65 {"Thu, 19/Apr\\2007 16:00:00 GMT", true, 1176998400},
66 {"Fri, 1 Jan 2010 01:01:50 GMT", true, 1262307710},
67 {"Wednesday, 1-Jan-2003 00:00:00 GMT", true, 1041379200},
68 {", 1-Jan-2003 00:00:00 GMT", true, 1041379200},
69 {" 1-Jan-2003 00:00:00 GMT", true, 1041379200},
70 {"1-Jan-2003 00:00:00 GMT", true, 1041379200},
71 {"Wed,18-Apr-07 22:50:12 GMT", true, 1176936612},
72 {"WillyWonka , 18-Apr-07 22:50:12 GMT", true, 1176936612},
73 {"WillyWonka , 18-Apr-07 22:50:12", true, 1176936612},
74 {"WillyWonka , 18-apr-07 22:50:12", true, 1176936612},
75 {"Mon, 18-Apr-1977 22:50:13 GMT", true, 230251813},
76 {"Mon, 18-Apr-77 22:50:13 GMT", true, 230251813},
77 // If the cookie came in with the expiration quoted (which in terms of
78 // the RFC you shouldn't do), we will get string quoted. Bug 1261605.
79 {"\"Sat, 15-Apr-17\\\"21:01:22\\\"GMT\"", true, 1492290082},
80 // Test with full month names and partial names.
81 {"Partyday, 18- April-07 22:50:12", true, 1176936612},
82 {"Partyday, 18 - Apri-07 22:50:12", true, 1176936612},
83 {"Wednes, 1-Januar-2003 00:00:00 GMT", true, 1041379200},
84 // Test that we always take GMT even with other time zones or bogus
85 // values. The RFC says everything should be GMT, and in the worst case
86 // we are 24 hours off because of zone issues.
87 {"Sat, 15-Apr-17 21:01:22", true, 1492290082},
88 {"Sat, 15-Apr-17 21:01:22 GMT-2", true, 1492290082},
89 {"Sat, 15-Apr-17 21:01:22 GMT BLAH", true, 1492290082},
90 {"Sat, 15-Apr-17 21:01:22 GMT-0400", true, 1492290082},
91 {"Sat, 15-Apr-17 21:01:22 GMT-0400 (EDT)", true, 1492290082},
92 {"Sat, 15-Apr-17 21:01:22 DST", true, 1492290082},
93 {"Sat, 15-Apr-17 21:01:22 -0400", true, 1492290082},
94 {"Sat, 15-Apr-17 21:01:22 (hello there)", true, 1492290082},
95 // Test that if we encounter multiple : fields, that we take the first
96 // that correctly parses.
97 {"Sat, 15-Apr-17 21:01:22 11:22:33", true, 1492290082},
98 {"Sat, 15-Apr-17 ::00 21:01:22", true, 1492290082},
99 {"Sat, 15-Apr-17 boink:z 21:01:22", true, 1492290082},
100 // We take the first, which in this case is invalid.
101 {"Sat, 15-Apr-17 91:22:33 21:01:22", false, 0},
102 // amazon.com formats their cookie expiration like this.
103 {"Thu Apr 18 22:50:12 2007 GMT", true, 1176936612},
104 // Test that hh:mm:ss can occur anywhere.
105 {"22:50:12 Thu Apr 18 2007 GMT", true, 1176936612},
106 {"Thu 22:50:12 Apr 18 2007 GMT", true, 1176936612},
107 {"Thu Apr 22:50:12 18 2007 GMT", true, 1176936612},
108 {"Thu Apr 18 22:50:12 2007 GMT", true, 1176936612},
109 {"Thu Apr 18 2007 22:50:12 GMT", true, 1176936612},
110 {"Thu Apr 18 2007 GMT 22:50:12", true, 1176936612},
111 // Test that the day and year can be anywhere if they are unambigious.
112 {"Sat, 15-Apr-17 21:01:22 GMT", true, 1492290082},
113 {"15-Sat, Apr-17 21:01:22 GMT", true, 1492290082},
114 {"15-Sat, Apr 21:01:22 GMT 17", true, 1492290082},
115 {"15-Sat, Apr 21:01:22 GMT 2017", true, 1492290082},
116 {"15 Apr 21:01:22 2017", true, 1492290082},
117 {"15 17 Apr 21:01:22", true, 1492290082},
118 {"Apr 15 17 21:01:22", true, 1492290082},
119 {"Apr 15 21:01:22 17", true, 1492290082},
120 {"2017 April 15 21:01:22", true, 1492290082},
121 {"15 April 2017 21:01:22", true, 1492290082},
122 // Some invalid dates
123 {"98 April 17 21:01:22", false, 0},
124 {"Thu, 012-Aug-2008 20:49:07 GMT", false, 0},
125 {"Thu, 12-Aug-9999999999 20:49:07 GMT", false, 0},
126 {"Thu, 999999999999-Aug-2007 20:49:07 GMT", false, 0},
127 {"Thu, 12-Aug-2007 20:61:99999999999 GMT", false, 0},
128 {"IAintNoDateFool", false, 0},
129 {"1600 April 33 21:01:22", false, 0},
130 {"1970 April 33 21:01:22", false, 0},
131 {"Thu, 33-Aug-31841 20:49:07 GMT", false, 0},
[email protected]5b9bc352012-07-18 13:13:34132 };
133
134 base::Time parsed_time;
viettrungluue4a8b882014-10-16 06:17:38135 for (size_t i = 0; i < arraysize(tests); ++i) {
mmenkeb6e73772016-10-20 18:40:32136 parsed_time = cookie_util::ParseCookieExpirationTime(tests[i].str);
[email protected]5b9bc352012-07-18 13:13:34137 if (!tests[i].valid) {
thestig52c42ca2015-05-06 21:22:59138 EXPECT_TRUE(parsed_time.is_null()) << tests[i].str;
[email protected]5b9bc352012-07-18 13:13:34139 continue;
140 }
141 EXPECT_TRUE(!parsed_time.is_null()) << tests[i].str;
142 EXPECT_EQ(tests[i].epoch, parsed_time.ToTimeT()) << tests[i].str;
143 }
144}
[email protected]184799df2014-07-22 16:03:24145
mmenkeb6e73772016-10-20 18:40:32146// Tests parsing dates that are beyond 2038. 32-bit (non-Mac) POSIX systems are
147// incapable of doing this, however the expectation is for cookie parsing to
148// succeed anyway (and return the minimum value Time::FromUTCExploded() can
149// parse on the current platform). Also checks a date outside the limit on
150// Windows, which is year 30827.
151TEST(CookieUtilTest, ParseCookieExpirationTimeBeyond2038) {
152 const char* kTests[] = {
153 "Thu, 12-Aug-31841 20:49:07 GMT", "2039 April 15 21:01:22",
154 "2039 April 15 21:01:22", "2038 April 15 21:01:22",
155 };
156
vmpstr6d9996c82017-02-23 00:43:25157 for (auto* test : kTests) {
mmenkeb6e73772016-10-20 18:40:32158 base::Time parsed_time = cookie_util::ParseCookieExpirationTime(test);
159 EXPECT_FALSE(parsed_time.is_null());
160
161 // It should either have an exact value, or be base::Time::Max(). For
162 // simplicity just check that it is greater than an arbitray date.
163 base::Time almost_jan_2038 =
164 base::Time::UnixEpoch() + base::TimeDelta::FromDays(365 * 68);
165 EXPECT_LT(almost_jan_2038, parsed_time);
166 }
167}
168
169// Tests parsing dates that are prior to (or around) 1970. Non-Mac POSIX systems
170// are incapable of doing this, however the expectation is for cookie parsing to
171// succeed anyway (and return a minimal base::Time).
172TEST(CookieUtilTest, ParseCookieExpirationTimeBefore1970) {
173 const char* kTests[] = {
Avi Drissmancfecbd12017-11-10 23:19:24174 // Times around the Unix epoch.
175 "1970 Jan 1 00:00:00", "1969 March 3 21:01:22",
176 // Times around the Windows epoch.
177 "1601 Jan 1 00:00:00", "1600 April 15 21:01:22",
178 // Times around kExplodedMinYear on Mac.
179 "1902 Jan 1 00:00:00", "1901 Jan 1 00:00:00",
mmenkeb6e73772016-10-20 18:40:32180 };
181
vmpstr6d9996c82017-02-23 00:43:25182 for (auto* test : kTests) {
mmenkeb6e73772016-10-20 18:40:32183 base::Time parsed_time = cookie_util::ParseCookieExpirationTime(test);
Avi Drissmancfecbd12017-11-10 23:19:24184 EXPECT_FALSE(parsed_time.is_null()) << test;
mmenkeb6e73772016-10-20 18:40:32185
186 // It should either have an exact value, or should be base::Time(1)
187 // For simplicity just check that it is less than the unix epoch.
Avi Drissmancfecbd12017-11-10 23:19:24188 EXPECT_LE(parsed_time, base::Time::UnixEpoch()) << test;
mmenkeb6e73772016-10-20 18:40:32189 }
190}
191
[email protected]184799df2014-07-22 16:03:24192TEST(CookieUtilTest, TestRequestCookieParsing) {
193 std::vector<RequestCookieParsingTest> tests;
194
195 // Simple case.
196 tests.push_back(RequestCookieParsingTest());
197 tests.back().str = "key=value";
198 tests.back().parsed.push_back(std::make_pair(std::string("key"),
199 std::string("value")));
200 // Multiple key/value pairs.
201 tests.push_back(RequestCookieParsingTest());
202 tests.back().str = "key1=value1; key2=value2";
203 tests.back().parsed.push_back(std::make_pair(std::string("key1"),
204 std::string("value1")));
205 tests.back().parsed.push_back(std::make_pair(std::string("key2"),
206 std::string("value2")));
207 // Empty value.
208 tests.push_back(RequestCookieParsingTest());
209 tests.back().str = "key=; otherkey=1234";
210 tests.back().parsed.push_back(std::make_pair(std::string("key"),
211 std::string()));
212 tests.back().parsed.push_back(std::make_pair(std::string("otherkey"),
213 std::string("1234")));
214 // Special characters (including equals signs) in value.
215 tests.push_back(RequestCookieParsingTest());
216 tests.back().str = "key=; a2=s=(./&t=:&u=a#$; a3=+~";
217 tests.back().parsed.push_back(std::make_pair(std::string("key"),
218 std::string()));
219 tests.back().parsed.push_back(std::make_pair(std::string("a2"),
220 std::string("s=(./&t=:&u=a#$")));
221 tests.back().parsed.push_back(std::make_pair(std::string("a3"),
222 std::string("+~")));
223 // Quoted value.
224 tests.push_back(RequestCookieParsingTest());
225 tests.back().str = "key=\"abcdef\"; otherkey=1234";
226 tests.back().parsed.push_back(std::make_pair(std::string("key"),
227 std::string("\"abcdef\"")));
228 tests.back().parsed.push_back(std::make_pair(std::string("otherkey"),
229 std::string("1234")));
230
231 for (size_t i = 0; i < tests.size(); i++) {
232 SCOPED_TRACE(testing::Message() << "Test " << i);
233 CheckParse(tests[i].str, tests[i].parsed);
234 CheckSerialize(tests[i].parsed, tests[i].str);
235 }
236}
yhirano5ca0f692015-01-29 14:57:39237
238TEST(CookieUtilTest, TestGetEffectiveDomain) {
239 // Note: registry_controlled_domains::GetDomainAndRegistry is tested in its
240 // own unittests.
241 EXPECT_EQ("example.com",
ttuttle859dc7a2015-04-23 19:42:29242 cookie_util::GetEffectiveDomain("http", "www.example.com"));
yhirano5ca0f692015-01-29 14:57:39243 EXPECT_EQ("example.com",
ttuttle859dc7a2015-04-23 19:42:29244 cookie_util::GetEffectiveDomain("https", "www.example.com"));
yhirano5ca0f692015-01-29 14:57:39245 EXPECT_EQ("example.com",
ttuttle859dc7a2015-04-23 19:42:29246 cookie_util::GetEffectiveDomain("ws", "www.example.com"));
yhirano5ca0f692015-01-29 14:57:39247 EXPECT_EQ("example.com",
ttuttle859dc7a2015-04-23 19:42:29248 cookie_util::GetEffectiveDomain("wss", "www.example.com"));
yhirano5ca0f692015-01-29 14:57:39249 EXPECT_EQ("www.example.com",
ttuttle859dc7a2015-04-23 19:42:29250 cookie_util::GetEffectiveDomain("ftp", "www.example.com"));
yhirano5ca0f692015-01-29 14:57:39251}
252
253} // namespace
ttuttle859dc7a2015-04-23 19:42:29254
255} // namespace net