node_modules: update (#358)

Co-authored-by: dawidd6 <9713907+dawidd6@users.noreply.github.com>
This commit is contained in:
Dawid Dziurlaanddawidd6 authored and GitHub committed 2026-10-29 12:32:12 +01:00
1 parent 0d58990203
commit b6b2177ec4
13 files changed
+154 -34

No files matched your search

+91 -10
View File
@@ -1,4 +1,5 @@
'use strict'
const buffer = require('node:buffer')
const { Transform } = require('node:stream')
const { isASCIINumber, isValidLastEventId } = require('./util')
@@ -23,11 +24,19 @@ const COLON = 0x3A
*/
const SPACE = 0x20
const defaultMaxEventSize = buffer.kStringMaxLength
const DATA = Buffer.from('data')
const EVENT = Buffer.from('event')
const ID = Buffer.from('id')
const RETRY = Buffer.from('retry')
// Each data field creates a string node, and each unconsumed input chunk keeps
// a Buffer wrapper. The absolute ceiling protects the large default byte limit.
const minParserItems = 1024
const maxParserItems = 131072
const bytesPerParserItem = 128
function isASCIINumberBytes (buffer, start) {
if (start >= buffer.length) {
return false
@@ -66,6 +75,12 @@ function isFieldName (line, length, field) {
return true
}
function createMaxEventSizeExceededError () {
const error = new Error('EventSource message size exceeded')
error.aborted = false
return error
}
/**
* @typedef {object} EventSourceStreamEvent
* @type {object}
@@ -114,6 +129,13 @@ class EventSourceStream extends Transform {
pos = 0
lineChunkIndex = 0
linePos = 0
lineLength = 0
eventSize = 0
eventFieldSizes = { data: 0, event: 0, id: 0, retry: 0 }
dataLineCount = 0
maxEventSize
maxDataLines
maxBufferedChunks
event = {
data: undefined,
@@ -124,6 +146,7 @@ class EventSourceStream extends Transform {
/**
* @param {object} options
* @param {number} [options.maxEventSize]
* @param {eventSourceSettings} options.eventSourceSettings
* @param {Function} [options.push]
*/
@@ -135,6 +158,12 @@ class EventSourceStream extends Transform {
super(options)
this.state = options.eventSourceSettings || {}
this.maxEventSize = options.maxEventSize ?? defaultMaxEventSize
const parserItemLimit = this.maxEventSize > 0
? Math.min(maxParserItems, Math.max(minParserItems, Math.floor(this.maxEventSize / bytesPerParserItem)))
: 0
this.maxDataLines = parserItemLimit
this.maxBufferedChunks = parserItemLimit
if (options.push) {
this.push = options.push
}
@@ -152,6 +181,14 @@ class EventSourceStream extends Transform {
return
}
// A leading line ending can immediately release the currently buffered
// line, even when it uses the final allowed chunk slot.
if (this.maxEventSize > 0 &&
this.chunks.length >= this.maxBufferedChunks &&
chunk[0] !== LF && chunk[0] !== CR) {
callback(createMaxEventSizeExceededError())
return
}
this.chunks.push(chunk)
// Strip leading byte-order-mark if we opened the stream and started
@@ -230,7 +267,12 @@ class EventSourceStream extends Transform {
// In any case, we can process the line as we reached an
// end-of-line character
this.parseLine(this.readLine(), this.event)
try {
this.parseLine(this.readLine(), this.event)
} catch (error) {
callback(error)
return
}
this.consumeCurrentByte()
// A line was processed and this could be the end of the event. We need
// to check if the next line is empty to determine if the event is
@@ -239,15 +281,28 @@ class EventSourceStream extends Transform {
continue
}
// readLine() is only called after CR or LF. Reject an unfinished line
// before it can retain an unbounded number of decoded chunks. The seven
// extra bytes allow the longest field prefix ("event: " or "retry: ").
if (this.maxEventSize > 0 && ++this.lineLength > this.maxEventSize + 7) {
callback(createMaxEventSizeExceededError())
return
}
this.advanceCursor()
}
callback()
}
_destroy (error, callback) {
this.chunks.length = 0
this.clearEvent()
super._destroy(error, callback)
}
/**
* @param {Buffer} line
* @param {EventStreamEvent} event
* @param {EventSourceStreamEvent} event
*/
parseLine (line, event) {
// If the line is empty (a blank line)
@@ -281,6 +336,13 @@ class EventSourceStream extends Transform {
}
if (isFieldName(line, fieldLength, DATA)) {
if (this.maxEventSize > 0 && this.dataLineCount >= this.maxDataLines) {
throw createMaxEventSizeExceededError()
}
const valueBytes = line.length - valueStart
const dataSize = this.eventFieldSizes.data + (event.data === undefined ? 0 : 1) + valueBytes
this.setEventFieldSize('data', dataSize)
const value = line.toString('utf8', valueStart)
if (event.data === undefined) {
@@ -288,11 +350,13 @@ class EventSourceStream extends Transform {
} else {
event.data += `\n${value}`
}
this.dataLineCount++
return
}
if (isFieldName(line, fieldLength, RETRY)) {
if (isASCIINumberBytes(line, valueStart)) {
this.setEventFieldSize('retry', line.length - valueStart)
event.retry = line.toString('utf8', valueStart)
}
return
@@ -300,20 +364,29 @@ class EventSourceStream extends Transform {
if (isFieldName(line, fieldLength, ID)) {
if (isValidLastEventIdBytes(line, valueStart)) {
this.setEventFieldSize('id', line.length - valueStart)
event.id = line.toString('utf8', valueStart)
}
return
}
if (isFieldName(line, fieldLength, EVENT)) {
const value = line.toString('utf8', valueStart)
if (value.length > 0) {
event.event = value
if (valueStart < line.length) {
this.setEventFieldSize('event', line.length - valueStart)
event.event = line.toString('utf8', valueStart)
}
}
}
setEventFieldSize (field, size) {
const eventSize = this.eventSize - this.eventFieldSizes[field] + size
if (this.maxEventSize > 0 && eventSize > this.maxEventSize) {
throw createMaxEventSizeExceededError()
}
this.eventSize = eventSize
this.eventFieldSizes[field] = size
}
/**
* @param {EventSourceStreamEvent} event
*/
@@ -344,6 +417,12 @@ class EventSourceStream extends Transform {
this.event.event = undefined
this.event.id = undefined
this.event.retry = undefined
this.eventSize = 0
this.dataLineCount = 0
this.eventFieldSizes.data = 0
this.eventFieldSizes.event = 0
this.eventFieldSizes.id = 0
this.eventFieldSizes.retry = 0
}
hasPendingEvent () {
@@ -379,14 +458,16 @@ class EventSourceStream extends Transform {
syncLineStartToCursor () {
this.lineChunkIndex = this.chunkIndex
this.linePos = this.pos
this.lineLength = 0
this.dropConsumedChunks()
}
dropConsumedChunks () {
while (this.lineChunkIndex > 0) {
this.chunks.shift()
this.lineChunkIndex--
this.chunkIndex--
if (this.lineChunkIndex > 0) {
const consumed = this.lineChunkIndex
this.chunks.splice(0, consumed)
this.lineChunkIndex = 0
this.chunkIndex -= consumed
}
if (this.chunkIndex === this.chunks.length) {