summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/cookies/attributes
diff options
context:
space:
mode:
Diffstat (limited to 'testing/web-platform/tests/cookies/attributes')
-rw-r--r--testing/web-platform/tests/cookies/attributes/attributes-ctl.sub.html99
-rw-r--r--testing/web-platform/tests/cookies/attributes/domain.sub.html24
-rw-r--r--testing/web-platform/tests/cookies/attributes/expires.html56
-rw-r--r--testing/web-platform/tests/cookies/attributes/invalid.html171
-rw-r--r--testing/web-platform/tests/cookies/attributes/max-age.html78
-rw-r--r--testing/web-platform/tests/cookies/attributes/path-redirect.html128
-rw-r--r--testing/web-platform/tests/cookies/attributes/path.html144
-rw-r--r--testing/web-platform/tests/cookies/attributes/resources/domain-child.sub.html401
-rw-r--r--testing/web-platform/tests/cookies/attributes/resources/path-redirect-shared.js11
-rw-r--r--testing/web-platform/tests/cookies/attributes/resources/path.html14
-rw-r--r--testing/web-platform/tests/cookies/attributes/resources/path.html.headers1
-rw-r--r--testing/web-platform/tests/cookies/attributes/resources/path/one.html14
-rw-r--r--testing/web-platform/tests/cookies/attributes/resources/path/three.html14
-rw-r--r--testing/web-platform/tests/cookies/attributes/resources/path/two.html14
-rw-r--r--testing/web-platform/tests/cookies/attributes/resources/pathfakeout.html14
-rw-r--r--testing/web-platform/tests/cookies/attributes/resources/pathfakeout/one.html14
-rw-r--r--testing/web-platform/tests/cookies/attributes/resources/secure-non-secure-child.html85
-rw-r--r--testing/web-platform/tests/cookies/attributes/secure-non-secure.html23
-rw-r--r--testing/web-platform/tests/cookies/attributes/secure.https.html65
19 files changed, 1370 insertions, 0 deletions
diff --git a/testing/web-platform/tests/cookies/attributes/attributes-ctl.sub.html b/testing/web-platform/tests/cookies/attributes/attributes-ctl.sub.html
new file mode 100644
index 0000000000..e741dfd9c2
--- /dev/null
+++ b/testing/web-platform/tests/cookies/attributes/attributes-ctl.sub.html
@@ -0,0 +1,99 @@
+<!doctype html>
+<html>
+ <head>
+ <meta charset=utf-8>
+ <title>Test cookie attribute parsing with control characters</title>
+ <meta name=help href="https://tools.ietf.org/html/rfc6265#section-5.2">
+ <meta name="timeout" content="long">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/resources/testdriver.js"></script>
+ <script src="/resources/testdriver-vendor.js"></script>
+ <script src="/cookies/resources/cookie-test.js"></script>
+ </head>
+ <body>
+ <div id=log></div>
+ <script>
+ const host = "{{host}}";
+ const path = "/cookies/attributes";
+
+ // Tests for control characters (CTLs) in a cookie's attribute values.
+ // CTLs are defined by RFC 5234 to be %x00-1F / %x7F.
+ const CTLS = getCtlCharacters();
+
+ // All CTLs, with the exception of %x09 (the tab character), should
+ // cause the cookie to be rejected.
+ // In these tests we rely on subsequent attributes with the same name
+ // overriding the earlier one. In the cases where the control character
+ // should cause the entire cookie line to be rejected, if the control
+ // character were not present the cookie line should be one that
+ // would not be rejected. That way, if the attribute value is ignored
+ // instead of the cookie line being rejected, the test will catch it.
+ for (const ctl of CTLS) {
+ const controlCharacterAttributeTests = [
+ {
+ cookie: `test${ctl.code}domain=t; Domain=test${ctl.chr}.co; Domain=${host};`,
+ name: `Cookie with %x${ctl.code.toString(16)} in Domain attribute value is handled correctly.`,
+ },
+ {
+ cookie: `test${ctl.code}domain2=t; Domain=${host}${ctl.chr};`,
+ name: `Cookie with %x${ctl.code.toString(16)} after Domain attribute value is handled correctly.`,
+ },
+ {
+ cookie: `test${ctl.code}path=t; Path=/te${ctl.chr}st; Path=${path}`,
+ name: `Cookie with %x${ctl.code.toString(16)} in Path attribute value is handled correctly.`,
+ },
+ {
+ cookie: `test${ctl.code}path2=t; Path=${path}${ctl.chr};`,
+ name: `Cookie with %x${ctl.code.toString(16)} after Path attribute value is handled correctly.`,
+ },
+ {
+ cookie: `test${ctl.code}maxage=t; Max-Age=10${ctl.chr}00; Max-Age=1000;`,
+ name: `Cookie with %x${ctl.code.toString(16)} in Max-Age attribute value is handled correctly.`,
+ },
+ {
+ cookie: `test${ctl.code}maxage2=t; Max-Age=1000${ctl.chr};`,
+ name: `Cookie with %x${ctl.code.toString(16)} after Max-Age attribute value is handled correctly.`,
+ },
+ {
+ cookie: `test${ctl.code}expires=t; Expires=Fri, 01 Jan 20${ctl.chr}38 00:00:00 GMT; ` +
+ 'Expires=Fri, 01 Jan 2038 00:00:00 GMT;',
+ name: `Cookie with %x${ctl.code.toString(16)} in Expires attribute value is handled correctly.`,
+ },
+ {
+ cookie: `test${ctl.code}expires2=t; Expires=Fri, 01 Jan 2038 00:00:00 GMT${ctl.chr};`,
+ name: `Cookie with %x${ctl.code.toString(16)} after Expires attribute value is handled correctly.`,
+ },
+ {
+ cookie: `test${ctl.code}secure=t; Sec${ctl.chr}ure;`,
+ name: `Cookie with %x${ctl.code.toString(16)} in Secure attribute is handled correctly.`,
+ },
+ {
+ cookie: `test${ctl.code}secure2=t; Secure${ctl.chr};`,
+ name: `Cookie with %x${ctl.code.toString(16)} after Secure attribute is handled correctly.`,
+ },
+ {
+ cookie: `test${ctl.code}httponly=t; Http${ctl.chr}Only;`,
+ name: `Cookie with %x${ctl.code.toString(16)} in HttpOnly attribute is handled correctly.`,
+ },
+ {
+ cookie: `test${ctl.code}samesite=t; SameSite=La${ctl.chr}x; SameSite=Lax;`,
+ name: `Cookie with %x${ctl.code.toString(16)} in SameSite attribute value is handled correctly.`,
+ },
+ {
+ cookie: `test${ctl.code}samesite2=t; SameSite=Lax${ctl.chr};`,
+ name: `Cookie with %x${ctl.code.toString(16)} after SameSite attribute value is handled correctly.`,
+ },
+ ];
+
+ for (const test of controlCharacterAttributeTests) {
+ if (ctl.code === 0x09) {
+ domCookieTest(test.cookie, test.cookie.split(";")[0], test.name);
+ } else {
+ domCookieTest(test.cookie, "", test.name);
+ }
+ }
+ }
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/cookies/attributes/domain.sub.html b/testing/web-platform/tests/cookies/attributes/domain.sub.html
new file mode 100644
index 0000000000..17bc3267c2
--- /dev/null
+++ b/testing/web-platform/tests/cookies/attributes/domain.sub.html
@@ -0,0 +1,24 @@
+<!doctype html>
+<html>
+ <head>
+ <meta charset=utf-8>
+ <title>Test cookie domain attribute parsing</title>
+ <meta name=help href="https://tools.ietf.org/html/rfc6265#section-5.2.3">
+ <meta name="timeout" content="long">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/resources/testdriver.js"></script>
+ <script src="/resources/testdriver-vendor.js"></script>
+ </head>
+ <body>
+ <script>
+ const port = "{{ports[http][0]}}";
+ const wwwHost = "{{domains[www]}}";
+
+ test(t => {
+ const win = window.open(`http://${wwwHost}:${port}/cookies/attributes/resources/domain-child.sub.html`);
+ fetch_tests_from_window(win);
+ });
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/cookies/attributes/expires.html b/testing/web-platform/tests/cookies/attributes/expires.html
new file mode 100644
index 0000000000..a6bacfd74e
--- /dev/null
+++ b/testing/web-platform/tests/cookies/attributes/expires.html
@@ -0,0 +1,56 @@
+<!doctype html>
+<html>
+ <head>
+ <meta charset=utf-8>
+ <title>Test expires attribute parsing</title>
+ <meta name=help href="https://tools.ietf.org/html/rfc6265#section-5.1.1">
+ <meta name="timeout" content="long">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/resources/testdriver.js"></script>
+ <script src="/resources/testdriver-vendor.js"></script>
+ <script src="/cookies/resources/cookie-test.js"></script>
+ </head>
+ <body>
+ <div id=log></div>
+ <script>
+ const expiresTests = [
+ {
+ cookie: "test=1; Expires=Fri, 01 Jan 2038 00:00:00 GMT",
+ expected: "test=1",
+ name: "Set cookie with expires value containing a comma",
+ },
+ {
+ cookie: "test=2; Expires=Fri 01 Jan 2038 00:00:00 GMT, baz=qux",
+ expected: "test=2",
+ name: "Set cookie with expires value followed by comma",
+ },
+ {
+ cookie: "test=3; Expires=Fri, 01 Jan 2038 00:00:00 GMT",
+ expected: "test=3",
+ name: "Set cookie with future expiration",
+ },
+ {
+ cookie: ["test=expired; Expires=Fri, 07 Aug 2007 08:04:19 GMT", "test=4; Expires=Fri, 07 Aug 2027 08:04:19 GMT"],
+ expected: "test=4",
+ name: "Set expired cookie along with valid cookie",
+ },
+ {
+ cookie: "test=5; expires=Thu, 10 Apr 1980 16:33:12 GMT",
+ expected: "",
+ name: "Don't set cookie with expires set to the past",
+ },
+ ];
+
+ // These tests evaluate setting cookies with expiration via HTTP headers.
+ for (const test of expiresTests) {
+ httpCookieTest(test.cookie, test.expected, test.name + " via HTTP headers");
+ }
+
+ // These tests evaluate setting cookies with expiration via document.cookie.
+ for (const test of expiresTests) {
+ domCookieTest(test.cookie, test.expected, test.name + " via document.cookie");
+ }
+ </script>
+ </body>
+</html> \ No newline at end of file
diff --git a/testing/web-platform/tests/cookies/attributes/invalid.html b/testing/web-platform/tests/cookies/attributes/invalid.html
new file mode 100644
index 0000000000..6d4a53916d
--- /dev/null
+++ b/testing/web-platform/tests/cookies/attributes/invalid.html
@@ -0,0 +1,171 @@
+<!doctype html>
+<html>
+ <head>
+ <meta charset=utf-8>
+ <title>Test invalid attribute parsing</title>
+ <meta name=help href="https://tools.ietf.org/html/rfc6265#section-5.2">
+ <meta name="timeout" content="long">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/resources/testdriver.js"></script>
+ <script src="/resources/testdriver-vendor.js"></script>
+ <script src="/cookies/resources/cookie-test.js"></script>
+ </head>
+ <body>
+ <div id=log></div>
+ <script>
+ // These tests ensure that invalid attributes don't affect
+ // cookie parsing. `Path` isn't important to the tests where it appears,
+ // but it's used to be able to place the invalid attribute in different
+ // locations.
+ const invalidAttributeTests = [
+ {
+ cookie: "test=1; lol; Path=/",
+ expected: "test=1",
+ name: "Set cookie with invalid attribute",
+ defaultPath: false
+ },
+ {
+ cookie: "test=2; Path=/; lol",
+ expected: "test=2",
+ name: "Set cookie ending with invalid attribute.",
+ defaultPath: false
+ },
+ {
+ cookie: "test=3; Path=/; 'lol'",
+ expected: "test=3",
+ name: "Set cookie ending with quoted invalid attribute.",
+ defaultPath: false
+ },
+ {
+ cookie: 'test=4; Path=/; "lol"',
+ expected: "test=4",
+ name: "Set cookie ending with double-quoted invalid attribute.",
+ defaultPath: false
+ },
+ {
+ cookie: "test=5; Path=/; lol=",
+ expected: "test=5",
+ name: "Set cookie ending with invalid attribute equals.",
+ defaultPath: false
+ },
+ {
+ cookie: 'test=6; lol="aaa;bbb"; Path=/',
+ expected: "test=6",
+ name: "Set cookie with two invalid attributes (lol=\"aaa and bbb).",
+ defaultPath: false
+ },
+ {
+ cookie: 'test=7; Path=/; lol="aaa;bbb"',
+ expected: "test=7",
+ name: "Set cookie ending with two invalid attributes (lol=\"aaa and bbb).",
+ defaultPath: false
+ },
+ {
+ cookie: 'test=8; "Secure"',
+ expected: "test=8",
+ // This gets parsed as an unrecognized \"Secure\" attribute, not a valid
+ // Secure attribute. That's why it gets set on an non-secure origin.
+ name: "Set cookie for quoted Secure attribute",
+ },
+ {
+ cookie: "test=9; Secure qux",
+ expected: "test=9",
+ // This should be parsed as an unrecognized "Secure qux" attribute
+ // and ignored. That is, the cookie will not be Secure.
+ name: "Set cookie for Secure qux",
+ },
+ {
+ cookie: "test=10; b,az=qux",
+ expected: "test=10",
+ name: "Ignore invalid attribute name with comma",
+ },
+ {
+ cookie: "test=11; baz=q,ux",
+ expected: "test=11",
+ name: "Ignore invalid attribute value with comma",
+ },
+ {
+ cookie: " test = 12 ;foo;;; bar",
+ expected: "test=12",
+ name: "Set cookie ignoring multiple invalid attributes, whitespace, and semicolons",
+ },
+ {
+ cookie: " test=== 13 ;foo;;; bar",
+ expected: "test=== 13",
+ name: "Set cookie with multiple '='s in its value, ignoring multiple invalid attributes, whitespace, and semicolons",
+ },
+ {
+ cookie: "test=14; version=1;",
+ expected: "test=14",
+ name: "Set cookie with (invalid) version=1 attribute",
+ },
+ {
+ cookie: "test=15; version=1000;",
+ expected: "test=15",
+ name: "Set cookie with (invalid) version=1000 attribute",
+ },
+ {
+ cookie: "test=16; customvalue='1000 or more';",
+ expected: "test=16",
+ name: "Set cookie ignoring anything after ; (which looks like an invalid attribute)",
+ },
+ {
+ cookie: "test=17; customvalue='1000 or more'",
+ expected: "test=17",
+ name: "Set cookie ignoring anything after ; (which looks like an invalid attribute, with no trailing semicolon)",
+ },
+ {
+ cookie: "test=18; foo=bar, a=b",
+ expected: "test=18",
+ name: "Ignore keys after semicolon",
+ },
+ {
+ cookie: "test=19;max-age=3600, c=d;path=/",
+ expected: "test=19",
+ name: "Ignore attributes after semicolon",
+ defaultPath: false,
+ },
+ {
+ cookie: ["testA=20", "=", "testb=20"],
+ expected: "testA=20; testb=20",
+ name: "Ignore `Set-Cookie: =`",
+ },
+ {
+ cookie: ["test=21", ""],
+ expected: "test=21",
+ name: "Ignore empty cookie string",
+ },
+ {
+ cookie: ["test22", "="],
+ expected: "test22",
+ name: "Ignore `Set-Cookie: =` with other `Set-Cookie` headers",
+ },
+ {
+ cookie: ["testA23", "; testB23"],
+ expected: "testA23",
+ name: "Ignore name- and value-less `Set-Cookie: ; bar`",
+ },
+ {
+ cookie: ["test24", " "],
+ expected: "test24",
+ name: "Ignore name- and value-less `Set-Cookie: `",
+ },
+ {
+ cookie: ["test25", "\t"],
+ expected: "test25",
+ name: "Ignore name- and value-less `Set-Cookie: \\t`",
+ },
+ {
+ cookie: "test=26; domain=.parser.test; ;; ;=; ,,, ===,abc,=; abracadabra! max-age=20;=;;",
+ expected: "",
+ name: "Ignore cookie with domain that won't domain match (along with other invalid noise)",
+ },
+ ];
+
+ for (const test of invalidAttributeTests) {
+ httpCookieTest(test.cookie, test.expected, test.name, test.defaultPath);
+ }
+ </script>
+ </body>
+</html> \ No newline at end of file
diff --git a/testing/web-platform/tests/cookies/attributes/max-age.html b/testing/web-platform/tests/cookies/attributes/max-age.html
new file mode 100644
index 0000000000..7b7ff6ed4c
--- /dev/null
+++ b/testing/web-platform/tests/cookies/attributes/max-age.html
@@ -0,0 +1,78 @@
+<!doctype html>
+<html>
+ <head>
+ <meta charset=utf-8>
+ <title>Test max-age attribute parsing</title>
+ <meta name=help href="https://tools.ietf.org/html/rfc6265#section-5.3.2">
+ <meta name="timeout" content="long">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/resources/testdriver.js"></script>
+ <script src="/resources/testdriver-vendor.js"></script>
+ <script src="/cookies/resources/cookie-test.js"></script>
+ </head>
+ <body>
+ <div id=log></div>
+ <script>
+ // TODO: there is more to test here, these tests capture the old
+ // ported http-state tests. Feel free to delete this comment when more
+ // are added.
+ const maxAgeTests = [
+ {
+ cookie: "test=1; Max-Age=50,399",
+ expected: "test=1",
+ name: "Ignore max-age attribute with invalid non-zero-digit (containing a comma)",
+ },
+ {
+ cookie: "test=2; max-age=10000",
+ expected: "test=2",
+ name: "Set cookie with age",
+ },
+ {
+ cookie: "test=3; max-age=0",
+ expected: "",
+ name: "Set no cookie with max-age=0",
+ },
+ {
+ cookie: "test=4; max-age=-1",
+ expected: "",
+ name: "Set no cookie with max-age=-1",
+ },
+ {
+ cookie: "test=5; max-age=-20",
+ expected: "",
+ name: "Set no cookie with max-age=-20",
+ },
+ {
+ cookie: ["testA=6; max-age=60", "testB=6; max-age=60"],
+ expected: "testA=6; testB=6",
+ name: "Set multiple cookies with max-age attribute",
+ },
+ {
+ cookie: ["testA=7; max-age=60", "testB=7; max-age=60", "testA=differentvalue; max-age=0"],
+ expected: "testB=7",
+ name: "Expire later cookie with same name and max-age=0",
+ },
+ {
+ cookie: ["testA=8; max-age=60", "testB=8; max-age=60", "testA=differentvalue; max-age=0", "testC=8; max-age=0"],
+ expected: "testB=8",
+ name: "Expire later cookie with same name and max-age=0, and don't set cookie with max-age=0",
+ },
+ {
+ cookie: ['test="9! = foo;bar\";" parser; max-age=6', "test9; max-age=2.63,"],
+ expected: 'test="9! = foo; test9',
+ name: "Set mulitiple cookies with valid max-age values",
+ },
+ {
+ cookie: ["test=10; max-age=0", "test10; max-age=0"],
+ expected: "",
+ name: "Don't set multiple cookies with max-age=0",
+ },
+ ];
+
+ for (const test of maxAgeTests) {
+ httpCookieTest(test.cookie, test.expected, test.name);
+ }
+ </script>
+ </body>
+</html> \ No newline at end of file
diff --git a/testing/web-platform/tests/cookies/attributes/path-redirect.html b/testing/web-platform/tests/cookies/attributes/path-redirect.html
new file mode 100644
index 0000000000..574879971f
--- /dev/null
+++ b/testing/web-platform/tests/cookies/attributes/path-redirect.html
@@ -0,0 +1,128 @@
+<!doctype html>
+<html>
+ <head>
+ <meta charset=utf-8>
+ <title>Test cookie path attribute parsing</title>
+ <meta name=help href="https://tools.ietf.org/html/rfc6265#section-5.2.4">
+ <meta name="timeout" content="long">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/resources/testdriver.js"></script>
+ <script src="/resources/testdriver-vendor.js"></script>
+ <script src="/cookies/resources/cookie-test.js"></script>
+ </head>
+ <body>
+ <script>
+ const pathRedirectTests = [
+ {
+ cookie: "test=1; path=/cookies/attributes/resources/path.html",
+ expected: "test=1",
+ name: "Cookie sent for exact redirected path match",
+ location: "/cookies/attributes/resources/path.html",
+ },
+ {
+ cookie: "test=2; path=/cookies/attributes/resources/path/one.html",
+ expected: "test=2",
+ name: "Cookie sent for exact redirected path match, one level deeper",
+ location: "/cookies/attributes/resources/path/one.html",
+ },
+ {
+ cookie: "test=3; path=/cookies/attributes/resources/path/",
+ expected: "test=3",
+ name: "Cookie sent for redirected path with trailing '/' and the redirected URL is one level deeper",
+ location: "/cookies/attributes/resources/path/one.html",
+ },
+ {
+ cookie: "test=4; path=/cookies/attributes/resources/path/",
+ expected: "test=4",
+ name: "Cookie sent for redirected path with trailing '/' and a double '/' in the redirected URL",
+ location: "/cookies/attributes/resources/path//one.html",
+ },
+ {
+ cookie: "test=5; path=/cookies/attributes/resources/path/one.html;",
+ expected: "test=5",
+ name: "Cookie sent for redirected path match with a trailing ';' after an unquoted Path",
+ location: "/cookies/attributes/resources/path/one.html",
+ },
+ {
+ cookie: 'test=6; path="/cookies/attributes/resources/path/one.html;"',
+ expected: "",
+ name: "No cookie sent for redirected path match with a trailing ';' inside a quoted Path",
+ location: "/cookies/attributes/resources/path/one.html",
+ },
+ {
+ cookie: "test=7a; path=/cookies/attributes/resources/p%61th/three.html",
+ expected: "",
+ name: "No cookie sent for redirected path match with partially URL encoded path",
+ location: "/cookies/attributes/resources/path/three.html",
+ },
+ {
+ cookie: ["test=8a; path=/cookies/attributes/resources",
+ "test=8b; path=/cookies/attributes/resources/"],
+ expected: "test=8b; test=8a",
+ name: "Multiple cookies sent for multiple redirected path matches, sorted by length",
+ location: "/cookies/attributes/resources/path.html",
+ },
+ {
+ cookie: "test=9; path=/cookies/attributes/resources/path.html",
+ expected: "",
+ name: "No cookie sent for redirected path mismatch where path and redirected URL begin with same string",
+ location: "/cookies/attributes/resources/pathfakeout.html",
+ },
+ {
+ cookie: "test=10; path=/cookies/attributes/resources/path/one.html",
+ expected: "",
+ name: "No cookie sent for redirected path mismatch where final path directory component and redirected URL resource begin with same string",
+ location: "/cookies/attributes/resources/path.html",
+ },
+ {
+ cookie: "test=11; path=/cookies/attributes/resources/path/one.html",
+ expected: "",
+ name: "No cookie sent for redirected path mismatch where final path directory component begins with same string as redirected URL final directory component",
+ location: "/cookies/attributes/resources/pathfakeout/one.html",
+ },
+ {
+ cookie: "test=12; path=/cookies/attributes/resources/path/one.html",
+ expected: "",
+ name: "No cookie sent for redirected path mismatch for different resources inside the same final directory component",
+ location: "/cookies/attributes/resources/path/two.html",
+ },
+ {
+ cookie: "test=13; path=/cookies/attributes/resources/path/one.html/",
+ expected: "",
+ name: "No cookie sent for redirected path mismatch where final path directory component ends in '/' and does not match redirected URL",
+ location: "/cookies/attributes/resources/path/two.html",
+ },
+ {
+ cookie: "test=14; path=/cookies/attributes/resources/path/",
+ expected: "",
+ name: "No cookie sent for redirected path mismatch with a similar start to the redirected URL",
+ location: "/cookies/attributes/resources/pathfakeout.html",
+ },
+ {
+ cookie: "test=15; path=/cookies/attributes/resources/path/one.html?",
+ expected: "",
+ name: "No cookie sent for redirected path mismatch with trailing '?' after unquoted Path",
+ location: "/cookies/attributes/resources/path/one.html",
+ },
+ {
+ cookie: "test=16; path=/cookies/attributes/resources/path/one.html#",
+ expected: "",
+ name: "No cookie sent for redirected path mismatch with trailing '#' after unquoted Path",
+ location: "/cookies/attributes/resources/path/one.html",
+ },
+ {
+ cookie: "test=17; path=/cookies/attributes/resources/path/one.html/",
+ expected: "",
+ name: "No cookie sent for redirected path mismatch with trailing '/' after unquoted Path",
+ location: "/cookies/attributes/resources/path/one.html",
+ },
+ ];
+
+ for (const test of pathRedirectTests) {
+ httpRedirectCookieTest(test.cookie, test.expected, test.name,
+ test.location);
+ }
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/cookies/attributes/path.html b/testing/web-platform/tests/cookies/attributes/path.html
new file mode 100644
index 0000000000..81adc08a19
--- /dev/null
+++ b/testing/web-platform/tests/cookies/attributes/path.html
@@ -0,0 +1,144 @@
+<!doctype html>
+<html>
+ <head>
+ <meta charset=utf-8>
+ <title>Test cookie path attribute parsing</title>
+ <meta name=help href="https://tools.ietf.org/html/rfc6265#section-5.2.4">
+ <meta name="timeout" content="long">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/resources/testdriver.js"></script>
+ <script src="/resources/testdriver-vendor.js"></script>
+ <script src="/cookies/resources/cookie-test.js"></script>
+ </head>
+ <body>
+ <script>
+ const pathTests = [
+ {
+ cookie: "test=1; Path",
+ expected: "test=1",
+ name: "Set cookie for bare Path",
+ },
+ {
+ cookie: "test=2; Path=",
+ expected: "test=2",
+ name: "Set cookie for Path=",
+ },
+ {
+ cookie: "test=3; Path=/",
+ expected: "test=3",
+ name: "Set cookie for Path=/",
+ defaultPath: false,
+ },
+ {
+ cookie: "test=4; Path=/qux",
+ expected: "",
+ name: "No cookie returned for mismatched path",
+ defaultPath: false,
+ },
+ {
+ cookie: "test=5; Path =/qux",
+ expected: "",
+ name: "No cookie returned for path space equals mismatched path",
+ defaultPath: false,
+ },
+ {
+ cookie: "test=6; Path= /qux",
+ expected: "",
+ name: "No cookie returned for path equals space mismatched path",
+ defaultPath: false,
+ },
+ {
+ cookie: "test=7; Path=/qux ; taz",
+ expected: "",
+ name: "No cookie returned for mismatched path and attribute",
+ defaultPath: false,
+ },
+ {
+ cookie: "test=8; Path=/qux; Path=/",
+ expected: "test=8",
+ name: "Set cookie for mismatched and root path",
+ },
+ {
+ cookie: "test=9; Path=/; Path=/qux",
+ expected: "",
+ name: "No cookie returned for root and mismatched path",
+ defaultPath: false,
+ },
+ {
+ cookie: "test=10; Path=/lol; Path=/qux",
+ expected: "",
+ name: "No cookie returned for multiple mismatched paths",
+ defaultPath: false,
+ },
+ {
+ cookie: ["testA=11; path=/", "testB=11; path=/cookies/attributes"],
+ expected: "testB=11; testA=11",
+ name: "Return 2 cookies sorted by matching path length (earlier name with shorter path set first)",
+ defaultPath: false,
+ },
+ {
+ cookie: ["testB=12; path=/", "testA=12; path=/cookies/attributes"],
+ expected: "testA=12; testB=12",
+ name: "Return 2 cookies sorted by matching path length (later name with shorter path set first)",
+ defaultPath: false,
+ },
+ {
+ cookie: ["testA=13; path=/cookies/attributes", "testB=13; path=/"],
+ expected: "testA=13; testB=13",
+ name: "Return 2 cookies sorted by matching path length (earlier name with longer path set first)",
+ defaultPath: false,
+ },
+ {
+ cookie: ["testB=14; path=/cookies/attributes", "testA=14; path=/"],
+ expected: "testB=14; testA=14",
+ name: "Return 2 cookies sorted by matching path length (later name with longer path set first)",
+ defaultPath: false,
+ },
+ {
+ cookie: ["test=15; path=/cookies/attributes/foo"],
+ expected: "",
+ name: "No cookie returned for partial path match",
+ defaultPath: false,
+ },
+ {
+ cookie: ["test=16", "test=0; path=/cookies/attributes/foo"],
+ expected: "test=16",
+ name: "No cookie returned for partial path match, return cookie for default path",
+ },
+ {
+ cookie: ["test=17; path= /"],
+ expected: "test=17",
+ name: "Return cookie for path= / (whitespace after equals)",
+ },
+ {
+ cookie: ["test=18; path=/cookies/ATTRIBUTES"],
+ expected: "",
+ name: "No cookie returned for case mismatched path",
+ defaultPath: false,
+ },
+ {
+ cookie: ["testA=19; path = /cookies/attributes", "testB=19; path = /book"],
+ expected: "testA=19",
+ name: "Return cookie A on path match, no cookie returned for path mismatch (plus whitespace)",
+ defaultPath: false,
+ },
+ {
+ cookie: ["test=20; path=; path=/dog"],
+ expected: "",
+ name: "No cookie returned for mismatched path (after bare path=)",
+ defaultPath: false,
+ },
+ {
+ cookie: ["test=21; path=/dog; path="],
+ expected: "test=21",
+ name: "Return cookie for bare path= (after mismatched path)",
+ },
+ ];
+
+ for (const test of pathTests) {
+ httpCookieTest(test.cookie, test.expected, test.name, test.defaultPath);
+ }
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/cookies/attributes/resources/domain-child.sub.html b/testing/web-platform/tests/cookies/attributes/resources/domain-child.sub.html
new file mode 100644
index 0000000000..515079b783
--- /dev/null
+++ b/testing/web-platform/tests/cookies/attributes/resources/domain-child.sub.html
@@ -0,0 +1,401 @@
+<!doctype html>
+<html>
+ <head>
+ <meta charset=utf-8>
+ <title>Test cookie domain attribute parsing</title>
+ <meta name=help href="https://tools.ietf.org/html/rfc6265#section-5.2.3">
+ <meta name="timeout" content="long">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testdriver.js"></script>
+ <script src="/resources/testdriver-vendor.js"></script>
+ <script src="/cookies/resources/cookie-test.js"></script>
+ </head>
+ <body>
+ <script>
+ const path = "path=/cookies/attributes"
+ const port = "{{ports[http][0]}}";
+ const host = "{{host}}"; // example.org
+ const wwwHost = "{{domains[www]}}"; // home.example.org
+ const www1Host = "{{domains[www1]}}"; // sibling.example.org
+ const www2wwwHost = "{{domains[www2.www]}}"; // subdomain.home.example.org
+
+ // naive helper method to return the TLD for a given domain
+ const getTLD = domain => {
+ let match = /\.[a-z]+$/.exec(domain);
+ if (match) {
+ return match[0];
+ } else {
+ throw 'Domain is malformed!';
+ }
+ }
+
+ // helper to take a domain like "www.example.org"
+ // and return a string like "www.eXaMpLe.org"
+ const makeBizarre = domain => {
+ let bizarre = "";
+ let domainArray = domain.split(".");
+ let secondLevel = domainArray[domainArray.length - 2];
+ for (let i in secondLevel) {
+ if (i % 2 == 1) {
+ bizarre += secondLevel[i].toUpperCase();
+ } else {
+ bizarre += secondLevel[i];
+ }
+ }
+ domainArray[domainArray.length - 2] = bizarre;
+ return domainArray.join(".");
+ }
+
+ // helper to change the current TLD to a TLD that doesn't exist, and is
+ // unlikely to exist in the future. (the main point is that the TLD
+ // *changes*, so there is no domain match, but we cant' predict how WPT
+ // servers may be set up in the wild so picking any valid TLD has the risk
+ // of future (unintentional) domain matching.
+ const changeTLD = domain => {
+ let domainArray = domain.split(".");
+ domainArray[domainArray.length - 1] += "zzz";
+ return domainArray.join(".");
+ }
+
+ const domainTests = [
+ {
+ cookie: `test=1; domain=${wwwHost}`,
+ expected: "test=1",
+ name: "Return cookie for a domain match",
+ location: `http://${wwwHost}:${port}/cookies/attributes/resources/path.html`,
+ },
+ {
+ cookie: `test=2; domain=${wwwHost}`,
+ expected: "",
+ name: "No cookie returned for domain mismatch (subdomains differ post-redirect)",
+ location: `http://${www1Host}:${port}/cookies/attributes/resources/path.html`,
+ },
+ {
+ cookie: `test=3; domain=.${wwwHost}`,
+ expected: "test=3",
+ name: "Return cookie for a domain match with leading '.'",
+ location: `http://${wwwHost}:${port}/cookies/attributes/resources/path.html`,
+ },
+ {
+ cookie: `test=4; domain=${wwwHost}`,
+ expected: "test=4",
+ name: "Return cookie for domain match (domain attribute is suffix of the host name and first level subdomain)",
+ location: `http://${www2wwwHost}:${port}/cookies/attributes/resources/path.html`,
+ },
+ {
+ cookie: `test=5; domain=.${wwwHost}`,
+ expected: "test=5",
+ name: "Return cookie for domain match (domain attribute is suffix of the host name and first level subdomain, with leading '.')",
+ location: `http://${www2wwwHost}:${port}/cookies/attributes/resources/path.html`,
+ },
+ {
+ cookie: `test=6; domain=.${wwwHost}`,
+ expected: "",
+ name: "No cookie returned for domain mismatch (subdomains differ, with leading '.')",
+ location: `http://${www1Host}:${port}/cookies/attributes/resources/path.html`,
+ },
+ {
+ cookie: `test=7; domain=${www1Host}`,
+ expected: "",
+ name: "No cookie returned for domain mismatch when cookie was created (which would match after the redirect, with one subdomain level)",
+ location: `http://${www1Host}:${port}/cookies/attributes/resources/path.html`,
+ },
+ {
+ cookie: `test=8; domain=.${host}`,
+ expected: "test=8",
+ name: "Return cookie for domain match (domain attribute is suffix of the host name, with leading '.')",
+ location: `http://${wwwHost}:${port}/cookies/attributes/resources/path.html`,
+ },
+ {
+ cookie: `test=9; domain=${host}`,
+ expected: "test=9",
+ name: "Return cookie for domain match (domain attribute is suffix of the host name)",
+ location: `http://${wwwHost}:${port}/cookies/attributes/resources/path.html`,
+ },
+ {
+ cookie: `test=10; domain=..${wwwHost}`,
+ expected: "",
+ name: "No cookie returned for domain attribute with double leading '.'",
+ location: `http://${wwwHost}:${port}/cookies/attributes/resources/path.html`,
+ },
+ {
+ cookie: `test=11; domain=www..${host}`,
+ expected: "",
+ name: "No cookie returned for domain attribute with subdomain followed by ..",
+ location: `http://${wwwHost}:${port}/cookies/attributes/resources/path.html`,
+ },
+ {
+ cookie: `test=12; domain= .${wwwHost}`,
+ expected: "test=12",
+ name: "Return cookie for a domain match with leading whitespace and '.'",
+ location: `http://${wwwHost}:${port}/cookies/attributes/resources/path.html`,
+ },
+ {
+ cookie: `test=13; domain= . ${wwwHost}`,
+ expected: "",
+ name: "No cookie returned for domain attribute with whitespace that surrounds a leading '.'",
+ location: `http://${wwwHost}:${port}/cookies/attributes/resources/path.html`,
+ },
+ {
+ cookie: `test=14; domain=${wwwHost}.`,
+ expected: "",
+ name: "No cookie returned for domain attribute with trailing '.'",
+ location: `http://${wwwHost}:${port}/cookies/attributes/resources/path.html`,
+ },
+ {
+ cookie: `test=15; domain=${wwwHost}..`,
+ expected: "",
+ name: "No cookie returned for domain attribute with trailing '..'",
+ location: `http://${wwwHost}:${port}/cookies/attributes/resources/path.html`,
+ },
+ {
+ cookie: `test=16; domain=${wwwHost} .`,
+ expected: "",
+ name: "No cookie returned for domain attribute with trailing whitespace and '.'",
+ location: `http://${wwwHost}:${port}/cookies/attributes/resources/path.html`,
+ },
+ {
+ cookie: `test=17; domain=${getTLD(host)}`,
+ expected: "",
+ name: "No cookie returned for domain attribute with TLD as value",
+ location: `http://${wwwHost}:${port}/cookies/attributes/resources/path.html`,
+ },
+ {
+ cookie: `test=18; domain=.${getTLD(host)}`,
+ expected: "",
+ name: "No cookie returned for domain attribute with TLD as value, with leading '.'",
+ location: `http://${wwwHost}:${port}/cookies/attributes/resources/path.html`,
+ },
+ {
+ cookie: `test=18b; domain=.${getTLD(host)}.`,
+ expected: "",
+ name: "No cookie returned for domain attribute with TLD as value, with leading and trailing '.'",
+ location: `http://${wwwHost}:${port}/cookies/attributes/resources/path.html`,
+ },
+ {
+ cookie: [`testA=19; domain=${wwwHost}`, `testB=19; domain=.${wwwHost}`],
+ expected: "testA=19; testB=19",
+ name: "Return multiple cookies that match on domain (without and with leading '.')",
+ location: `http://${wwwHost}:${port}/cookies/attributes/resources/path.html`,
+ },
+ {
+ cookie: [`testB=20; domain=.${wwwHost}`, `testA=20; domain=${wwwHost}`],
+ expected: "testB=20; testA=20",
+ name: "Return multiple cookies that match on domain (with and without leading '.')",
+ location: `http://${wwwHost}:${port}/cookies/attributes/resources/path.html`,
+ },
+ {
+ cookie: `test=21; domain="${wwwHost}"`,
+ expected: "",
+ name: "No cookie returned for domain attribute value between quotes",
+ location: `http://${wwwHost}:${port}/cookies/attributes/resources/path.html`,
+ },
+ {
+ cookie: [`testA=22; domain=${wwwHost}`, `testB=22; domain=.${host}`],
+ expected: "testA=22; testB=22",
+ name: "Return multiple cookies that match on subdomain and domain (without and with leading '.')",
+ location: `http://${wwwHost}:${port}/cookies/attributes/resources/path.html`,
+ },
+ {
+ cookie: [`testB=23; domain=.${host}`, `testA=23; domain=${wwwHost}`],
+ expected: "testB=23; testA=23",
+ name: "Return multiple cookies that match on domain and subdomain (with and without leading '.')",
+ location: `http://${wwwHost}:${port}/cookies/attributes/resources/path.html`,
+ },
+ {
+ cookie: `test=24; domain=.${host}; domain=${wwwHost}`,
+ expected: "",
+ name: "No cookie returned when domain attribute does not domain-match (and first does)",
+ location: `http://${www1Host}:${port}/cookies/attributes/resources/path.html`,
+ },
+ {
+ cookie: `test=25; domain=${wwwHost}; domain=.${host}`,
+ expected: "test=25",
+ name: "Return cookie for domain attribute match (first does not, but second does)",
+ location: `http://${www1Host}:${port}/cookies/attributes/resources/path.html`,
+ },
+ {
+ cookie: `test=26; domain=${makeBizarre(wwwHost)}`,
+ expected: "test=26",
+ name: "Return cookie for domain match (with bizarre capitalization for domain attribute value)",
+ location: `http://${wwwHost}:${port}/cookies/attributes/resources/path.html`,
+ },
+ {
+ cookie: `test=27; domain="${wwwHost}:${port}"`,
+ expected: "",
+ name: "No cookie returned for domain attribute value with port",
+ location: `http://${wwwHost}:${port}/cookies/attributes/resources/path.html`,
+ },
+ {
+ cookie: `test=28; domain=${www2wwwHost}`,
+ expected: "",
+ name: "No cookie returned for domain mismatch when cookie was created (which would match after the redirect, with two subdomain levels)",
+ location: `http://${www2wwwHost}:${port}/cookies/attributes/resources/path.html`,
+ },
+ {
+ cookie: `test=29`,
+ expected: "",
+ name: "No cookie returned for cookie set on different domain (with no domain attribute)",
+ location: `http://${www2wwwHost}:${port}/cookies/attributes/resources/path.html`,
+ },
+ {
+ cookie: "test=30; domain=",
+ expected: "test=30",
+ name: "Return cookie set with bare domain= attribute",
+ location: `http://${wwwHost}:${port}/cookies/attributes/resources/path.html`,
+ },
+ {
+ cookie: `test=31; domain=${wwwHost}`,
+ expected: "test=31",
+ name: "Return cookie that domain-matches with bizarre-cased URL",
+ location: `http://${makeBizarre(wwwHost)}:${port}/cookies/attributes/resources/path.html`,
+ },
+ {
+ cookie: `test=32; domain=${wwwHost}; domain=${changeTLD(wwwHost)}`,
+ expected: "",
+ name: "No cookie returned for domain attribute mismatch (first attribute matches, but second does not)",
+ location: `http://${wwwHost}:${port}/cookies/attributes/resources/path.html`,
+ },
+ {
+ cookie: `test=33; domain=${changeTLD(wwwHost)}; domain=${wwwHost}`,
+ expected: "test=33",
+ name: "Return cookie for domain match (first attribute doesn't, but second does)",
+ location: `http://${wwwHost}:${port}/cookies/attributes/resources/path.html`,
+ },
+ {
+ cookie: `test=34; domain=${wwwHost}; domain=${changeTLD(wwwHost)}; domain=${wwwHost}`,
+ expected: "test=34",
+ name: "Return cookie for domain match (first attribute matches, second doesn't, third does)",
+ location: `http://${wwwHost}:${port}/cookies/attributes/resources/path.html`,
+ },
+ {
+ cookie: `test=35; domain=${changeTLD(wwwHost)}; domain=${wwwHost}; domain=${changeTLD(wwwHost)}`,
+ expected: "",
+ name: "No cookie returned for domain attribute mismatch (first attribute doesn't, second does, third doesn't)",
+ location: `http://${wwwHost}:${port}/cookies/attributes/resources/path.html`,
+ },
+ {
+ cookie: `test=36; domain=${wwwHost}; domain=${wwwHost}`,
+ expected: "test=36",
+ name: "Return cookie for domain match (with two identical domain attributes)",
+ location: `http://${wwwHost}:${port}/cookies/attributes/resources/path.html`,
+ },
+ {
+ cookie: `test=37; domain=${wwwHost}; domain=${host}`,
+ expected: "test=37",
+ name: "Return cookie for domain match (with first domain attribute a match for host name and second as suffix of host name)",
+ location: `http://${wwwHost}:${port}/cookies/attributes/resources/path.html`,
+ },
+ {
+ cookie: `test=38; domain=${host}; domain=${wwwHost}`,
+ expected: "test=38",
+ name: "Return cookie for domain match (with first domain attribute as suffix of host name and second a match for host name)",
+ location: `http://${wwwHost}:${port}/cookies/attributes/resources/path.html`,
+ },
+ {
+ cookie: `test=39; domain=.${www1Host}`,
+ expected: "",
+ name: "No cookie set on domain mismatch before a (domain matching) redirect",
+ location: `http://${www1Host}:${port}/cookies/attributes/resources/path.html`,
+ },
+ {
+ cookie: `test=40; domain=.${www2wwwHost}`,
+ expected: "",
+ name: "No cookie set on domain mismatch before a (domain matching) redirect (for second level subdomain)",
+ location: `http://${www2wwwHost}:${port}/cookies/attributes/resources/path.html`,
+ },
+ {
+ cookie: `test=41; domain=${host}; domain=`,
+ expected: "test=41",
+ name: "Return cookie for domain match (with first domain attribute as suffix of host name and second a bare attribute)",
+ location: `http://${wwwHost}:${port}/cookies/attributes/resources/path.html`,
+ },
+ {
+ cookie: `test=42; domain=${www1Host}; domain=`,
+ expected: "test=42",
+ name: "Cookie returned for bare domain attribute following mismatched domain attribute (after redirect to same-origin page).",
+ location: `http://${wwwHost}:${port}/cookies/attributes/resources/path.html`,
+ },
+ {
+ cookie: `test=43; domain=${www1Host}; domain=`,
+ expected: "",
+ name: "No cookie returned for domain mismatch (first attribute is a different subdomain and second is bare)",
+ location: `http://${www2wwwHost}:${port}/cookies/attributes/resources/path.html`,
+ },
+ {
+ cookie: [`test=not44; domain=${wwwHost}`, `test=44; domain=.${wwwHost}`],
+ expected: "test=44",
+ name: "Cookies with same name, path, and domain (differing only in leading '.') overwrite each other ('.' second)",
+ location: `http://${wwwHost}:${port}/cookies/attributes/resources/path.html`,
+ },
+ {
+ cookie: [`test=not45; domain=.${wwwHost}`, `test=45; domain=${wwwHost}`],
+ expected: "test=45",
+ name: "Cookies with same name, path, and domain (differing only in leading '.') overwrite each other ('.' first)",
+ location: `http://${wwwHost}:${port}/cookies/attributes/resources/path.html`,
+ },
+ {
+ cookie: `test=46; domain=.`,
+ expected: "",
+ name: "No cookie returned for domain with single dot ('.') value.",
+ location: `http://${wwwHost}:${port}/cookies/attributes/resources/path.html`,
+ },
+ {
+ cookie: `test=46b; domain=.; domain=${host}`,
+ expected: "test=46b",
+ name: "Return cookie with valid domain after domain with single dot ('.') value.",
+ location: `http://${wwwHost}:${port}/cookies/attributes/resources/path.html`,
+ },
+ {
+ cookie: ["test=47", `test=47b; domain=${host}`,`test=47b; domain=${www1Host}; domain=`],
+ expected: "test=47b; test=47b",
+ name: "Empty domain treated as host cookie 1",
+ location: `http://${wwwHost}:${port}/cookies/attributes/resources/path.html`,
+ },
+ {
+ cookie: ["test=48", `test=48b; domain=${host}`,`test=48b; domain=${host}; domain=`],
+ expected: "test=48b; test=48b",
+ name: "Empty domain treated as host cookie 2",
+ location: `http://${wwwHost}:${port}/cookies/attributes/resources/path.html`,
+ },
+ {
+ cookie: ["test=49", `test=49b; domain=${host}`,`test=49b; domain=`],
+ expected: "test=49b; test=49b",
+ name: "Empty domain treated as host cookie 3",
+ location: `http://${wwwHost}:${port}/cookies/attributes/resources/path.html`,
+ },
+ {
+ cookie: ["test=50", `test=50b; domain=${host}`,`test=50b; domain=${www1Host}; domain=`],
+ expected: "test=50b",
+ name: "No host cookies returned for host cookies after non-host redirect 1",
+ location: `http://${www2wwwHost}:${port}/cookies/attributes/resources/path.html`,
+ },
+ {
+ cookie: ["test=51", `test=51b; domain=${host}`,`test=51b; domain=${host}; domain=`],
+ expected: "test=51b",
+ name: "No host cookies returned for host cookies after non-host redirect 2",
+ location: `http://${www2wwwHost}:${port}/cookies/attributes/resources/path.html`,
+ },
+ {
+ cookie: ["test=52", `test=52b; domain=${host}`,`test=52b; domain=`],
+ expected: "test=52b",
+ name: "No host cookies returned for host cookies after non-host redirect 3",
+ location: `http://${www2wwwHost}:${port}/cookies/attributes/resources/path.html`,
+ },
+ ];
+
+ for (const test of domainTests) {
+ if (Array.isArray(test.cookie)) {
+ for (let i in test.cookie) {
+ test.cookie[i] += `; ${path}`;
+ }
+ } else {
+ test.cookie += `; ${path}`;
+ }
+
+ httpRedirectCookieTest(test.cookie, test.expected, test.name,
+ test.location);
+ }
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/cookies/attributes/resources/path-redirect-shared.js b/testing/web-platform/tests/cookies/attributes/resources/path-redirect-shared.js
new file mode 100644
index 0000000000..777d0abd33
--- /dev/null
+++ b/testing/web-platform/tests/cookies/attributes/resources/path-redirect-shared.js
@@ -0,0 +1,11 @@
+// Note: this function has a dependency on testdriver.js. Any test files calling
+// it should include testdriver.js and testdriver-vendor.js
+window.addEventListener("message", (e) => {
+ setTestContextUsingRootWindow();
+ if (e.data == "getAndExpireCookiesForRedirectTest") {
+ const cookies = document.cookie;
+ test_driver.delete_all_cookies().then(() => {
+ e.source.postMessage({"cookies": cookies}, '*');
+ });
+ }
+}); \ No newline at end of file
diff --git a/testing/web-platform/tests/cookies/attributes/resources/path.html b/testing/web-platform/tests/cookies/attributes/resources/path.html
new file mode 100644
index 0000000000..5ff90b9f15
--- /dev/null
+++ b/testing/web-platform/tests/cookies/attributes/resources/path.html
@@ -0,0 +1,14 @@
+<!doctype html>
+<html>
+<head>
+ <meta charset=utf-8>
+ <title>helper iframe for matching cookie path redirect tests</title>
+ <meta name=help href="http://tools.ietf.org/html/rfc6265#section-5.1.4">
+</head>
+<body>
+ <script src="/resources/testdriver.js"></script>
+ <script src="/resources/testdriver-vendor.js"></script>
+ <script src="/cookies/resources/cookie-test.js"></script>
+ <script src="/cookies/attributes/resources/path-redirect-shared.js"></script>
+</body>
+</html> \ No newline at end of file
diff --git a/testing/web-platform/tests/cookies/attributes/resources/path.html.headers b/testing/web-platform/tests/cookies/attributes/resources/path.html.headers
new file mode 100644
index 0000000000..23de552c1a
--- /dev/null
+++ b/testing/web-platform/tests/cookies/attributes/resources/path.html.headers
@@ -0,0 +1 @@
+Access-Control-Allow-Origin: * \ No newline at end of file
diff --git a/testing/web-platform/tests/cookies/attributes/resources/path/one.html b/testing/web-platform/tests/cookies/attributes/resources/path/one.html
new file mode 100644
index 0000000000..5ff90b9f15
--- /dev/null
+++ b/testing/web-platform/tests/cookies/attributes/resources/path/one.html
@@ -0,0 +1,14 @@
+<!doctype html>
+<html>
+<head>
+ <meta charset=utf-8>
+ <title>helper iframe for matching cookie path redirect tests</title>
+ <meta name=help href="http://tools.ietf.org/html/rfc6265#section-5.1.4">
+</head>
+<body>
+ <script src="/resources/testdriver.js"></script>
+ <script src="/resources/testdriver-vendor.js"></script>
+ <script src="/cookies/resources/cookie-test.js"></script>
+ <script src="/cookies/attributes/resources/path-redirect-shared.js"></script>
+</body>
+</html> \ No newline at end of file
diff --git a/testing/web-platform/tests/cookies/attributes/resources/path/three.html b/testing/web-platform/tests/cookies/attributes/resources/path/three.html
new file mode 100644
index 0000000000..5ff90b9f15
--- /dev/null
+++ b/testing/web-platform/tests/cookies/attributes/resources/path/three.html
@@ -0,0 +1,14 @@
+<!doctype html>
+<html>
+<head>
+ <meta charset=utf-8>
+ <title>helper iframe for matching cookie path redirect tests</title>
+ <meta name=help href="http://tools.ietf.org/html/rfc6265#section-5.1.4">
+</head>
+<body>
+ <script src="/resources/testdriver.js"></script>
+ <script src="/resources/testdriver-vendor.js"></script>
+ <script src="/cookies/resources/cookie-test.js"></script>
+ <script src="/cookies/attributes/resources/path-redirect-shared.js"></script>
+</body>
+</html> \ No newline at end of file
diff --git a/testing/web-platform/tests/cookies/attributes/resources/path/two.html b/testing/web-platform/tests/cookies/attributes/resources/path/two.html
new file mode 100644
index 0000000000..5ff90b9f15
--- /dev/null
+++ b/testing/web-platform/tests/cookies/attributes/resources/path/two.html
@@ -0,0 +1,14 @@
+<!doctype html>
+<html>
+<head>
+ <meta charset=utf-8>
+ <title>helper iframe for matching cookie path redirect tests</title>
+ <meta name=help href="http://tools.ietf.org/html/rfc6265#section-5.1.4">
+</head>
+<body>
+ <script src="/resources/testdriver.js"></script>
+ <script src="/resources/testdriver-vendor.js"></script>
+ <script src="/cookies/resources/cookie-test.js"></script>
+ <script src="/cookies/attributes/resources/path-redirect-shared.js"></script>
+</body>
+</html> \ No newline at end of file
diff --git a/testing/web-platform/tests/cookies/attributes/resources/pathfakeout.html b/testing/web-platform/tests/cookies/attributes/resources/pathfakeout.html
new file mode 100644
index 0000000000..5ff90b9f15
--- /dev/null
+++ b/testing/web-platform/tests/cookies/attributes/resources/pathfakeout.html
@@ -0,0 +1,14 @@
+<!doctype html>
+<html>
+<head>
+ <meta charset=utf-8>
+ <title>helper iframe for matching cookie path redirect tests</title>
+ <meta name=help href="http://tools.ietf.org/html/rfc6265#section-5.1.4">
+</head>
+<body>
+ <script src="/resources/testdriver.js"></script>
+ <script src="/resources/testdriver-vendor.js"></script>
+ <script src="/cookies/resources/cookie-test.js"></script>
+ <script src="/cookies/attributes/resources/path-redirect-shared.js"></script>
+</body>
+</html> \ No newline at end of file
diff --git a/testing/web-platform/tests/cookies/attributes/resources/pathfakeout/one.html b/testing/web-platform/tests/cookies/attributes/resources/pathfakeout/one.html
new file mode 100644
index 0000000000..5ff90b9f15
--- /dev/null
+++ b/testing/web-platform/tests/cookies/attributes/resources/pathfakeout/one.html
@@ -0,0 +1,14 @@
+<!doctype html>
+<html>
+<head>
+ <meta charset=utf-8>
+ <title>helper iframe for matching cookie path redirect tests</title>
+ <meta name=help href="http://tools.ietf.org/html/rfc6265#section-5.1.4">
+</head>
+<body>
+ <script src="/resources/testdriver.js"></script>
+ <script src="/resources/testdriver-vendor.js"></script>
+ <script src="/cookies/resources/cookie-test.js"></script>
+ <script src="/cookies/attributes/resources/path-redirect-shared.js"></script>
+</body>
+</html> \ No newline at end of file
diff --git a/testing/web-platform/tests/cookies/attributes/resources/secure-non-secure-child.html b/testing/web-platform/tests/cookies/attributes/resources/secure-non-secure-child.html
new file mode 100644
index 0000000000..e5d68b8d07
--- /dev/null
+++ b/testing/web-platform/tests/cookies/attributes/resources/secure-non-secure-child.html
@@ -0,0 +1,85 @@
+<!doctype html>
+<html>
+ <head>
+ <meta charset=utf-8>
+ <title>Test cookie secure attribute parsing (on non-secure page)</title>
+ <meta name=help href="https://tools.ietf.org/html/rfc6265#section-5.2.5">
+ <meta name="timeout" content="long">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testdriver.js"></script>
+ <script src="/resources/testdriver-vendor.js"></script>
+ <script src="/cookies/resources/cookie-test.js"></script>
+ </head>
+ <body>
+ <script>
+ setTestContextUsingRootWindow();
+ // These tests are the non-secure analog to secure.https.html.
+ // They're not in the /cookies/attributes folder because they shouldn't
+ // be run by themselves. Instead, /cookies/attributes/secure.https.html
+ // opens this in a non-secure window.
+ const secureNonSecureTests = [
+ {
+ cookie: "test=1; Secure",
+ expected: "",
+ name: "(non-secure) Ignore cookie for Secure attribute",
+ },
+ {
+ cookie: "test=2; seCURe",
+ expected: "",
+ name: "(non-secure) Ignore cookie for seCURe attribute",
+ },
+ {
+ cookie: "test=3; Secure=",
+ expected: "",
+ name: "(non-secure) Ignore cookie for for Secure= attribute",
+ },
+ {
+ cookie: "test=4; Secure=aaaa",
+ expected: "",
+ name: "(non-secure) Ignore cookie for Secure=aaaa",
+ },
+ {
+ cookie: "test=5; Secure =aaaaa",
+ expected: "",
+ name: "(non-secure) Ignore cookie for Secure space equals",
+ },
+ {
+ cookie: "test=6; Secure= aaaaa",
+ expected: "",
+ name: "(non-secure) Ignore cookie for Secure equals space",
+ },
+ {
+ cookie: "test=7; Secure",
+ expected: "",
+ name: "(non-secure) Ignore cookie for spaced Secure",
+ },
+ {
+ cookie: "test=8; Secure ;",
+ expected: "",
+ name: "(non-secure) Ignore cookie for space Secure with ;",
+ },
+ {
+ cookie: "__Secure-test=9; Secure",
+ expected: "",
+ name: "(non-secure) Ignore cookie with __Secure- prefix and Secure",
+ },
+ {
+ cookie: "__Secure-test=10",
+ expected: "",
+ name: "(non-secure) Ignore cookie with __Secure- prefix and without Secure",
+ },
+ // This is really a test that the cookie name isn't URL-decoded, but this
+ // is here to be next to the other __Secure- prefix tests.
+ {
+ cookie: "__%53ecure-test=11",
+ expected: "__%53ecure-test=11",
+ name: "(non-secure) Cookie returned with __%53ecure- prefix and without Secure",
+ },
+ ];
+
+ for (const test of secureNonSecureTests) {
+ httpCookieTest(test.cookie, test.expected, test.name, test.defaultPath);
+ }
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/cookies/attributes/secure-non-secure.html b/testing/web-platform/tests/cookies/attributes/secure-non-secure.html
new file mode 100644
index 0000000000..578cdbc1f7
--- /dev/null
+++ b/testing/web-platform/tests/cookies/attributes/secure-non-secure.html
@@ -0,0 +1,23 @@
+<!doctype html>
+<html>
+ <head>
+ <meta charset=utf-8>
+ <title>Test cookie secure attribute parsing (non-secure origin)</title>
+ <meta name=help href="https://tools.ietf.org/html/rfc6265#section-5.2.5">
+ <meta name="timeout" content="long">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/resources/testdriver.js"></script>
+ <script src="/resources/testdriver-vendor.js"></script>
+ <script src="/cookies/resources/cookie-helper.sub.js"></script>
+ </head>
+ <body>
+ <div id=log></div>
+ <script>
+ test(t => {
+ const win = window.open(`${INSECURE_ORIGIN}/cookies/attributes/resources/secure-non-secure-child.html`);
+ fetch_tests_from_window(win);
+ });
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/cookies/attributes/secure.https.html b/testing/web-platform/tests/cookies/attributes/secure.https.html
new file mode 100644
index 0000000000..9308899694
--- /dev/null
+++ b/testing/web-platform/tests/cookies/attributes/secure.https.html
@@ -0,0 +1,65 @@
+<!doctype html>
+<html>
+ <head>
+ <meta charset=utf-8>
+ <title>Test cookie secure attribute parsing</title>
+ <meta name=help href="https://tools.ietf.org/html/rfc6265#section-5.2.5">
+ <meta name="timeout" content="long">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/resources/testdriver.js"></script>
+ <script src="/resources/testdriver-vendor.js"></script>
+ <script src="/cookies/resources/cookie-test.js"></script>
+ </head>
+ <body>
+ <div id=log></div>
+ <script>
+ const secureTests = [
+ {
+ cookie: "test=1; Secure",
+ expected: "test=1",
+ name: "Set cookie for Secure attribute",
+ },
+ {
+ cookie: "test=2; seCURe",
+ expected: "test=2",
+ name: "Set cookie for seCURe attribute",
+ },
+ {
+ cookie: "test=3; Secure=",
+ expected: "test=3",
+ name: "Set cookie for for Secure= attribute",
+ },
+ {
+ cookie: "test=4; Secure=aaaa",
+ expected: "test=4",
+ name: "Set cookie for Secure=aaaa",
+ },
+ {
+ cookie: "test=5; Secure =aaaaa",
+ expected: "test=5",
+ name: "Set cookie for Secure space equals",
+ },
+ {
+ cookie: "test=6; Secure= aaaaa",
+ expected: "test=6",
+ name: "Set cookie for Secure equals space",
+ },
+ {
+ cookie: "test=7; Secure",
+ expected: "test=7",
+ name: "Set cookie for spaced Secure",
+ },
+ {
+ cookie: "test=8; Secure ;",
+ expected: "test=8",
+ name: "Set cookie for space Secure with ;",
+ }
+ ];
+
+ for (const test of secureTests) {
+ httpCookieTest(test.cookie, test.expected, test.name, test.defaultPath);
+ }
+ </script>
+ </body>
+</html>