Skip to content

Commit f3c7217

Browse files
committed
test(serialize): additional tests for name, domain and path RFC validations
These tests better align with the proper RFC rules for the cookie attributes of `name`, `domain`, and `path`. These test are meant to be implemented along with [PR jshttp#167][1] that adds more fine-grained validations based on RFC rules. [1]: jshttp#167
1 parent 38323ba commit f3c7217

File tree

1 file changed

+125
-15
lines changed

1 file changed

+125
-15
lines changed

test/serialize.js

Lines changed: 125 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -17,23 +17,98 @@ describe('cookie.serialize(name, value)', function () {
1717
assert.equal(cookie.serialize('foo', ''), 'foo=')
1818
})
1919

20+
it('should serialize valid name', function () {
21+
const validNames = [
22+
'foo',
23+
'foo!bar',
24+
'foo#bar',
25+
'foo$bar',
26+
`foo'bar`,
27+
'foo*bar',
28+
'foo+bar',
29+
'foo-bar',
30+
'foo.bar',
31+
'foo^bar',
32+
'foo_bar',
33+
'foo`bar',
34+
'foo|bar',
35+
'foo~bar',
36+
'foo7bar',
37+
];
38+
39+
validNames.forEach((name) => {
40+
assert.equal(cookie.serialize(name, 'baz'), `${name}=baz`, `Expected serialized value for name: "${name}"`);
41+
});
42+
});
43+
2044
it('should throw for invalid name', function () {
21-
assert.throws(cookie.serialize.bind(cookie, 'foo\n', 'bar'), /argument name is invalid/)
22-
assert.throws(cookie.serialize.bind(cookie, 'foo\u280a', 'bar'), /argument name is invalid/)
23-
})
45+
const invalidNames = [
46+
'foo\n',
47+
'foo\u280a',
48+
'foo/foo',
49+
'foo,foo',
50+
'foo;foo',
51+
'foo@foo',
52+
'foo[foo]',
53+
'foo?foo',
54+
'foo:foo',
55+
'foo!foo',
56+
'foo{foo}',
57+
'foo foo',
58+
'foo\tfoo',
59+
'foo"foo',
60+
'foo<script>foo'
61+
];
62+
63+
invalidNames.forEach((name) => {
64+
assert.throws(
65+
cookie.serialize.bind(cookie, name, 'bar'),
66+
/argument name is invalid/,
67+
`Expected an error for invalid name: "${name}"`
68+
);
69+
});
70+
});
2471
})
2572

2673
describe('cookie.serialize(name, value, options)', function () {
2774
describe('with "domain" option', function () {
28-
it('should serialize domain', function () {
29-
assert.equal(cookie.serialize('foo', 'bar', { domain: 'example.com' }),
30-
'foo=bar; Domain=example.com')
31-
})
75+
76+
it('should serialize valid domain', function () {
77+
const validDomains = [
78+
'example.com',
79+
'sub.example.com',
80+
'my-site.org',
81+
'localhost'
82+
];
83+
84+
validDomains.forEach((domain) => {
85+
assert.equal(
86+
cookie.serialize('foo', 'bar', { domain }),
87+
`foo=bar; Domain=${domain}`,
88+
`Expected serialized value for domain: "${domain}"`
89+
);
90+
});
91+
});
3292

3393
it('should throw for invalid value', function () {
34-
assert.throws(cookie.serialize.bind(cookie, 'foo', 'bar', { domain: 'example.com\n' }),
35-
/option domain is invalid/)
36-
})
94+
const invalidDomains = [
95+
'example.com\n',
96+
'sub.example.com\u0000',
97+
'my site.org',
98+
'domain..com',
99+
'.example.com',
100+
'example.com; Path=/',
101+
'example.com /* inject a comment */'
102+
];
103+
104+
invalidDomains.forEach((domain) => {
105+
assert.throws(
106+
cookie.serialize.bind(cookie, 'foo', 'bar', { domain }),
107+
/option domain is invalid/,
108+
`Expected an error for invalid domain: "${domain}"`
109+
);
110+
});
111+
});
37112
})
38113

39114
describe('with "encode" option', function () {
@@ -128,14 +203,49 @@ describe('cookie.serialize(name, value, options)', function () {
128203
})
129204

130205
describe('with "path" option', function () {
206+
131207
it('should serialize path', function () {
132-
assert.equal(cookie.serialize('foo', 'bar', { path: '/' }), 'foo=bar; Path=/')
133-
})
208+
const validPaths = [
209+
'/',
210+
'/login',
211+
'/foo.bar/baz',
212+
'/foo-bar',
213+
'/foo=bar?baz',
214+
'/foo"bar"',
215+
'/../foo/bar',
216+
'../foo/',
217+
'./'
218+
];
219+
220+
validPaths.forEach((path) => {
221+
assert.equal(
222+
cookie.serialize('foo', 'bar', { path }),
223+
`foo=bar; Path=${path}`,
224+
`Expected serialized value for path: "${path}"`
225+
);
226+
});
227+
});
134228

135229
it('should throw for invalid value', function () {
136-
assert.throws(cookie.serialize.bind(cookie, 'foo', 'bar', { path: '/\n' }),
137-
/option path is invalid/)
138-
})
230+
const invalidPaths = [
231+
'/\n',
232+
'/foo\u0000',
233+
'/foo bar',
234+
'/path/with\rnewline',
235+
'/path\\with\\backslash',
236+
'/; Path=/sensitive-data',
237+
'/login"><script>alert(1)</script>'
238+
];
239+
240+
invalidPaths.forEach((path) => {
241+
assert.throws(
242+
cookie.serialize.bind(cookie, 'foo', 'bar', { path }),
243+
/option path is invalid/,
244+
`Expected an error for invalid path: "${path}"`
245+
);
246+
});
247+
});
248+
139249
})
140250

141251
describe('with "priority" option', function () {

0 commit comments

Comments
 (0)