Skip to content

Commit ff1bcd8

Browse files
Uzlopaktsctx
authored andcommitted
fix: isCTLExcludingHtab (nodejs#2790)
* fix: isCTLExcludingHtab * Update benchmarks/cookiesIsCTLExcludingHtab.mjs Co-authored-by: tsctx <91457664+tsctx@users.noreply.github.com> * Update lib/cookies/util.js Co-authored-by: tsctx <91457664+tsctx@users.noreply.github.com> * simplify * fix paths --------- Co-authored-by: tsctx <91457664+tsctx@users.noreply.github.com>
1 parent f05e00a commit ff1bcd8

3 files changed

Lines changed: 112 additions & 9 deletions

File tree

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { bench, group, run } from 'mitata'
2+
import { isCTLExcludingHtab } from '../lib/web/cookies/util.js'
3+
4+
const valid = 'Space=Cat; Secure; HttpOnly; Max-Age=2'
5+
const invalid = 'Space=Cat; Secure; HttpOnly; Max-Age=2\x7F'
6+
7+
group('isCTLExcludingHtab', () => {
8+
bench(`valid: ${valid}`, () => {
9+
return isCTLExcludingHtab(valid)
10+
})
11+
12+
bench(`invalid: ${invalid}`, () => {
13+
return isCTLExcludingHtab(invalid)
14+
})
15+
})
16+
17+
await run()

lib/web/cookies/util.js

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,22 +3,23 @@
33
const assert = require('node:assert')
44
const { kHeadersList } = require('../../core/symbols')
55

6+
/**
7+
* @param {string} value
8+
* @returns {boolean}
9+
*/
610
function isCTLExcludingHtab (value) {
7-
if (value.length === 0) {
8-
return false
9-
}
10-
11-
for (const char of value) {
12-
const code = char.charCodeAt(0)
11+
for (let i = 0; i < value.length; ++i) {
12+
const code = value.charCodeAt(i)
1313

1414
if (
15-
(code >= 0x00 || code <= 0x08) ||
16-
(code >= 0x0A || code <= 0x1F) ||
15+
(code >= 0x00 && code <= 0x08) ||
16+
(code >= 0x0A && code <= 0x1F) ||
1717
code === 0x7F
1818
) {
19-
return false
19+
return true
2020
}
2121
}
22+
return false
2223
}
2324

2425
/**
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
'use strict'
2+
3+
const { test, describe } = require('node:test')
4+
const { strictEqual } = require('node:assert')
5+
6+
const {
7+
isCTLExcludingHtab
8+
} = require('../../lib/web/cookies/util')
9+
10+
describe('isCTLExcludingHtab', () => {
11+
test('should return false for 0x00 - 0x08 characters', () => {
12+
strictEqual(isCTLExcludingHtab('\x00'), true)
13+
strictEqual(isCTLExcludingHtab('\x01'), true)
14+
strictEqual(isCTLExcludingHtab('\x02'), true)
15+
strictEqual(isCTLExcludingHtab('\x03'), true)
16+
strictEqual(isCTLExcludingHtab('\x04'), true)
17+
strictEqual(isCTLExcludingHtab('\x05'), true)
18+
strictEqual(isCTLExcludingHtab('\x06'), true)
19+
strictEqual(isCTLExcludingHtab('\x07'), true)
20+
strictEqual(isCTLExcludingHtab('\x08'), true)
21+
})
22+
23+
test('should return false for 0x09 HTAB character', () => {
24+
strictEqual(isCTLExcludingHtab('\x09'), false)
25+
})
26+
27+
test('should return false for 0x0A - 0x1F characters', () => {
28+
strictEqual(isCTLExcludingHtab('\x0A'), true)
29+
strictEqual(isCTLExcludingHtab('\x0B'), true)
30+
strictEqual(isCTLExcludingHtab('\x0C'), true)
31+
strictEqual(isCTLExcludingHtab('\x0D'), true)
32+
strictEqual(isCTLExcludingHtab('\x0E'), true)
33+
strictEqual(isCTLExcludingHtab('\x0F'), true)
34+
strictEqual(isCTLExcludingHtab('\x10'), true)
35+
strictEqual(isCTLExcludingHtab('\x11'), true)
36+
strictEqual(isCTLExcludingHtab('\x12'), true)
37+
strictEqual(isCTLExcludingHtab('\x13'), true)
38+
strictEqual(isCTLExcludingHtab('\x14'), true)
39+
strictEqual(isCTLExcludingHtab('\x15'), true)
40+
strictEqual(isCTLExcludingHtab('\x16'), true)
41+
strictEqual(isCTLExcludingHtab('\x17'), true)
42+
strictEqual(isCTLExcludingHtab('\x18'), true)
43+
strictEqual(isCTLExcludingHtab('\x19'), true)
44+
strictEqual(isCTLExcludingHtab('\x1A'), true)
45+
strictEqual(isCTLExcludingHtab('\x1B'), true)
46+
strictEqual(isCTLExcludingHtab('\x1C'), true)
47+
strictEqual(isCTLExcludingHtab('\x1D'), true)
48+
strictEqual(isCTLExcludingHtab('\x1E'), true)
49+
strictEqual(isCTLExcludingHtab('\x1F'), true)
50+
})
51+
52+
test('should return false for a 0x7F character', t => {
53+
strictEqual(isCTLExcludingHtab('\x7F'), true)
54+
})
55+
56+
test('should return false for a 0x20 / space character', t => {
57+
strictEqual(isCTLExcludingHtab(' '), false)
58+
})
59+
60+
test('should return false for a printable character', t => {
61+
strictEqual(isCTLExcludingHtab('A'), false)
62+
strictEqual(isCTLExcludingHtab('Z'), false)
63+
strictEqual(isCTLExcludingHtab('a'), false)
64+
strictEqual(isCTLExcludingHtab('z'), false)
65+
strictEqual(isCTLExcludingHtab('!'), false)
66+
})
67+
68+
test('should return false for an empty string', () => {
69+
strictEqual(isCTLExcludingHtab(''), false)
70+
})
71+
72+
test('all printable characters (0x20 - 0x7E)', () => {
73+
for (let i = 0x20; i < 0x7F; i++) {
74+
strictEqual(isCTLExcludingHtab(String.fromCharCode(i)), false)
75+
}
76+
})
77+
78+
test('valid case', () => {
79+
strictEqual(isCTLExcludingHtab('Space=Cat; Secure; HttpOnly; Max-Age=2'), false)
80+
})
81+
82+
test('invalid case', () => {
83+
strictEqual(isCTLExcludingHtab('Space=Cat; Secure; HttpOnly; Max-Age=2\x7F'), true)
84+
})
85+
})

0 commit comments

Comments
 (0)