|
24 | 24 | const { |
25 | 25 | MathMin, |
26 | 26 | Symbol, |
| 27 | + Uint8Array, |
27 | 28 | } = primordials; |
28 | 29 | const { setImmediate } = require('timers'); |
29 | 30 |
|
@@ -205,14 +206,49 @@ function freeParser(parser, req, socket) { |
205 | 206 | } |
206 | 207 | } |
207 | 208 |
|
| 209 | +// Character code ranges for valid HTTP tokens |
| 210 | +// Valid chars: ^_`a-zA-Z-0-9!#$%&'*+.|~ |
| 211 | +// Based on RFC 7230 Section 3.2.6 token definition |
| 212 | +// See https://tools.ietf.org/html/rfc7230#section-3.2.6 |
208 | 213 | const tokenRegExp = /^[\^_`a-zA-Z\-0-9!#$%&'*+.|~]+$/; |
| 214 | +const validTokenChars = new Uint8Array([ |
| 215 | + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0-15 |
| 216 | + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 16-31 |
| 217 | + 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, // 32-47 (!"#$%&'()*+,-./) |
| 218 | + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, // 48-63 (0-9:;<=>?) |
| 219 | + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 64-79 (@A-O) |
| 220 | + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, // 80-95 (P-Z[\]^_) |
| 221 | + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 96-111 (`a-o) |
| 222 | + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, // 112-127 (p-z{|}~) |
| 223 | + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 128-143 |
| 224 | + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 144-159 |
| 225 | + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 160-175 |
| 226 | + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 176-191 |
| 227 | + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 192-207 |
| 228 | + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 208-223 |
| 229 | + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 224-239 |
| 230 | + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 240-255 |
| 231 | +]); |
| 232 | + |
209 | 233 | /** |
210 | 234 | * Verifies that the given val is a valid HTTP token |
211 | 235 | * per the rules defined in RFC 7230 |
212 | 236 | * See https://tools.ietf.org/html/rfc7230#section-3.2.6 |
213 | 237 | */ |
214 | 238 | function checkIsHttpToken(val) { |
215 | | - return tokenRegExp.test(val); |
| 239 | + if (val.length >= 10) { |
| 240 | + return tokenRegExp.test(val); |
| 241 | + } |
| 242 | + |
| 243 | + if (val.length === 0) return false; |
| 244 | + |
| 245 | + // Use lookup table for short strings, regex for longer ones |
| 246 | + for (let i = 0; i < val.length; i++) { |
| 247 | + if (!validTokenChars[val.charCodeAt(i)]) { |
| 248 | + return false; |
| 249 | + } |
| 250 | + } |
| 251 | + return true; |
216 | 252 | } |
217 | 253 |
|
218 | 254 | const headerCharRegex = /[^\t\x20-\x7e\x80-\xff]/; |
|
0 commit comments