Skip to content

Commit d5809f4

Browse files
⬆️📜 Update patch updates to v7.8.5 (#199)
Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
1 parent e1cbea9 commit d5809f4

5 files changed

Lines changed: 280 additions & 90 deletions

File tree

dist/index.js

Lines changed: 130 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -455,17 +455,21 @@ const replaceTildes = (comp, options) => {
455455

456456
const replaceTilde = (comp, options) => {
457457
const r = options.loose ? re[t.TILDELOOSE] : re[t.TILDE]
458+
// if we're including prereleases in the match, then the lower bound is
459+
// -0, the lowest possible prerelease value, just like x-ranges and carets.
460+
// this keeps `~1.2` equivalent to the `1.2.x` x-range it's documented as.
461+
const z = options.includePrerelease ? '-0' : ''
458462
return comp.replace(r, (_, M, m, p, pr) => {
459463
debug('tilde', comp, _, M, m, p, pr)
460464
let ret
461465

462466
if (isX(M)) {
463467
ret = ''
464468
} else if (isX(m)) {
465-
ret = `>=${M}.0.0 <${+M + 1}.0.0-0`
469+
ret = `>=${M}.0.0${z} <${+M + 1}.0.0-0`
466470
} else if (isX(p)) {
467471
// ~1.2 == >=1.2.0 <1.3.0-0
468-
ret = `>=${M}.${m}.0 <${M}.${+m + 1}.0-0`
472+
ret = `>=${M}.${m}.0${z} <${M}.${+m + 1}.0-0`
469473
} else if (pr) {
470474
debug('replaceTilde pr', pr)
471475
ret = `>=${M}.${m}.${p}-${pr
@@ -7522,6 +7526,9 @@ const EMPTY_BUF = Buffer.alloc(0)
75227526
const FastBuffer = Buffer[Symbol.species]
75237527
const addListener = util.addListener
75247528
const removeAllListeners = util.removeAllListeners
7529+
const kIdleSocketValidation = Symbol('kIdleSocketValidation')
7530+
const kIdleSocketValidationTimeout = Symbol('kIdleSocketValidationTimeout')
7531+
const kSocketUsed = Symbol('kSocketUsed')
75257532

75267533
let extractBody
75277534

@@ -7836,6 +7843,11 @@ class Parser {
78367843
return -1
78377844
}
78387845

7846+
if (client[kRunning] === 0) {
7847+
util.destroy(socket, new SocketError('bad response', util.getSocketInfo(socket)))
7848+
return -1
7849+
}
7850+
78397851
const request = client[kQueue][client[kRunningIdx]]
78407852
if (!request) {
78417853
return -1
@@ -7939,6 +7951,11 @@ class Parser {
79397951
return -1
79407952
}
79417953

7954+
if (client[kRunning] === 0) {
7955+
util.destroy(socket, new SocketError('bad response', util.getSocketInfo(socket)))
7956+
return -1
7957+
}
7958+
79427959
const request = client[kQueue][client[kRunningIdx]]
79437960

79447961
/* istanbul ignore next: difficult to make a test case for */
@@ -8112,6 +8129,7 @@ class Parser {
81128129
request.onComplete(headers)
81138130

81148131
client[kQueue][client[kRunningIdx]++] = null
8132+
socket[kSocketUsed] = true
81158133

81168134
if (socket[kWriting]) {
81178135
assert(client[kRunning] === 0)
@@ -8170,6 +8188,9 @@ async function connectH1 (client, socket) {
81708188
socket[kWriting] = false
81718189
socket[kReset] = false
81728190
socket[kBlocking] = false
8191+
socket[kIdleSocketValidation] = 0
8192+
socket[kIdleSocketValidationTimeout] = null
8193+
socket[kSocketUsed] = false
81738194
socket[kParser] = new Parser(client, socket, llhttpInstance)
81748195

81758196
addListener(socket, 'error', function (err) {
@@ -8216,6 +8237,8 @@ async function connectH1 (client, socket) {
82168237
const client = this[kClient]
82178238
const parser = this[kParser]
82188239

8240+
clearIdleSocketValidation(this)
8241+
82198242
if (parser) {
82208243
if (!this[kError] && parser.statusCode && !parser.shouldKeepAlive) {
82218244
this[kError] = parser.finish() || this[kError]
@@ -8281,7 +8304,7 @@ async function connectH1 (client, socket) {
82818304
return socket.destroyed
82828305
},
82838306
busy (request) {
8284-
if (socket[kWriting] || socket[kReset] || socket[kBlocking]) {
8307+
if (socket[kWriting] || socket[kReset] || socket[kBlocking] || socket[kIdleSocketValidation] === 1) {
82858308
return true
82868309
}
82878310

@@ -8319,6 +8342,31 @@ async function connectH1 (client, socket) {
83198342
}
83208343
}
83218344

8345+
function clearIdleSocketValidation (socket) {
8346+
if (socket[kIdleSocketValidationTimeout]) {
8347+
clearTimeout(socket[kIdleSocketValidationTimeout])
8348+
socket[kIdleSocketValidationTimeout] = null
8349+
}
8350+
8351+
socket[kIdleSocketValidation] = 0
8352+
}
8353+
8354+
function scheduleIdleSocketValidation (client, socket) {
8355+
socket[kIdleSocketValidation] = 1
8356+
socket[kIdleSocketValidationTimeout] = setTimeout(() => {
8357+
socket[kIdleSocketValidationTimeout] = null
8358+
socket[kIdleSocketValidation] = 2
8359+
8360+
if (client[kSocket] === socket && !socket.destroyed) {
8361+
client[kResume]()
8362+
}
8363+
}, 0)
8364+
socket[kIdleSocketValidationTimeout].unref?.()
8365+
}
8366+
8367+
/**
8368+
* @param {import('./client.js')} client
8369+
*/
83228370
function resumeH1 (client) {
83238371
const socket = client[kSocket]
83248372

@@ -8333,6 +8381,32 @@ function resumeH1 (client) {
83338381
socket[kNoRef] = false
83348382
}
83358383

8384+
if (client[kRunning] === 0 && client[kPending] > 0 && socket[kSocketUsed]) {
8385+
if (socket[kIdleSocketValidation] === 0) {
8386+
scheduleIdleSocketValidation(client, socket)
8387+
socket[kParser].readMore()
8388+
if (socket.destroyed) {
8389+
return
8390+
}
8391+
return
8392+
}
8393+
8394+
if (socket[kIdleSocketValidation] === 1) {
8395+
socket[kParser].readMore()
8396+
if (socket.destroyed) {
8397+
return
8398+
}
8399+
return
8400+
}
8401+
}
8402+
8403+
if (client[kRunning] === 0) {
8404+
socket[kParser].readMore()
8405+
if (socket.destroyed) {
8406+
return
8407+
}
8408+
}
8409+
83368410
if (client[kSize] === 0) {
83378411
if (socket[kParser].timeoutType !== TIMEOUT_KEEP_ALIVE) {
83388412
socket[kParser].setTimeout(client[kKeepAliveTimeoutValue], TIMEOUT_KEEP_ALIVE)
@@ -8426,6 +8500,7 @@ function writeH1 (client, request) {
84268500
}
84278501

84288502
const socket = client[kSocket]
8503+
clearIdleSocketValidation(socket)
84298504

84308505
const abort = (err) => {
84318506
if (request.aborted || request.completed) {
@@ -10295,6 +10370,7 @@ class DispatcherBase extends Dispatcher {
1029510370

1029610371
get webSocketOptions () {
1029710372
return {
10373+
maxFragments: this[kWebSocketOptions].maxFragments ?? 131072,
1029810374
maxPayloadSize: this[kWebSocketOptions].maxPayloadSize ?? 128 * 1024 * 1024
1029910375
}
1030010376
}
@@ -16194,32 +16270,25 @@ function parseUnparsedAttributes (unparsedAttributes, cookieAttributeList = {})
1619416270
// If the attribute-name case-insensitively matches the string
1619516271
// "SameSite", the user agent MUST process the cookie-av as follows:
1619616272

16197-
// 1. Let enforcement be "Default".
16198-
let enforcement = 'Default'
16199-
1620016273
const attributeValueLowercase = attributeValue.toLowerCase()
16201-
// 2. If cookie-av's attribute-value is a case-insensitive match for
16202-
// "None", set enforcement to "None".
16203-
if (attributeValueLowercase.includes('none')) {
16204-
enforcement = 'None'
16205-
}
1620616274

16207-
// 3. If cookie-av's attribute-value is a case-insensitive match for
16208-
// "Strict", set enforcement to "Strict".
16209-
if (attributeValueLowercase.includes('strict')) {
16210-
enforcement = 'Strict'
16275+
// 1. If cookie-av's attribute-value is a case-insensitive match for
16276+
// "None", append an attribute to the cookie-attribute-list with an
16277+
// attribute-name of "SameSite" and an attribute-value of "None".
16278+
if (attributeValueLowercase === 'none') {
16279+
cookieAttributeList.sameSite = 'None'
16280+
} else if (attributeValueLowercase === 'strict') {
16281+
// 2. If cookie-av's attribute-value is a case-insensitive match for
16282+
// "Strict", append an attribute to the cookie-attribute-list with
16283+
// an attribute-name of "SameSite" and an attribute-value of
16284+
// "Strict".
16285+
cookieAttributeList.sameSite = 'Strict'
16286+
} else if (attributeValueLowercase === 'lax') {
16287+
// 3. If cookie-av's attribute-value is a case-insensitive match for
16288+
// "Lax", append an attribute to the cookie-attribute-list with an
16289+
// attribute-name of "SameSite" and an attribute-value of "Lax".
16290+
cookieAttributeList.sameSite = 'Lax'
1621116291
}
16212-
16213-
// 4. If cookie-av's attribute-value is a case-insensitive match for
16214-
// "Lax", set enforcement to "Lax".
16215-
if (attributeValueLowercase.includes('lax')) {
16216-
enforcement = 'Lax'
16217-
}
16218-
16219-
// 5. Append an attribute to the cookie-attribute-list with an
16220-
// attribute-name of "SameSite" and an attribute-value of
16221-
// enforcement.
16222-
cookieAttributeList.sameSite = enforcement
1622316292
} else {
1622416293
cookieAttributeList.unparsed ??= []
1622516294

@@ -29015,6 +29084,11 @@ const { closeWebSocketConnection } = __nccwpck_require__(6897)
2901529084
const { PerMessageDeflate } = __nccwpck_require__(9469)
2901629085
const { MessageSizeExceededError } = __nccwpck_require__(8707)
2901729086

29087+
function failWebsocketConnectionWithCode (ws, code, reason) {
29088+
closeWebSocketConnection(ws, code, reason, Buffer.byteLength(reason))
29089+
failWebsocketConnection(ws, reason)
29090+
}
29091+
2901829092
// This code was influenced by ws released under the MIT license.
2901929093
// Copyright (c) 2011 Einar Otto Stangvik <einaros@gmail.com>
2902029094
// Copyright (c) 2013 Arnout Kazemier and contributors
@@ -29034,19 +29108,23 @@ class ByteParser extends Writable {
2903429108
/** @type {Map<string, PerMessageDeflate>} */
2903529109
#extensions
2903629110

29111+
/** @type {number} */
29112+
#maxFragments
29113+
2903729114
/** @type {number} */
2903829115
#maxPayloadSize
2903929116

2904029117
/**
2904129118
* @param {import('./websocket').WebSocket} ws
2904229119
* @param {Map<string, string>|null} extensions
29043-
* @param {{ maxPayloadSize?: number }} [options]
29120+
* @param {{ maxFragments?: number, maxPayloadSize?: number }} [options]
2904429121
*/
2904529122
constructor (ws, extensions, options = {}) {
2904629123
super()
2904729124

2904829125
this.ws = ws
2904929126
this.#extensions = extensions == null ? new Map() : extensions
29127+
this.#maxFragments = options.maxFragments ?? 0
2905029128
this.#maxPayloadSize = options.maxPayloadSize ?? 0
2905129129

2905229130
if (this.#extensions.has('permessage-deflate')) {
@@ -29070,9 +29148,9 @@ class ByteParser extends Writable {
2907029148
if (
2907129149
this.#maxPayloadSize > 0 &&
2907229150
!isControlFrame(this.#info.opcode) &&
29073-
this.#info.payloadLength > this.#maxPayloadSize
29151+
this.#info.payloadLength + this.#fragmentsBytes > this.#maxPayloadSize
2907429152
) {
29075-
failWebsocketConnection(this.ws, 'Payload size exceeds maximum allowed size')
29153+
failWebsocketConnectionWithCode(this.ws, 1009, 'Payload size exceeds maximum allowed size')
2907629154
return false
2907729155
}
2907829156

@@ -29237,10 +29315,12 @@ class ByteParser extends Writable {
2923729315
this.#state = parserStates.INFO
2923829316
} else {
2923929317
if (!this.#info.compressed) {
29240-
this.writeFragments(body)
29318+
if (!this.writeFragments(body)) {
29319+
return
29320+
}
2924129321

2924229322
if (this.#maxPayloadSize > 0 && this.#fragmentsBytes > this.#maxPayloadSize) {
29243-
failWebsocketConnection(this.ws, new MessageSizeExceededError().message)
29323+
failWebsocketConnectionWithCode(this.ws, 1009, new MessageSizeExceededError().message)
2924429324
return
2924529325
}
2924629326

@@ -29259,14 +29339,17 @@ class ByteParser extends Writable {
2925929339
this.#info.fin,
2926029340
(error, data) => {
2926129341
if (error) {
29262-
failWebsocketConnection(this.ws, error.message)
29342+
const code = error instanceof MessageSizeExceededError ? 1009 : 1007
29343+
failWebsocketConnectionWithCode(this.ws, code, error.message)
2926329344
return
2926429345
}
2926529346

29266-
this.writeFragments(data)
29347+
if (!this.writeFragments(data)) {
29348+
return
29349+
}
2926729350

2926829351
if (this.#maxPayloadSize > 0 && this.#fragmentsBytes > this.#maxPayloadSize) {
29269-
failWebsocketConnection(this.ws, new MessageSizeExceededError().message)
29352+
failWebsocketConnectionWithCode(this.ws, 1009, new MessageSizeExceededError().message)
2927029353
return
2927129354
}
2927229355

@@ -29336,8 +29419,17 @@ class ByteParser extends Writable {
2933629419
}
2933729420

2933829421
writeFragments (fragment) {
29422+
if (
29423+
this.#maxFragments > 0 &&
29424+
this.#fragments.length === this.#maxFragments
29425+
) {
29426+
failWebsocketConnectionWithCode(this.ws, 1008, 'Too many message fragments')
29427+
return false
29428+
}
29429+
2933929430
this.#fragmentsBytes += fragment.length
2934029431
this.#fragments.push(fragment)
29432+
return true
2934129433
}
2934229434

2934329435
consumeFragments () {
@@ -30386,9 +30478,12 @@ class WebSocket extends EventTarget {
3038630478
// once this happens, the connection is open
3038730479
this[kResponse] = response
3038830480

30389-
const maxPayloadSize = this[kController]?.dispatcher?.webSocketOptions?.maxPayloadSize
30481+
const webSocketOptions = this[kController]?.dispatcher?.webSocketOptions
30482+
const maxFragments = webSocketOptions?.maxFragments
30483+
const maxPayloadSize = webSocketOptions?.maxPayloadSize
3039030484

3039130485
const parser = new ByteParser(this, parsedExtensions, {
30486+
maxFragments,
3039230487
maxPayloadSize
3039330488
})
3039430489
parser.on('drain', onParserDrain)

dist/index.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)