| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 05f541b commit bcfe21d
16 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -218,17 +218,62 @@ class MemoryCacheStore extends EventEmitter { | |||
| 218 | 218 | } | |
| 219 | 219 | ||
| 220 | 220 | function findEntry (key, entries, now) { | |
| 221 | - return entries.find((entry) => ( | ||
| 222 | - entry.deleteAt > now && | ||
| 223 | - entry.method === key.method && | ||
| 224 | - (entry.vary == null || Object.keys(entry.vary).every(headerName => { | ||
| 225 | - if (entry.vary[headerName] === null) { | ||
| 226 | - return key.headers[headerName] === undefined | ||
| 221 | + for (let i = 0; i < entries.length; i++) { | ||
| 222 | + const entry = entries[i] | ||
| 223 | + if ( | ||
| 224 | + entry.deleteAt > now && | ||
| 225 | + entry.method === key.method && | ||
| 226 | + varyMatches(key, entry) | ||
| 227 | + ) { | ||
| 228 | + return entry | ||
| 229 | + } | ||
| 230 | + } | ||
| 231 | + } | ||
| 232 | + | ||
| 233 | + function varyMatches (key, entry) { | ||
| 234 | + if (entry.vary == null) { | ||
| 235 | + return true | ||
| 236 | + } | ||
| 237 | + | ||
| 238 | + for (const headerName in entry.vary) { | ||
| 239 | + if (Object.hasOwn(entry.vary, headerName) && !headerValueEquals(key.headers?.[headerName], entry.vary[headerName])) { | ||
| 240 | + return false | ||
| 241 | + } | ||
| 242 | + } | ||
| 243 | + | ||
| 244 | + return true | ||
| 245 | + } | ||
| 246 | + | ||
| 247 | + /** | ||
| 248 | + * @param {string|string[]|null|undefined} lhs | ||
| 249 | + * @param {string|string[]|null|undefined} rhs | ||
| 250 | + * @returns {boolean} | ||
| 251 | + */ | ||
| 252 | + function headerValueEquals (lhs, rhs) { | ||
| 253 | + if (lhs == null && rhs == null) { | ||
| 254 | + return true | ||
| 255 | + } | ||
| 256 | + | ||
| 257 | + if ((lhs == null && rhs != null) || | ||
| 258 | + (lhs != null && rhs == null)) { | ||
| 259 | + return false | ||
| 260 | + } | ||
| 261 | + | ||
| 262 | + if (Array.isArray(lhs) && Array.isArray(rhs)) { | ||
| 263 | + if (lhs.length !== rhs.length) { | ||
| 264 | + return false | ||
| 265 | + } | ||
| 266 | + | ||
| 267 | + for (let i = 0; i < lhs.length; i++) { | ||
| 268 | + if (lhs[i] !== rhs[i]) { | ||
| 269 | + return false | ||
| 227 | 270 | } | |
| 271 | + } | ||
| 272 | + | ||
| 273 | + return true | ||
| 274 | + } | ||
| 228 | 275 | ||
| 229 | - return entry.vary[headerName] === key.headers[headerName] | ||
| 230 | - })) | ||
| 231 | - )) | ||
| 276 | + return lhs === rhs | ||
| 232 | 277 | } | |
| 233 | 278 | ||
| 234 | 279 | module.exports = MemoryCacheStore | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -454,7 +454,13 @@ function headerValueEquals (lhs, rhs) { | |||
| 454 | 454 | return false | |
| 455 | 455 | } | |
| 456 | 456 | ||
| 457 | - return lhs.every((x, i) => x === rhs[i]) | ||
| 457 | + for (let i = 0; i < lhs.length; i++) { | ||
| 458 | + if (lhs[i] !== rhs[i]) { | ||
| 459 | + return false | ||
| 460 | + } | ||
| 461 | + } | ||
| 462 | + | ||
| 463 | + return true | ||
| 458 | 464 | } | |
| 459 | 465 | ||
| 460 | 466 | return lhs === rhs | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -390,7 +390,13 @@ function processHeader (request, key, val) { | |||
| 390 | 390 | } else if (typeof val[i] === 'object') { | |
| 391 | 391 | throw new InvalidArgumentError(`invalid ${key} header`) | |
| 392 | 392 | } else { | |
| 393 | - arr.push(`${val[i]}`) | ||
| 393 | + // Coerce primitives (and reject unsafe coercions such as functions | ||
| 394 | + // with a crafted toString/Symbol.toPrimitive). | ||
| 395 | + const str = `${val[i]}` | ||
| 396 | + if (!isValidHeaderValue(str)) { | ||
| 397 | + throw new InvalidArgumentError(`invalid ${key} header`) | ||
| 398 | + } | ||
| 399 | + arr.push(str) | ||
| 394 | 400 | } | |
| 395 | 401 | } | |
| 396 | 402 | val = arr | |
@@ -401,7 +407,12 @@ function processHeader (request, key, val) { | |||
| 401 | 407 | } else if (val === null) { | |
| 402 | 408 | val = '' | |
| 403 | 409 | } else { | |
| 410 | + // Coerce primitives (and reject unsafe coercions such as functions | ||
| 411 | + // with a crafted toString/Symbol.toPrimitive). | ||
| 404 | 412 | val = `${val}` | |
| 413 | + if (!isValidHeaderValue(val)) { | ||
| 414 | + throw new InvalidArgumentError(`invalid ${key} header`) | ||
| 415 | + } | ||
| 405 | 416 | } | |
| 406 | 417 | ||
| 407 | 418 | if (headerName === 'host') { | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -10,6 +10,7 @@ const { | |||
| 10 | 10 | RequestContentLengthMismatchError, | |
| 11 | 11 | ResponseContentLengthMismatchError, | |
| 12 | 12 | RequestAbortedError, | |
| 13 | + InvalidArgumentError, | ||
| 13 | 14 | HeadersTimeoutError, | |
| 14 | 15 | HeadersOverflowError, | |
| 15 | 16 | SocketError, | |
@@ -1134,8 +1135,16 @@ function writeH1 (client, request) { | |||
| 1134 | 1135 | } | |
| 1135 | 1136 | body = bodyStream.stream | |
| 1136 | 1137 | contentLength = bodyStream.length | |
| 1137 | - } else if (util.isBlobLike(body) && request.contentType == null && body.type) { | ||
| 1138 | - headers.push('content-type', body.type) | ||
| 1138 | + } else if (util.isBlobLike(body) && request.contentType == null) { | ||
| 1139 | + const contentType = body.type | ||
| 1140 | + if (contentType) { | ||
| 1141 | + const contentTypeValue = `${contentType}` | ||
| 1142 | + if (!util.isValidHeaderValue(contentTypeValue)) { | ||
| 1143 | + util.errorRequest(client, request, new InvalidArgumentError('invalid content-type header')) | ||
| 1144 | + return false | ||
| 1145 | + } | ||
| 1146 | + headers.push('content-type', contentTypeValue) | ||
| 1147 | + } | ||
| 1139 | 1148 | } | |
| 1140 | 1149 | ||
| 1141 | 1150 | if (body && typeof body.read === 'function') { | |
| Back | FazBrowse Home | New Git URL |
0 commit comments