blob: d2f6b730d5a927c1ed156da87f5382a2a552ef45 [file] [log] [blame]
[email protected]ebfe3172012-07-12 12:21:411// 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
5#include <string>
6
[email protected]ab2d75c82013-04-19 18:39:047#include "net/cookies/cookie_constants.h"
[email protected]ebfe3172012-07-12 12:21:418#include "net/cookies/parsed_cookie.h"
9#include "testing/gtest/include/gtest/gtest.h"
10
11namespace net {
12
[email protected]ebfe3172012-07-12 12:21:4113TEST(ParsedCookieTest, TestBasic) {
14 ParsedCookie pc("a=b");
15 EXPECT_TRUE(pc.IsValid());
16 EXPECT_FALSE(pc.IsSecure());
17 EXPECT_EQ("a", pc.Name());
18 EXPECT_EQ("b", pc.Value());
19}
20
jww03e6ff8c2016-08-17 19:19:5821// De facto standard behavior, per https://crbug.com/601786.
[email protected]8fbe410412014-07-28 17:17:4122TEST(ParsedCookieTest, TestEmpty) {
jww03e6ff8c2016-08-17 19:19:5823 const struct {
24 const char* cookie;
25 const char* expected_path;
26 bool expect_secure;
27 } kTestCookieLines[]{{"", "", false}, {" ", "", false},
28 {"=;", "", false}, {"=; path=/; secure;", "/", true},
29 {"= ;", "", false}, {"= ; path=/; secure;", "/", true},
30 {" =;", "", false}, {" =; path=/; secure;", "/", true},
31 {" = ;", "", false}, {" = ; path=/; secure;", "/", true},
32 {" ;", "", false}, {" ; path=/; secure;", "/", true},
33 {";", "", false}, {"; path=/; secure;", "/", true},
34 {"\t;", "", false}, {"\t; path=/; secure;", "/", true}};
35
36 for (const auto& test : kTestCookieLines) {
37 ParsedCookie pc(test.cookie);
38 EXPECT_TRUE(pc.IsValid());
39 EXPECT_EQ("", pc.Name());
40 EXPECT_EQ("", pc.Value());
41 EXPECT_EQ(test.expected_path, pc.Path());
42 EXPECT_EQ(test.expect_secure, pc.IsSecure());
43 }
[email protected]8fbe410412014-07-28 17:17:4144}
45
[email protected]ebfe3172012-07-12 12:21:4146TEST(ParsedCookieTest, TestQuoted) {
47 // These are some quoting cases which the major browsers all
48 // handle differently. I've tested Internet Explorer 6, Opera 9.6,
49 // Firefox 3, and Safari Windows 3.2.1. We originally tried to match
50 // Firefox closely, however we now match Internet Explorer and Safari.
Ryan Sleevi435a3a22018-05-15 02:16:0751 const struct {
52 const char* input;
53 const char* expected;
54 } kTests[] = {
mkwstbe84af312015-02-20 08:52:4555 // Trailing whitespace after a quoted value. The whitespace after
56 // the quote is stripped in all browsers.
Ryan Sleevi435a3a22018-05-15 02:16:0757 {"\"zzz \" ", "\"zzz \""},
mkwstbe84af312015-02-20 08:52:4558 // Handling a quoted value with a ';', like FOO="zz;pp" ;
59 // IE and Safari: "zz;
60 // Firefox and Opera: "zz;pp"
Ryan Sleevi435a3a22018-05-15 02:16:0761 {"\"zz;pp\" ;", "\"zz"},
mkwstbe84af312015-02-20 08:52:4562 // Handling a value with multiple quoted parts, like FOO="zzz " "ppp" ;
63 // IE and Safari: "zzz " "ppp";
64 // Firefox: "zzz ";
65 // Opera: <rejects cookie>
Ryan Sleevi435a3a22018-05-15 02:16:0766 {
67 "\"zzz \" \"ppp\" ", "\"zzz \" \"ppp\"",
68 },
mkwstbe84af312015-02-20 08:52:4569 // A quote in a value that didn't start quoted. like FOO=A"B ;
70 // IE, Safari, and Firefox: A"B;
71 // Opera: <rejects cookie>
Ryan Sleevi435a3a22018-05-15 02:16:0772 {
73 "A\"B", "A\"B",
74 }};
[email protected]ebfe3172012-07-12 12:21:4175
Ryan Sleevi435a3a22018-05-15 02:16:0776 for (const auto& test : kTests) {
77 ParsedCookie pc(std::string("aBc=") + test.input +
78 " ; path=\"/\" ; httponly ");
[email protected]ebfe3172012-07-12 12:21:4179 EXPECT_TRUE(pc.IsValid());
80 EXPECT_FALSE(pc.IsSecure());
81 EXPECT_TRUE(pc.IsHttpOnly());
82 EXPECT_TRUE(pc.HasPath());
83 EXPECT_EQ("aBc", pc.Name());
Ryan Sleevi435a3a22018-05-15 02:16:0784 EXPECT_EQ(test.expected, pc.Value());
[email protected]ebfe3172012-07-12 12:21:4185
86 // If a path was quoted, the path attribute keeps the quotes. This will
87 // make the cookie effectively useless, but path parameters aren't supposed
88 // to be quoted. Bug 1261605.
89 EXPECT_EQ("\"/\"", pc.Path());
90 }
91}
92
93TEST(ParsedCookieTest, TestNameless) {
94 ParsedCookie pc("BLAHHH; path=/; secure;");
95 EXPECT_TRUE(pc.IsValid());
96 EXPECT_TRUE(pc.IsSecure());
97 EXPECT_TRUE(pc.HasPath());
98 EXPECT_EQ("/", pc.Path());
99 EXPECT_EQ("", pc.Name());
100 EXPECT_EQ("BLAHHH", pc.Value());
[email protected]ab2d75c82013-04-19 18:39:04101 EXPECT_EQ(COOKIE_PRIORITY_DEFAULT, pc.Priority());
[email protected]ebfe3172012-07-12 12:21:41102}
103
104TEST(ParsedCookieTest, TestAttributeCase) {
mkwste1a29582016-03-15 10:07:52105 ParsedCookie pc(
106 "BLAHHH; Path=/; sECuRe; httpONLY; sAmESitE=StrIct; pRIoRitY=hIgH");
[email protected]ebfe3172012-07-12 12:21:41107 EXPECT_TRUE(pc.IsValid());
108 EXPECT_TRUE(pc.IsSecure());
109 EXPECT_TRUE(pc.IsHttpOnly());
mkwste1a29582016-03-15 10:07:52110 EXPECT_EQ(CookieSameSite::STRICT_MODE, pc.SameSite());
[email protected]ebfe3172012-07-12 12:21:41111 EXPECT_TRUE(pc.HasPath());
112 EXPECT_EQ("/", pc.Path());
113 EXPECT_EQ("", pc.Name());
114 EXPECT_EQ("BLAHHH", pc.Value());
[email protected]ab2d75c82013-04-19 18:39:04115 EXPECT_EQ(COOKIE_PRIORITY_HIGH, pc.Priority());
mkwstae819bb2015-02-23 05:10:31116 EXPECT_EQ(5U, pc.NumberOfAttributes());
[email protected]ebfe3172012-07-12 12:21:41117}
118
119TEST(ParsedCookieTest, TestDoubleQuotedNameless) {
120 ParsedCookie pc("\"BLA\\\"HHH\"; path=/; secure;");
121 EXPECT_TRUE(pc.IsValid());
122 EXPECT_TRUE(pc.IsSecure());
123 EXPECT_TRUE(pc.HasPath());
124 EXPECT_EQ("/", pc.Path());
125 EXPECT_EQ("", pc.Name());
126 EXPECT_EQ("\"BLA\\\"HHH\"", pc.Value());
[email protected]ab2d75c82013-04-19 18:39:04127 EXPECT_EQ(COOKIE_PRIORITY_DEFAULT, pc.Priority());
[email protected]ebfe3172012-07-12 12:21:41128 EXPECT_EQ(2U, pc.NumberOfAttributes());
129}
130
131TEST(ParsedCookieTest, QuoteOffTheEnd) {
132 ParsedCookie pc("a=\"B");
133 EXPECT_TRUE(pc.IsValid());
134 EXPECT_EQ("a", pc.Name());
135 EXPECT_EQ("\"B", pc.Value());
[email protected]ab2d75c82013-04-19 18:39:04136 EXPECT_EQ(COOKIE_PRIORITY_DEFAULT, pc.Priority());
[email protected]ebfe3172012-07-12 12:21:41137 EXPECT_EQ(0U, pc.NumberOfAttributes());
138}
139
140TEST(ParsedCookieTest, MissingName) {
141 ParsedCookie pc("=ABC");
142 EXPECT_TRUE(pc.IsValid());
143 EXPECT_EQ("", pc.Name());
144 EXPECT_EQ("ABC", pc.Value());
[email protected]ab2d75c82013-04-19 18:39:04145 EXPECT_EQ(COOKIE_PRIORITY_DEFAULT, pc.Priority());
[email protected]ebfe3172012-07-12 12:21:41146 EXPECT_EQ(0U, pc.NumberOfAttributes());
147}
148
149TEST(ParsedCookieTest, MissingValue) {
150 ParsedCookie pc("ABC=; path = /wee");
151 EXPECT_TRUE(pc.IsValid());
152 EXPECT_EQ("ABC", pc.Name());
153 EXPECT_EQ("", pc.Value());
154 EXPECT_TRUE(pc.HasPath());
155 EXPECT_EQ("/wee", pc.Path());
[email protected]ab2d75c82013-04-19 18:39:04156 EXPECT_EQ(COOKIE_PRIORITY_DEFAULT, pc.Priority());
[email protected]ebfe3172012-07-12 12:21:41157 EXPECT_EQ(1U, pc.NumberOfAttributes());
158}
159
160TEST(ParsedCookieTest, Whitespace) {
mkwste1a29582016-03-15 10:07:52161 ParsedCookie pc(" A = BC ;secure;;; samesite = lax ");
[email protected]ebfe3172012-07-12 12:21:41162 EXPECT_TRUE(pc.IsValid());
163 EXPECT_EQ("A", pc.Name());
164 EXPECT_EQ("BC", pc.Value());
165 EXPECT_FALSE(pc.HasPath());
166 EXPECT_FALSE(pc.HasDomain());
167 EXPECT_TRUE(pc.IsSecure());
mkwstae819bb2015-02-23 05:10:31168 EXPECT_FALSE(pc.IsHttpOnly());
mkwste1a29582016-03-15 10:07:52169 EXPECT_EQ(CookieSameSite::LAX_MODE, pc.SameSite());
[email protected]ab2d75c82013-04-19 18:39:04170 EXPECT_EQ(COOKIE_PRIORITY_DEFAULT, pc.Priority());
[email protected]ebfe3172012-07-12 12:21:41171 // We parse anything between ; as attributes, so we end up with two
172 // attributes with an empty string name and value.
173 EXPECT_EQ(4U, pc.NumberOfAttributes());
174}
175TEST(ParsedCookieTest, MultipleEquals) {
176 ParsedCookie pc(" A=== BC ;secure;;; httponly");
177 EXPECT_TRUE(pc.IsValid());
178 EXPECT_EQ("A", pc.Name());
179 EXPECT_EQ("== BC", pc.Value());
180 EXPECT_FALSE(pc.HasPath());
181 EXPECT_FALSE(pc.HasDomain());
182 EXPECT_TRUE(pc.IsSecure());
183 EXPECT_TRUE(pc.IsHttpOnly());
Lily Chen324657c2019-04-19 14:09:44184 EXPECT_EQ(CookieSameSite::UNSPECIFIED, pc.SameSite());
[email protected]ab2d75c82013-04-19 18:39:04185 EXPECT_EQ(COOKIE_PRIORITY_DEFAULT, pc.Priority());
[email protected]ebfe3172012-07-12 12:21:41186 EXPECT_EQ(4U, pc.NumberOfAttributes());
187}
188
[email protected]ebfe3172012-07-12 12:21:41189TEST(ParsedCookieTest, QuotedTrailingWhitespace) {
mkwstbe84af312015-02-20 08:52:45190 ParsedCookie pc(
191 "ANCUUID=\"zohNumRKgI0oxyhSsV3Z7D\" ; "
192 "expires=Sun, 18-Apr-2027 21:06:29 GMT ; "
193 "path=/ ; ");
[email protected]ebfe3172012-07-12 12:21:41194 EXPECT_TRUE(pc.IsValid());
195 EXPECT_EQ("ANCUUID", pc.Name());
196 // Stripping whitespace after the quotes matches all other major browsers.
197 EXPECT_EQ("\"zohNumRKgI0oxyhSsV3Z7D\"", pc.Value());
198 EXPECT_TRUE(pc.HasExpires());
199 EXPECT_TRUE(pc.HasPath());
200 EXPECT_EQ("/", pc.Path());
[email protected]ab2d75c82013-04-19 18:39:04201 EXPECT_EQ(COOKIE_PRIORITY_DEFAULT, pc.Priority());
[email protected]ebfe3172012-07-12 12:21:41202 EXPECT_EQ(2U, pc.NumberOfAttributes());
203}
204
205TEST(ParsedCookieTest, TrailingWhitespace) {
mkwstbe84af312015-02-20 08:52:45206 ParsedCookie pc(
207 "ANCUUID=zohNumRKgI0oxyhSsV3Z7D ; "
208 "expires=Sun, 18-Apr-2027 21:06:29 GMT ; "
209 "path=/ ; ");
[email protected]ebfe3172012-07-12 12:21:41210 EXPECT_TRUE(pc.IsValid());
211 EXPECT_EQ("ANCUUID", pc.Name());
212 EXPECT_EQ("zohNumRKgI0oxyhSsV3Z7D", pc.Value());
213 EXPECT_TRUE(pc.HasExpires());
214 EXPECT_TRUE(pc.HasPath());
215 EXPECT_EQ("/", pc.Path());
[email protected]ab2d75c82013-04-19 18:39:04216 EXPECT_EQ(COOKIE_PRIORITY_DEFAULT, pc.Priority());
[email protected]ebfe3172012-07-12 12:21:41217 EXPECT_EQ(2U, pc.NumberOfAttributes());
218}
219
mkwstbadf4bf2017-05-15 10:49:13220TEST(ParsedCookieTest, LotsOfPairs) {
221 for (int i = 1; i < 100; i++) {
222 std::string blankpairs;
223 blankpairs.resize(i, ';');
[email protected]ebfe3172012-07-12 12:21:41224
mkwstbadf4bf2017-05-15 10:49:13225 ParsedCookie c("a=b;" + blankpairs + "secure");
226 EXPECT_EQ("a", c.Name());
227 EXPECT_EQ("b", c.Value());
228 EXPECT_TRUE(c.IsValid());
229 EXPECT_TRUE(c.IsSecure());
230 }
[email protected]ebfe3172012-07-12 12:21:41231}
232
233// TODO(erikwright): some better test cases for invalid cookies.
[email protected]ebfe3172012-07-12 12:21:41234TEST(ParsedCookieTest, InvalidTooLong) {
235 std::string maxstr;
236 maxstr.resize(ParsedCookie::kMaxCookieSize, 'a');
237
238 ParsedCookie pc1(maxstr);
239 EXPECT_TRUE(pc1.IsValid());
240
241 ParsedCookie pc2(maxstr + "A");
242 EXPECT_FALSE(pc2.IsValid());
243}
244
[email protected]ebfe3172012-07-12 12:21:41245TEST(ParsedCookieTest, EmbeddedTerminator) {
246 ParsedCookie pc1("AAA=BB\0ZYX");
247 ParsedCookie pc2("AAA=BB\rZYX");
248 ParsedCookie pc3("AAA=BB\nZYX");
249 EXPECT_TRUE(pc1.IsValid());
250 EXPECT_EQ("AAA", pc1.Name());
251 EXPECT_EQ("BB", pc1.Value());
252 EXPECT_TRUE(pc2.IsValid());
253 EXPECT_EQ("AAA", pc2.Name());
254 EXPECT_EQ("BB", pc2.Value());
255 EXPECT_TRUE(pc3.IsValid());
256 EXPECT_EQ("AAA", pc3.Name());
257 EXPECT_EQ("BB", pc3.Value());
258}
259
260TEST(ParsedCookieTest, ParseTokensAndValues) {
mkwstbe84af312015-02-20 08:52:45261 EXPECT_EQ("hello", ParsedCookie::ParseTokenString("hello\nworld"));
262 EXPECT_EQ("fs!!@", ParsedCookie::ParseTokenString("fs!!@;helloworld"));
[email protected]ebfe3172012-07-12 12:21:41263 EXPECT_EQ("hello world\tgood",
264 ParsedCookie::ParseTokenString("hello world\tgood\rbye"));
mkwstbe84af312015-02-20 08:52:45265 EXPECT_EQ("A", ParsedCookie::ParseTokenString("A=B=C;D=E"));
266 EXPECT_EQ("hello", ParsedCookie::ParseValueString("hello\nworld"));
267 EXPECT_EQ("fs!!@", ParsedCookie::ParseValueString("fs!!@;helloworld"));
[email protected]ebfe3172012-07-12 12:21:41268 EXPECT_EQ("hello world\tgood",
269 ParsedCookie::ParseValueString("hello world\tgood\rbye"));
mkwstbe84af312015-02-20 08:52:45270 EXPECT_EQ("A=B=C", ParsedCookie::ParseValueString("A=B=C;D=E"));
[email protected]ebfe3172012-07-12 12:21:41271}
272
[email protected]64527a52012-08-02 13:37:41273TEST(ParsedCookieTest, SerializeCookieLine) {
mkwstbe84af312015-02-20 08:52:45274 const char input[] =
275 "ANCUUID=zohNumRKgI0oxyhSsV3Z7D ; "
276 "expires=Sun, 18-Apr-2027 21:06:29 GMT ; "
277 "path=/ ; priority=low ; ";
278 const char output[] =
279 "ANCUUID=zohNumRKgI0oxyhSsV3Z7D; "
280 "expires=Sun, 18-Apr-2027 21:06:29 GMT; "
281 "path=/; priority=low";
[email protected]64527a52012-08-02 13:37:41282 ParsedCookie pc(input);
283 EXPECT_EQ(output, pc.ToCookieLine());
284}
285
[email protected]64527a52012-08-02 13:37:41286TEST(ParsedCookieTest, SetNameAndValue) {
[email protected]007b3f82013-04-09 08:46:45287 ParsedCookie empty((std::string()));
jww03e6ff8c2016-08-17 19:19:58288 EXPECT_TRUE(empty.IsValid());
289 EXPECT_TRUE(empty.SetDomain("foobar.com"));
[email protected]64527a52012-08-02 13:37:41290 EXPECT_TRUE(empty.SetName("name"));
291 EXPECT_TRUE(empty.SetValue("value"));
jww03e6ff8c2016-08-17 19:19:58292 EXPECT_EQ("name=value; domain=foobar.com", empty.ToCookieLine());
[email protected]64527a52012-08-02 13:37:41293 EXPECT_TRUE(empty.IsValid());
294
295 // We don't test
296 // ParsedCookie invalid("@foo=bar");
297 // EXPECT_FALSE(invalid.IsValid());
298 // here because we are slightly more tolerant to invalid cookie names and
299 // values that are set by webservers. We only enforce a correct name and
300 // value if set via SetName() and SetValue().
301
302 ParsedCookie pc("name=value");
303 EXPECT_TRUE(pc.IsValid());
304
305 // Set invalid name / value.
306 EXPECT_FALSE(pc.SetName("@foobar"));
307 EXPECT_EQ("name=value", pc.ToCookieLine());
308 EXPECT_TRUE(pc.IsValid());
309
[email protected]64527a52012-08-02 13:37:41310 EXPECT_FALSE(pc.SetValue("foo bar"));
311 EXPECT_EQ("name=value", pc.ToCookieLine());
312 EXPECT_TRUE(pc.IsValid());
313
314 EXPECT_FALSE(pc.SetValue("\"foobar"));
315 EXPECT_EQ("name=value", pc.ToCookieLine());
316 EXPECT_TRUE(pc.IsValid());
317
318 // Set valid name / value
jww03e6ff8c2016-08-17 19:19:58319 EXPECT_TRUE(pc.SetName(std::string()));
320 EXPECT_EQ("=value", pc.ToCookieLine());
321 EXPECT_TRUE(pc.IsValid());
322
[email protected]64527a52012-08-02 13:37:41323 EXPECT_TRUE(pc.SetName("test"));
324 EXPECT_EQ("test=value", pc.ToCookieLine());
325 EXPECT_TRUE(pc.IsValid());
326
327 EXPECT_TRUE(pc.SetValue("\"foobar\""));
328 EXPECT_EQ("test=\"foobar\"", pc.ToCookieLine());
329 EXPECT_TRUE(pc.IsValid());
330
[email protected]007b3f82013-04-09 08:46:45331 EXPECT_TRUE(pc.SetValue(std::string()));
[email protected]64527a52012-08-02 13:37:41332 EXPECT_EQ("test=", pc.ToCookieLine());
333 EXPECT_TRUE(pc.IsValid());
334}
335
336TEST(ParsedCookieTest, SetAttributes) {
337 ParsedCookie pc("name=value");
338 EXPECT_TRUE(pc.IsValid());
339
340 // Clear an unset attribute.
[email protected]007b3f82013-04-09 08:46:45341 EXPECT_TRUE(pc.SetDomain(std::string()));
[email protected]64527a52012-08-02 13:37:41342 EXPECT_FALSE(pc.HasDomain());
343 EXPECT_EQ("name=value", pc.ToCookieLine());
344 EXPECT_TRUE(pc.IsValid());
345
346 // Set a string containing an invalid character
347 EXPECT_FALSE(pc.SetDomain("foo;bar"));
348 EXPECT_FALSE(pc.HasDomain());
349 EXPECT_EQ("name=value", pc.ToCookieLine());
350 EXPECT_TRUE(pc.IsValid());
351
352 // Set all other attributes and check that they are appended in order.
353 EXPECT_TRUE(pc.SetDomain("domain.com"));
354 EXPECT_TRUE(pc.SetPath("/"));
[email protected]64527a52012-08-02 13:37:41355 EXPECT_TRUE(pc.SetExpires("Sun, 18-Apr-2027 21:06:29 GMT"));
356 EXPECT_TRUE(pc.SetMaxAge("12345"));
357 EXPECT_TRUE(pc.SetIsSecure(true));
358 EXPECT_TRUE(pc.SetIsHttpOnly(true));
[email protected]ab2d75c82013-04-19 18:39:04359 EXPECT_TRUE(pc.SetIsHttpOnly(true));
mkwste1a29582016-03-15 10:07:52360 EXPECT_TRUE(pc.SetSameSite("LAX"));
[email protected]ab2d75c82013-04-19 18:39:04361 EXPECT_TRUE(pc.SetPriority("HIGH"));
mkwstbe84af312015-02-20 08:52:45362 EXPECT_EQ(
363 "name=value; domain=domain.com; path=/; "
364 "expires=Sun, 18-Apr-2027 21:06:29 GMT; max-age=12345; secure; "
mkwste1a29582016-03-15 10:07:52365 "httponly; samesite=LAX; priority=HIGH",
mkwstbe84af312015-02-20 08:52:45366 pc.ToCookieLine());
[email protected]64527a52012-08-02 13:37:41367 EXPECT_TRUE(pc.HasDomain());
368 EXPECT_TRUE(pc.HasPath());
[email protected]64527a52012-08-02 13:37:41369 EXPECT_TRUE(pc.HasExpires());
370 EXPECT_TRUE(pc.HasMaxAge());
371 EXPECT_TRUE(pc.IsSecure());
372 EXPECT_TRUE(pc.IsHttpOnly());
mkwste1a29582016-03-15 10:07:52373 EXPECT_EQ(CookieSameSite::LAX_MODE, pc.SameSite());
[email protected]ab2d75c82013-04-19 18:39:04374 EXPECT_EQ(COOKIE_PRIORITY_HIGH, pc.Priority());
[email protected]64527a52012-08-02 13:37:41375
376 // Clear one attribute from the middle.
[email protected]dedec0b2013-02-28 04:50:10377 EXPECT_TRUE(pc.SetPath("/foo"));
[email protected]64527a52012-08-02 13:37:41378 EXPECT_TRUE(pc.HasDomain());
379 EXPECT_TRUE(pc.HasPath());
[email protected]64527a52012-08-02 13:37:41380 EXPECT_TRUE(pc.HasExpires());
[email protected]64527a52012-08-02 13:37:41381 EXPECT_TRUE(pc.IsSecure());
382 EXPECT_TRUE(pc.IsHttpOnly());
mkwstbe84af312015-02-20 08:52:45383 EXPECT_EQ(
384 "name=value; domain=domain.com; path=/foo; "
385 "expires=Sun, 18-Apr-2027 21:06:29 GMT; max-age=12345; secure; "
mkwste1a29582016-03-15 10:07:52386 "httponly; samesite=LAX; priority=HIGH",
mkwstbe84af312015-02-20 08:52:45387 pc.ToCookieLine());
[email protected]ab2d75c82013-04-19 18:39:04388
389 // Set priority to medium.
390 EXPECT_TRUE(pc.SetPriority("medium"));
mkwstbe84af312015-02-20 08:52:45391 EXPECT_EQ(
392 "name=value; domain=domain.com; path=/foo; "
393 "expires=Sun, 18-Apr-2027 21:06:29 GMT; max-age=12345; secure; "
mkwste1a29582016-03-15 10:07:52394 "httponly; samesite=LAX; priority=medium",
mkwstbe84af312015-02-20 08:52:45395 pc.ToCookieLine());
[email protected]64527a52012-08-02 13:37:41396
397 // Clear the rest and change the name and value.
[email protected]007b3f82013-04-09 08:46:45398 EXPECT_TRUE(pc.SetDomain(std::string()));
399 EXPECT_TRUE(pc.SetPath(std::string()));
400 EXPECT_TRUE(pc.SetExpires(std::string()));
401 EXPECT_TRUE(pc.SetMaxAge(std::string()));
[email protected]64527a52012-08-02 13:37:41402 EXPECT_TRUE(pc.SetIsSecure(false));
403 EXPECT_TRUE(pc.SetIsHttpOnly(false));
mkwste1a29582016-03-15 10:07:52404 EXPECT_TRUE(pc.SetSameSite(std::string()));
[email protected]64527a52012-08-02 13:37:41405 EXPECT_TRUE(pc.SetName("name2"));
406 EXPECT_TRUE(pc.SetValue("value2"));
[email protected]ab2d75c82013-04-19 18:39:04407 EXPECT_TRUE(pc.SetPriority(std::string()));
[email protected]64527a52012-08-02 13:37:41408 EXPECT_FALSE(pc.HasDomain());
409 EXPECT_FALSE(pc.HasPath());
[email protected]64527a52012-08-02 13:37:41410 EXPECT_FALSE(pc.HasExpires());
411 EXPECT_FALSE(pc.HasMaxAge());
412 EXPECT_FALSE(pc.IsSecure());
413 EXPECT_FALSE(pc.IsHttpOnly());
Lily Chen324657c2019-04-19 14:09:44414 EXPECT_EQ(CookieSameSite::UNSPECIFIED, pc.SameSite());
[email protected]64527a52012-08-02 13:37:41415 EXPECT_EQ("name2=value2", pc.ToCookieLine());
416}
417
jww03e6ff8c2016-08-17 19:19:58418// Set the domain attribute twice in a cookie line. If the second attribute's
419// value is empty, it shoud be ignored.
420//
421// This is de facto standard behavior, per https://crbug.com/601786.
422TEST(ParsedCookieTest, MultipleDomainAttributes) {
423 ParsedCookie pc1("name=value; domain=foo.com; domain=bar.com");
424 EXPECT_EQ("bar.com", pc1.Domain());
425 ParsedCookie pc2("name=value; domain=foo.com; domain=");
426 EXPECT_EQ("foo.com", pc2.Domain());
427}
428
[email protected]ab2d75c82013-04-19 18:39:04429TEST(ParsedCookieTest, SetPriority) {
430 ParsedCookie pc("name=value");
431 EXPECT_TRUE(pc.IsValid());
432
433 EXPECT_EQ("name=value", pc.ToCookieLine());
434 EXPECT_EQ(COOKIE_PRIORITY_DEFAULT, pc.Priority());
435
436 // Test each priority, expect case-insensitive compare.
437 EXPECT_TRUE(pc.SetPriority("high"));
438 EXPECT_EQ("name=value; priority=high", pc.ToCookieLine());
439 EXPECT_EQ(COOKIE_PRIORITY_HIGH, pc.Priority());
440
441 EXPECT_TRUE(pc.SetPriority("mEDium"));
442 EXPECT_EQ("name=value; priority=mEDium", pc.ToCookieLine());
443 EXPECT_EQ(COOKIE_PRIORITY_MEDIUM, pc.Priority());
444
445 EXPECT_TRUE(pc.SetPriority("LOW"));
446 EXPECT_EQ("name=value; priority=LOW", pc.ToCookieLine());
447 EXPECT_EQ(COOKIE_PRIORITY_LOW, pc.Priority());
448
449 // Interpret invalid priority values as COOKIE_PRIORITY_DEFAULT.
450 EXPECT_TRUE(pc.SetPriority("Blah"));
451 EXPECT_EQ("name=value; priority=Blah", pc.ToCookieLine());
452 EXPECT_EQ(COOKIE_PRIORITY_DEFAULT, pc.Priority());
453
454 EXPECT_TRUE(pc.SetPriority("lowerest"));
455 EXPECT_EQ("name=value; priority=lowerest", pc.ToCookieLine());
456 EXPECT_EQ(COOKIE_PRIORITY_DEFAULT, pc.Priority());
457
458 EXPECT_TRUE(pc.SetPriority(""));
459 EXPECT_EQ("name=value", pc.ToCookieLine());
460 EXPECT_EQ(COOKIE_PRIORITY_DEFAULT, pc.Priority());
461}
462
mkwste1a29582016-03-15 10:07:52463TEST(ParsedCookieTest, SetSameSite) {
464 ParsedCookie pc("name=value");
465 EXPECT_TRUE(pc.IsValid());
466
467 EXPECT_EQ("name=value", pc.ToCookieLine());
Lily Chen324657c2019-04-19 14:09:44468 EXPECT_EQ(CookieSameSite::UNSPECIFIED, pc.SameSite());
mkwste1a29582016-03-15 10:07:52469
Eric Lawrence5fbb75e92018-04-12 20:39:53470 // Test each samesite directive, expect case-insensitive compare.
mkwste1a29582016-03-15 10:07:52471 EXPECT_TRUE(pc.SetSameSite("strict"));
472 EXPECT_EQ("name=value; samesite=strict", pc.ToCookieLine());
473 EXPECT_EQ(CookieSameSite::STRICT_MODE, pc.SameSite());
mkwst1a9ce0d2016-04-06 19:44:21474 EXPECT_TRUE(pc.IsValid());
mkwste1a29582016-03-15 10:07:52475
476 EXPECT_TRUE(pc.SetSameSite("lAx"));
477 EXPECT_EQ("name=value; samesite=lAx", pc.ToCookieLine());
478 EXPECT_EQ(CookieSameSite::LAX_MODE, pc.SameSite());
mkwst1a9ce0d2016-04-06 19:44:21479 EXPECT_TRUE(pc.IsValid());
mkwste1a29582016-03-15 10:07:52480
481 EXPECT_TRUE(pc.SetSameSite("LAX"));
482 EXPECT_EQ("name=value; samesite=LAX", pc.ToCookieLine());
483 EXPECT_EQ(CookieSameSite::LAX_MODE, pc.SameSite());
mkwst1a9ce0d2016-04-06 19:44:21484 EXPECT_TRUE(pc.IsValid());
mkwste1a29582016-03-15 10:07:52485
Lily Chen324657c2019-04-19 14:09:44486 EXPECT_TRUE(pc.SetSameSite("None"));
487 EXPECT_EQ("name=value; samesite=None", pc.ToCookieLine());
488 EXPECT_EQ(CookieSameSite::NO_RESTRICTION, pc.SameSite());
489 EXPECT_TRUE(pc.IsValid());
490
491 EXPECT_TRUE(pc.SetSameSite("NONE"));
492 EXPECT_EQ("name=value; samesite=NONE", pc.ToCookieLine());
493 EXPECT_EQ(CookieSameSite::NO_RESTRICTION, pc.SameSite());
494 EXPECT_TRUE(pc.IsValid());
495
Eric Lawrence5fbb75e92018-04-12 20:39:53496 // Remove the SameSite attribute.
mkwste1a29582016-03-15 10:07:52497 EXPECT_TRUE(pc.SetSameSite(""));
498 EXPECT_EQ("name=value", pc.ToCookieLine());
Lily Chen324657c2019-04-19 14:09:44499 EXPECT_EQ(CookieSameSite::UNSPECIFIED, pc.SameSite());
mkwst1a9ce0d2016-04-06 19:44:21500 EXPECT_TRUE(pc.IsValid());
501
502 EXPECT_TRUE(pc.SetSameSite("Blah"));
Eric Lawrence5fbb75e92018-04-12 20:39:53503 EXPECT_EQ("name=value; samesite=Blah", pc.ToCookieLine());
Lily Chen324657c2019-04-19 14:09:44504 EXPECT_EQ(CookieSameSite::UNSPECIFIED, pc.SameSite());
Eric Lawrence5fbb75e92018-04-12 20:39:53505 EXPECT_TRUE(pc.IsValid());
mkwst1a9ce0d2016-04-06 19:44:21506}
507
Lily Chen9a9c08a92019-09-18 00:18:16508// Test that the correct enum value is returned for the SameSite attribute
509// string.
510TEST(ParsedCookieTest, CookieSameSiteStringEnum) {
511 ParsedCookie pc("name=value; SameSite");
512 CookieSameSiteString actual = CookieSameSiteString::kLax;
513 EXPECT_EQ(CookieSameSite::UNSPECIFIED, pc.SameSite(&actual));
514 EXPECT_EQ(CookieSameSiteString::kEmptyString, actual);
515
516 pc.SetSameSite("Strict");
517 EXPECT_EQ(CookieSameSite::STRICT_MODE, pc.SameSite(&actual));
518 EXPECT_EQ(CookieSameSiteString::kStrict, actual);
519
520 pc.SetSameSite("Lax");
521 EXPECT_EQ(CookieSameSite::LAX_MODE, pc.SameSite(&actual));
522 EXPECT_EQ(CookieSameSiteString::kLax, actual);
523
524 pc.SetSameSite("None");
525 EXPECT_EQ(CookieSameSite::NO_RESTRICTION, pc.SameSite(&actual));
526 EXPECT_EQ(CookieSameSiteString::kNone, actual);
527
528 pc.SetSameSite("Extended");
Caleb Raittof1af4b32019-10-28 20:02:31529 EXPECT_EQ(CookieSameSite::UNSPECIFIED, pc.SameSite(&actual));
Lily Chen9a9c08a92019-09-18 00:18:16530 EXPECT_EQ(CookieSameSiteString::kExtended, actual);
531
532 pc.SetSameSite("Bananas");
533 EXPECT_EQ(CookieSameSite::UNSPECIFIED, pc.SameSite(&actual));
534 EXPECT_EQ(CookieSameSiteString::kUnrecognized, actual);
535
536 ParsedCookie pc2("no_samesite=1");
537 EXPECT_EQ(CookieSameSite::UNSPECIFIED, pc2.SameSite(&actual));
538 EXPECT_EQ(CookieSameSiteString::kUnspecified, actual);
539}
540
Daniel McArdle7c8bd14d2019-06-18 22:57:33541TEST(ParsedCookieTest, SettersInputValidation) {
542 ParsedCookie pc("name=foobar");
543 EXPECT_TRUE(pc.SetPath("baz"));
544 EXPECT_EQ(pc.ToCookieLine(), "name=foobar; path=baz");
545
546 EXPECT_TRUE(pc.SetPath(" baz "));
547 EXPECT_EQ(pc.ToCookieLine(), "name=foobar; path=baz");
548
549 EXPECT_TRUE(pc.SetPath(" "));
550 EXPECT_EQ(pc.ToCookieLine(), "name=foobar");
551
552 EXPECT_TRUE(pc.SetDomain(" baz "));
553 EXPECT_EQ(pc.ToCookieLine(), "name=foobar; domain=baz");
554
555 // Invalid characters
556 EXPECT_FALSE(pc.SetPath(" baz\n "));
557 EXPECT_FALSE(pc.SetPath("f;oo"));
558 EXPECT_FALSE(pc.SetPath("\r"));
559 EXPECT_FALSE(pc.SetPath("\a"));
560 EXPECT_FALSE(pc.SetPath("\t"));
561 EXPECT_FALSE(pc.SetSameSite("\r"));
562}
563
Daniel McArdleef614252019-06-24 21:56:38564TEST(ParsedCookieTest, ToCookieLineSpecialTokens) {
565 // Special tokens "secure" and "httponly" should be treated as any other name
566 // when they are in the first position.
567 {
568 ParsedCookie pc("");
569 pc.SetName("secure");
570 EXPECT_EQ(pc.ToCookieLine(), "secure=");
571 }
572 {
573 ParsedCookie pc("secure");
574 EXPECT_EQ(pc.ToCookieLine(), "=secure");
575 }
576 {
577 ParsedCookie pc("secure=foo");
578 EXPECT_EQ(pc.ToCookieLine(), "secure=foo");
579 }
580 {
581 ParsedCookie pc("foo=secure");
582 EXPECT_EQ(pc.ToCookieLine(), "foo=secure");
583 }
584 {
585 ParsedCookie pc("httponly=foo");
586 EXPECT_EQ(pc.ToCookieLine(), "httponly=foo");
587 }
588 {
589 ParsedCookie pc("foo");
590 pc.SetName("secure");
591 EXPECT_EQ(pc.ToCookieLine(), "secure=foo");
592 }
593 {
594 ParsedCookie pc("bar");
595 pc.SetName("httponly");
596 EXPECT_EQ(pc.ToCookieLine(), "httponly=bar");
597 }
598 {
599 ParsedCookie pc("foo=bar; baz=bob");
600 EXPECT_EQ(pc.ToCookieLine(), "foo=bar; baz=bob");
601 }
602 // Outside of the first position, the value associated with a special name
603 // should not be printed.
604 {
605 ParsedCookie pc("name=foo; secure");
606 EXPECT_EQ(pc.ToCookieLine(), "name=foo; secure");
607 }
608 {
609 ParsedCookie pc("name=foo; secure=bar");
610 EXPECT_EQ(pc.ToCookieLine(), "name=foo; secure");
611 }
612 {
613 ParsedCookie pc("name=foo; httponly=baz");
614 EXPECT_EQ(pc.ToCookieLine(), "name=foo; httponly");
615 }
616 {
617 ParsedCookie pc("name=foo; bar=secure");
618 EXPECT_EQ(pc.ToCookieLine(), "name=foo; bar=secure");
619 }
620}
621
Eric Lawrence5fbb75e92018-04-12 20:39:53622TEST(ParsedCookieTest, SameSiteValues) {
mkwst1a9ce0d2016-04-06 19:44:21623 struct TestCase {
624 const char* cookie;
625 bool valid;
626 CookieSameSite mode;
627 } cases[]{{"n=v; samesite=strict", true, CookieSameSite::STRICT_MODE},
628 {"n=v; samesite=lax", true, CookieSameSite::LAX_MODE},
Lily Chen324657c2019-04-19 14:09:44629 {"n=v; samesite=none", true, CookieSameSite::NO_RESTRICTION},
630 {"n=v; samesite=boo", true, CookieSameSite::UNSPECIFIED},
631 {"n=v; samesite", true, CookieSameSite::UNSPECIFIED},
632 {"n=v", true, CookieSameSite::UNSPECIFIED}};
mkwst1a9ce0d2016-04-06 19:44:21633
634 for (const auto& test : cases) {
635 SCOPED_TRACE(test.cookie);
636 ParsedCookie pc(test.cookie);
637 EXPECT_EQ(test.valid, pc.IsValid());
638 EXPECT_EQ(test.mode, pc.SameSite());
639 }
mkwste1a29582016-03-15 10:07:52640}
641
[email protected]6210ce52013-09-20 03:33:14642TEST(ParsedCookieTest, InvalidNonAlphanumericChars) {
643 ParsedCookie pc1("name=\x05");
mkwstbe84af312015-02-20 08:52:45644 ParsedCookie pc2(
645 "name=foo"
646 "\x1c"
647 "bar");
648 ParsedCookie pc3(
649 "name=foobar"
650 "\x11");
651 ParsedCookie pc4(
652 "name=\x02"
653 "foobar");
[email protected]6210ce52013-09-20 03:33:14654
655 ParsedCookie pc5("\x05=value");
mkwstbe84af312015-02-20 08:52:45656 ParsedCookie pc6(
657 "foo"
658 "\x05"
659 "bar=value");
660 ParsedCookie pc7(
661 "foobar"
662 "\x05"
663 "=value");
664 ParsedCookie pc8(
665 "\x05"
666 "foobar"
667 "=value");
[email protected]6210ce52013-09-20 03:33:14668
mkwstbe84af312015-02-20 08:52:45669 ParsedCookie pc9(
670 "foo"
671 "\x05"
672 "bar"
673 "=foo"
674 "\x05"
675 "bar");
[email protected]6210ce52013-09-20 03:33:14676
mkwstbe84af312015-02-20 08:52:45677 ParsedCookie pc10(
678 "foo=bar;ba"
679 "\x05"
680 "z=boo");
681 ParsedCookie pc11(
682 "foo=bar;baz=bo"
683 "\x05"
684 "o");
685 ParsedCookie pc12(
686 "foo=bar;ba"
687 "\05"
688 "z=bo"
689 "\x05"
690 "o");
[email protected]6210ce52013-09-20 03:33:14691
692 EXPECT_FALSE(pc1.IsValid());
693 EXPECT_FALSE(pc2.IsValid());
694 EXPECT_FALSE(pc3.IsValid());
695 EXPECT_FALSE(pc4.IsValid());
696 EXPECT_FALSE(pc5.IsValid());
697 EXPECT_FALSE(pc6.IsValid());
698 EXPECT_FALSE(pc7.IsValid());
699 EXPECT_FALSE(pc8.IsValid());
700 EXPECT_FALSE(pc9.IsValid());
701 EXPECT_FALSE(pc10.IsValid());
702 EXPECT_FALSE(pc11.IsValid());
703 EXPECT_FALSE(pc12.IsValid());
704}
705
706TEST(ParsedCookieTest, ValidNonAlphanumericChars) {
707 // Note that some of these words are pasted backwords thanks to poor vim bidi
708 // support. This should not affect the tests, however.
thestig9d3bb0c2015-01-24 00:49:51709 const char pc1_literal[] = "name=العربية";
710 const char pc2_literal[] = "name=普通話";
711 const char pc3_literal[] = "name=ภาษาไทย";
712 const char pc4_literal[] = "name=עִבְרִית";
713 const char pc5_literal[] = "العربية=value";
714 const char pc6_literal[] = "普通話=value";
715 const char pc7_literal[] = "ภาษาไทย=value";
716 const char pc8_literal[] = "עִבְרִית=value";
[email protected]6210ce52013-09-20 03:33:14717 ParsedCookie pc1(pc1_literal);
718 ParsedCookie pc2(pc2_literal);
719 ParsedCookie pc3(pc3_literal);
720 ParsedCookie pc4(pc4_literal);
721 ParsedCookie pc5(pc5_literal);
722 ParsedCookie pc6(pc6_literal);
723 ParsedCookie pc7(pc7_literal);
724 ParsedCookie pc8(pc8_literal);
725
726 EXPECT_TRUE(pc1.IsValid());
727 EXPECT_EQ(pc1_literal, pc1.ToCookieLine());
728 EXPECT_TRUE(pc2.IsValid());
729 EXPECT_EQ(pc2_literal, pc2.ToCookieLine());
730 EXPECT_TRUE(pc3.IsValid());
731 EXPECT_EQ(pc3_literal, pc3.ToCookieLine());
732 EXPECT_TRUE(pc4.IsValid());
733 EXPECT_EQ(pc4_literal, pc4.ToCookieLine());
734 EXPECT_TRUE(pc5.IsValid());
735 EXPECT_EQ(pc5_literal, pc5.ToCookieLine());
736 EXPECT_TRUE(pc6.IsValid());
737 EXPECT_EQ(pc6_literal, pc6.ToCookieLine());
738 EXPECT_TRUE(pc7.IsValid());
739 EXPECT_EQ(pc7_literal, pc7.ToCookieLine());
740 EXPECT_TRUE(pc8.IsValid());
741 EXPECT_EQ(pc8_literal, pc8.ToCookieLine());
742}
bncd479b3c2017-05-24 18:54:53743
744} // namespace net