Skip to content

Commit e0e99bb

Browse files
author
GitHub Actions
committed
(chore) updating dist
1 parent 37d964d commit e0e99bb

1 file changed

Lines changed: 135 additions & 16 deletions

File tree

dist/index.js

Lines changed: 135 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -34943,6 +34943,24 @@ class SecureProxyConnectionError extends UndiciError {
3494334943
[kSecureProxyConnectionError] = true
3494434944
}
3494534945

34946+
const kMessageSizeExceededError = Symbol.for('undici.error.UND_ERR_WS_MESSAGE_SIZE_EXCEEDED')
34947+
class MessageSizeExceededError extends UndiciError {
34948+
constructor (message) {
34949+
super(message)
34950+
this.name = 'MessageSizeExceededError'
34951+
this.message = message || 'Max decompressed message size exceeded'
34952+
this.code = 'UND_ERR_WS_MESSAGE_SIZE_EXCEEDED'
34953+
}
34954+
34955+
static [Symbol.hasInstance] (instance) {
34956+
return instance && instance[kMessageSizeExceededError] === true
34957+
}
34958+
34959+
get [kMessageSizeExceededError] () {
34960+
return true
34961+
}
34962+
}
34963+
3494634964
module.exports = {
3494734965
AbortError,
3494834966
HTTPParserError,
@@ -34966,7 +34984,8 @@ module.exports = {
3496634984
ResponseExceededMaxSizeError,
3496734985
RequestRetryError,
3496834986
ResponseError,
34969-
SecureProxyConnectionError
34987+
SecureProxyConnectionError,
34988+
MessageSizeExceededError
3497034989
}
3497134990

3497234991

@@ -35044,6 +35063,10 @@ class Request {
3504435063
throw new InvalidArgumentError('upgrade must be a string')
3504535064
}
3504635065

35066+
if (upgrade && !isValidHeaderValue(upgrade)) {
35067+
throw new InvalidArgumentError('invalid upgrade header')
35068+
}
35069+
3504735070
if (headersTimeout != null && (!Number.isFinite(headersTimeout) || headersTimeout < 0)) {
3504835071
throw new InvalidArgumentError('invalid headersTimeout')
3504935072
}
@@ -35338,13 +35361,19 @@ function processHeader (request, key, val) {
3533835361
val = `${val}`
3533935362
}
3534035363

35341-
if (request.host === null && headerName === 'host') {
35364+
if (headerName === 'host') {
35365+
if (request.host !== null) {
35366+
throw new InvalidArgumentError('duplicate host header')
35367+
}
3534235368
if (typeof val !== 'string') {
3534335369
throw new InvalidArgumentError('invalid host header')
3534435370
}
3534535371
// Consumed by Client
3534635372
request.host = val
35347-
} else if (request.contentLength === null && headerName === 'content-length') {
35373+
} else if (headerName === 'content-length') {
35374+
if (request.contentLength !== null) {
35375+
throw new InvalidArgumentError('duplicate content-length header')
35376+
}
3534835377
request.contentLength = parseInt(val, 10)
3534935378
if (!Number.isFinite(request.contentLength)) {
3535035379
throw new InvalidArgumentError('invalid content-length header')
@@ -58135,20 +58164,38 @@ module.exports = {
5813558164

5813658165
const { createInflateRaw, Z_DEFAULT_WINDOWBITS } = __nccwpck_require__(8522)
5813758166
const { isValidClientWindowBits } = __nccwpck_require__(8625)
58167+
const { MessageSizeExceededError } = __nccwpck_require__(8707)
5813858168

5813958169
const tail = Buffer.from([0x00, 0x00, 0xff, 0xff])
5814058170
const kBuffer = Symbol('kBuffer')
5814158171
const kLength = Symbol('kLength')
5814258172

58173+
// Default maximum decompressed message size: 4 MB
58174+
const kDefaultMaxDecompressedSize = 4 * 1024 * 1024
58175+
5814358176
class PerMessageDeflate {
5814458177
/** @type {import('node:zlib').InflateRaw} */
5814558178
#inflate
5814658179

5814758180
#options = {}
5814858181

58149-
constructor (extensions) {
58182+
/** @type {number} */
58183+
#maxDecompressedSize
58184+
58185+
/** @type {boolean} */
58186+
#aborted = false
58187+
58188+
/** @type {Function|null} */
58189+
#currentCallback = null
58190+
58191+
/**
58192+
* @param {Map<string, string>} extensions
58193+
* @param {{ maxDecompressedMessageSize?: number }} [options]
58194+
*/
58195+
constructor (extensions, options = {}) {
5815058196
this.#options.serverNoContextTakeover = extensions.has('server_no_context_takeover')
5815158197
this.#options.serverMaxWindowBits = extensions.get('server_max_window_bits')
58198+
this.#maxDecompressedSize = options.maxDecompressedMessageSize ?? kDefaultMaxDecompressedSize
5815258199
}
5815358200

5815458201
decompress (chunk, fin, callback) {
@@ -58157,6 +58204,11 @@ class PerMessageDeflate {
5815758204
// payload of the message.
5815858205
// 2. Decompress the resulting data using DEFLATE.
5815958206

58207+
if (this.#aborted) {
58208+
callback(new MessageSizeExceededError())
58209+
return
58210+
}
58211+
5816058212
if (!this.#inflate) {
5816158213
let windowBits = Z_DEFAULT_WINDOWBITS
5816258214

@@ -58169,13 +58221,37 @@ class PerMessageDeflate {
5816958221
windowBits = Number.parseInt(this.#options.serverMaxWindowBits)
5817058222
}
5817158223

58172-
this.#inflate = createInflateRaw({ windowBits })
58224+
try {
58225+
this.#inflate = createInflateRaw({ windowBits })
58226+
} catch (err) {
58227+
callback(err)
58228+
return
58229+
}
5817358230
this.#inflate[kBuffer] = []
5817458231
this.#inflate[kLength] = 0
5817558232

5817658233
this.#inflate.on('data', (data) => {
58177-
this.#inflate[kBuffer].push(data)
58234+
if (this.#aborted) {
58235+
return
58236+
}
58237+
5817858238
this.#inflate[kLength] += data.length
58239+
58240+
if (this.#inflate[kLength] > this.#maxDecompressedSize) {
58241+
this.#aborted = true
58242+
this.#inflate.removeAllListeners()
58243+
this.#inflate.destroy()
58244+
this.#inflate = null
58245+
58246+
if (this.#currentCallback) {
58247+
const cb = this.#currentCallback
58248+
this.#currentCallback = null
58249+
cb(new MessageSizeExceededError())
58250+
}
58251+
return
58252+
}
58253+
58254+
this.#inflate[kBuffer].push(data)
5817958255
})
5818058256

5818158257
this.#inflate.on('error', (err) => {
@@ -58184,16 +58260,22 @@ class PerMessageDeflate {
5818458260
})
5818558261
}
5818658262

58263+
this.#currentCallback = callback
5818758264
this.#inflate.write(chunk)
5818858265
if (fin) {
5818958266
this.#inflate.write(tail)
5819058267
}
5819158268

5819258269
this.#inflate.flush(() => {
58270+
if (this.#aborted || !this.#inflate) {
58271+
return
58272+
}
58273+
5819358274
const full = Buffer.concat(this.#inflate[kBuffer], this.#inflate[kLength])
5819458275

5819558276
this.#inflate[kBuffer].length = 0
5819658277
this.#inflate[kLength] = 0
58278+
this.#currentCallback = null
5819758279

5819858280
callback(null, full)
5819958281
})
@@ -58248,14 +58330,23 @@ class ByteParser extends Writable {
5824858330
/** @type {Map<string, PerMessageDeflate>} */
5824958331
#extensions
5825058332

58251-
constructor (ws, extensions) {
58333+
/** @type {{ maxDecompressedMessageSize?: number }} */
58334+
#options
58335+
58336+
/**
58337+
* @param {import('./websocket').WebSocket} ws
58338+
* @param {Map<string, string>|null} extensions
58339+
* @param {{ maxDecompressedMessageSize?: number }} [options]
58340+
*/
58341+
constructor (ws, extensions, options = {}) {
5825258342
super()
5825358343

5825458344
this.ws = ws
5825558345
this.#extensions = extensions == null ? new Map() : extensions
58346+
this.#options = options
5825658347

5825758348
if (this.#extensions.has('permessage-deflate')) {
58258-
this.#extensions.set('permessage-deflate', new PerMessageDeflate(extensions))
58349+
this.#extensions.set('permessage-deflate', new PerMessageDeflate(extensions, options))
5825958350
}
5826058351
}
5826158352

@@ -58390,21 +58481,20 @@ class ByteParser extends Writable {
5839058481

5839158482
const buffer = this.consume(8)
5839258483
const upper = buffer.readUInt32BE(0)
58484+
const lower = buffer.readUInt32BE(4)
5839358485

5839458486
// 2^31 is the maximum bytes an arraybuffer can contain
5839558487
// on 32-bit systems. Although, on 64-bit systems, this is
5839658488
// 2^53-1 bytes.
5839758489
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Invalid_array_length
5839858490
// https://source.chromium.org/chromium/chromium/src/+/main:v8/src/common/globals.h;drc=1946212ac0100668f14eb9e2843bdd846e510a1e;bpv=1;bpt=1;l=1275
5839958491
// https://source.chromium.org/chromium/chromium/src/+/main:v8/src/objects/js-array-buffer.h;l=34;drc=1946212ac0100668f14eb9e2843bdd846e510a1e
58400-
if (upper > 2 ** 31 - 1) {
58492+
if (upper !== 0 || lower > 2 ** 31 - 1) {
5840158493
failWebsocketConnection(this.ws, 'Received payload length > 2^31 bytes.')
5840258494
return
5840358495
}
5840458496

58405-
const lower = buffer.readUInt32BE(4)
58406-
58407-
this.#info.payloadLength = (upper << 8) + lower
58497+
this.#info.payloadLength = lower
5840858498
this.#state = parserStates.READ_DATA
5840958499
} else if (this.#state === parserStates.READ_DATA) {
5841058500
if (this.#byteOffset < this.#info.payloadLength) {
@@ -58434,7 +58524,7 @@ class ByteParser extends Writable {
5843458524
} else {
5843558525
this.#extensions.get('permessage-deflate').decompress(body, this.#info.fin, (error, data) => {
5843658526
if (error) {
58437-
closeWebSocketConnection(this.ws, 1007, error.message, error.message.length)
58527+
failWebsocketConnection(this.ws, error.message)
5843858528
return
5843958529
}
5844058530

@@ -59041,6 +59131,12 @@ function parseExtensions (extensions) {
5904159131
* @param {string} value
5904259132
*/
5904359133
function isValidClientWindowBits (value) {
59134+
// Must have at least one character
59135+
if (value.length === 0) {
59136+
return false
59137+
}
59138+
59139+
// Check all characters are ASCII digits
5904459140
for (let i = 0; i < value.length; i++) {
5904559141
const byte = value.charCodeAt(i)
5904659142

@@ -59049,7 +59145,9 @@ function isValidClientWindowBits (value) {
5904959145
}
5905059146
}
5905159147

59052-
return true
59148+
// Check numeric range: zlib requires windowBits in range 8-15
59149+
const num = Number.parseInt(value, 10)
59150+
return num >= 8 && num <= 15
5905359151
}
5905459152

5905559153
// https://nodejs.org/api/intl.html#detecting-internationalization-support
@@ -59141,6 +59239,9 @@ class WebSocket extends EventTarget {
5914159239
/** @type {SendQueue} */
5914259240
#sendQueue
5914359241

59242+
/** @type {{ maxDecompressedMessageSize?: number }} */
59243+
#options
59244+
5914459245
/**
5914559246
* @param {string} url
5914659247
* @param {string|string[]} protocols
@@ -59214,6 +59315,11 @@ class WebSocket extends EventTarget {
5921459315
// 10. Set this's url to urlRecord.
5921559316
this[kWebSocketURL] = new URL(urlRecord.href)
5921659317

59318+
// Store options for later use (e.g., maxDecompressedMessageSize)
59319+
this.#options = {
59320+
maxDecompressedMessageSize: options.maxDecompressedMessageSize
59321+
}
59322+
5921759323
// 11. Let client be this's relevant settings object.
5921859324
const client = environmentSettingsObject.settingsObject
5921959325

@@ -59528,11 +59634,11 @@ class WebSocket extends EventTarget {
5952859634
* @see https://websockets.spec.whatwg.org/#feedback-from-the-protocol
5952959635
*/
5953059636
#onConnectionEstablished (response, parsedExtensions) {
59531-
// processResponse is called when the "responses header list has been received and initialized."
59637+
// processResponse is called when the "response's header list has been received and initialized."
5953259638
// once this happens, the connection is open
5953359639
this[kResponse] = response
5953459640

59535-
const parser = new ByteParser(this, parsedExtensions)
59641+
const parser = new ByteParser(this, parsedExtensions, this.#options)
5953659642
parser.on('drain', onParserDrain)
5953759643
parser.on('error', onParserError.bind(this))
5953859644

@@ -59635,6 +59741,19 @@ webidl.converters.WebSocketInit = webidl.dictionaryConverter([
5963559741
{
5963659742
key: 'headers',
5963759743
converter: webidl.nullableConverter(webidl.converters.HeadersInit)
59744+
},
59745+
{
59746+
key: 'maxDecompressedMessageSize',
59747+
converter: webidl.nullableConverter((V) => {
59748+
V = webidl.converters['unsigned long long'](V)
59749+
if (V <= 0) {
59750+
throw webidl.errors.exception({
59751+
header: 'WebSocket constructor',
59752+
message: 'maxDecompressedMessageSize must be greater than 0'
59753+
})
59754+
}
59755+
return V
59756+
})
5963859757
}
5963959758
])
5964059759

0 commit comments

Comments
 (0)