diff --git a/.github/actions/javascript/authorChecklist/index.js b/.github/actions/javascript/authorChecklist/index.js index b06a43adc37e..01c1761a5ca4 100644 --- a/.github/actions/javascript/authorChecklist/index.js +++ b/.github/actions/javascript/authorChecklist/index.js @@ -2107,6 +2107,7 @@ var require_dispatcher = __commonJS({ var require_dispatcher_base = __commonJS({ "node_modules/undici/lib/dispatcher/dispatcher-base.js"(exports, module) { "use strict"; + var buffer = __require("node:buffer"); var Dispatcher = require_dispatcher(); var { ClientDestroyedError, @@ -2118,6 +2119,7 @@ var require_dispatcher_base = __commonJS({ var kOnClosed = /* @__PURE__ */ Symbol("onClosed"); var kInterceptedDispatch = /* @__PURE__ */ Symbol("Intercepted Dispatch"); var kWebSocketOptions = /* @__PURE__ */ Symbol("webSocketOptions"); + var kEventSourceOptions = /* @__PURE__ */ Symbol("eventSourceOptions"); var DispatcherBase = class extends Dispatcher { constructor(opts) { super(); @@ -2126,6 +2128,7 @@ var require_dispatcher_base = __commonJS({ this[kClosed] = false; this[kOnClosed] = []; this[kWebSocketOptions] = opts?.webSocket ?? {}; + this[kEventSourceOptions] = opts?.eventSource ?? {}; } get webSocketOptions() { return { @@ -2133,6 +2136,11 @@ var require_dispatcher_base = __commonJS({ maxPayloadSize: this[kWebSocketOptions].maxPayloadSize ?? 128 * 1024 * 1024 }; } + get eventSourceOptions() { + return { + maxEventSize: this[kEventSourceOptions].maxEventSize ?? buffer.kStringMaxLength + }; + } get destroyed() { return this[kDestroyed]; } @@ -6280,7 +6288,6 @@ var require_client_h1 = __commonJS({ socket[kSocketUsed] = false; socket[kParser] = new Parser(client, socket, llhttpInstance); addListener(socket, "error", function(err) { - assert(err.code !== "ERR_TLS_CERT_ALTNAME_INVALID"); const parser = this[kParser]; if (err.code === "ECONNRESET" && parser.statusCode && !parser.shouldKeepAlive) { const parserErr = parser.finish(); @@ -6964,7 +6971,6 @@ var require_client_h2 = __commonJS({ client[kHTTP2Session] = session; socket[kHTTP2Session] = session; util.addListener(socket, "error", function(err) { - assert(err.code !== "ERR_TLS_CERT_ALTNAME_INVALID"); this[kError] = err; this[kClient][kOnError](err); }); @@ -7023,7 +7029,6 @@ var require_client_h2 = __commonJS({ } } function onHttp2SessionError(err) { - assert(err.code !== "ERR_TLS_CERT_ALTNAME_INVALID"); this[kSocket][kError] = err; this[kClient][kOnError](err); } @@ -7717,9 +7722,10 @@ var require_client = __commonJS({ // h2 maxConcurrentStreams, allowH2, - webSocket + webSocket, + eventSource } = {}) { - super({ webSocket }); + super({ webSocket, eventSource }); if (keepAlive !== void 0) { throw new InvalidArgumentError("unsupported keepAlive, use pipelining=0 instead"); } @@ -8616,7 +8622,7 @@ var require_agent = __commonJS({ return opts && opts.connections === 1 ? new Client(origin, opts) : new Pool(origin, opts); } var Agent = class extends DispatcherBase { - constructor({ factory = defaultFactory, maxRedirections = 0, connect, ...options } = {}) { + constructor({ factory = defaultFactory, maxRedirections = 0, connect, tls, ...options } = {}) { if (typeof factory !== "function") { throw new InvalidArgumentError("factory must be a function."); } @@ -8630,8 +8636,11 @@ var require_agent = __commonJS({ if (connect && typeof connect !== "function") { connect = { ...connect }; } + if (tls && typeof tls !== "function") { + tls = { ...tls }; + } this[kInterceptors] = options.interceptors?.Agent && Array.isArray(options.interceptors.Agent) ? options.interceptors.Agent : [createRedirectInterceptor({ maxRedirections })]; - this[kOptions] = { ...util.deepClone(options), connect }; + this[kOptions] = { ...util.deepClone(options), connect, tls }; this[kOptions].interceptors = options.interceptors ? { ...options.interceptors } : void 0; this[kMaxRedirections] = maxRedirections; this[kFactory] = factory; @@ -14359,8 +14368,9 @@ var require_fetch = __commonJS({ } ); response.body = { stream, source: null, length: null }; - fetchParams.controller.onAborted = onAborted; - fetchParams.controller.on("terminated", onAborted); + if (!fetchParams.controller.resume) { + fetchParams.controller.on("terminated", onAborted); + } fetchParams.controller.resume = async () => { while (true) { let bytes; @@ -14460,7 +14470,6 @@ var require_fetch = __commonJS({ headersList.append(bufferToLowerCasedHeaderName(rawHeaders[i]), rawHeaders[i + 1].toString("latin1"), true); } location = headersList.get("location", true); - this.body = new Readable({ read: resume }); const decoders = []; const willFollow = location && request2.redirect === "follow" && redirectStatusSet.has(status); if (request2.method !== "HEAD" && request2.method !== "CONNECT" && !nullBodyStatus.includes(status) && !willFollow) { @@ -14468,7 +14477,7 @@ var require_fetch = __commonJS({ const codings = contentEncoding ? contentEncoding.toLowerCase().split(",") : []; const maxContentEncodings = 5; if (codings.length > maxContentEncodings) { - reject(new Error(`too many content-encodings in response: ${codings.length}, maximum allowed is ${maxContentEncodings}`)); + this.abort(new Error(`too many content-encodings in response: ${codings.length}, maximum allowed is ${maxContentEncodings}`)); return true; } for (let i = codings.length - 1; i >= 0; --i) { @@ -14498,6 +14507,7 @@ var require_fetch = __commonJS({ } } } + this.body = new Readable({ read: resume }); const onError = this.onError.bind(this); resolve({ status, @@ -14523,9 +14533,6 @@ var require_fetch = __commonJS({ if (this.abort) { fetchParams.controller.off("terminated", this.abort); } - if (fetchParams.controller.onAborted) { - fetchParams.controller.off("terminated", fetchParams.controller.onAborted); - } fetchParams.controller.ended = true; this.body.push(null); }, @@ -17599,6 +17606,16 @@ var require_receiver = __commonJS({ if (isControlFrame(this.#info.opcode)) { this.#loop = this.parseControlFrame(body); this.#state = parserStates.INFO; + const socket = this.ws[kResponse].socket; + if (this.#loop && socket.writableNeedDrain) { + this.#loop = false; + socket.once("drain", () => { + if (this.destroyed) return; + this.#loop = true; + this.run(callback); + }); + return; + } } else { if (!this.#info.compressed) { if (!this.writeFragments(body)) { @@ -18292,6 +18309,7 @@ var require_util8 = __commonJS({ var require_eventsource_stream = __commonJS({ "node_modules/undici/lib/web/eventsource/eventsource-stream.js"(exports, module) { "use strict"; + var buffer = __require("node:buffer"); var { Transform } = __require("node:stream"); var { isASCIINumber, isValidLastEventId } = require_util8(); var BOM = [239, 187, 191]; @@ -18299,24 +18317,28 @@ var require_eventsource_stream = __commonJS({ var CR = 13; var COLON = 58; var SPACE = 32; + var defaultMaxEventSize = buffer.kStringMaxLength; var DATA = Buffer.from("data"); var EVENT = Buffer.from("event"); var ID = Buffer.from("id"); var RETRY = Buffer.from("retry"); - function isASCIINumberBytes(buffer, start) { - if (start >= buffer.length) { + var minParserItems = 1024; + var maxParserItems = 131072; + var bytesPerParserItem = 128; + function isASCIINumberBytes(buffer2, start) { + if (start >= buffer2.length) { return false; } - for (let i = start; i < buffer.length; i++) { - if (buffer[i] < 48 || buffer[i] > 57) { + for (let i = start; i < buffer2.length; i++) { + if (buffer2[i] < 48 || buffer2[i] > 57) { return false; } } return true; } - function isValidLastEventIdBytes(buffer, start) { - for (let i = start; i < buffer.length; i++) { - if (buffer[i] === 0) { + function isValidLastEventIdBytes(buffer2, start) { + for (let i = start; i < buffer2.length; i++) { + if (buffer2[i] === 0) { return false; } } @@ -18333,6 +18355,11 @@ var require_eventsource_stream = __commonJS({ } return true; } + function createMaxEventSizeExceededError() { + const error2 = new Error("EventSource message size exceeded"); + error2.aborted = false; + return error2; + } var EventSourceStream = class extends Transform { /** * @type {eventSourceSettings} @@ -18359,6 +18386,13 @@ var require_eventsource_stream = __commonJS({ 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: void 0, event: void 0, @@ -18367,6 +18401,7 @@ var require_eventsource_stream = __commonJS({ }; /** * @param {object} options + * @param {number} [options.maxEventSize] * @param {eventSourceSettings} options.eventSourceSettings * @param {Function} [options.push] */ @@ -18374,6 +18409,10 @@ var require_eventsource_stream = __commonJS({ options.readableObjectMode = true; 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; } @@ -18389,6 +18428,10 @@ var require_eventsource_stream = __commonJS({ callback(); return; } + if (this.maxEventSize > 0 && this.chunks.length >= this.maxBufferedChunks && chunk[0] !== LF && chunk[0] !== CR) { + callback(createMaxEventSizeExceededError()); + return; + } this.chunks.push(chunk); if (this.checkBOM) { if (this.handleBOM()) { @@ -18425,18 +18468,32 @@ var require_eventsource_stream = __commonJS({ if (byte === CR) { this.crlfCheck = true; } - this.parseLine(this.readLine(), this.event); + try { + this.parseLine(this.readLine(), this.event); + } catch (error2) { + callback(error2); + return; + } this.consumeCurrentByte(); this.eventEndCheck = true; continue; } + if (this.maxEventSize > 0 && ++this.lineLength > this.maxEventSize + 7) { + callback(createMaxEventSizeExceededError()); + return; + } this.advanceCursor(); } callback(); } + _destroy(error2, callback) { + this.chunks.length = 0; + this.clearEvent(); + super._destroy(error2, callback); + } /** * @param {Buffer} line - * @param {EventStreamEvent} event + * @param {EventSourceStreamEvent} event */ parseLine(line, event) { if (line.length === 0) { @@ -18456,6 +18513,12 @@ var require_eventsource_stream = __commonJS({ } } 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 === void 0 ? 0 : 1) + valueBytes; + this.setEventFieldSize("data", dataSize); const value = line.toString("utf8", valueStart); if (event.data === void 0) { event.data = value; @@ -18463,27 +18526,38 @@ var require_eventsource_stream = __commonJS({ event.data += ` ${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; } 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 */ @@ -18510,6 +18584,12 @@ ${value}`; this.event.event = void 0; this.event.id = void 0; this.event.retry = void 0; + this.eventSize = 0; + this.dataLineCount = 0; + this.eventFieldSizes.data = 0; + this.eventFieldSizes.event = 0; + this.eventFieldSizes.id = 0; + this.eventFieldSizes.retry = 0; } hasPendingEvent() { return this.event.data !== void 0 || this.event.event !== void 0 || this.event.id !== void 0 || this.event.retry !== void 0; @@ -18534,13 +18614,15 @@ ${value}`; 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) { this.chunks.length = 0; @@ -18643,6 +18725,7 @@ var require_eventsource = __commonJS({ var { delay } = require_util8(); var { kEnumerableProperty } = require_util(); var { environmentSettingsObject } = require_util2(); + var { getGlobalDispatcher } = require_global2(); var experimentalWarned = false; var defaultReconnectionTime = 3e3; var CONNECTING = 0; @@ -18783,6 +18866,7 @@ var require_eventsource = __commonJS({ this.#state.origin = response.urlList[response.urlList.length - 1].origin; const eventSourceStream = new EventSourceStream({ eventSourceSettings: this.#state, + maxEventSize: this.#dispatcher.eventSourceOptions?.maxEventSize, push: (event) => { this.dispatchEvent(createFastMessageEvent( event.type, @@ -18915,7 +18999,8 @@ var require_eventsource = __commonJS({ { key: "dispatcher", // undici only - converter: webidl.converters.any + converter: webidl.converters.any, + defaultValue: () => getGlobalDispatcher() } ]); module.exports = { diff --git a/.github/actions/javascript/awaitStagingDeploys/index.js b/.github/actions/javascript/awaitStagingDeploys/index.js index 00e2f735fcb4..9452accf9513 100644 --- a/.github/actions/javascript/awaitStagingDeploys/index.js +++ b/.github/actions/javascript/awaitStagingDeploys/index.js @@ -2107,6 +2107,7 @@ var require_dispatcher = __commonJS({ var require_dispatcher_base = __commonJS({ "node_modules/undici/lib/dispatcher/dispatcher-base.js"(exports, module) { "use strict"; + var buffer = __require("node:buffer"); var Dispatcher = require_dispatcher(); var { ClientDestroyedError, @@ -2118,6 +2119,7 @@ var require_dispatcher_base = __commonJS({ var kOnClosed = /* @__PURE__ */ Symbol("onClosed"); var kInterceptedDispatch = /* @__PURE__ */ Symbol("Intercepted Dispatch"); var kWebSocketOptions = /* @__PURE__ */ Symbol("webSocketOptions"); + var kEventSourceOptions = /* @__PURE__ */ Symbol("eventSourceOptions"); var DispatcherBase = class extends Dispatcher { constructor(opts) { super(); @@ -2126,6 +2128,7 @@ var require_dispatcher_base = __commonJS({ this[kClosed] = false; this[kOnClosed] = []; this[kWebSocketOptions] = opts?.webSocket ?? {}; + this[kEventSourceOptions] = opts?.eventSource ?? {}; } get webSocketOptions() { return { @@ -2133,6 +2136,11 @@ var require_dispatcher_base = __commonJS({ maxPayloadSize: this[kWebSocketOptions].maxPayloadSize ?? 128 * 1024 * 1024 }; } + get eventSourceOptions() { + return { + maxEventSize: this[kEventSourceOptions].maxEventSize ?? buffer.kStringMaxLength + }; + } get destroyed() { return this[kDestroyed]; } @@ -6280,7 +6288,6 @@ var require_client_h1 = __commonJS({ socket[kSocketUsed] = false; socket[kParser] = new Parser(client, socket, llhttpInstance); addListener(socket, "error", function(err) { - assert(err.code !== "ERR_TLS_CERT_ALTNAME_INVALID"); const parser = this[kParser]; if (err.code === "ECONNRESET" && parser.statusCode && !parser.shouldKeepAlive) { const parserErr = parser.finish(); @@ -6964,7 +6971,6 @@ var require_client_h2 = __commonJS({ client[kHTTP2Session] = session; socket[kHTTP2Session] = session; util.addListener(socket, "error", function(err) { - assert(err.code !== "ERR_TLS_CERT_ALTNAME_INVALID"); this[kError] = err; this[kClient][kOnError](err); }); @@ -7023,7 +7029,6 @@ var require_client_h2 = __commonJS({ } } function onHttp2SessionError(err) { - assert(err.code !== "ERR_TLS_CERT_ALTNAME_INVALID"); this[kSocket][kError] = err; this[kClient][kOnError](err); } @@ -7717,9 +7722,10 @@ var require_client = __commonJS({ // h2 maxConcurrentStreams, allowH2, - webSocket + webSocket, + eventSource } = {}) { - super({ webSocket }); + super({ webSocket, eventSource }); if (keepAlive !== void 0) { throw new InvalidArgumentError("unsupported keepAlive, use pipelining=0 instead"); } @@ -8616,7 +8622,7 @@ var require_agent = __commonJS({ return opts && opts.connections === 1 ? new Client(origin, opts) : new Pool(origin, opts); } var Agent = class extends DispatcherBase { - constructor({ factory = defaultFactory, maxRedirections = 0, connect, ...options } = {}) { + constructor({ factory = defaultFactory, maxRedirections = 0, connect, tls, ...options } = {}) { if (typeof factory !== "function") { throw new InvalidArgumentError("factory must be a function."); } @@ -8630,8 +8636,11 @@ var require_agent = __commonJS({ if (connect && typeof connect !== "function") { connect = { ...connect }; } + if (tls && typeof tls !== "function") { + tls = { ...tls }; + } this[kInterceptors] = options.interceptors?.Agent && Array.isArray(options.interceptors.Agent) ? options.interceptors.Agent : [createRedirectInterceptor({ maxRedirections })]; - this[kOptions] = { ...util.deepClone(options), connect }; + this[kOptions] = { ...util.deepClone(options), connect, tls }; this[kOptions].interceptors = options.interceptors ? { ...options.interceptors } : void 0; this[kMaxRedirections] = maxRedirections; this[kFactory] = factory; @@ -14359,8 +14368,9 @@ var require_fetch = __commonJS({ } ); response.body = { stream, source: null, length: null }; - fetchParams.controller.onAborted = onAborted; - fetchParams.controller.on("terminated", onAborted); + if (!fetchParams.controller.resume) { + fetchParams.controller.on("terminated", onAborted); + } fetchParams.controller.resume = async () => { while (true) { let bytes; @@ -14460,7 +14470,6 @@ var require_fetch = __commonJS({ headersList.append(bufferToLowerCasedHeaderName(rawHeaders[i]), rawHeaders[i + 1].toString("latin1"), true); } location = headersList.get("location", true); - this.body = new Readable({ read: resume }); const decoders = []; const willFollow = location && request2.redirect === "follow" && redirectStatusSet.has(status); if (request2.method !== "HEAD" && request2.method !== "CONNECT" && !nullBodyStatus.includes(status) && !willFollow) { @@ -14468,7 +14477,7 @@ var require_fetch = __commonJS({ const codings = contentEncoding ? contentEncoding.toLowerCase().split(",") : []; const maxContentEncodings = 5; if (codings.length > maxContentEncodings) { - reject(new Error(`too many content-encodings in response: ${codings.length}, maximum allowed is ${maxContentEncodings}`)); + this.abort(new Error(`too many content-encodings in response: ${codings.length}, maximum allowed is ${maxContentEncodings}`)); return true; } for (let i = codings.length - 1; i >= 0; --i) { @@ -14498,6 +14507,7 @@ var require_fetch = __commonJS({ } } } + this.body = new Readable({ read: resume }); const onError = this.onError.bind(this); resolve({ status, @@ -14523,9 +14533,6 @@ var require_fetch = __commonJS({ if (this.abort) { fetchParams.controller.off("terminated", this.abort); } - if (fetchParams.controller.onAborted) { - fetchParams.controller.off("terminated", fetchParams.controller.onAborted); - } fetchParams.controller.ended = true; this.body.push(null); }, @@ -17599,6 +17606,16 @@ var require_receiver = __commonJS({ if (isControlFrame(this.#info.opcode)) { this.#loop = this.parseControlFrame(body); this.#state = parserStates.INFO; + const socket = this.ws[kResponse].socket; + if (this.#loop && socket.writableNeedDrain) { + this.#loop = false; + socket.once("drain", () => { + if (this.destroyed) return; + this.#loop = true; + this.run(callback); + }); + return; + } } else { if (!this.#info.compressed) { if (!this.writeFragments(body)) { @@ -18292,6 +18309,7 @@ var require_util8 = __commonJS({ var require_eventsource_stream = __commonJS({ "node_modules/undici/lib/web/eventsource/eventsource-stream.js"(exports, module) { "use strict"; + var buffer = __require("node:buffer"); var { Transform } = __require("node:stream"); var { isASCIINumber, isValidLastEventId } = require_util8(); var BOM = [239, 187, 191]; @@ -18299,24 +18317,28 @@ var require_eventsource_stream = __commonJS({ var CR = 13; var COLON = 58; var SPACE = 32; + var defaultMaxEventSize = buffer.kStringMaxLength; var DATA = Buffer.from("data"); var EVENT = Buffer.from("event"); var ID = Buffer.from("id"); var RETRY = Buffer.from("retry"); - function isASCIINumberBytes(buffer, start) { - if (start >= buffer.length) { + var minParserItems = 1024; + var maxParserItems = 131072; + var bytesPerParserItem = 128; + function isASCIINumberBytes(buffer2, start) { + if (start >= buffer2.length) { return false; } - for (let i = start; i < buffer.length; i++) { - if (buffer[i] < 48 || buffer[i] > 57) { + for (let i = start; i < buffer2.length; i++) { + if (buffer2[i] < 48 || buffer2[i] > 57) { return false; } } return true; } - function isValidLastEventIdBytes(buffer, start) { - for (let i = start; i < buffer.length; i++) { - if (buffer[i] === 0) { + function isValidLastEventIdBytes(buffer2, start) { + for (let i = start; i < buffer2.length; i++) { + if (buffer2[i] === 0) { return false; } } @@ -18333,6 +18355,11 @@ var require_eventsource_stream = __commonJS({ } return true; } + function createMaxEventSizeExceededError() { + const error2 = new Error("EventSource message size exceeded"); + error2.aborted = false; + return error2; + } var EventSourceStream = class extends Transform { /** * @type {eventSourceSettings} @@ -18359,6 +18386,13 @@ var require_eventsource_stream = __commonJS({ 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: void 0, event: void 0, @@ -18367,6 +18401,7 @@ var require_eventsource_stream = __commonJS({ }; /** * @param {object} options + * @param {number} [options.maxEventSize] * @param {eventSourceSettings} options.eventSourceSettings * @param {Function} [options.push] */ @@ -18374,6 +18409,10 @@ var require_eventsource_stream = __commonJS({ options.readableObjectMode = true; 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; } @@ -18389,6 +18428,10 @@ var require_eventsource_stream = __commonJS({ callback(); return; } + if (this.maxEventSize > 0 && this.chunks.length >= this.maxBufferedChunks && chunk[0] !== LF && chunk[0] !== CR) { + callback(createMaxEventSizeExceededError()); + return; + } this.chunks.push(chunk); if (this.checkBOM) { if (this.handleBOM()) { @@ -18425,18 +18468,32 @@ var require_eventsource_stream = __commonJS({ if (byte === CR) { this.crlfCheck = true; } - this.parseLine(this.readLine(), this.event); + try { + this.parseLine(this.readLine(), this.event); + } catch (error2) { + callback(error2); + return; + } this.consumeCurrentByte(); this.eventEndCheck = true; continue; } + if (this.maxEventSize > 0 && ++this.lineLength > this.maxEventSize + 7) { + callback(createMaxEventSizeExceededError()); + return; + } this.advanceCursor(); } callback(); } + _destroy(error2, callback) { + this.chunks.length = 0; + this.clearEvent(); + super._destroy(error2, callback); + } /** * @param {Buffer} line - * @param {EventStreamEvent} event + * @param {EventSourceStreamEvent} event */ parseLine(line, event) { if (line.length === 0) { @@ -18456,6 +18513,12 @@ var require_eventsource_stream = __commonJS({ } } 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 === void 0 ? 0 : 1) + valueBytes; + this.setEventFieldSize("data", dataSize); const value = line.toString("utf8", valueStart); if (event.data === void 0) { event.data = value; @@ -18463,27 +18526,38 @@ var require_eventsource_stream = __commonJS({ event.data += ` ${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; } 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 */ @@ -18510,6 +18584,12 @@ ${value}`; this.event.event = void 0; this.event.id = void 0; this.event.retry = void 0; + this.eventSize = 0; + this.dataLineCount = 0; + this.eventFieldSizes.data = 0; + this.eventFieldSizes.event = 0; + this.eventFieldSizes.id = 0; + this.eventFieldSizes.retry = 0; } hasPendingEvent() { return this.event.data !== void 0 || this.event.event !== void 0 || this.event.id !== void 0 || this.event.retry !== void 0; @@ -18534,13 +18614,15 @@ ${value}`; 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) { this.chunks.length = 0; @@ -18643,6 +18725,7 @@ var require_eventsource = __commonJS({ var { delay } = require_util8(); var { kEnumerableProperty } = require_util(); var { environmentSettingsObject } = require_util2(); + var { getGlobalDispatcher } = require_global2(); var experimentalWarned = false; var defaultReconnectionTime = 3e3; var CONNECTING = 0; @@ -18783,6 +18866,7 @@ var require_eventsource = __commonJS({ this.#state.origin = response.urlList[response.urlList.length - 1].origin; const eventSourceStream = new EventSourceStream({ eventSourceSettings: this.#state, + maxEventSize: this.#dispatcher.eventSourceOptions?.maxEventSize, push: (event) => { this.dispatchEvent(createFastMessageEvent( event.type, @@ -18915,7 +18999,8 @@ var require_eventsource = __commonJS({ { key: "dispatcher", // undici only - converter: webidl.converters.any + converter: webidl.converters.any, + defaultValue: () => getGlobalDispatcher() } ]); module.exports = { diff --git a/.github/actions/javascript/bumpVersion/index.js b/.github/actions/javascript/bumpVersion/index.js index c2258fb0a82d..6a1020bf0603 100644 --- a/.github/actions/javascript/bumpVersion/index.js +++ b/.github/actions/javascript/bumpVersion/index.js @@ -2556,6 +2556,7 @@ var require_dispatcher = __commonJS({ var require_dispatcher_base = __commonJS({ "node_modules/undici/lib/dispatcher/dispatcher-base.js"(exports, module) { "use strict"; + var buffer = __require("node:buffer"); var Dispatcher = require_dispatcher(); var { ClientDestroyedError, @@ -2567,6 +2568,7 @@ var require_dispatcher_base = __commonJS({ var kOnClosed = /* @__PURE__ */ Symbol("onClosed"); var kInterceptedDispatch = /* @__PURE__ */ Symbol("Intercepted Dispatch"); var kWebSocketOptions = /* @__PURE__ */ Symbol("webSocketOptions"); + var kEventSourceOptions = /* @__PURE__ */ Symbol("eventSourceOptions"); var DispatcherBase = class extends Dispatcher { constructor(opts) { super(); @@ -2575,6 +2577,7 @@ var require_dispatcher_base = __commonJS({ this[kClosed] = false; this[kOnClosed] = []; this[kWebSocketOptions] = opts?.webSocket ?? {}; + this[kEventSourceOptions] = opts?.eventSource ?? {}; } get webSocketOptions() { return { @@ -2582,6 +2585,11 @@ var require_dispatcher_base = __commonJS({ maxPayloadSize: this[kWebSocketOptions].maxPayloadSize ?? 128 * 1024 * 1024 }; } + get eventSourceOptions() { + return { + maxEventSize: this[kEventSourceOptions].maxEventSize ?? buffer.kStringMaxLength + }; + } get destroyed() { return this[kDestroyed]; } @@ -6729,7 +6737,6 @@ var require_client_h1 = __commonJS({ socket[kSocketUsed] = false; socket[kParser] = new Parser(client, socket, llhttpInstance); addListener(socket, "error", function(err) { - assert(err.code !== "ERR_TLS_CERT_ALTNAME_INVALID"); const parser = this[kParser]; if (err.code === "ECONNRESET" && parser.statusCode && !parser.shouldKeepAlive) { const parserErr = parser.finish(); @@ -7413,7 +7420,6 @@ var require_client_h2 = __commonJS({ client[kHTTP2Session] = session; socket[kHTTP2Session] = session; util.addListener(socket, "error", function(err) { - assert(err.code !== "ERR_TLS_CERT_ALTNAME_INVALID"); this[kError] = err; this[kClient][kOnError](err); }); @@ -7472,7 +7478,6 @@ var require_client_h2 = __commonJS({ } } function onHttp2SessionError(err) { - assert(err.code !== "ERR_TLS_CERT_ALTNAME_INVALID"); this[kSocket][kError] = err; this[kClient][kOnError](err); } @@ -8166,9 +8171,10 @@ var require_client = __commonJS({ // h2 maxConcurrentStreams, allowH2, - webSocket + webSocket, + eventSource } = {}) { - super({ webSocket }); + super({ webSocket, eventSource }); if (keepAlive !== void 0) { throw new InvalidArgumentError("unsupported keepAlive, use pipelining=0 instead"); } @@ -9065,7 +9071,7 @@ var require_agent = __commonJS({ return opts && opts.connections === 1 ? new Client(origin, opts) : new Pool(origin, opts); } var Agent = class extends DispatcherBase { - constructor({ factory = defaultFactory, maxRedirections = 0, connect, ...options } = {}) { + constructor({ factory = defaultFactory, maxRedirections = 0, connect, tls, ...options } = {}) { if (typeof factory !== "function") { throw new InvalidArgumentError("factory must be a function."); } @@ -9079,8 +9085,11 @@ var require_agent = __commonJS({ if (connect && typeof connect !== "function") { connect = { ...connect }; } + if (tls && typeof tls !== "function") { + tls = { ...tls }; + } this[kInterceptors] = options.interceptors?.Agent && Array.isArray(options.interceptors.Agent) ? options.interceptors.Agent : [createRedirectInterceptor({ maxRedirections })]; - this[kOptions] = { ...util.deepClone(options), connect }; + this[kOptions] = { ...util.deepClone(options), connect, tls }; this[kOptions].interceptors = options.interceptors ? { ...options.interceptors } : void 0; this[kMaxRedirections] = maxRedirections; this[kFactory] = factory; @@ -14808,8 +14817,9 @@ var require_fetch = __commonJS({ } ); response.body = { stream, source: null, length: null }; - fetchParams.controller.onAborted = onAborted; - fetchParams.controller.on("terminated", onAborted); + if (!fetchParams.controller.resume) { + fetchParams.controller.on("terminated", onAborted); + } fetchParams.controller.resume = async () => { while (true) { let bytes; @@ -14909,7 +14919,6 @@ var require_fetch = __commonJS({ headersList.append(bufferToLowerCasedHeaderName(rawHeaders[i]), rawHeaders[i + 1].toString("latin1"), true); } location = headersList.get("location", true); - this.body = new Readable({ read: resume }); const decoders = []; const willFollow = location && request.redirect === "follow" && redirectStatusSet.has(status); if (request.method !== "HEAD" && request.method !== "CONNECT" && !nullBodyStatus.includes(status) && !willFollow) { @@ -14917,7 +14926,7 @@ var require_fetch = __commonJS({ const codings = contentEncoding ? contentEncoding.toLowerCase().split(",") : []; const maxContentEncodings = 5; if (codings.length > maxContentEncodings) { - reject(new Error(`too many content-encodings in response: ${codings.length}, maximum allowed is ${maxContentEncodings}`)); + this.abort(new Error(`too many content-encodings in response: ${codings.length}, maximum allowed is ${maxContentEncodings}`)); return true; } for (let i = codings.length - 1; i >= 0; --i) { @@ -14947,6 +14956,7 @@ var require_fetch = __commonJS({ } } } + this.body = new Readable({ read: resume }); const onError = this.onError.bind(this); resolve({ status, @@ -14972,9 +14982,6 @@ var require_fetch = __commonJS({ if (this.abort) { fetchParams.controller.off("terminated", this.abort); } - if (fetchParams.controller.onAborted) { - fetchParams.controller.off("terminated", fetchParams.controller.onAborted); - } fetchParams.controller.ended = true; this.body.push(null); }, @@ -18048,6 +18055,16 @@ var require_receiver = __commonJS({ if (isControlFrame(this.#info.opcode)) { this.#loop = this.parseControlFrame(body); this.#state = parserStates.INFO; + const socket = this.ws[kResponse].socket; + if (this.#loop && socket.writableNeedDrain) { + this.#loop = false; + socket.once("drain", () => { + if (this.destroyed) return; + this.#loop = true; + this.run(callback); + }); + return; + } } else { if (!this.#info.compressed) { if (!this.writeFragments(body)) { @@ -18741,6 +18758,7 @@ var require_util8 = __commonJS({ var require_eventsource_stream = __commonJS({ "node_modules/undici/lib/web/eventsource/eventsource-stream.js"(exports, module) { "use strict"; + var buffer = __require("node:buffer"); var { Transform } = __require("node:stream"); var { isASCIINumber, isValidLastEventId } = require_util8(); var BOM = [239, 187, 191]; @@ -18748,24 +18766,28 @@ var require_eventsource_stream = __commonJS({ var CR = 13; var COLON = 58; var SPACE = 32; + var defaultMaxEventSize = buffer.kStringMaxLength; var DATA = Buffer.from("data"); var EVENT = Buffer.from("event"); var ID = Buffer.from("id"); var RETRY = Buffer.from("retry"); - function isASCIINumberBytes(buffer, start) { - if (start >= buffer.length) { + var minParserItems = 1024; + var maxParserItems = 131072; + var bytesPerParserItem = 128; + function isASCIINumberBytes(buffer2, start) { + if (start >= buffer2.length) { return false; } - for (let i = start; i < buffer.length; i++) { - if (buffer[i] < 48 || buffer[i] > 57) { + for (let i = start; i < buffer2.length; i++) { + if (buffer2[i] < 48 || buffer2[i] > 57) { return false; } } return true; } - function isValidLastEventIdBytes(buffer, start) { - for (let i = start; i < buffer.length; i++) { - if (buffer[i] === 0) { + function isValidLastEventIdBytes(buffer2, start) { + for (let i = start; i < buffer2.length; i++) { + if (buffer2[i] === 0) { return false; } } @@ -18782,6 +18804,11 @@ var require_eventsource_stream = __commonJS({ } return true; } + function createMaxEventSizeExceededError() { + const error2 = new Error("EventSource message size exceeded"); + error2.aborted = false; + return error2; + } var EventSourceStream = class extends Transform { /** * @type {eventSourceSettings} @@ -18808,6 +18835,13 @@ var require_eventsource_stream = __commonJS({ 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: void 0, event: void 0, @@ -18816,6 +18850,7 @@ var require_eventsource_stream = __commonJS({ }; /** * @param {object} options + * @param {number} [options.maxEventSize] * @param {eventSourceSettings} options.eventSourceSettings * @param {Function} [options.push] */ @@ -18823,6 +18858,10 @@ var require_eventsource_stream = __commonJS({ options.readableObjectMode = true; 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; } @@ -18838,6 +18877,10 @@ var require_eventsource_stream = __commonJS({ callback(); return; } + if (this.maxEventSize > 0 && this.chunks.length >= this.maxBufferedChunks && chunk[0] !== LF && chunk[0] !== CR) { + callback(createMaxEventSizeExceededError()); + return; + } this.chunks.push(chunk); if (this.checkBOM) { if (this.handleBOM()) { @@ -18874,18 +18917,32 @@ var require_eventsource_stream = __commonJS({ if (byte === CR) { this.crlfCheck = true; } - this.parseLine(this.readLine(), this.event); + try { + this.parseLine(this.readLine(), this.event); + } catch (error2) { + callback(error2); + return; + } this.consumeCurrentByte(); this.eventEndCheck = true; continue; } + if (this.maxEventSize > 0 && ++this.lineLength > this.maxEventSize + 7) { + callback(createMaxEventSizeExceededError()); + return; + } this.advanceCursor(); } callback(); } + _destroy(error2, callback) { + this.chunks.length = 0; + this.clearEvent(); + super._destroy(error2, callback); + } /** * @param {Buffer} line - * @param {EventStreamEvent} event + * @param {EventSourceStreamEvent} event */ parseLine(line, event) { if (line.length === 0) { @@ -18905,6 +18962,12 @@ var require_eventsource_stream = __commonJS({ } } 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 === void 0 ? 0 : 1) + valueBytes; + this.setEventFieldSize("data", dataSize); const value = line.toString("utf8", valueStart); if (event.data === void 0) { event.data = value; @@ -18912,27 +18975,38 @@ var require_eventsource_stream = __commonJS({ event.data += ` ${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; } 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 */ @@ -18959,6 +19033,12 @@ ${value}`; this.event.event = void 0; this.event.id = void 0; this.event.retry = void 0; + this.eventSize = 0; + this.dataLineCount = 0; + this.eventFieldSizes.data = 0; + this.eventFieldSizes.event = 0; + this.eventFieldSizes.id = 0; + this.eventFieldSizes.retry = 0; } hasPendingEvent() { return this.event.data !== void 0 || this.event.event !== void 0 || this.event.id !== void 0 || this.event.retry !== void 0; @@ -18983,13 +19063,15 @@ ${value}`; 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) { this.chunks.length = 0; @@ -19092,6 +19174,7 @@ var require_eventsource = __commonJS({ var { delay } = require_util8(); var { kEnumerableProperty } = require_util(); var { environmentSettingsObject } = require_util2(); + var { getGlobalDispatcher } = require_global2(); var experimentalWarned = false; var defaultReconnectionTime = 3e3; var CONNECTING = 0; @@ -19232,6 +19315,7 @@ var require_eventsource = __commonJS({ this.#state.origin = response.urlList[response.urlList.length - 1].origin; const eventSourceStream = new EventSourceStream({ eventSourceSettings: this.#state, + maxEventSize: this.#dispatcher.eventSourceOptions?.maxEventSize, push: (event) => { this.dispatchEvent(createFastMessageEvent( event.type, @@ -19364,7 +19448,8 @@ var require_eventsource = __commonJS({ { key: "dispatcher", // undici only - converter: webidl.converters.any + converter: webidl.converters.any, + defaultValue: () => getGlobalDispatcher() } ]); module.exports = { diff --git a/.github/actions/javascript/checkAndroidStatus/index.js b/.github/actions/javascript/checkAndroidStatus/index.js index de9e0e53ebc4..b32e06df785a 100644 --- a/.github/actions/javascript/checkAndroidStatus/index.js +++ b/.github/actions/javascript/checkAndroidStatus/index.js @@ -2119,6 +2119,7 @@ var require_dispatcher = __commonJS({ var require_dispatcher_base = __commonJS({ "node_modules/undici/lib/dispatcher/dispatcher-base.js"(exports, module) { "use strict"; + var buffer = __require("node:buffer"); var Dispatcher = require_dispatcher(); var { ClientDestroyedError, @@ -2130,6 +2131,7 @@ var require_dispatcher_base = __commonJS({ var kOnClosed = /* @__PURE__ */ Symbol("onClosed"); var kInterceptedDispatch = /* @__PURE__ */ Symbol("Intercepted Dispatch"); var kWebSocketOptions = /* @__PURE__ */ Symbol("webSocketOptions"); + var kEventSourceOptions = /* @__PURE__ */ Symbol("eventSourceOptions"); var DispatcherBase = class extends Dispatcher { constructor(opts) { super(); @@ -2138,6 +2140,7 @@ var require_dispatcher_base = __commonJS({ this[kClosed] = false; this[kOnClosed] = []; this[kWebSocketOptions] = opts?.webSocket ?? {}; + this[kEventSourceOptions] = opts?.eventSource ?? {}; } get webSocketOptions() { return { @@ -2145,6 +2148,11 @@ var require_dispatcher_base = __commonJS({ maxPayloadSize: this[kWebSocketOptions].maxPayloadSize ?? 128 * 1024 * 1024 }; } + get eventSourceOptions() { + return { + maxEventSize: this[kEventSourceOptions].maxEventSize ?? buffer.kStringMaxLength + }; + } get destroyed() { return this[kDestroyed]; } @@ -6292,7 +6300,6 @@ var require_client_h1 = __commonJS({ socket[kSocketUsed] = false; socket[kParser] = new Parser(client, socket, llhttpInstance); addListener(socket, "error", function(err) { - assert(err.code !== "ERR_TLS_CERT_ALTNAME_INVALID"); const parser = this[kParser]; if (err.code === "ECONNRESET" && parser.statusCode && !parser.shouldKeepAlive) { const parserErr = parser.finish(); @@ -6976,7 +6983,6 @@ var require_client_h2 = __commonJS({ client[kHTTP2Session] = session; socket[kHTTP2Session] = session; util.addListener(socket, "error", function(err) { - assert(err.code !== "ERR_TLS_CERT_ALTNAME_INVALID"); this[kError] = err; this[kClient][kOnError](err); }); @@ -7035,7 +7041,6 @@ var require_client_h2 = __commonJS({ } } function onHttp2SessionError(err) { - assert(err.code !== "ERR_TLS_CERT_ALTNAME_INVALID"); this[kSocket][kError] = err; this[kClient][kOnError](err); } @@ -7729,9 +7734,10 @@ var require_client = __commonJS({ // h2 maxConcurrentStreams, allowH2, - webSocket + webSocket, + eventSource } = {}) { - super({ webSocket }); + super({ webSocket, eventSource }); if (keepAlive !== void 0) { throw new InvalidArgumentError("unsupported keepAlive, use pipelining=0 instead"); } @@ -8628,7 +8634,7 @@ var require_agent = __commonJS({ return opts && opts.connections === 1 ? new Client(origin, opts) : new Pool(origin, opts); } var Agent = class extends DispatcherBase { - constructor({ factory = defaultFactory, maxRedirections = 0, connect, ...options } = {}) { + constructor({ factory = defaultFactory, maxRedirections = 0, connect, tls, ...options } = {}) { if (typeof factory !== "function") { throw new InvalidArgumentError("factory must be a function."); } @@ -8642,8 +8648,11 @@ var require_agent = __commonJS({ if (connect && typeof connect !== "function") { connect = { ...connect }; } + if (tls && typeof tls !== "function") { + tls = { ...tls }; + } this[kInterceptors] = options.interceptors?.Agent && Array.isArray(options.interceptors.Agent) ? options.interceptors.Agent : [createRedirectInterceptor({ maxRedirections })]; - this[kOptions] = { ...util.deepClone(options), connect }; + this[kOptions] = { ...util.deepClone(options), connect, tls }; this[kOptions].interceptors = options.interceptors ? { ...options.interceptors } : void 0; this[kMaxRedirections] = maxRedirections; this[kFactory] = factory; @@ -14371,8 +14380,9 @@ var require_fetch = __commonJS({ } ); response.body = { stream, source: null, length: null }; - fetchParams.controller.onAborted = onAborted; - fetchParams.controller.on("terminated", onAborted); + if (!fetchParams.controller.resume) { + fetchParams.controller.on("terminated", onAborted); + } fetchParams.controller.resume = async () => { while (true) { let bytes; @@ -14472,7 +14482,6 @@ var require_fetch = __commonJS({ headersList.append(bufferToLowerCasedHeaderName(rawHeaders[i2]), rawHeaders[i2 + 1].toString("latin1"), true); } location = headersList.get("location", true); - this.body = new Readable({ read: resume }); const decoders = []; const willFollow = location && request2.redirect === "follow" && redirectStatusSet.has(status); if (request2.method !== "HEAD" && request2.method !== "CONNECT" && !nullBodyStatus.includes(status) && !willFollow) { @@ -14480,7 +14489,7 @@ var require_fetch = __commonJS({ const codings = contentEncoding ? contentEncoding.toLowerCase().split(",") : []; const maxContentEncodings = 5; if (codings.length > maxContentEncodings) { - reject(new Error(`too many content-encodings in response: ${codings.length}, maximum allowed is ${maxContentEncodings}`)); + this.abort(new Error(`too many content-encodings in response: ${codings.length}, maximum allowed is ${maxContentEncodings}`)); return true; } for (let i2 = codings.length - 1; i2 >= 0; --i2) { @@ -14510,6 +14519,7 @@ var require_fetch = __commonJS({ } } } + this.body = new Readable({ read: resume }); const onError = this.onError.bind(this); resolve({ status, @@ -14535,9 +14545,6 @@ var require_fetch = __commonJS({ if (this.abort) { fetchParams.controller.off("terminated", this.abort); } - if (fetchParams.controller.onAborted) { - fetchParams.controller.off("terminated", fetchParams.controller.onAborted); - } fetchParams.controller.ended = true; this.body.push(null); }, @@ -17611,6 +17618,16 @@ var require_receiver = __commonJS({ if (isControlFrame(this.#info.opcode)) { this.#loop = this.parseControlFrame(body); this.#state = parserStates.INFO; + const socket = this.ws[kResponse].socket; + if (this.#loop && socket.writableNeedDrain) { + this.#loop = false; + socket.once("drain", () => { + if (this.destroyed) return; + this.#loop = true; + this.run(callback); + }); + return; + } } else { if (!this.#info.compressed) { if (!this.writeFragments(body)) { @@ -18304,6 +18321,7 @@ var require_util8 = __commonJS({ var require_eventsource_stream = __commonJS({ "node_modules/undici/lib/web/eventsource/eventsource-stream.js"(exports, module) { "use strict"; + var buffer = __require("node:buffer"); var { Transform } = __require("node:stream"); var { isASCIINumber, isValidLastEventId } = require_util8(); var BOM = [239, 187, 191]; @@ -18311,24 +18329,28 @@ var require_eventsource_stream = __commonJS({ var CR2 = 13; var COLON2 = 58; var SPACE2 = 32; + var defaultMaxEventSize = buffer.kStringMaxLength; var DATA = Buffer.from("data"); var EVENT = Buffer.from("event"); var ID = Buffer.from("id"); var RETRY = Buffer.from("retry"); - function isASCIINumberBytes(buffer, start) { - if (start >= buffer.length) { + var minParserItems = 1024; + var maxParserItems = 131072; + var bytesPerParserItem = 128; + function isASCIINumberBytes(buffer2, start) { + if (start >= buffer2.length) { return false; } - for (let i2 = start; i2 < buffer.length; i2++) { - if (buffer[i2] < 48 || buffer[i2] > 57) { + for (let i2 = start; i2 < buffer2.length; i2++) { + if (buffer2[i2] < 48 || buffer2[i2] > 57) { return false; } } return true; } - function isValidLastEventIdBytes(buffer, start) { - for (let i2 = start; i2 < buffer.length; i2++) { - if (buffer[i2] === 0) { + function isValidLastEventIdBytes(buffer2, start) { + for (let i2 = start; i2 < buffer2.length; i2++) { + if (buffer2[i2] === 0) { return false; } } @@ -18345,6 +18367,11 @@ var require_eventsource_stream = __commonJS({ } return true; } + function createMaxEventSizeExceededError() { + const error2 = new Error("EventSource message size exceeded"); + error2.aborted = false; + return error2; + } var EventSourceStream = class extends Transform { /** * @type {eventSourceSettings} @@ -18371,6 +18398,13 @@ var require_eventsource_stream = __commonJS({ 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: void 0, event: void 0, @@ -18379,6 +18413,7 @@ var require_eventsource_stream = __commonJS({ }; /** * @param {object} options + * @param {number} [options.maxEventSize] * @param {eventSourceSettings} options.eventSourceSettings * @param {Function} [options.push] */ @@ -18386,6 +18421,10 @@ var require_eventsource_stream = __commonJS({ options.readableObjectMode = true; 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; } @@ -18401,6 +18440,10 @@ var require_eventsource_stream = __commonJS({ callback(); return; } + if (this.maxEventSize > 0 && this.chunks.length >= this.maxBufferedChunks && chunk[0] !== LF2 && chunk[0] !== CR2) { + callback(createMaxEventSizeExceededError()); + return; + } this.chunks.push(chunk); if (this.checkBOM) { if (this.handleBOM()) { @@ -18437,18 +18480,32 @@ var require_eventsource_stream = __commonJS({ if (byte === CR2) { this.crlfCheck = true; } - this.parseLine(this.readLine(), this.event); + try { + this.parseLine(this.readLine(), this.event); + } catch (error2) { + callback(error2); + return; + } this.consumeCurrentByte(); this.eventEndCheck = true; continue; } + if (this.maxEventSize > 0 && ++this.lineLength > this.maxEventSize + 7) { + callback(createMaxEventSizeExceededError()); + return; + } this.advanceCursor(); } callback(); } + _destroy(error2, callback) { + this.chunks.length = 0; + this.clearEvent(); + super._destroy(error2, callback); + } /** * @param {Buffer} line - * @param {EventStreamEvent} event + * @param {EventSourceStreamEvent} event */ parseLine(line, event) { if (line.length === 0) { @@ -18468,6 +18525,12 @@ var require_eventsource_stream = __commonJS({ } } 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 === void 0 ? 0 : 1) + valueBytes; + this.setEventFieldSize("data", dataSize); const value = line.toString("utf8", valueStart); if (event.data === void 0) { event.data = value; @@ -18475,27 +18538,38 @@ var require_eventsource_stream = __commonJS({ event.data += ` ${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; } 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 */ @@ -18522,6 +18596,12 @@ ${value}`; this.event.event = void 0; this.event.id = void 0; this.event.retry = void 0; + this.eventSize = 0; + this.dataLineCount = 0; + this.eventFieldSizes.data = 0; + this.eventFieldSizes.event = 0; + this.eventFieldSizes.id = 0; + this.eventFieldSizes.retry = 0; } hasPendingEvent() { return this.event.data !== void 0 || this.event.event !== void 0 || this.event.id !== void 0 || this.event.retry !== void 0; @@ -18546,13 +18626,15 @@ ${value}`; 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) { this.chunks.length = 0; @@ -18655,6 +18737,7 @@ var require_eventsource = __commonJS({ var { delay } = require_util8(); var { kEnumerableProperty } = require_util(); var { environmentSettingsObject } = require_util2(); + var { getGlobalDispatcher } = require_global2(); var experimentalWarned = false; var defaultReconnectionTime = 3e3; var CONNECTING = 0; @@ -18795,6 +18878,7 @@ var require_eventsource = __commonJS({ this.#state.origin = response.urlList[response.urlList.length - 1].origin; const eventSourceStream = new EventSourceStream({ eventSourceSettings: this.#state, + maxEventSize: this.#dispatcher.eventSourceOptions?.maxEventSize, push: (event) => { this.dispatchEvent(createFastMessageEvent( event.type, @@ -18927,7 +19011,8 @@ var require_eventsource = __commonJS({ { key: "dispatcher", // undici only - converter: webidl.converters.any + converter: webidl.converters.any, + defaultValue: () => getGlobalDispatcher() } ]); module.exports = { diff --git a/.github/actions/javascript/checkDeployBlockers/index.js b/.github/actions/javascript/checkDeployBlockers/index.js index c59c854097c1..bea120fe2647 100644 --- a/.github/actions/javascript/checkDeployBlockers/index.js +++ b/.github/actions/javascript/checkDeployBlockers/index.js @@ -2107,6 +2107,7 @@ var require_dispatcher = __commonJS({ var require_dispatcher_base = __commonJS({ "node_modules/undici/lib/dispatcher/dispatcher-base.js"(exports, module) { "use strict"; + var buffer = __require("node:buffer"); var Dispatcher = require_dispatcher(); var { ClientDestroyedError, @@ -2118,6 +2119,7 @@ var require_dispatcher_base = __commonJS({ var kOnClosed = /* @__PURE__ */ Symbol("onClosed"); var kInterceptedDispatch = /* @__PURE__ */ Symbol("Intercepted Dispatch"); var kWebSocketOptions = /* @__PURE__ */ Symbol("webSocketOptions"); + var kEventSourceOptions = /* @__PURE__ */ Symbol("eventSourceOptions"); var DispatcherBase = class extends Dispatcher { constructor(opts) { super(); @@ -2126,6 +2128,7 @@ var require_dispatcher_base = __commonJS({ this[kClosed] = false; this[kOnClosed] = []; this[kWebSocketOptions] = opts?.webSocket ?? {}; + this[kEventSourceOptions] = opts?.eventSource ?? {}; } get webSocketOptions() { return { @@ -2133,6 +2136,11 @@ var require_dispatcher_base = __commonJS({ maxPayloadSize: this[kWebSocketOptions].maxPayloadSize ?? 128 * 1024 * 1024 }; } + get eventSourceOptions() { + return { + maxEventSize: this[kEventSourceOptions].maxEventSize ?? buffer.kStringMaxLength + }; + } get destroyed() { return this[kDestroyed]; } @@ -6280,7 +6288,6 @@ var require_client_h1 = __commonJS({ socket[kSocketUsed] = false; socket[kParser] = new Parser(client, socket, llhttpInstance); addListener(socket, "error", function(err) { - assert(err.code !== "ERR_TLS_CERT_ALTNAME_INVALID"); const parser = this[kParser]; if (err.code === "ECONNRESET" && parser.statusCode && !parser.shouldKeepAlive) { const parserErr = parser.finish(); @@ -6964,7 +6971,6 @@ var require_client_h2 = __commonJS({ client[kHTTP2Session] = session; socket[kHTTP2Session] = session; util.addListener(socket, "error", function(err) { - assert(err.code !== "ERR_TLS_CERT_ALTNAME_INVALID"); this[kError] = err; this[kClient][kOnError](err); }); @@ -7023,7 +7029,6 @@ var require_client_h2 = __commonJS({ } } function onHttp2SessionError(err) { - assert(err.code !== "ERR_TLS_CERT_ALTNAME_INVALID"); this[kSocket][kError] = err; this[kClient][kOnError](err); } @@ -7717,9 +7722,10 @@ var require_client = __commonJS({ // h2 maxConcurrentStreams, allowH2, - webSocket + webSocket, + eventSource } = {}) { - super({ webSocket }); + super({ webSocket, eventSource }); if (keepAlive !== void 0) { throw new InvalidArgumentError("unsupported keepAlive, use pipelining=0 instead"); } @@ -8616,7 +8622,7 @@ var require_agent = __commonJS({ return opts && opts.connections === 1 ? new Client(origin, opts) : new Pool(origin, opts); } var Agent = class extends DispatcherBase { - constructor({ factory = defaultFactory, maxRedirections = 0, connect, ...options } = {}) { + constructor({ factory = defaultFactory, maxRedirections = 0, connect, tls, ...options } = {}) { if (typeof factory !== "function") { throw new InvalidArgumentError("factory must be a function."); } @@ -8630,8 +8636,11 @@ var require_agent = __commonJS({ if (connect && typeof connect !== "function") { connect = { ...connect }; } + if (tls && typeof tls !== "function") { + tls = { ...tls }; + } this[kInterceptors] = options.interceptors?.Agent && Array.isArray(options.interceptors.Agent) ? options.interceptors.Agent : [createRedirectInterceptor({ maxRedirections })]; - this[kOptions] = { ...util.deepClone(options), connect }; + this[kOptions] = { ...util.deepClone(options), connect, tls }; this[kOptions].interceptors = options.interceptors ? { ...options.interceptors } : void 0; this[kMaxRedirections] = maxRedirections; this[kFactory] = factory; @@ -14359,8 +14368,9 @@ var require_fetch = __commonJS({ } ); response.body = { stream, source: null, length: null }; - fetchParams.controller.onAborted = onAborted; - fetchParams.controller.on("terminated", onAborted); + if (!fetchParams.controller.resume) { + fetchParams.controller.on("terminated", onAborted); + } fetchParams.controller.resume = async () => { while (true) { let bytes; @@ -14460,7 +14470,6 @@ var require_fetch = __commonJS({ headersList.append(bufferToLowerCasedHeaderName(rawHeaders[i]), rawHeaders[i + 1].toString("latin1"), true); } location = headersList.get("location", true); - this.body = new Readable({ read: resume }); const decoders = []; const willFollow = location && request2.redirect === "follow" && redirectStatusSet.has(status); if (request2.method !== "HEAD" && request2.method !== "CONNECT" && !nullBodyStatus.includes(status) && !willFollow) { @@ -14468,7 +14477,7 @@ var require_fetch = __commonJS({ const codings = contentEncoding ? contentEncoding.toLowerCase().split(",") : []; const maxContentEncodings = 5; if (codings.length > maxContentEncodings) { - reject(new Error(`too many content-encodings in response: ${codings.length}, maximum allowed is ${maxContentEncodings}`)); + this.abort(new Error(`too many content-encodings in response: ${codings.length}, maximum allowed is ${maxContentEncodings}`)); return true; } for (let i = codings.length - 1; i >= 0; --i) { @@ -14498,6 +14507,7 @@ var require_fetch = __commonJS({ } } } + this.body = new Readable({ read: resume }); const onError = this.onError.bind(this); resolve({ status, @@ -14523,9 +14533,6 @@ var require_fetch = __commonJS({ if (this.abort) { fetchParams.controller.off("terminated", this.abort); } - if (fetchParams.controller.onAborted) { - fetchParams.controller.off("terminated", fetchParams.controller.onAborted); - } fetchParams.controller.ended = true; this.body.push(null); }, @@ -17599,6 +17606,16 @@ var require_receiver = __commonJS({ if (isControlFrame(this.#info.opcode)) { this.#loop = this.parseControlFrame(body); this.#state = parserStates.INFO; + const socket = this.ws[kResponse].socket; + if (this.#loop && socket.writableNeedDrain) { + this.#loop = false; + socket.once("drain", () => { + if (this.destroyed) return; + this.#loop = true; + this.run(callback); + }); + return; + } } else { if (!this.#info.compressed) { if (!this.writeFragments(body)) { @@ -18292,6 +18309,7 @@ var require_util8 = __commonJS({ var require_eventsource_stream = __commonJS({ "node_modules/undici/lib/web/eventsource/eventsource-stream.js"(exports, module) { "use strict"; + var buffer = __require("node:buffer"); var { Transform } = __require("node:stream"); var { isASCIINumber, isValidLastEventId } = require_util8(); var BOM = [239, 187, 191]; @@ -18299,24 +18317,28 @@ var require_eventsource_stream = __commonJS({ var CR = 13; var COLON = 58; var SPACE = 32; + var defaultMaxEventSize = buffer.kStringMaxLength; var DATA = Buffer.from("data"); var EVENT = Buffer.from("event"); var ID = Buffer.from("id"); var RETRY = Buffer.from("retry"); - function isASCIINumberBytes(buffer, start) { - if (start >= buffer.length) { + var minParserItems = 1024; + var maxParserItems = 131072; + var bytesPerParserItem = 128; + function isASCIINumberBytes(buffer2, start) { + if (start >= buffer2.length) { return false; } - for (let i = start; i < buffer.length; i++) { - if (buffer[i] < 48 || buffer[i] > 57) { + for (let i = start; i < buffer2.length; i++) { + if (buffer2[i] < 48 || buffer2[i] > 57) { return false; } } return true; } - function isValidLastEventIdBytes(buffer, start) { - for (let i = start; i < buffer.length; i++) { - if (buffer[i] === 0) { + function isValidLastEventIdBytes(buffer2, start) { + for (let i = start; i < buffer2.length; i++) { + if (buffer2[i] === 0) { return false; } } @@ -18333,6 +18355,11 @@ var require_eventsource_stream = __commonJS({ } return true; } + function createMaxEventSizeExceededError() { + const error2 = new Error("EventSource message size exceeded"); + error2.aborted = false; + return error2; + } var EventSourceStream = class extends Transform { /** * @type {eventSourceSettings} @@ -18359,6 +18386,13 @@ var require_eventsource_stream = __commonJS({ 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: void 0, event: void 0, @@ -18367,6 +18401,7 @@ var require_eventsource_stream = __commonJS({ }; /** * @param {object} options + * @param {number} [options.maxEventSize] * @param {eventSourceSettings} options.eventSourceSettings * @param {Function} [options.push] */ @@ -18374,6 +18409,10 @@ var require_eventsource_stream = __commonJS({ options.readableObjectMode = true; 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; } @@ -18389,6 +18428,10 @@ var require_eventsource_stream = __commonJS({ callback(); return; } + if (this.maxEventSize > 0 && this.chunks.length >= this.maxBufferedChunks && chunk[0] !== LF && chunk[0] !== CR) { + callback(createMaxEventSizeExceededError()); + return; + } this.chunks.push(chunk); if (this.checkBOM) { if (this.handleBOM()) { @@ -18425,18 +18468,32 @@ var require_eventsource_stream = __commonJS({ if (byte === CR) { this.crlfCheck = true; } - this.parseLine(this.readLine(), this.event); + try { + this.parseLine(this.readLine(), this.event); + } catch (error2) { + callback(error2); + return; + } this.consumeCurrentByte(); this.eventEndCheck = true; continue; } + if (this.maxEventSize > 0 && ++this.lineLength > this.maxEventSize + 7) { + callback(createMaxEventSizeExceededError()); + return; + } this.advanceCursor(); } callback(); } + _destroy(error2, callback) { + this.chunks.length = 0; + this.clearEvent(); + super._destroy(error2, callback); + } /** * @param {Buffer} line - * @param {EventStreamEvent} event + * @param {EventSourceStreamEvent} event */ parseLine(line, event) { if (line.length === 0) { @@ -18456,6 +18513,12 @@ var require_eventsource_stream = __commonJS({ } } 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 === void 0 ? 0 : 1) + valueBytes; + this.setEventFieldSize("data", dataSize); const value = line.toString("utf8", valueStart); if (event.data === void 0) { event.data = value; @@ -18463,27 +18526,38 @@ var require_eventsource_stream = __commonJS({ event.data += ` ${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; } 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 */ @@ -18510,6 +18584,12 @@ ${value}`; this.event.event = void 0; this.event.id = void 0; this.event.retry = void 0; + this.eventSize = 0; + this.dataLineCount = 0; + this.eventFieldSizes.data = 0; + this.eventFieldSizes.event = 0; + this.eventFieldSizes.id = 0; + this.eventFieldSizes.retry = 0; } hasPendingEvent() { return this.event.data !== void 0 || this.event.event !== void 0 || this.event.id !== void 0 || this.event.retry !== void 0; @@ -18534,13 +18614,15 @@ ${value}`; 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) { this.chunks.length = 0; @@ -18643,6 +18725,7 @@ var require_eventsource = __commonJS({ var { delay } = require_util8(); var { kEnumerableProperty } = require_util(); var { environmentSettingsObject } = require_util2(); + var { getGlobalDispatcher } = require_global2(); var experimentalWarned = false; var defaultReconnectionTime = 3e3; var CONNECTING = 0; @@ -18783,6 +18866,7 @@ var require_eventsource = __commonJS({ this.#state.origin = response.urlList[response.urlList.length - 1].origin; const eventSourceStream = new EventSourceStream({ eventSourceSettings: this.#state, + maxEventSize: this.#dispatcher.eventSourceOptions?.maxEventSize, push: (event) => { this.dispatchEvent(createFastMessageEvent( event.type, @@ -18915,7 +18999,8 @@ var require_eventsource = __commonJS({ { key: "dispatcher", // undici only - converter: webidl.converters.any + converter: webidl.converters.any, + defaultValue: () => getGlobalDispatcher() } ]); module.exports = { diff --git a/.github/actions/javascript/checkSVGCompression/index.js b/.github/actions/javascript/checkSVGCompression/index.js index cad1560febba..5b2c26a5daee 100644 --- a/.github/actions/javascript/checkSVGCompression/index.js +++ b/.github/actions/javascript/checkSVGCompression/index.js @@ -2107,6 +2107,7 @@ var require_dispatcher = __commonJS({ var require_dispatcher_base = __commonJS({ "node_modules/undici/lib/dispatcher/dispatcher-base.js"(exports, module) { "use strict"; + var buffer = __require("node:buffer"); var Dispatcher = require_dispatcher(); var { ClientDestroyedError, @@ -2118,6 +2119,7 @@ var require_dispatcher_base = __commonJS({ var kOnClosed = /* @__PURE__ */ Symbol("onClosed"); var kInterceptedDispatch = /* @__PURE__ */ Symbol("Intercepted Dispatch"); var kWebSocketOptions = /* @__PURE__ */ Symbol("webSocketOptions"); + var kEventSourceOptions = /* @__PURE__ */ Symbol("eventSourceOptions"); var DispatcherBase = class extends Dispatcher { constructor(opts) { super(); @@ -2126,6 +2128,7 @@ var require_dispatcher_base = __commonJS({ this[kClosed] = false; this[kOnClosed] = []; this[kWebSocketOptions] = opts?.webSocket ?? {}; + this[kEventSourceOptions] = opts?.eventSource ?? {}; } get webSocketOptions() { return { @@ -2133,6 +2136,11 @@ var require_dispatcher_base = __commonJS({ maxPayloadSize: this[kWebSocketOptions].maxPayloadSize ?? 128 * 1024 * 1024 }; } + get eventSourceOptions() { + return { + maxEventSize: this[kEventSourceOptions].maxEventSize ?? buffer.kStringMaxLength + }; + } get destroyed() { return this[kDestroyed]; } @@ -6280,7 +6288,6 @@ var require_client_h1 = __commonJS({ socket[kSocketUsed] = false; socket[kParser] = new Parser(client, socket, llhttpInstance); addListener(socket, "error", function(err) { - assert(err.code !== "ERR_TLS_CERT_ALTNAME_INVALID"); const parser = this[kParser]; if (err.code === "ECONNRESET" && parser.statusCode && !parser.shouldKeepAlive) { const parserErr = parser.finish(); @@ -6964,7 +6971,6 @@ var require_client_h2 = __commonJS({ client[kHTTP2Session] = session; socket[kHTTP2Session] = session; util.addListener(socket, "error", function(err) { - assert(err.code !== "ERR_TLS_CERT_ALTNAME_INVALID"); this[kError] = err; this[kClient][kOnError](err); }); @@ -7023,7 +7029,6 @@ var require_client_h2 = __commonJS({ } } function onHttp2SessionError(err) { - assert(err.code !== "ERR_TLS_CERT_ALTNAME_INVALID"); this[kSocket][kError] = err; this[kClient][kOnError](err); } @@ -7717,9 +7722,10 @@ var require_client = __commonJS({ // h2 maxConcurrentStreams, allowH2, - webSocket + webSocket, + eventSource } = {}) { - super({ webSocket }); + super({ webSocket, eventSource }); if (keepAlive !== void 0) { throw new InvalidArgumentError("unsupported keepAlive, use pipelining=0 instead"); } @@ -8616,7 +8622,7 @@ var require_agent = __commonJS({ return opts && opts.connections === 1 ? new Client(origin, opts) : new Pool(origin, opts); } var Agent = class extends DispatcherBase { - constructor({ factory = defaultFactory, maxRedirections = 0, connect, ...options } = {}) { + constructor({ factory = defaultFactory, maxRedirections = 0, connect, tls, ...options } = {}) { if (typeof factory !== "function") { throw new InvalidArgumentError("factory must be a function."); } @@ -8630,8 +8636,11 @@ var require_agent = __commonJS({ if (connect && typeof connect !== "function") { connect = { ...connect }; } + if (tls && typeof tls !== "function") { + tls = { ...tls }; + } this[kInterceptors] = options.interceptors?.Agent && Array.isArray(options.interceptors.Agent) ? options.interceptors.Agent : [createRedirectInterceptor({ maxRedirections })]; - this[kOptions] = { ...util.deepClone(options), connect }; + this[kOptions] = { ...util.deepClone(options), connect, tls }; this[kOptions].interceptors = options.interceptors ? { ...options.interceptors } : void 0; this[kMaxRedirections] = maxRedirections; this[kFactory] = factory; @@ -14359,8 +14368,9 @@ var require_fetch = __commonJS({ } ); response.body = { stream, source: null, length: null }; - fetchParams.controller.onAborted = onAborted; - fetchParams.controller.on("terminated", onAborted); + if (!fetchParams.controller.resume) { + fetchParams.controller.on("terminated", onAborted); + } fetchParams.controller.resume = async () => { while (true) { let bytes; @@ -14460,7 +14470,6 @@ var require_fetch = __commonJS({ headersList.append(bufferToLowerCasedHeaderName(rawHeaders[i]), rawHeaders[i + 1].toString("latin1"), true); } location = headersList.get("location", true); - this.body = new Readable({ read: resume }); const decoders = []; const willFollow = location && request2.redirect === "follow" && redirectStatusSet.has(status); if (request2.method !== "HEAD" && request2.method !== "CONNECT" && !nullBodyStatus.includes(status) && !willFollow) { @@ -14468,7 +14477,7 @@ var require_fetch = __commonJS({ const codings = contentEncoding ? contentEncoding.toLowerCase().split(",") : []; const maxContentEncodings = 5; if (codings.length > maxContentEncodings) { - reject(new Error(`too many content-encodings in response: ${codings.length}, maximum allowed is ${maxContentEncodings}`)); + this.abort(new Error(`too many content-encodings in response: ${codings.length}, maximum allowed is ${maxContentEncodings}`)); return true; } for (let i = codings.length - 1; i >= 0; --i) { @@ -14498,6 +14507,7 @@ var require_fetch = __commonJS({ } } } + this.body = new Readable({ read: resume }); const onError = this.onError.bind(this); resolve2({ status, @@ -14523,9 +14533,6 @@ var require_fetch = __commonJS({ if (this.abort) { fetchParams.controller.off("terminated", this.abort); } - if (fetchParams.controller.onAborted) { - fetchParams.controller.off("terminated", fetchParams.controller.onAborted); - } fetchParams.controller.ended = true; this.body.push(null); }, @@ -17599,6 +17606,16 @@ var require_receiver = __commonJS({ if (isControlFrame(this.#info.opcode)) { this.#loop = this.parseControlFrame(body); this.#state = parserStates.INFO; + const socket = this.ws[kResponse].socket; + if (this.#loop && socket.writableNeedDrain) { + this.#loop = false; + socket.once("drain", () => { + if (this.destroyed) return; + this.#loop = true; + this.run(callback); + }); + return; + } } else { if (!this.#info.compressed) { if (!this.writeFragments(body)) { @@ -18292,6 +18309,7 @@ var require_util8 = __commonJS({ var require_eventsource_stream = __commonJS({ "node_modules/undici/lib/web/eventsource/eventsource-stream.js"(exports, module) { "use strict"; + var buffer = __require("node:buffer"); var { Transform } = __require("node:stream"); var { isASCIINumber, isValidLastEventId } = require_util8(); var BOM = [239, 187, 191]; @@ -18299,24 +18317,28 @@ var require_eventsource_stream = __commonJS({ var CR = 13; var COLON = 58; var SPACE = 32; + var defaultMaxEventSize = buffer.kStringMaxLength; var DATA = Buffer.from("data"); var EVENT = Buffer.from("event"); var ID = Buffer.from("id"); var RETRY = Buffer.from("retry"); - function isASCIINumberBytes(buffer, start) { - if (start >= buffer.length) { + var minParserItems = 1024; + var maxParserItems = 131072; + var bytesPerParserItem = 128; + function isASCIINumberBytes(buffer2, start) { + if (start >= buffer2.length) { return false; } - for (let i = start; i < buffer.length; i++) { - if (buffer[i] < 48 || buffer[i] > 57) { + for (let i = start; i < buffer2.length; i++) { + if (buffer2[i] < 48 || buffer2[i] > 57) { return false; } } return true; } - function isValidLastEventIdBytes(buffer, start) { - for (let i = start; i < buffer.length; i++) { - if (buffer[i] === 0) { + function isValidLastEventIdBytes(buffer2, start) { + for (let i = start; i < buffer2.length; i++) { + if (buffer2[i] === 0) { return false; } } @@ -18333,6 +18355,11 @@ var require_eventsource_stream = __commonJS({ } return true; } + function createMaxEventSizeExceededError() { + const error2 = new Error("EventSource message size exceeded"); + error2.aborted = false; + return error2; + } var EventSourceStream = class extends Transform { /** * @type {eventSourceSettings} @@ -18359,6 +18386,13 @@ var require_eventsource_stream = __commonJS({ 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: void 0, event: void 0, @@ -18367,6 +18401,7 @@ var require_eventsource_stream = __commonJS({ }; /** * @param {object} options + * @param {number} [options.maxEventSize] * @param {eventSourceSettings} options.eventSourceSettings * @param {Function} [options.push] */ @@ -18374,6 +18409,10 @@ var require_eventsource_stream = __commonJS({ options.readableObjectMode = true; 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; } @@ -18389,6 +18428,10 @@ var require_eventsource_stream = __commonJS({ callback(); return; } + if (this.maxEventSize > 0 && this.chunks.length >= this.maxBufferedChunks && chunk[0] !== LF && chunk[0] !== CR) { + callback(createMaxEventSizeExceededError()); + return; + } this.chunks.push(chunk); if (this.checkBOM) { if (this.handleBOM()) { @@ -18425,18 +18468,32 @@ var require_eventsource_stream = __commonJS({ if (byte === CR) { this.crlfCheck = true; } - this.parseLine(this.readLine(), this.event); + try { + this.parseLine(this.readLine(), this.event); + } catch (error2) { + callback(error2); + return; + } this.consumeCurrentByte(); this.eventEndCheck = true; continue; } + if (this.maxEventSize > 0 && ++this.lineLength > this.maxEventSize + 7) { + callback(createMaxEventSizeExceededError()); + return; + } this.advanceCursor(); } callback(); } + _destroy(error2, callback) { + this.chunks.length = 0; + this.clearEvent(); + super._destroy(error2, callback); + } /** * @param {Buffer} line - * @param {EventStreamEvent} event + * @param {EventSourceStreamEvent} event */ parseLine(line, event) { if (line.length === 0) { @@ -18456,6 +18513,12 @@ var require_eventsource_stream = __commonJS({ } } 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 === void 0 ? 0 : 1) + valueBytes; + this.setEventFieldSize("data", dataSize); const value = line.toString("utf8", valueStart); if (event.data === void 0) { event.data = value; @@ -18463,27 +18526,38 @@ var require_eventsource_stream = __commonJS({ event.data += ` ${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; } 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 */ @@ -18510,6 +18584,12 @@ ${value}`; this.event.event = void 0; this.event.id = void 0; this.event.retry = void 0; + this.eventSize = 0; + this.dataLineCount = 0; + this.eventFieldSizes.data = 0; + this.eventFieldSizes.event = 0; + this.eventFieldSizes.id = 0; + this.eventFieldSizes.retry = 0; } hasPendingEvent() { return this.event.data !== void 0 || this.event.event !== void 0 || this.event.id !== void 0 || this.event.retry !== void 0; @@ -18534,13 +18614,15 @@ ${value}`; 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) { this.chunks.length = 0; @@ -18643,6 +18725,7 @@ var require_eventsource = __commonJS({ var { delay } = require_util8(); var { kEnumerableProperty } = require_util(); var { environmentSettingsObject } = require_util2(); + var { getGlobalDispatcher } = require_global2(); var experimentalWarned = false; var defaultReconnectionTime = 3e3; var CONNECTING = 0; @@ -18783,6 +18866,7 @@ var require_eventsource = __commonJS({ this.#state.origin = response.urlList[response.urlList.length - 1].origin; const eventSourceStream = new EventSourceStream({ eventSourceSettings: this.#state, + maxEventSize: this.#dispatcher.eventSourceOptions?.maxEventSize, push: (event) => { this.dispatchEvent(createFastMessageEvent( event.type, @@ -18915,7 +18999,8 @@ var require_eventsource = __commonJS({ { key: "dispatcher", // undici only - converter: webidl.converters.any + converter: webidl.converters.any, + defaultValue: () => getGlobalDispatcher() } ]); module.exports = { diff --git a/.github/actions/javascript/failureNotifier/index.js b/.github/actions/javascript/failureNotifier/index.js index 208e6286e656..8e01c9f9da40 100644 --- a/.github/actions/javascript/failureNotifier/index.js +++ b/.github/actions/javascript/failureNotifier/index.js @@ -2107,6 +2107,7 @@ var require_dispatcher = __commonJS({ var require_dispatcher_base = __commonJS({ "node_modules/undici/lib/dispatcher/dispatcher-base.js"(exports, module) { "use strict"; + var buffer = __require("node:buffer"); var Dispatcher = require_dispatcher(); var { ClientDestroyedError, @@ -2118,6 +2119,7 @@ var require_dispatcher_base = __commonJS({ var kOnClosed = /* @__PURE__ */ Symbol("onClosed"); var kInterceptedDispatch = /* @__PURE__ */ Symbol("Intercepted Dispatch"); var kWebSocketOptions = /* @__PURE__ */ Symbol("webSocketOptions"); + var kEventSourceOptions = /* @__PURE__ */ Symbol("eventSourceOptions"); var DispatcherBase = class extends Dispatcher { constructor(opts) { super(); @@ -2126,6 +2128,7 @@ var require_dispatcher_base = __commonJS({ this[kClosed] = false; this[kOnClosed] = []; this[kWebSocketOptions] = opts?.webSocket ?? {}; + this[kEventSourceOptions] = opts?.eventSource ?? {}; } get webSocketOptions() { return { @@ -2133,6 +2136,11 @@ var require_dispatcher_base = __commonJS({ maxPayloadSize: this[kWebSocketOptions].maxPayloadSize ?? 128 * 1024 * 1024 }; } + get eventSourceOptions() { + return { + maxEventSize: this[kEventSourceOptions].maxEventSize ?? buffer.kStringMaxLength + }; + } get destroyed() { return this[kDestroyed]; } @@ -6280,7 +6288,6 @@ var require_client_h1 = __commonJS({ socket[kSocketUsed] = false; socket[kParser] = new Parser(client, socket, llhttpInstance); addListener(socket, "error", function(err) { - assert(err.code !== "ERR_TLS_CERT_ALTNAME_INVALID"); const parser = this[kParser]; if (err.code === "ECONNRESET" && parser.statusCode && !parser.shouldKeepAlive) { const parserErr = parser.finish(); @@ -6964,7 +6971,6 @@ var require_client_h2 = __commonJS({ client[kHTTP2Session] = session; socket[kHTTP2Session] = session; util.addListener(socket, "error", function(err) { - assert(err.code !== "ERR_TLS_CERT_ALTNAME_INVALID"); this[kError] = err; this[kClient][kOnError](err); }); @@ -7023,7 +7029,6 @@ var require_client_h2 = __commonJS({ } } function onHttp2SessionError(err) { - assert(err.code !== "ERR_TLS_CERT_ALTNAME_INVALID"); this[kSocket][kError] = err; this[kClient][kOnError](err); } @@ -7717,9 +7722,10 @@ var require_client = __commonJS({ // h2 maxConcurrentStreams, allowH2, - webSocket + webSocket, + eventSource } = {}) { - super({ webSocket }); + super({ webSocket, eventSource }); if (keepAlive !== void 0) { throw new InvalidArgumentError("unsupported keepAlive, use pipelining=0 instead"); } @@ -8616,7 +8622,7 @@ var require_agent = __commonJS({ return opts && opts.connections === 1 ? new Client(origin, opts) : new Pool(origin, opts); } var Agent = class extends DispatcherBase { - constructor({ factory = defaultFactory, maxRedirections = 0, connect, ...options } = {}) { + constructor({ factory = defaultFactory, maxRedirections = 0, connect, tls, ...options } = {}) { if (typeof factory !== "function") { throw new InvalidArgumentError("factory must be a function."); } @@ -8630,8 +8636,11 @@ var require_agent = __commonJS({ if (connect && typeof connect !== "function") { connect = { ...connect }; } + if (tls && typeof tls !== "function") { + tls = { ...tls }; + } this[kInterceptors] = options.interceptors?.Agent && Array.isArray(options.interceptors.Agent) ? options.interceptors.Agent : [createRedirectInterceptor({ maxRedirections })]; - this[kOptions] = { ...util.deepClone(options), connect }; + this[kOptions] = { ...util.deepClone(options), connect, tls }; this[kOptions].interceptors = options.interceptors ? { ...options.interceptors } : void 0; this[kMaxRedirections] = maxRedirections; this[kFactory] = factory; @@ -14359,8 +14368,9 @@ var require_fetch = __commonJS({ } ); response.body = { stream, source: null, length: null }; - fetchParams.controller.onAborted = onAborted; - fetchParams.controller.on("terminated", onAborted); + if (!fetchParams.controller.resume) { + fetchParams.controller.on("terminated", onAborted); + } fetchParams.controller.resume = async () => { while (true) { let bytes; @@ -14460,7 +14470,6 @@ var require_fetch = __commonJS({ headersList.append(bufferToLowerCasedHeaderName(rawHeaders[i]), rawHeaders[i + 1].toString("latin1"), true); } location = headersList.get("location", true); - this.body = new Readable({ read: resume }); const decoders = []; const willFollow = location && request2.redirect === "follow" && redirectStatusSet.has(status); if (request2.method !== "HEAD" && request2.method !== "CONNECT" && !nullBodyStatus.includes(status) && !willFollow) { @@ -14468,7 +14477,7 @@ var require_fetch = __commonJS({ const codings = contentEncoding ? contentEncoding.toLowerCase().split(",") : []; const maxContentEncodings = 5; if (codings.length > maxContentEncodings) { - reject(new Error(`too many content-encodings in response: ${codings.length}, maximum allowed is ${maxContentEncodings}`)); + this.abort(new Error(`too many content-encodings in response: ${codings.length}, maximum allowed is ${maxContentEncodings}`)); return true; } for (let i = codings.length - 1; i >= 0; --i) { @@ -14498,6 +14507,7 @@ var require_fetch = __commonJS({ } } } + this.body = new Readable({ read: resume }); const onError = this.onError.bind(this); resolve({ status, @@ -14523,9 +14533,6 @@ var require_fetch = __commonJS({ if (this.abort) { fetchParams.controller.off("terminated", this.abort); } - if (fetchParams.controller.onAborted) { - fetchParams.controller.off("terminated", fetchParams.controller.onAborted); - } fetchParams.controller.ended = true; this.body.push(null); }, @@ -17599,6 +17606,16 @@ var require_receiver = __commonJS({ if (isControlFrame(this.#info.opcode)) { this.#loop = this.parseControlFrame(body); this.#state = parserStates.INFO; + const socket = this.ws[kResponse].socket; + if (this.#loop && socket.writableNeedDrain) { + this.#loop = false; + socket.once("drain", () => { + if (this.destroyed) return; + this.#loop = true; + this.run(callback); + }); + return; + } } else { if (!this.#info.compressed) { if (!this.writeFragments(body)) { @@ -18292,6 +18309,7 @@ var require_util8 = __commonJS({ var require_eventsource_stream = __commonJS({ "node_modules/undici/lib/web/eventsource/eventsource-stream.js"(exports, module) { "use strict"; + var buffer = __require("node:buffer"); var { Transform } = __require("node:stream"); var { isASCIINumber, isValidLastEventId } = require_util8(); var BOM = [239, 187, 191]; @@ -18299,24 +18317,28 @@ var require_eventsource_stream = __commonJS({ var CR = 13; var COLON = 58; var SPACE = 32; + var defaultMaxEventSize = buffer.kStringMaxLength; var DATA = Buffer.from("data"); var EVENT = Buffer.from("event"); var ID = Buffer.from("id"); var RETRY = Buffer.from("retry"); - function isASCIINumberBytes(buffer, start) { - if (start >= buffer.length) { + var minParserItems = 1024; + var maxParserItems = 131072; + var bytesPerParserItem = 128; + function isASCIINumberBytes(buffer2, start) { + if (start >= buffer2.length) { return false; } - for (let i = start; i < buffer.length; i++) { - if (buffer[i] < 48 || buffer[i] > 57) { + for (let i = start; i < buffer2.length; i++) { + if (buffer2[i] < 48 || buffer2[i] > 57) { return false; } } return true; } - function isValidLastEventIdBytes(buffer, start) { - for (let i = start; i < buffer.length; i++) { - if (buffer[i] === 0) { + function isValidLastEventIdBytes(buffer2, start) { + for (let i = start; i < buffer2.length; i++) { + if (buffer2[i] === 0) { return false; } } @@ -18333,6 +18355,11 @@ var require_eventsource_stream = __commonJS({ } return true; } + function createMaxEventSizeExceededError() { + const error2 = new Error("EventSource message size exceeded"); + error2.aborted = false; + return error2; + } var EventSourceStream = class extends Transform { /** * @type {eventSourceSettings} @@ -18359,6 +18386,13 @@ var require_eventsource_stream = __commonJS({ 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: void 0, event: void 0, @@ -18367,6 +18401,7 @@ var require_eventsource_stream = __commonJS({ }; /** * @param {object} options + * @param {number} [options.maxEventSize] * @param {eventSourceSettings} options.eventSourceSettings * @param {Function} [options.push] */ @@ -18374,6 +18409,10 @@ var require_eventsource_stream = __commonJS({ options.readableObjectMode = true; 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; } @@ -18389,6 +18428,10 @@ var require_eventsource_stream = __commonJS({ callback(); return; } + if (this.maxEventSize > 0 && this.chunks.length >= this.maxBufferedChunks && chunk[0] !== LF && chunk[0] !== CR) { + callback(createMaxEventSizeExceededError()); + return; + } this.chunks.push(chunk); if (this.checkBOM) { if (this.handleBOM()) { @@ -18425,18 +18468,32 @@ var require_eventsource_stream = __commonJS({ if (byte === CR) { this.crlfCheck = true; } - this.parseLine(this.readLine(), this.event); + try { + this.parseLine(this.readLine(), this.event); + } catch (error2) { + callback(error2); + return; + } this.consumeCurrentByte(); this.eventEndCheck = true; continue; } + if (this.maxEventSize > 0 && ++this.lineLength > this.maxEventSize + 7) { + callback(createMaxEventSizeExceededError()); + return; + } this.advanceCursor(); } callback(); } + _destroy(error2, callback) { + this.chunks.length = 0; + this.clearEvent(); + super._destroy(error2, callback); + } /** * @param {Buffer} line - * @param {EventStreamEvent} event + * @param {EventSourceStreamEvent} event */ parseLine(line, event) { if (line.length === 0) { @@ -18456,6 +18513,12 @@ var require_eventsource_stream = __commonJS({ } } 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 === void 0 ? 0 : 1) + valueBytes; + this.setEventFieldSize("data", dataSize); const value = line.toString("utf8", valueStart); if (event.data === void 0) { event.data = value; @@ -18463,27 +18526,38 @@ var require_eventsource_stream = __commonJS({ event.data += ` ${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; } 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 */ @@ -18510,6 +18584,12 @@ ${value}`; this.event.event = void 0; this.event.id = void 0; this.event.retry = void 0; + this.eventSize = 0; + this.dataLineCount = 0; + this.eventFieldSizes.data = 0; + this.eventFieldSizes.event = 0; + this.eventFieldSizes.id = 0; + this.eventFieldSizes.retry = 0; } hasPendingEvent() { return this.event.data !== void 0 || this.event.event !== void 0 || this.event.id !== void 0 || this.event.retry !== void 0; @@ -18534,13 +18614,15 @@ ${value}`; 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) { this.chunks.length = 0; @@ -18643,6 +18725,7 @@ var require_eventsource = __commonJS({ var { delay } = require_util8(); var { kEnumerableProperty } = require_util(); var { environmentSettingsObject } = require_util2(); + var { getGlobalDispatcher } = require_global2(); var experimentalWarned = false; var defaultReconnectionTime = 3e3; var CONNECTING = 0; @@ -18783,6 +18866,7 @@ var require_eventsource = __commonJS({ this.#state.origin = response.urlList[response.urlList.length - 1].origin; const eventSourceStream = new EventSourceStream({ eventSourceSettings: this.#state, + maxEventSize: this.#dispatcher.eventSourceOptions?.maxEventSize, push: (event) => { this.dispatchEvent(createFastMessageEvent( event.type, @@ -18915,7 +18999,8 @@ var require_eventsource = __commonJS({ { key: "dispatcher", // undici only - converter: webidl.converters.any + converter: webidl.converters.any, + defaultValue: () => getGlobalDispatcher() } ]); module.exports = { diff --git a/.github/actions/javascript/formatCodeCovComment/index.js b/.github/actions/javascript/formatCodeCovComment/index.js index 9aac21e43b56..ccb02ab6de16 100644 --- a/.github/actions/javascript/formatCodeCovComment/index.js +++ b/.github/actions/javascript/formatCodeCovComment/index.js @@ -2107,6 +2107,7 @@ var require_dispatcher = __commonJS({ var require_dispatcher_base = __commonJS({ "node_modules/undici/lib/dispatcher/dispatcher-base.js"(exports, module) { "use strict"; + var buffer = __require("node:buffer"); var Dispatcher = require_dispatcher(); var { ClientDestroyedError, @@ -2118,6 +2119,7 @@ var require_dispatcher_base = __commonJS({ var kOnClosed = /* @__PURE__ */ Symbol("onClosed"); var kInterceptedDispatch = /* @__PURE__ */ Symbol("Intercepted Dispatch"); var kWebSocketOptions = /* @__PURE__ */ Symbol("webSocketOptions"); + var kEventSourceOptions = /* @__PURE__ */ Symbol("eventSourceOptions"); var DispatcherBase = class extends Dispatcher { constructor(opts) { super(); @@ -2126,6 +2128,7 @@ var require_dispatcher_base = __commonJS({ this[kClosed] = false; this[kOnClosed] = []; this[kWebSocketOptions] = opts?.webSocket ?? {}; + this[kEventSourceOptions] = opts?.eventSource ?? {}; } get webSocketOptions() { return { @@ -2133,6 +2136,11 @@ var require_dispatcher_base = __commonJS({ maxPayloadSize: this[kWebSocketOptions].maxPayloadSize ?? 128 * 1024 * 1024 }; } + get eventSourceOptions() { + return { + maxEventSize: this[kEventSourceOptions].maxEventSize ?? buffer.kStringMaxLength + }; + } get destroyed() { return this[kDestroyed]; } @@ -6280,7 +6288,6 @@ var require_client_h1 = __commonJS({ socket[kSocketUsed] = false; socket[kParser] = new Parser(client, socket, llhttpInstance); addListener(socket, "error", function(err) { - assert(err.code !== "ERR_TLS_CERT_ALTNAME_INVALID"); const parser = this[kParser]; if (err.code === "ECONNRESET" && parser.statusCode && !parser.shouldKeepAlive) { const parserErr = parser.finish(); @@ -6964,7 +6971,6 @@ var require_client_h2 = __commonJS({ client[kHTTP2Session] = session; socket[kHTTP2Session] = session; util.addListener(socket, "error", function(err) { - assert(err.code !== "ERR_TLS_CERT_ALTNAME_INVALID"); this[kError] = err; this[kClient][kOnError](err); }); @@ -7023,7 +7029,6 @@ var require_client_h2 = __commonJS({ } } function onHttp2SessionError(err) { - assert(err.code !== "ERR_TLS_CERT_ALTNAME_INVALID"); this[kSocket][kError] = err; this[kClient][kOnError](err); } @@ -7717,9 +7722,10 @@ var require_client = __commonJS({ // h2 maxConcurrentStreams, allowH2, - webSocket + webSocket, + eventSource } = {}) { - super({ webSocket }); + super({ webSocket, eventSource }); if (keepAlive !== void 0) { throw new InvalidArgumentError("unsupported keepAlive, use pipelining=0 instead"); } @@ -8616,7 +8622,7 @@ var require_agent = __commonJS({ return opts && opts.connections === 1 ? new Client(origin, opts) : new Pool(origin, opts); } var Agent = class extends DispatcherBase { - constructor({ factory = defaultFactory, maxRedirections = 0, connect, ...options } = {}) { + constructor({ factory = defaultFactory, maxRedirections = 0, connect, tls, ...options } = {}) { if (typeof factory !== "function") { throw new InvalidArgumentError("factory must be a function."); } @@ -8630,8 +8636,11 @@ var require_agent = __commonJS({ if (connect && typeof connect !== "function") { connect = { ...connect }; } + if (tls && typeof tls !== "function") { + tls = { ...tls }; + } this[kInterceptors] = options.interceptors?.Agent && Array.isArray(options.interceptors.Agent) ? options.interceptors.Agent : [createRedirectInterceptor({ maxRedirections })]; - this[kOptions] = { ...util.deepClone(options), connect }; + this[kOptions] = { ...util.deepClone(options), connect, tls }; this[kOptions].interceptors = options.interceptors ? { ...options.interceptors } : void 0; this[kMaxRedirections] = maxRedirections; this[kFactory] = factory; @@ -14359,8 +14368,9 @@ var require_fetch = __commonJS({ } ); response.body = { stream, source: null, length: null }; - fetchParams.controller.onAborted = onAborted; - fetchParams.controller.on("terminated", onAborted); + if (!fetchParams.controller.resume) { + fetchParams.controller.on("terminated", onAborted); + } fetchParams.controller.resume = async () => { while (true) { let bytes; @@ -14460,7 +14470,6 @@ var require_fetch = __commonJS({ headersList.append(bufferToLowerCasedHeaderName(rawHeaders[i]), rawHeaders[i + 1].toString("latin1"), true); } location = headersList.get("location", true); - this.body = new Readable({ read: resume }); const decoders = []; const willFollow = location && request2.redirect === "follow" && redirectStatusSet.has(status); if (request2.method !== "HEAD" && request2.method !== "CONNECT" && !nullBodyStatus.includes(status) && !willFollow) { @@ -14468,7 +14477,7 @@ var require_fetch = __commonJS({ const codings = contentEncoding ? contentEncoding.toLowerCase().split(",") : []; const maxContentEncodings = 5; if (codings.length > maxContentEncodings) { - reject(new Error(`too many content-encodings in response: ${codings.length}, maximum allowed is ${maxContentEncodings}`)); + this.abort(new Error(`too many content-encodings in response: ${codings.length}, maximum allowed is ${maxContentEncodings}`)); return true; } for (let i = codings.length - 1; i >= 0; --i) { @@ -14498,6 +14507,7 @@ var require_fetch = __commonJS({ } } } + this.body = new Readable({ read: resume }); const onError = this.onError.bind(this); resolve({ status, @@ -14523,9 +14533,6 @@ var require_fetch = __commonJS({ if (this.abort) { fetchParams.controller.off("terminated", this.abort); } - if (fetchParams.controller.onAborted) { - fetchParams.controller.off("terminated", fetchParams.controller.onAborted); - } fetchParams.controller.ended = true; this.body.push(null); }, @@ -17599,6 +17606,16 @@ var require_receiver = __commonJS({ if (isControlFrame(this.#info.opcode)) { this.#loop = this.parseControlFrame(body); this.#state = parserStates.INFO; + const socket = this.ws[kResponse].socket; + if (this.#loop && socket.writableNeedDrain) { + this.#loop = false; + socket.once("drain", () => { + if (this.destroyed) return; + this.#loop = true; + this.run(callback); + }); + return; + } } else { if (!this.#info.compressed) { if (!this.writeFragments(body)) { @@ -18292,6 +18309,7 @@ var require_util8 = __commonJS({ var require_eventsource_stream = __commonJS({ "node_modules/undici/lib/web/eventsource/eventsource-stream.js"(exports, module) { "use strict"; + var buffer = __require("node:buffer"); var { Transform } = __require("node:stream"); var { isASCIINumber, isValidLastEventId } = require_util8(); var BOM = [239, 187, 191]; @@ -18299,24 +18317,28 @@ var require_eventsource_stream = __commonJS({ var CR = 13; var COLON = 58; var SPACE = 32; + var defaultMaxEventSize = buffer.kStringMaxLength; var DATA = Buffer.from("data"); var EVENT = Buffer.from("event"); var ID = Buffer.from("id"); var RETRY = Buffer.from("retry"); - function isASCIINumberBytes(buffer, start) { - if (start >= buffer.length) { + var minParserItems = 1024; + var maxParserItems = 131072; + var bytesPerParserItem = 128; + function isASCIINumberBytes(buffer2, start) { + if (start >= buffer2.length) { return false; } - for (let i = start; i < buffer.length; i++) { - if (buffer[i] < 48 || buffer[i] > 57) { + for (let i = start; i < buffer2.length; i++) { + if (buffer2[i] < 48 || buffer2[i] > 57) { return false; } } return true; } - function isValidLastEventIdBytes(buffer, start) { - for (let i = start; i < buffer.length; i++) { - if (buffer[i] === 0) { + function isValidLastEventIdBytes(buffer2, start) { + for (let i = start; i < buffer2.length; i++) { + if (buffer2[i] === 0) { return false; } } @@ -18333,6 +18355,11 @@ var require_eventsource_stream = __commonJS({ } return true; } + function createMaxEventSizeExceededError() { + const error2 = new Error("EventSource message size exceeded"); + error2.aborted = false; + return error2; + } var EventSourceStream = class extends Transform { /** * @type {eventSourceSettings} @@ -18359,6 +18386,13 @@ var require_eventsource_stream = __commonJS({ 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: void 0, event: void 0, @@ -18367,6 +18401,7 @@ var require_eventsource_stream = __commonJS({ }; /** * @param {object} options + * @param {number} [options.maxEventSize] * @param {eventSourceSettings} options.eventSourceSettings * @param {Function} [options.push] */ @@ -18374,6 +18409,10 @@ var require_eventsource_stream = __commonJS({ options.readableObjectMode = true; 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; } @@ -18389,6 +18428,10 @@ var require_eventsource_stream = __commonJS({ callback(); return; } + if (this.maxEventSize > 0 && this.chunks.length >= this.maxBufferedChunks && chunk[0] !== LF && chunk[0] !== CR) { + callback(createMaxEventSizeExceededError()); + return; + } this.chunks.push(chunk); if (this.checkBOM) { if (this.handleBOM()) { @@ -18425,18 +18468,32 @@ var require_eventsource_stream = __commonJS({ if (byte === CR) { this.crlfCheck = true; } - this.parseLine(this.readLine(), this.event); + try { + this.parseLine(this.readLine(), this.event); + } catch (error2) { + callback(error2); + return; + } this.consumeCurrentByte(); this.eventEndCheck = true; continue; } + if (this.maxEventSize > 0 && ++this.lineLength > this.maxEventSize + 7) { + callback(createMaxEventSizeExceededError()); + return; + } this.advanceCursor(); } callback(); } + _destroy(error2, callback) { + this.chunks.length = 0; + this.clearEvent(); + super._destroy(error2, callback); + } /** * @param {Buffer} line - * @param {EventStreamEvent} event + * @param {EventSourceStreamEvent} event */ parseLine(line, event) { if (line.length === 0) { @@ -18456,6 +18513,12 @@ var require_eventsource_stream = __commonJS({ } } 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 === void 0 ? 0 : 1) + valueBytes; + this.setEventFieldSize("data", dataSize); const value = line.toString("utf8", valueStart); if (event.data === void 0) { event.data = value; @@ -18463,27 +18526,38 @@ var require_eventsource_stream = __commonJS({ event.data += ` ${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; } 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 */ @@ -18510,6 +18584,12 @@ ${value}`; this.event.event = void 0; this.event.id = void 0; this.event.retry = void 0; + this.eventSize = 0; + this.dataLineCount = 0; + this.eventFieldSizes.data = 0; + this.eventFieldSizes.event = 0; + this.eventFieldSizes.id = 0; + this.eventFieldSizes.retry = 0; } hasPendingEvent() { return this.event.data !== void 0 || this.event.event !== void 0 || this.event.id !== void 0 || this.event.retry !== void 0; @@ -18534,13 +18614,15 @@ ${value}`; 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) { this.chunks.length = 0; @@ -18643,6 +18725,7 @@ var require_eventsource = __commonJS({ var { delay } = require_util8(); var { kEnumerableProperty } = require_util(); var { environmentSettingsObject } = require_util2(); + var { getGlobalDispatcher } = require_global2(); var experimentalWarned = false; var defaultReconnectionTime = 3e3; var CONNECTING = 0; @@ -18783,6 +18866,7 @@ var require_eventsource = __commonJS({ this.#state.origin = response.urlList[response.urlList.length - 1].origin; const eventSourceStream = new EventSourceStream({ eventSourceSettings: this.#state, + maxEventSize: this.#dispatcher.eventSourceOptions?.maxEventSize, push: (event) => { this.dispatchEvent(createFastMessageEvent( event.type, @@ -18915,7 +18999,8 @@ var require_eventsource = __commonJS({ { key: "dispatcher", // undici only - converter: webidl.converters.any + converter: webidl.converters.any, + defaultValue: () => getGlobalDispatcher() } ]); module.exports = { diff --git a/.github/actions/javascript/generateHelpPreviewComment/index.js b/.github/actions/javascript/generateHelpPreviewComment/index.js index 222ea227535c..fa4710b1fb20 100644 --- a/.github/actions/javascript/generateHelpPreviewComment/index.js +++ b/.github/actions/javascript/generateHelpPreviewComment/index.js @@ -2107,6 +2107,7 @@ var require_dispatcher = __commonJS({ var require_dispatcher_base = __commonJS({ "node_modules/undici/lib/dispatcher/dispatcher-base.js"(exports, module) { "use strict"; + var buffer = __require("node:buffer"); var Dispatcher = require_dispatcher(); var { ClientDestroyedError, @@ -2118,6 +2119,7 @@ var require_dispatcher_base = __commonJS({ var kOnClosed = /* @__PURE__ */ Symbol("onClosed"); var kInterceptedDispatch = /* @__PURE__ */ Symbol("Intercepted Dispatch"); var kWebSocketOptions = /* @__PURE__ */ Symbol("webSocketOptions"); + var kEventSourceOptions = /* @__PURE__ */ Symbol("eventSourceOptions"); var DispatcherBase = class extends Dispatcher { constructor(opts) { super(); @@ -2126,6 +2128,7 @@ var require_dispatcher_base = __commonJS({ this[kClosed] = false; this[kOnClosed] = []; this[kWebSocketOptions] = opts?.webSocket ?? {}; + this[kEventSourceOptions] = opts?.eventSource ?? {}; } get webSocketOptions() { return { @@ -2133,6 +2136,11 @@ var require_dispatcher_base = __commonJS({ maxPayloadSize: this[kWebSocketOptions].maxPayloadSize ?? 128 * 1024 * 1024 }; } + get eventSourceOptions() { + return { + maxEventSize: this[kEventSourceOptions].maxEventSize ?? buffer.kStringMaxLength + }; + } get destroyed() { return this[kDestroyed]; } @@ -6280,7 +6288,6 @@ var require_client_h1 = __commonJS({ socket[kSocketUsed] = false; socket[kParser] = new Parser(client, socket, llhttpInstance); addListener(socket, "error", function(err) { - assert(err.code !== "ERR_TLS_CERT_ALTNAME_INVALID"); const parser = this[kParser]; if (err.code === "ECONNRESET" && parser.statusCode && !parser.shouldKeepAlive) { const parserErr = parser.finish(); @@ -6964,7 +6971,6 @@ var require_client_h2 = __commonJS({ client[kHTTP2Session] = session; socket[kHTTP2Session] = session; util.addListener(socket, "error", function(err) { - assert(err.code !== "ERR_TLS_CERT_ALTNAME_INVALID"); this[kError] = err; this[kClient][kOnError](err); }); @@ -7023,7 +7029,6 @@ var require_client_h2 = __commonJS({ } } function onHttp2SessionError(err) { - assert(err.code !== "ERR_TLS_CERT_ALTNAME_INVALID"); this[kSocket][kError] = err; this[kClient][kOnError](err); } @@ -7717,9 +7722,10 @@ var require_client = __commonJS({ // h2 maxConcurrentStreams, allowH2, - webSocket + webSocket, + eventSource } = {}) { - super({ webSocket }); + super({ webSocket, eventSource }); if (keepAlive !== void 0) { throw new InvalidArgumentError("unsupported keepAlive, use pipelining=0 instead"); } @@ -8616,7 +8622,7 @@ var require_agent = __commonJS({ return opts && opts.connections === 1 ? new Client(origin, opts) : new Pool(origin, opts); } var Agent = class extends DispatcherBase { - constructor({ factory = defaultFactory, maxRedirections = 0, connect, ...options } = {}) { + constructor({ factory = defaultFactory, maxRedirections = 0, connect, tls, ...options } = {}) { if (typeof factory !== "function") { throw new InvalidArgumentError("factory must be a function."); } @@ -8630,8 +8636,11 @@ var require_agent = __commonJS({ if (connect && typeof connect !== "function") { connect = { ...connect }; } + if (tls && typeof tls !== "function") { + tls = { ...tls }; + } this[kInterceptors] = options.interceptors?.Agent && Array.isArray(options.interceptors.Agent) ? options.interceptors.Agent : [createRedirectInterceptor({ maxRedirections })]; - this[kOptions] = { ...util.deepClone(options), connect }; + this[kOptions] = { ...util.deepClone(options), connect, tls }; this[kOptions].interceptors = options.interceptors ? { ...options.interceptors } : void 0; this[kMaxRedirections] = maxRedirections; this[kFactory] = factory; @@ -14359,8 +14368,9 @@ var require_fetch = __commonJS({ } ); response.body = { stream, source: null, length: null }; - fetchParams.controller.onAborted = onAborted; - fetchParams.controller.on("terminated", onAborted); + if (!fetchParams.controller.resume) { + fetchParams.controller.on("terminated", onAborted); + } fetchParams.controller.resume = async () => { while (true) { let bytes; @@ -14460,7 +14470,6 @@ var require_fetch = __commonJS({ headersList.append(bufferToLowerCasedHeaderName(rawHeaders[i]), rawHeaders[i + 1].toString("latin1"), true); } location = headersList.get("location", true); - this.body = new Readable({ read: resume }); const decoders = []; const willFollow = location && request2.redirect === "follow" && redirectStatusSet.has(status); if (request2.method !== "HEAD" && request2.method !== "CONNECT" && !nullBodyStatus.includes(status) && !willFollow) { @@ -14468,7 +14477,7 @@ var require_fetch = __commonJS({ const codings = contentEncoding ? contentEncoding.toLowerCase().split(",") : []; const maxContentEncodings = 5; if (codings.length > maxContentEncodings) { - reject(new Error(`too many content-encodings in response: ${codings.length}, maximum allowed is ${maxContentEncodings}`)); + this.abort(new Error(`too many content-encodings in response: ${codings.length}, maximum allowed is ${maxContentEncodings}`)); return true; } for (let i = codings.length - 1; i >= 0; --i) { @@ -14498,6 +14507,7 @@ var require_fetch = __commonJS({ } } } + this.body = new Readable({ read: resume }); const onError = this.onError.bind(this); resolve({ status, @@ -14523,9 +14533,6 @@ var require_fetch = __commonJS({ if (this.abort) { fetchParams.controller.off("terminated", this.abort); } - if (fetchParams.controller.onAborted) { - fetchParams.controller.off("terminated", fetchParams.controller.onAborted); - } fetchParams.controller.ended = true; this.body.push(null); }, @@ -17599,6 +17606,16 @@ var require_receiver = __commonJS({ if (isControlFrame(this.#info.opcode)) { this.#loop = this.parseControlFrame(body); this.#state = parserStates.INFO; + const socket = this.ws[kResponse].socket; + if (this.#loop && socket.writableNeedDrain) { + this.#loop = false; + socket.once("drain", () => { + if (this.destroyed) return; + this.#loop = true; + this.run(callback); + }); + return; + } } else { if (!this.#info.compressed) { if (!this.writeFragments(body)) { @@ -18292,6 +18309,7 @@ var require_util8 = __commonJS({ var require_eventsource_stream = __commonJS({ "node_modules/undici/lib/web/eventsource/eventsource-stream.js"(exports, module) { "use strict"; + var buffer = __require("node:buffer"); var { Transform } = __require("node:stream"); var { isASCIINumber, isValidLastEventId } = require_util8(); var BOM = [239, 187, 191]; @@ -18299,24 +18317,28 @@ var require_eventsource_stream = __commonJS({ var CR = 13; var COLON = 58; var SPACE = 32; + var defaultMaxEventSize = buffer.kStringMaxLength; var DATA = Buffer.from("data"); var EVENT = Buffer.from("event"); var ID = Buffer.from("id"); var RETRY = Buffer.from("retry"); - function isASCIINumberBytes(buffer, start) { - if (start >= buffer.length) { + var minParserItems = 1024; + var maxParserItems = 131072; + var bytesPerParserItem = 128; + function isASCIINumberBytes(buffer2, start) { + if (start >= buffer2.length) { return false; } - for (let i = start; i < buffer.length; i++) { - if (buffer[i] < 48 || buffer[i] > 57) { + for (let i = start; i < buffer2.length; i++) { + if (buffer2[i] < 48 || buffer2[i] > 57) { return false; } } return true; } - function isValidLastEventIdBytes(buffer, start) { - for (let i = start; i < buffer.length; i++) { - if (buffer[i] === 0) { + function isValidLastEventIdBytes(buffer2, start) { + for (let i = start; i < buffer2.length; i++) { + if (buffer2[i] === 0) { return false; } } @@ -18333,6 +18355,11 @@ var require_eventsource_stream = __commonJS({ } return true; } + function createMaxEventSizeExceededError() { + const error = new Error("EventSource message size exceeded"); + error.aborted = false; + return error; + } var EventSourceStream = class extends Transform { /** * @type {eventSourceSettings} @@ -18359,6 +18386,13 @@ var require_eventsource_stream = __commonJS({ 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: void 0, event: void 0, @@ -18367,6 +18401,7 @@ var require_eventsource_stream = __commonJS({ }; /** * @param {object} options + * @param {number} [options.maxEventSize] * @param {eventSourceSettings} options.eventSourceSettings * @param {Function} [options.push] */ @@ -18374,6 +18409,10 @@ var require_eventsource_stream = __commonJS({ options.readableObjectMode = true; 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; } @@ -18389,6 +18428,10 @@ var require_eventsource_stream = __commonJS({ callback(); return; } + if (this.maxEventSize > 0 && this.chunks.length >= this.maxBufferedChunks && chunk[0] !== LF && chunk[0] !== CR) { + callback(createMaxEventSizeExceededError()); + return; + } this.chunks.push(chunk); if (this.checkBOM) { if (this.handleBOM()) { @@ -18425,18 +18468,32 @@ var require_eventsource_stream = __commonJS({ if (byte === CR) { this.crlfCheck = true; } - this.parseLine(this.readLine(), this.event); + try { + this.parseLine(this.readLine(), this.event); + } catch (error) { + callback(error); + return; + } this.consumeCurrentByte(); this.eventEndCheck = true; continue; } + 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 (line.length === 0) { @@ -18456,6 +18513,12 @@ var require_eventsource_stream = __commonJS({ } } 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 === void 0 ? 0 : 1) + valueBytes; + this.setEventFieldSize("data", dataSize); const value = line.toString("utf8", valueStart); if (event.data === void 0) { event.data = value; @@ -18463,27 +18526,38 @@ var require_eventsource_stream = __commonJS({ event.data += ` ${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; } 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 */ @@ -18510,6 +18584,12 @@ ${value}`; this.event.event = void 0; this.event.id = void 0; this.event.retry = void 0; + this.eventSize = 0; + this.dataLineCount = 0; + this.eventFieldSizes.data = 0; + this.eventFieldSizes.event = 0; + this.eventFieldSizes.id = 0; + this.eventFieldSizes.retry = 0; } hasPendingEvent() { return this.event.data !== void 0 || this.event.event !== void 0 || this.event.id !== void 0 || this.event.retry !== void 0; @@ -18534,13 +18614,15 @@ ${value}`; 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) { this.chunks.length = 0; @@ -18643,6 +18725,7 @@ var require_eventsource = __commonJS({ var { delay } = require_util8(); var { kEnumerableProperty } = require_util(); var { environmentSettingsObject } = require_util2(); + var { getGlobalDispatcher } = require_global2(); var experimentalWarned = false; var defaultReconnectionTime = 3e3; var CONNECTING = 0; @@ -18783,6 +18866,7 @@ var require_eventsource = __commonJS({ this.#state.origin = response.urlList[response.urlList.length - 1].origin; const eventSourceStream = new EventSourceStream({ eventSourceSettings: this.#state, + maxEventSize: this.#dispatcher.eventSourceOptions?.maxEventSize, push: (event) => { this.dispatchEvent(createFastMessageEvent( event.type, @@ -18915,7 +18999,8 @@ var require_eventsource = __commonJS({ { key: "dispatcher", // undici only - converter: webidl.converters.any + converter: webidl.converters.any, + defaultValue: () => getGlobalDispatcher() } ]); module.exports = { diff --git a/.github/actions/javascript/getAndroidRolloutPercentage/index.js b/.github/actions/javascript/getAndroidRolloutPercentage/index.js index 1abd092e27ea..8decd4a64612 100644 --- a/.github/actions/javascript/getAndroidRolloutPercentage/index.js +++ b/.github/actions/javascript/getAndroidRolloutPercentage/index.js @@ -2119,6 +2119,7 @@ var require_dispatcher = __commonJS({ var require_dispatcher_base = __commonJS({ "node_modules/undici/lib/dispatcher/dispatcher-base.js"(exports, module) { "use strict"; + var buffer = __require("node:buffer"); var Dispatcher = require_dispatcher(); var { ClientDestroyedError, @@ -2130,6 +2131,7 @@ var require_dispatcher_base = __commonJS({ var kOnClosed = /* @__PURE__ */ Symbol("onClosed"); var kInterceptedDispatch = /* @__PURE__ */ Symbol("Intercepted Dispatch"); var kWebSocketOptions = /* @__PURE__ */ Symbol("webSocketOptions"); + var kEventSourceOptions = /* @__PURE__ */ Symbol("eventSourceOptions"); var DispatcherBase = class extends Dispatcher { constructor(opts) { super(); @@ -2138,6 +2140,7 @@ var require_dispatcher_base = __commonJS({ this[kClosed] = false; this[kOnClosed] = []; this[kWebSocketOptions] = opts?.webSocket ?? {}; + this[kEventSourceOptions] = opts?.eventSource ?? {}; } get webSocketOptions() { return { @@ -2145,6 +2148,11 @@ var require_dispatcher_base = __commonJS({ maxPayloadSize: this[kWebSocketOptions].maxPayloadSize ?? 128 * 1024 * 1024 }; } + get eventSourceOptions() { + return { + maxEventSize: this[kEventSourceOptions].maxEventSize ?? buffer.kStringMaxLength + }; + } get destroyed() { return this[kDestroyed]; } @@ -6292,7 +6300,6 @@ var require_client_h1 = __commonJS({ socket[kSocketUsed] = false; socket[kParser] = new Parser(client, socket, llhttpInstance); addListener(socket, "error", function(err) { - assert(err.code !== "ERR_TLS_CERT_ALTNAME_INVALID"); const parser = this[kParser]; if (err.code === "ECONNRESET" && parser.statusCode && !parser.shouldKeepAlive) { const parserErr = parser.finish(); @@ -6976,7 +6983,6 @@ var require_client_h2 = __commonJS({ client[kHTTP2Session] = session; socket[kHTTP2Session] = session; util.addListener(socket, "error", function(err) { - assert(err.code !== "ERR_TLS_CERT_ALTNAME_INVALID"); this[kError] = err; this[kClient][kOnError](err); }); @@ -7035,7 +7041,6 @@ var require_client_h2 = __commonJS({ } } function onHttp2SessionError(err) { - assert(err.code !== "ERR_TLS_CERT_ALTNAME_INVALID"); this[kSocket][kError] = err; this[kClient][kOnError](err); } @@ -7729,9 +7734,10 @@ var require_client = __commonJS({ // h2 maxConcurrentStreams, allowH2, - webSocket + webSocket, + eventSource } = {}) { - super({ webSocket }); + super({ webSocket, eventSource }); if (keepAlive !== void 0) { throw new InvalidArgumentError("unsupported keepAlive, use pipelining=0 instead"); } @@ -8628,7 +8634,7 @@ var require_agent = __commonJS({ return opts && opts.connections === 1 ? new Client(origin, opts) : new Pool(origin, opts); } var Agent = class extends DispatcherBase { - constructor({ factory = defaultFactory, maxRedirections = 0, connect, ...options } = {}) { + constructor({ factory = defaultFactory, maxRedirections = 0, connect, tls, ...options } = {}) { if (typeof factory !== "function") { throw new InvalidArgumentError("factory must be a function."); } @@ -8642,8 +8648,11 @@ var require_agent = __commonJS({ if (connect && typeof connect !== "function") { connect = { ...connect }; } + if (tls && typeof tls !== "function") { + tls = { ...tls }; + } this[kInterceptors] = options.interceptors?.Agent && Array.isArray(options.interceptors.Agent) ? options.interceptors.Agent : [createRedirectInterceptor({ maxRedirections })]; - this[kOptions] = { ...util.deepClone(options), connect }; + this[kOptions] = { ...util.deepClone(options), connect, tls }; this[kOptions].interceptors = options.interceptors ? { ...options.interceptors } : void 0; this[kMaxRedirections] = maxRedirections; this[kFactory] = factory; @@ -14371,8 +14380,9 @@ var require_fetch = __commonJS({ } ); response.body = { stream, source: null, length: null }; - fetchParams.controller.onAborted = onAborted; - fetchParams.controller.on("terminated", onAborted); + if (!fetchParams.controller.resume) { + fetchParams.controller.on("terminated", onAborted); + } fetchParams.controller.resume = async () => { while (true) { let bytes; @@ -14472,7 +14482,6 @@ var require_fetch = __commonJS({ headersList.append(bufferToLowerCasedHeaderName(rawHeaders[i2]), rawHeaders[i2 + 1].toString("latin1"), true); } location = headersList.get("location", true); - this.body = new Readable({ read: resume }); const decoders = []; const willFollow = location && request.redirect === "follow" && redirectStatusSet.has(status); if (request.method !== "HEAD" && request.method !== "CONNECT" && !nullBodyStatus.includes(status) && !willFollow) { @@ -14480,7 +14489,7 @@ var require_fetch = __commonJS({ const codings = contentEncoding ? contentEncoding.toLowerCase().split(",") : []; const maxContentEncodings = 5; if (codings.length > maxContentEncodings) { - reject(new Error(`too many content-encodings in response: ${codings.length}, maximum allowed is ${maxContentEncodings}`)); + this.abort(new Error(`too many content-encodings in response: ${codings.length}, maximum allowed is ${maxContentEncodings}`)); return true; } for (let i2 = codings.length - 1; i2 >= 0; --i2) { @@ -14510,6 +14519,7 @@ var require_fetch = __commonJS({ } } } + this.body = new Readable({ read: resume }); const onError = this.onError.bind(this); resolve({ status, @@ -14535,9 +14545,6 @@ var require_fetch = __commonJS({ if (this.abort) { fetchParams.controller.off("terminated", this.abort); } - if (fetchParams.controller.onAborted) { - fetchParams.controller.off("terminated", fetchParams.controller.onAborted); - } fetchParams.controller.ended = true; this.body.push(null); }, @@ -17611,6 +17618,16 @@ var require_receiver = __commonJS({ if (isControlFrame(this.#info.opcode)) { this.#loop = this.parseControlFrame(body); this.#state = parserStates.INFO; + const socket = this.ws[kResponse].socket; + if (this.#loop && socket.writableNeedDrain) { + this.#loop = false; + socket.once("drain", () => { + if (this.destroyed) return; + this.#loop = true; + this.run(callback); + }); + return; + } } else { if (!this.#info.compressed) { if (!this.writeFragments(body)) { @@ -18304,6 +18321,7 @@ var require_util8 = __commonJS({ var require_eventsource_stream = __commonJS({ "node_modules/undici/lib/web/eventsource/eventsource-stream.js"(exports, module) { "use strict"; + var buffer = __require("node:buffer"); var { Transform } = __require("node:stream"); var { isASCIINumber, isValidLastEventId } = require_util8(); var BOM = [239, 187, 191]; @@ -18311,24 +18329,28 @@ var require_eventsource_stream = __commonJS({ var CR2 = 13; var COLON2 = 58; var SPACE2 = 32; + var defaultMaxEventSize = buffer.kStringMaxLength; var DATA = Buffer.from("data"); var EVENT = Buffer.from("event"); var ID = Buffer.from("id"); var RETRY = Buffer.from("retry"); - function isASCIINumberBytes(buffer, start) { - if (start >= buffer.length) { + var minParserItems = 1024; + var maxParserItems = 131072; + var bytesPerParserItem = 128; + function isASCIINumberBytes(buffer2, start) { + if (start >= buffer2.length) { return false; } - for (let i2 = start; i2 < buffer.length; i2++) { - if (buffer[i2] < 48 || buffer[i2] > 57) { + for (let i2 = start; i2 < buffer2.length; i2++) { + if (buffer2[i2] < 48 || buffer2[i2] > 57) { return false; } } return true; } - function isValidLastEventIdBytes(buffer, start) { - for (let i2 = start; i2 < buffer.length; i2++) { - if (buffer[i2] === 0) { + function isValidLastEventIdBytes(buffer2, start) { + for (let i2 = start; i2 < buffer2.length; i2++) { + if (buffer2[i2] === 0) { return false; } } @@ -18345,6 +18367,11 @@ var require_eventsource_stream = __commonJS({ } return true; } + function createMaxEventSizeExceededError() { + const error = new Error("EventSource message size exceeded"); + error.aborted = false; + return error; + } var EventSourceStream = class extends Transform { /** * @type {eventSourceSettings} @@ -18371,6 +18398,13 @@ var require_eventsource_stream = __commonJS({ 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: void 0, event: void 0, @@ -18379,6 +18413,7 @@ var require_eventsource_stream = __commonJS({ }; /** * @param {object} options + * @param {number} [options.maxEventSize] * @param {eventSourceSettings} options.eventSourceSettings * @param {Function} [options.push] */ @@ -18386,6 +18421,10 @@ var require_eventsource_stream = __commonJS({ options.readableObjectMode = true; 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; } @@ -18401,6 +18440,10 @@ var require_eventsource_stream = __commonJS({ callback(); return; } + if (this.maxEventSize > 0 && this.chunks.length >= this.maxBufferedChunks && chunk[0] !== LF2 && chunk[0] !== CR2) { + callback(createMaxEventSizeExceededError()); + return; + } this.chunks.push(chunk); if (this.checkBOM) { if (this.handleBOM()) { @@ -18437,18 +18480,32 @@ var require_eventsource_stream = __commonJS({ if (byte === CR2) { this.crlfCheck = true; } - this.parseLine(this.readLine(), this.event); + try { + this.parseLine(this.readLine(), this.event); + } catch (error) { + callback(error); + return; + } this.consumeCurrentByte(); this.eventEndCheck = true; continue; } + 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 (line.length === 0) { @@ -18468,6 +18525,12 @@ var require_eventsource_stream = __commonJS({ } } 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 === void 0 ? 0 : 1) + valueBytes; + this.setEventFieldSize("data", dataSize); const value = line.toString("utf8", valueStart); if (event.data === void 0) { event.data = value; @@ -18475,27 +18538,38 @@ var require_eventsource_stream = __commonJS({ event.data += ` ${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; } 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 */ @@ -18522,6 +18596,12 @@ ${value}`; this.event.event = void 0; this.event.id = void 0; this.event.retry = void 0; + this.eventSize = 0; + this.dataLineCount = 0; + this.eventFieldSizes.data = 0; + this.eventFieldSizes.event = 0; + this.eventFieldSizes.id = 0; + this.eventFieldSizes.retry = 0; } hasPendingEvent() { return this.event.data !== void 0 || this.event.event !== void 0 || this.event.id !== void 0 || this.event.retry !== void 0; @@ -18546,13 +18626,15 @@ ${value}`; 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) { this.chunks.length = 0; @@ -18655,6 +18737,7 @@ var require_eventsource = __commonJS({ var { delay } = require_util8(); var { kEnumerableProperty } = require_util(); var { environmentSettingsObject } = require_util2(); + var { getGlobalDispatcher } = require_global2(); var experimentalWarned = false; var defaultReconnectionTime = 3e3; var CONNECTING = 0; @@ -18795,6 +18878,7 @@ var require_eventsource = __commonJS({ this.#state.origin = response.urlList[response.urlList.length - 1].origin; const eventSourceStream = new EventSourceStream({ eventSourceSettings: this.#state, + maxEventSize: this.#dispatcher.eventSourceOptions?.maxEventSize, push: (event) => { this.dispatchEvent(createFastMessageEvent( event.type, @@ -18927,7 +19011,8 @@ var require_eventsource = __commonJS({ { key: "dispatcher", // undici only - converter: webidl.converters.any + converter: webidl.converters.any, + defaultValue: () => getGlobalDispatcher() } ]); module.exports = { diff --git a/.github/actions/javascript/getArtifactInfo/index.js b/.github/actions/javascript/getArtifactInfo/index.js index b511ee174521..acd34034165c 100644 --- a/.github/actions/javascript/getArtifactInfo/index.js +++ b/.github/actions/javascript/getArtifactInfo/index.js @@ -2107,6 +2107,7 @@ var require_dispatcher = __commonJS({ var require_dispatcher_base = __commonJS({ "node_modules/undici/lib/dispatcher/dispatcher-base.js"(exports, module) { "use strict"; + var buffer = __require("node:buffer"); var Dispatcher = require_dispatcher(); var { ClientDestroyedError, @@ -2118,6 +2119,7 @@ var require_dispatcher_base = __commonJS({ var kOnClosed = /* @__PURE__ */ Symbol("onClosed"); var kInterceptedDispatch = /* @__PURE__ */ Symbol("Intercepted Dispatch"); var kWebSocketOptions = /* @__PURE__ */ Symbol("webSocketOptions"); + var kEventSourceOptions = /* @__PURE__ */ Symbol("eventSourceOptions"); var DispatcherBase = class extends Dispatcher { constructor(opts) { super(); @@ -2126,6 +2128,7 @@ var require_dispatcher_base = __commonJS({ this[kClosed] = false; this[kOnClosed] = []; this[kWebSocketOptions] = opts?.webSocket ?? {}; + this[kEventSourceOptions] = opts?.eventSource ?? {}; } get webSocketOptions() { return { @@ -2133,6 +2136,11 @@ var require_dispatcher_base = __commonJS({ maxPayloadSize: this[kWebSocketOptions].maxPayloadSize ?? 128 * 1024 * 1024 }; } + get eventSourceOptions() { + return { + maxEventSize: this[kEventSourceOptions].maxEventSize ?? buffer.kStringMaxLength + }; + } get destroyed() { return this[kDestroyed]; } @@ -6280,7 +6288,6 @@ var require_client_h1 = __commonJS({ socket[kSocketUsed] = false; socket[kParser] = new Parser(client, socket, llhttpInstance); addListener(socket, "error", function(err) { - assert(err.code !== "ERR_TLS_CERT_ALTNAME_INVALID"); const parser = this[kParser]; if (err.code === "ECONNRESET" && parser.statusCode && !parser.shouldKeepAlive) { const parserErr = parser.finish(); @@ -6964,7 +6971,6 @@ var require_client_h2 = __commonJS({ client[kHTTP2Session] = session; socket[kHTTP2Session] = session; util.addListener(socket, "error", function(err) { - assert(err.code !== "ERR_TLS_CERT_ALTNAME_INVALID"); this[kError] = err; this[kClient][kOnError](err); }); @@ -7023,7 +7029,6 @@ var require_client_h2 = __commonJS({ } } function onHttp2SessionError(err) { - assert(err.code !== "ERR_TLS_CERT_ALTNAME_INVALID"); this[kSocket][kError] = err; this[kClient][kOnError](err); } @@ -7717,9 +7722,10 @@ var require_client = __commonJS({ // h2 maxConcurrentStreams, allowH2, - webSocket + webSocket, + eventSource } = {}) { - super({ webSocket }); + super({ webSocket, eventSource }); if (keepAlive !== void 0) { throw new InvalidArgumentError("unsupported keepAlive, use pipelining=0 instead"); } @@ -8616,7 +8622,7 @@ var require_agent = __commonJS({ return opts && opts.connections === 1 ? new Client(origin, opts) : new Pool(origin, opts); } var Agent = class extends DispatcherBase { - constructor({ factory = defaultFactory, maxRedirections = 0, connect, ...options } = {}) { + constructor({ factory = defaultFactory, maxRedirections = 0, connect, tls, ...options } = {}) { if (typeof factory !== "function") { throw new InvalidArgumentError("factory must be a function."); } @@ -8630,8 +8636,11 @@ var require_agent = __commonJS({ if (connect && typeof connect !== "function") { connect = { ...connect }; } + if (tls && typeof tls !== "function") { + tls = { ...tls }; + } this[kInterceptors] = options.interceptors?.Agent && Array.isArray(options.interceptors.Agent) ? options.interceptors.Agent : [createRedirectInterceptor({ maxRedirections })]; - this[kOptions] = { ...util.deepClone(options), connect }; + this[kOptions] = { ...util.deepClone(options), connect, tls }; this[kOptions].interceptors = options.interceptors ? { ...options.interceptors } : void 0; this[kMaxRedirections] = maxRedirections; this[kFactory] = factory; @@ -14359,8 +14368,9 @@ var require_fetch = __commonJS({ } ); response.body = { stream, source: null, length: null }; - fetchParams.controller.onAborted = onAborted; - fetchParams.controller.on("terminated", onAborted); + if (!fetchParams.controller.resume) { + fetchParams.controller.on("terminated", onAborted); + } fetchParams.controller.resume = async () => { while (true) { let bytes; @@ -14460,7 +14470,6 @@ var require_fetch = __commonJS({ headersList.append(bufferToLowerCasedHeaderName(rawHeaders[i]), rawHeaders[i + 1].toString("latin1"), true); } location = headersList.get("location", true); - this.body = new Readable({ read: resume }); const decoders = []; const willFollow = location && request2.redirect === "follow" && redirectStatusSet.has(status); if (request2.method !== "HEAD" && request2.method !== "CONNECT" && !nullBodyStatus.includes(status) && !willFollow) { @@ -14468,7 +14477,7 @@ var require_fetch = __commonJS({ const codings = contentEncoding ? contentEncoding.toLowerCase().split(",") : []; const maxContentEncodings = 5; if (codings.length > maxContentEncodings) { - reject(new Error(`too many content-encodings in response: ${codings.length}, maximum allowed is ${maxContentEncodings}`)); + this.abort(new Error(`too many content-encodings in response: ${codings.length}, maximum allowed is ${maxContentEncodings}`)); return true; } for (let i = codings.length - 1; i >= 0; --i) { @@ -14498,6 +14507,7 @@ var require_fetch = __commonJS({ } } } + this.body = new Readable({ read: resume }); const onError = this.onError.bind(this); resolve({ status, @@ -14523,9 +14533,6 @@ var require_fetch = __commonJS({ if (this.abort) { fetchParams.controller.off("terminated", this.abort); } - if (fetchParams.controller.onAborted) { - fetchParams.controller.off("terminated", fetchParams.controller.onAborted); - } fetchParams.controller.ended = true; this.body.push(null); }, @@ -17599,6 +17606,16 @@ var require_receiver = __commonJS({ if (isControlFrame(this.#info.opcode)) { this.#loop = this.parseControlFrame(body); this.#state = parserStates.INFO; + const socket = this.ws[kResponse].socket; + if (this.#loop && socket.writableNeedDrain) { + this.#loop = false; + socket.once("drain", () => { + if (this.destroyed) return; + this.#loop = true; + this.run(callback); + }); + return; + } } else { if (!this.#info.compressed) { if (!this.writeFragments(body)) { @@ -18292,6 +18309,7 @@ var require_util8 = __commonJS({ var require_eventsource_stream = __commonJS({ "node_modules/undici/lib/web/eventsource/eventsource-stream.js"(exports, module) { "use strict"; + var buffer = __require("node:buffer"); var { Transform } = __require("node:stream"); var { isASCIINumber, isValidLastEventId } = require_util8(); var BOM = [239, 187, 191]; @@ -18299,24 +18317,28 @@ var require_eventsource_stream = __commonJS({ var CR = 13; var COLON = 58; var SPACE = 32; + var defaultMaxEventSize = buffer.kStringMaxLength; var DATA = Buffer.from("data"); var EVENT = Buffer.from("event"); var ID = Buffer.from("id"); var RETRY = Buffer.from("retry"); - function isASCIINumberBytes(buffer, start) { - if (start >= buffer.length) { + var minParserItems = 1024; + var maxParserItems = 131072; + var bytesPerParserItem = 128; + function isASCIINumberBytes(buffer2, start) { + if (start >= buffer2.length) { return false; } - for (let i = start; i < buffer.length; i++) { - if (buffer[i] < 48 || buffer[i] > 57) { + for (let i = start; i < buffer2.length; i++) { + if (buffer2[i] < 48 || buffer2[i] > 57) { return false; } } return true; } - function isValidLastEventIdBytes(buffer, start) { - for (let i = start; i < buffer.length; i++) { - if (buffer[i] === 0) { + function isValidLastEventIdBytes(buffer2, start) { + for (let i = start; i < buffer2.length; i++) { + if (buffer2[i] === 0) { return false; } } @@ -18333,6 +18355,11 @@ var require_eventsource_stream = __commonJS({ } return true; } + function createMaxEventSizeExceededError() { + const error2 = new Error("EventSource message size exceeded"); + error2.aborted = false; + return error2; + } var EventSourceStream = class extends Transform { /** * @type {eventSourceSettings} @@ -18359,6 +18386,13 @@ var require_eventsource_stream = __commonJS({ 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: void 0, event: void 0, @@ -18367,6 +18401,7 @@ var require_eventsource_stream = __commonJS({ }; /** * @param {object} options + * @param {number} [options.maxEventSize] * @param {eventSourceSettings} options.eventSourceSettings * @param {Function} [options.push] */ @@ -18374,6 +18409,10 @@ var require_eventsource_stream = __commonJS({ options.readableObjectMode = true; 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; } @@ -18389,6 +18428,10 @@ var require_eventsource_stream = __commonJS({ callback(); return; } + if (this.maxEventSize > 0 && this.chunks.length >= this.maxBufferedChunks && chunk[0] !== LF && chunk[0] !== CR) { + callback(createMaxEventSizeExceededError()); + return; + } this.chunks.push(chunk); if (this.checkBOM) { if (this.handleBOM()) { @@ -18425,18 +18468,32 @@ var require_eventsource_stream = __commonJS({ if (byte === CR) { this.crlfCheck = true; } - this.parseLine(this.readLine(), this.event); + try { + this.parseLine(this.readLine(), this.event); + } catch (error2) { + callback(error2); + return; + } this.consumeCurrentByte(); this.eventEndCheck = true; continue; } + if (this.maxEventSize > 0 && ++this.lineLength > this.maxEventSize + 7) { + callback(createMaxEventSizeExceededError()); + return; + } this.advanceCursor(); } callback(); } + _destroy(error2, callback) { + this.chunks.length = 0; + this.clearEvent(); + super._destroy(error2, callback); + } /** * @param {Buffer} line - * @param {EventStreamEvent} event + * @param {EventSourceStreamEvent} event */ parseLine(line, event) { if (line.length === 0) { @@ -18456,6 +18513,12 @@ var require_eventsource_stream = __commonJS({ } } 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 === void 0 ? 0 : 1) + valueBytes; + this.setEventFieldSize("data", dataSize); const value = line.toString("utf8", valueStart); if (event.data === void 0) { event.data = value; @@ -18463,27 +18526,38 @@ var require_eventsource_stream = __commonJS({ event.data += ` ${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; } 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 */ @@ -18510,6 +18584,12 @@ ${value}`; this.event.event = void 0; this.event.id = void 0; this.event.retry = void 0; + this.eventSize = 0; + this.dataLineCount = 0; + this.eventFieldSizes.data = 0; + this.eventFieldSizes.event = 0; + this.eventFieldSizes.id = 0; + this.eventFieldSizes.retry = 0; } hasPendingEvent() { return this.event.data !== void 0 || this.event.event !== void 0 || this.event.id !== void 0 || this.event.retry !== void 0; @@ -18534,13 +18614,15 @@ ${value}`; 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) { this.chunks.length = 0; @@ -18643,6 +18725,7 @@ var require_eventsource = __commonJS({ var { delay } = require_util8(); var { kEnumerableProperty } = require_util(); var { environmentSettingsObject } = require_util2(); + var { getGlobalDispatcher } = require_global2(); var experimentalWarned = false; var defaultReconnectionTime = 3e3; var CONNECTING = 0; @@ -18783,6 +18866,7 @@ var require_eventsource = __commonJS({ this.#state.origin = response.urlList[response.urlList.length - 1].origin; const eventSourceStream = new EventSourceStream({ eventSourceSettings: this.#state, + maxEventSize: this.#dispatcher.eventSourceOptions?.maxEventSize, push: (event) => { this.dispatchEvent(createFastMessageEvent( event.type, @@ -18915,7 +18999,8 @@ var require_eventsource = __commonJS({ { key: "dispatcher", // undici only - converter: webidl.converters.any + converter: webidl.converters.any, + defaultValue: () => getGlobalDispatcher() } ]); module.exports = { diff --git a/.github/actions/javascript/getDeployPullRequestList/index.js b/.github/actions/javascript/getDeployPullRequestList/index.js index f81fc1699679..ffcb5be3d7ab 100644 --- a/.github/actions/javascript/getDeployPullRequestList/index.js +++ b/.github/actions/javascript/getDeployPullRequestList/index.js @@ -2107,6 +2107,7 @@ var require_dispatcher = __commonJS({ var require_dispatcher_base = __commonJS({ "node_modules/undici/lib/dispatcher/dispatcher-base.js"(exports, module) { "use strict"; + var buffer = __require("node:buffer"); var Dispatcher = require_dispatcher(); var { ClientDestroyedError, @@ -2118,6 +2119,7 @@ var require_dispatcher_base = __commonJS({ var kOnClosed = /* @__PURE__ */ Symbol("onClosed"); var kInterceptedDispatch = /* @__PURE__ */ Symbol("Intercepted Dispatch"); var kWebSocketOptions = /* @__PURE__ */ Symbol("webSocketOptions"); + var kEventSourceOptions = /* @__PURE__ */ Symbol("eventSourceOptions"); var DispatcherBase = class extends Dispatcher { constructor(opts) { super(); @@ -2126,6 +2128,7 @@ var require_dispatcher_base = __commonJS({ this[kClosed] = false; this[kOnClosed] = []; this[kWebSocketOptions] = opts?.webSocket ?? {}; + this[kEventSourceOptions] = opts?.eventSource ?? {}; } get webSocketOptions() { return { @@ -2133,6 +2136,11 @@ var require_dispatcher_base = __commonJS({ maxPayloadSize: this[kWebSocketOptions].maxPayloadSize ?? 128 * 1024 * 1024 }; } + get eventSourceOptions() { + return { + maxEventSize: this[kEventSourceOptions].maxEventSize ?? buffer.kStringMaxLength + }; + } get destroyed() { return this[kDestroyed]; } @@ -6280,7 +6288,6 @@ var require_client_h1 = __commonJS({ socket[kSocketUsed] = false; socket[kParser] = new Parser(client, socket, llhttpInstance); addListener(socket, "error", function(err) { - assert(err.code !== "ERR_TLS_CERT_ALTNAME_INVALID"); const parser = this[kParser]; if (err.code === "ECONNRESET" && parser.statusCode && !parser.shouldKeepAlive) { const parserErr = parser.finish(); @@ -6964,7 +6971,6 @@ var require_client_h2 = __commonJS({ client[kHTTP2Session] = session; socket[kHTTP2Session] = session; util.addListener(socket, "error", function(err) { - assert(err.code !== "ERR_TLS_CERT_ALTNAME_INVALID"); this[kError] = err; this[kClient][kOnError](err); }); @@ -7023,7 +7029,6 @@ var require_client_h2 = __commonJS({ } } function onHttp2SessionError(err) { - assert(err.code !== "ERR_TLS_CERT_ALTNAME_INVALID"); this[kSocket][kError] = err; this[kClient][kOnError](err); } @@ -7717,9 +7722,10 @@ var require_client = __commonJS({ // h2 maxConcurrentStreams, allowH2, - webSocket + webSocket, + eventSource } = {}) { - super({ webSocket }); + super({ webSocket, eventSource }); if (keepAlive !== void 0) { throw new InvalidArgumentError("unsupported keepAlive, use pipelining=0 instead"); } @@ -8616,7 +8622,7 @@ var require_agent = __commonJS({ return opts && opts.connections === 1 ? new Client(origin, opts) : new Pool(origin, opts); } var Agent = class extends DispatcherBase { - constructor({ factory = defaultFactory, maxRedirections = 0, connect, ...options } = {}) { + constructor({ factory = defaultFactory, maxRedirections = 0, connect, tls, ...options } = {}) { if (typeof factory !== "function") { throw new InvalidArgumentError("factory must be a function."); } @@ -8630,8 +8636,11 @@ var require_agent = __commonJS({ if (connect && typeof connect !== "function") { connect = { ...connect }; } + if (tls && typeof tls !== "function") { + tls = { ...tls }; + } this[kInterceptors] = options.interceptors?.Agent && Array.isArray(options.interceptors.Agent) ? options.interceptors.Agent : [createRedirectInterceptor({ maxRedirections })]; - this[kOptions] = { ...util.deepClone(options), connect }; + this[kOptions] = { ...util.deepClone(options), connect, tls }; this[kOptions].interceptors = options.interceptors ? { ...options.interceptors } : void 0; this[kMaxRedirections] = maxRedirections; this[kFactory] = factory; @@ -14359,8 +14368,9 @@ var require_fetch = __commonJS({ } ); response.body = { stream, source: null, length: null }; - fetchParams.controller.onAborted = onAborted; - fetchParams.controller.on("terminated", onAborted); + if (!fetchParams.controller.resume) { + fetchParams.controller.on("terminated", onAborted); + } fetchParams.controller.resume = async () => { while (true) { let bytes; @@ -14460,7 +14470,6 @@ var require_fetch = __commonJS({ headersList.append(bufferToLowerCasedHeaderName(rawHeaders[i]), rawHeaders[i + 1].toString("latin1"), true); } location = headersList.get("location", true); - this.body = new Readable({ read: resume }); const decoders = []; const willFollow = location && request2.redirect === "follow" && redirectStatusSet.has(status); if (request2.method !== "HEAD" && request2.method !== "CONNECT" && !nullBodyStatus.includes(status) && !willFollow) { @@ -14468,7 +14477,7 @@ var require_fetch = __commonJS({ const codings = contentEncoding ? contentEncoding.toLowerCase().split(",") : []; const maxContentEncodings = 5; if (codings.length > maxContentEncodings) { - reject(new Error(`too many content-encodings in response: ${codings.length}, maximum allowed is ${maxContentEncodings}`)); + this.abort(new Error(`too many content-encodings in response: ${codings.length}, maximum allowed is ${maxContentEncodings}`)); return true; } for (let i = codings.length - 1; i >= 0; --i) { @@ -14498,6 +14507,7 @@ var require_fetch = __commonJS({ } } } + this.body = new Readable({ read: resume }); const onError = this.onError.bind(this); resolve({ status, @@ -14523,9 +14533,6 @@ var require_fetch = __commonJS({ if (this.abort) { fetchParams.controller.off("terminated", this.abort); } - if (fetchParams.controller.onAborted) { - fetchParams.controller.off("terminated", fetchParams.controller.onAborted); - } fetchParams.controller.ended = true; this.body.push(null); }, @@ -17599,6 +17606,16 @@ var require_receiver = __commonJS({ if (isControlFrame(this.#info.opcode)) { this.#loop = this.parseControlFrame(body); this.#state = parserStates.INFO; + const socket = this.ws[kResponse].socket; + if (this.#loop && socket.writableNeedDrain) { + this.#loop = false; + socket.once("drain", () => { + if (this.destroyed) return; + this.#loop = true; + this.run(callback); + }); + return; + } } else { if (!this.#info.compressed) { if (!this.writeFragments(body)) { @@ -18292,6 +18309,7 @@ var require_util8 = __commonJS({ var require_eventsource_stream = __commonJS({ "node_modules/undici/lib/web/eventsource/eventsource-stream.js"(exports, module) { "use strict"; + var buffer = __require("node:buffer"); var { Transform } = __require("node:stream"); var { isASCIINumber, isValidLastEventId } = require_util8(); var BOM = [239, 187, 191]; @@ -18299,24 +18317,28 @@ var require_eventsource_stream = __commonJS({ var CR = 13; var COLON = 58; var SPACE = 32; + var defaultMaxEventSize = buffer.kStringMaxLength; var DATA = Buffer.from("data"); var EVENT = Buffer.from("event"); var ID = Buffer.from("id"); var RETRY = Buffer.from("retry"); - function isASCIINumberBytes(buffer, start) { - if (start >= buffer.length) { + var minParserItems = 1024; + var maxParserItems = 131072; + var bytesPerParserItem = 128; + function isASCIINumberBytes(buffer2, start) { + if (start >= buffer2.length) { return false; } - for (let i = start; i < buffer.length; i++) { - if (buffer[i] < 48 || buffer[i] > 57) { + for (let i = start; i < buffer2.length; i++) { + if (buffer2[i] < 48 || buffer2[i] > 57) { return false; } } return true; } - function isValidLastEventIdBytes(buffer, start) { - for (let i = start; i < buffer.length; i++) { - if (buffer[i] === 0) { + function isValidLastEventIdBytes(buffer2, start) { + for (let i = start; i < buffer2.length; i++) { + if (buffer2[i] === 0) { return false; } } @@ -18333,6 +18355,11 @@ var require_eventsource_stream = __commonJS({ } return true; } + function createMaxEventSizeExceededError() { + const error2 = new Error("EventSource message size exceeded"); + error2.aborted = false; + return error2; + } var EventSourceStream = class extends Transform { /** * @type {eventSourceSettings} @@ -18359,6 +18386,13 @@ var require_eventsource_stream = __commonJS({ 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: void 0, event: void 0, @@ -18367,6 +18401,7 @@ var require_eventsource_stream = __commonJS({ }; /** * @param {object} options + * @param {number} [options.maxEventSize] * @param {eventSourceSettings} options.eventSourceSettings * @param {Function} [options.push] */ @@ -18374,6 +18409,10 @@ var require_eventsource_stream = __commonJS({ options.readableObjectMode = true; 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; } @@ -18389,6 +18428,10 @@ var require_eventsource_stream = __commonJS({ callback(); return; } + if (this.maxEventSize > 0 && this.chunks.length >= this.maxBufferedChunks && chunk[0] !== LF && chunk[0] !== CR) { + callback(createMaxEventSizeExceededError()); + return; + } this.chunks.push(chunk); if (this.checkBOM) { if (this.handleBOM()) { @@ -18425,18 +18468,32 @@ var require_eventsource_stream = __commonJS({ if (byte === CR) { this.crlfCheck = true; } - this.parseLine(this.readLine(), this.event); + try { + this.parseLine(this.readLine(), this.event); + } catch (error2) { + callback(error2); + return; + } this.consumeCurrentByte(); this.eventEndCheck = true; continue; } + if (this.maxEventSize > 0 && ++this.lineLength > this.maxEventSize + 7) { + callback(createMaxEventSizeExceededError()); + return; + } this.advanceCursor(); } callback(); } + _destroy(error2, callback) { + this.chunks.length = 0; + this.clearEvent(); + super._destroy(error2, callback); + } /** * @param {Buffer} line - * @param {EventStreamEvent} event + * @param {EventSourceStreamEvent} event */ parseLine(line, event) { if (line.length === 0) { @@ -18456,6 +18513,12 @@ var require_eventsource_stream = __commonJS({ } } 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 === void 0 ? 0 : 1) + valueBytes; + this.setEventFieldSize("data", dataSize); const value = line.toString("utf8", valueStart); if (event.data === void 0) { event.data = value; @@ -18463,27 +18526,38 @@ var require_eventsource_stream = __commonJS({ event.data += ` ${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; } 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 */ @@ -18510,6 +18584,12 @@ ${value}`; this.event.event = void 0; this.event.id = void 0; this.event.retry = void 0; + this.eventSize = 0; + this.dataLineCount = 0; + this.eventFieldSizes.data = 0; + this.eventFieldSizes.event = 0; + this.eventFieldSizes.id = 0; + this.eventFieldSizes.retry = 0; } hasPendingEvent() { return this.event.data !== void 0 || this.event.event !== void 0 || this.event.id !== void 0 || this.event.retry !== void 0; @@ -18534,13 +18614,15 @@ ${value}`; 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) { this.chunks.length = 0; @@ -18643,6 +18725,7 @@ var require_eventsource = __commonJS({ var { delay } = require_util8(); var { kEnumerableProperty } = require_util(); var { environmentSettingsObject } = require_util2(); + var { getGlobalDispatcher } = require_global2(); var experimentalWarned = false; var defaultReconnectionTime = 3e3; var CONNECTING = 0; @@ -18783,6 +18866,7 @@ var require_eventsource = __commonJS({ this.#state.origin = response.urlList[response.urlList.length - 1].origin; const eventSourceStream = new EventSourceStream({ eventSourceSettings: this.#state, + maxEventSize: this.#dispatcher.eventSourceOptions?.maxEventSize, push: (event) => { this.dispatchEvent(createFastMessageEvent( event.type, @@ -18915,7 +18999,8 @@ var require_eventsource = __commonJS({ { key: "dispatcher", // undici only - converter: webidl.converters.any + converter: webidl.converters.any, + defaultValue: () => getGlobalDispatcher() } ]); module.exports = { diff --git a/.github/actions/javascript/getPreviousVersion/index.js b/.github/actions/javascript/getPreviousVersion/index.js index dc48a205f79b..2c6af65960f9 100644 --- a/.github/actions/javascript/getPreviousVersion/index.js +++ b/.github/actions/javascript/getPreviousVersion/index.js @@ -2107,6 +2107,7 @@ var require_dispatcher = __commonJS({ var require_dispatcher_base = __commonJS({ "node_modules/undici/lib/dispatcher/dispatcher-base.js"(exports, module) { "use strict"; + var buffer = __require("node:buffer"); var Dispatcher = require_dispatcher(); var { ClientDestroyedError, @@ -2118,6 +2119,7 @@ var require_dispatcher_base = __commonJS({ var kOnClosed = /* @__PURE__ */ Symbol("onClosed"); var kInterceptedDispatch = /* @__PURE__ */ Symbol("Intercepted Dispatch"); var kWebSocketOptions = /* @__PURE__ */ Symbol("webSocketOptions"); + var kEventSourceOptions = /* @__PURE__ */ Symbol("eventSourceOptions"); var DispatcherBase = class extends Dispatcher { constructor(opts) { super(); @@ -2126,6 +2128,7 @@ var require_dispatcher_base = __commonJS({ this[kClosed] = false; this[kOnClosed] = []; this[kWebSocketOptions] = opts?.webSocket ?? {}; + this[kEventSourceOptions] = opts?.eventSource ?? {}; } get webSocketOptions() { return { @@ -2133,6 +2136,11 @@ var require_dispatcher_base = __commonJS({ maxPayloadSize: this[kWebSocketOptions].maxPayloadSize ?? 128 * 1024 * 1024 }; } + get eventSourceOptions() { + return { + maxEventSize: this[kEventSourceOptions].maxEventSize ?? buffer.kStringMaxLength + }; + } get destroyed() { return this[kDestroyed]; } @@ -6280,7 +6288,6 @@ var require_client_h1 = __commonJS({ socket[kSocketUsed] = false; socket[kParser] = new Parser(client, socket, llhttpInstance); addListener(socket, "error", function(err) { - assert(err.code !== "ERR_TLS_CERT_ALTNAME_INVALID"); const parser = this[kParser]; if (err.code === "ECONNRESET" && parser.statusCode && !parser.shouldKeepAlive) { const parserErr = parser.finish(); @@ -6964,7 +6971,6 @@ var require_client_h2 = __commonJS({ client[kHTTP2Session] = session; socket[kHTTP2Session] = session; util.addListener(socket, "error", function(err) { - assert(err.code !== "ERR_TLS_CERT_ALTNAME_INVALID"); this[kError] = err; this[kClient][kOnError](err); }); @@ -7023,7 +7029,6 @@ var require_client_h2 = __commonJS({ } } function onHttp2SessionError(err) { - assert(err.code !== "ERR_TLS_CERT_ALTNAME_INVALID"); this[kSocket][kError] = err; this[kClient][kOnError](err); } @@ -7717,9 +7722,10 @@ var require_client = __commonJS({ // h2 maxConcurrentStreams, allowH2, - webSocket + webSocket, + eventSource } = {}) { - super({ webSocket }); + super({ webSocket, eventSource }); if (keepAlive !== void 0) { throw new InvalidArgumentError("unsupported keepAlive, use pipelining=0 instead"); } @@ -8616,7 +8622,7 @@ var require_agent = __commonJS({ return opts && opts.connections === 1 ? new Client(origin, opts) : new Pool(origin, opts); } var Agent = class extends DispatcherBase { - constructor({ factory = defaultFactory, maxRedirections = 0, connect, ...options } = {}) { + constructor({ factory = defaultFactory, maxRedirections = 0, connect, tls, ...options } = {}) { if (typeof factory !== "function") { throw new InvalidArgumentError("factory must be a function."); } @@ -8630,8 +8636,11 @@ var require_agent = __commonJS({ if (connect && typeof connect !== "function") { connect = { ...connect }; } + if (tls && typeof tls !== "function") { + tls = { ...tls }; + } this[kInterceptors] = options.interceptors?.Agent && Array.isArray(options.interceptors.Agent) ? options.interceptors.Agent : [createRedirectInterceptor({ maxRedirections })]; - this[kOptions] = { ...util.deepClone(options), connect }; + this[kOptions] = { ...util.deepClone(options), connect, tls }; this[kOptions].interceptors = options.interceptors ? { ...options.interceptors } : void 0; this[kMaxRedirections] = maxRedirections; this[kFactory] = factory; @@ -14359,8 +14368,9 @@ var require_fetch = __commonJS({ } ); response.body = { stream, source: null, length: null }; - fetchParams.controller.onAborted = onAborted; - fetchParams.controller.on("terminated", onAborted); + if (!fetchParams.controller.resume) { + fetchParams.controller.on("terminated", onAborted); + } fetchParams.controller.resume = async () => { while (true) { let bytes; @@ -14460,7 +14470,6 @@ var require_fetch = __commonJS({ headersList.append(bufferToLowerCasedHeaderName(rawHeaders[i]), rawHeaders[i + 1].toString("latin1"), true); } location = headersList.get("location", true); - this.body = new Readable({ read: resume }); const decoders = []; const willFollow = location && request2.redirect === "follow" && redirectStatusSet.has(status); if (request2.method !== "HEAD" && request2.method !== "CONNECT" && !nullBodyStatus.includes(status) && !willFollow) { @@ -14468,7 +14477,7 @@ var require_fetch = __commonJS({ const codings = contentEncoding ? contentEncoding.toLowerCase().split(",") : []; const maxContentEncodings = 5; if (codings.length > maxContentEncodings) { - reject(new Error(`too many content-encodings in response: ${codings.length}, maximum allowed is ${maxContentEncodings}`)); + this.abort(new Error(`too many content-encodings in response: ${codings.length}, maximum allowed is ${maxContentEncodings}`)); return true; } for (let i = codings.length - 1; i >= 0; --i) { @@ -14498,6 +14507,7 @@ var require_fetch = __commonJS({ } } } + this.body = new Readable({ read: resume }); const onError = this.onError.bind(this); resolve({ status, @@ -14523,9 +14533,6 @@ var require_fetch = __commonJS({ if (this.abort) { fetchParams.controller.off("terminated", this.abort); } - if (fetchParams.controller.onAborted) { - fetchParams.controller.off("terminated", fetchParams.controller.onAborted); - } fetchParams.controller.ended = true; this.body.push(null); }, @@ -17599,6 +17606,16 @@ var require_receiver = __commonJS({ if (isControlFrame(this.#info.opcode)) { this.#loop = this.parseControlFrame(body); this.#state = parserStates.INFO; + const socket = this.ws[kResponse].socket; + if (this.#loop && socket.writableNeedDrain) { + this.#loop = false; + socket.once("drain", () => { + if (this.destroyed) return; + this.#loop = true; + this.run(callback); + }); + return; + } } else { if (!this.#info.compressed) { if (!this.writeFragments(body)) { @@ -18292,6 +18309,7 @@ var require_util8 = __commonJS({ var require_eventsource_stream = __commonJS({ "node_modules/undici/lib/web/eventsource/eventsource-stream.js"(exports, module) { "use strict"; + var buffer = __require("node:buffer"); var { Transform } = __require("node:stream"); var { isASCIINumber, isValidLastEventId } = require_util8(); var BOM = [239, 187, 191]; @@ -18299,24 +18317,28 @@ var require_eventsource_stream = __commonJS({ var CR = 13; var COLON = 58; var SPACE = 32; + var defaultMaxEventSize = buffer.kStringMaxLength; var DATA = Buffer.from("data"); var EVENT = Buffer.from("event"); var ID = Buffer.from("id"); var RETRY = Buffer.from("retry"); - function isASCIINumberBytes(buffer, start) { - if (start >= buffer.length) { + var minParserItems = 1024; + var maxParserItems = 131072; + var bytesPerParserItem = 128; + function isASCIINumberBytes(buffer2, start) { + if (start >= buffer2.length) { return false; } - for (let i = start; i < buffer.length; i++) { - if (buffer[i] < 48 || buffer[i] > 57) { + for (let i = start; i < buffer2.length; i++) { + if (buffer2[i] < 48 || buffer2[i] > 57) { return false; } } return true; } - function isValidLastEventIdBytes(buffer, start) { - for (let i = start; i < buffer.length; i++) { - if (buffer[i] === 0) { + function isValidLastEventIdBytes(buffer2, start) { + for (let i = start; i < buffer2.length; i++) { + if (buffer2[i] === 0) { return false; } } @@ -18333,6 +18355,11 @@ var require_eventsource_stream = __commonJS({ } return true; } + function createMaxEventSizeExceededError() { + const error2 = new Error("EventSource message size exceeded"); + error2.aborted = false; + return error2; + } var EventSourceStream = class extends Transform { /** * @type {eventSourceSettings} @@ -18359,6 +18386,13 @@ var require_eventsource_stream = __commonJS({ 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: void 0, event: void 0, @@ -18367,6 +18401,7 @@ var require_eventsource_stream = __commonJS({ }; /** * @param {object} options + * @param {number} [options.maxEventSize] * @param {eventSourceSettings} options.eventSourceSettings * @param {Function} [options.push] */ @@ -18374,6 +18409,10 @@ var require_eventsource_stream = __commonJS({ options.readableObjectMode = true; 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; } @@ -18389,6 +18428,10 @@ var require_eventsource_stream = __commonJS({ callback(); return; } + if (this.maxEventSize > 0 && this.chunks.length >= this.maxBufferedChunks && chunk[0] !== LF && chunk[0] !== CR) { + callback(createMaxEventSizeExceededError()); + return; + } this.chunks.push(chunk); if (this.checkBOM) { if (this.handleBOM()) { @@ -18425,18 +18468,32 @@ var require_eventsource_stream = __commonJS({ if (byte === CR) { this.crlfCheck = true; } - this.parseLine(this.readLine(), this.event); + try { + this.parseLine(this.readLine(), this.event); + } catch (error2) { + callback(error2); + return; + } this.consumeCurrentByte(); this.eventEndCheck = true; continue; } + if (this.maxEventSize > 0 && ++this.lineLength > this.maxEventSize + 7) { + callback(createMaxEventSizeExceededError()); + return; + } this.advanceCursor(); } callback(); } + _destroy(error2, callback) { + this.chunks.length = 0; + this.clearEvent(); + super._destroy(error2, callback); + } /** * @param {Buffer} line - * @param {EventStreamEvent} event + * @param {EventSourceStreamEvent} event */ parseLine(line, event) { if (line.length === 0) { @@ -18456,6 +18513,12 @@ var require_eventsource_stream = __commonJS({ } } 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 === void 0 ? 0 : 1) + valueBytes; + this.setEventFieldSize("data", dataSize); const value = line.toString("utf8", valueStart); if (event.data === void 0) { event.data = value; @@ -18463,27 +18526,38 @@ var require_eventsource_stream = __commonJS({ event.data += ` ${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; } 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 */ @@ -18510,6 +18584,12 @@ ${value}`; this.event.event = void 0; this.event.id = void 0; this.event.retry = void 0; + this.eventSize = 0; + this.dataLineCount = 0; + this.eventFieldSizes.data = 0; + this.eventFieldSizes.event = 0; + this.eventFieldSizes.id = 0; + this.eventFieldSizes.retry = 0; } hasPendingEvent() { return this.event.data !== void 0 || this.event.event !== void 0 || this.event.id !== void 0 || this.event.retry !== void 0; @@ -18534,13 +18614,15 @@ ${value}`; 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) { this.chunks.length = 0; @@ -18643,6 +18725,7 @@ var require_eventsource = __commonJS({ var { delay } = require_util8(); var { kEnumerableProperty } = require_util(); var { environmentSettingsObject } = require_util2(); + var { getGlobalDispatcher } = require_global2(); var experimentalWarned = false; var defaultReconnectionTime = 3e3; var CONNECTING = 0; @@ -18783,6 +18866,7 @@ var require_eventsource = __commonJS({ this.#state.origin = response.urlList[response.urlList.length - 1].origin; const eventSourceStream = new EventSourceStream({ eventSourceSettings: this.#state, + maxEventSize: this.#dispatcher.eventSourceOptions?.maxEventSize, push: (event) => { this.dispatchEvent(createFastMessageEvent( event.type, @@ -18915,7 +18999,8 @@ var require_eventsource = __commonJS({ { key: "dispatcher", // undici only - converter: webidl.converters.any + converter: webidl.converters.any, + defaultValue: () => getGlobalDispatcher() } ]); module.exports = { diff --git a/.github/actions/javascript/getPullRequestDetails/index.js b/.github/actions/javascript/getPullRequestDetails/index.js index b7443787fc9b..0eace171a9df 100644 --- a/.github/actions/javascript/getPullRequestDetails/index.js +++ b/.github/actions/javascript/getPullRequestDetails/index.js @@ -2107,6 +2107,7 @@ var require_dispatcher = __commonJS({ var require_dispatcher_base = __commonJS({ "node_modules/undici/lib/dispatcher/dispatcher-base.js"(exports, module) { "use strict"; + var buffer = __require("node:buffer"); var Dispatcher = require_dispatcher(); var { ClientDestroyedError, @@ -2118,6 +2119,7 @@ var require_dispatcher_base = __commonJS({ var kOnClosed = /* @__PURE__ */ Symbol("onClosed"); var kInterceptedDispatch = /* @__PURE__ */ Symbol("Intercepted Dispatch"); var kWebSocketOptions = /* @__PURE__ */ Symbol("webSocketOptions"); + var kEventSourceOptions = /* @__PURE__ */ Symbol("eventSourceOptions"); var DispatcherBase = class extends Dispatcher { constructor(opts) { super(); @@ -2126,6 +2128,7 @@ var require_dispatcher_base = __commonJS({ this[kClosed] = false; this[kOnClosed] = []; this[kWebSocketOptions] = opts?.webSocket ?? {}; + this[kEventSourceOptions] = opts?.eventSource ?? {}; } get webSocketOptions() { return { @@ -2133,6 +2136,11 @@ var require_dispatcher_base = __commonJS({ maxPayloadSize: this[kWebSocketOptions].maxPayloadSize ?? 128 * 1024 * 1024 }; } + get eventSourceOptions() { + return { + maxEventSize: this[kEventSourceOptions].maxEventSize ?? buffer.kStringMaxLength + }; + } get destroyed() { return this[kDestroyed]; } @@ -6280,7 +6288,6 @@ var require_client_h1 = __commonJS({ socket[kSocketUsed] = false; socket[kParser] = new Parser(client, socket, llhttpInstance); addListener(socket, "error", function(err) { - assert(err.code !== "ERR_TLS_CERT_ALTNAME_INVALID"); const parser = this[kParser]; if (err.code === "ECONNRESET" && parser.statusCode && !parser.shouldKeepAlive) { const parserErr = parser.finish(); @@ -6964,7 +6971,6 @@ var require_client_h2 = __commonJS({ client[kHTTP2Session] = session; socket[kHTTP2Session] = session; util.addListener(socket, "error", function(err) { - assert(err.code !== "ERR_TLS_CERT_ALTNAME_INVALID"); this[kError] = err; this[kClient][kOnError](err); }); @@ -7023,7 +7029,6 @@ var require_client_h2 = __commonJS({ } } function onHttp2SessionError(err) { - assert(err.code !== "ERR_TLS_CERT_ALTNAME_INVALID"); this[kSocket][kError] = err; this[kClient][kOnError](err); } @@ -7717,9 +7722,10 @@ var require_client = __commonJS({ // h2 maxConcurrentStreams, allowH2, - webSocket + webSocket, + eventSource } = {}) { - super({ webSocket }); + super({ webSocket, eventSource }); if (keepAlive !== void 0) { throw new InvalidArgumentError("unsupported keepAlive, use pipelining=0 instead"); } @@ -8616,7 +8622,7 @@ var require_agent = __commonJS({ return opts && opts.connections === 1 ? new Client(origin, opts) : new Pool(origin, opts); } var Agent = class extends DispatcherBase { - constructor({ factory = defaultFactory, maxRedirections = 0, connect, ...options } = {}) { + constructor({ factory = defaultFactory, maxRedirections = 0, connect, tls, ...options } = {}) { if (typeof factory !== "function") { throw new InvalidArgumentError("factory must be a function."); } @@ -8630,8 +8636,11 @@ var require_agent = __commonJS({ if (connect && typeof connect !== "function") { connect = { ...connect }; } + if (tls && typeof tls !== "function") { + tls = { ...tls }; + } this[kInterceptors] = options.interceptors?.Agent && Array.isArray(options.interceptors.Agent) ? options.interceptors.Agent : [createRedirectInterceptor({ maxRedirections })]; - this[kOptions] = { ...util.deepClone(options), connect }; + this[kOptions] = { ...util.deepClone(options), connect, tls }; this[kOptions].interceptors = options.interceptors ? { ...options.interceptors } : void 0; this[kMaxRedirections] = maxRedirections; this[kFactory] = factory; @@ -14359,8 +14368,9 @@ var require_fetch = __commonJS({ } ); response.body = { stream, source: null, length: null }; - fetchParams.controller.onAborted = onAborted; - fetchParams.controller.on("terminated", onAborted); + if (!fetchParams.controller.resume) { + fetchParams.controller.on("terminated", onAborted); + } fetchParams.controller.resume = async () => { while (true) { let bytes; @@ -14460,7 +14470,6 @@ var require_fetch = __commonJS({ headersList.append(bufferToLowerCasedHeaderName(rawHeaders[i]), rawHeaders[i + 1].toString("latin1"), true); } location = headersList.get("location", true); - this.body = new Readable({ read: resume }); const decoders = []; const willFollow = location && request2.redirect === "follow" && redirectStatusSet.has(status); if (request2.method !== "HEAD" && request2.method !== "CONNECT" && !nullBodyStatus.includes(status) && !willFollow) { @@ -14468,7 +14477,7 @@ var require_fetch = __commonJS({ const codings = contentEncoding ? contentEncoding.toLowerCase().split(",") : []; const maxContentEncodings = 5; if (codings.length > maxContentEncodings) { - reject(new Error(`too many content-encodings in response: ${codings.length}, maximum allowed is ${maxContentEncodings}`)); + this.abort(new Error(`too many content-encodings in response: ${codings.length}, maximum allowed is ${maxContentEncodings}`)); return true; } for (let i = codings.length - 1; i >= 0; --i) { @@ -14498,6 +14507,7 @@ var require_fetch = __commonJS({ } } } + this.body = new Readable({ read: resume }); const onError = this.onError.bind(this); resolve({ status, @@ -14523,9 +14533,6 @@ var require_fetch = __commonJS({ if (this.abort) { fetchParams.controller.off("terminated", this.abort); } - if (fetchParams.controller.onAborted) { - fetchParams.controller.off("terminated", fetchParams.controller.onAborted); - } fetchParams.controller.ended = true; this.body.push(null); }, @@ -17599,6 +17606,16 @@ var require_receiver = __commonJS({ if (isControlFrame(this.#info.opcode)) { this.#loop = this.parseControlFrame(body); this.#state = parserStates.INFO; + const socket = this.ws[kResponse].socket; + if (this.#loop && socket.writableNeedDrain) { + this.#loop = false; + socket.once("drain", () => { + if (this.destroyed) return; + this.#loop = true; + this.run(callback); + }); + return; + } } else { if (!this.#info.compressed) { if (!this.writeFragments(body)) { @@ -18292,6 +18309,7 @@ var require_util8 = __commonJS({ var require_eventsource_stream = __commonJS({ "node_modules/undici/lib/web/eventsource/eventsource-stream.js"(exports, module) { "use strict"; + var buffer = __require("node:buffer"); var { Transform } = __require("node:stream"); var { isASCIINumber, isValidLastEventId } = require_util8(); var BOM = [239, 187, 191]; @@ -18299,24 +18317,28 @@ var require_eventsource_stream = __commonJS({ var CR = 13; var COLON = 58; var SPACE = 32; + var defaultMaxEventSize = buffer.kStringMaxLength; var DATA = Buffer.from("data"); var EVENT = Buffer.from("event"); var ID = Buffer.from("id"); var RETRY = Buffer.from("retry"); - function isASCIINumberBytes(buffer, start) { - if (start >= buffer.length) { + var minParserItems = 1024; + var maxParserItems = 131072; + var bytesPerParserItem = 128; + function isASCIINumberBytes(buffer2, start) { + if (start >= buffer2.length) { return false; } - for (let i = start; i < buffer.length; i++) { - if (buffer[i] < 48 || buffer[i] > 57) { + for (let i = start; i < buffer2.length; i++) { + if (buffer2[i] < 48 || buffer2[i] > 57) { return false; } } return true; } - function isValidLastEventIdBytes(buffer, start) { - for (let i = start; i < buffer.length; i++) { - if (buffer[i] === 0) { + function isValidLastEventIdBytes(buffer2, start) { + for (let i = start; i < buffer2.length; i++) { + if (buffer2[i] === 0) { return false; } } @@ -18333,6 +18355,11 @@ var require_eventsource_stream = __commonJS({ } return true; } + function createMaxEventSizeExceededError() { + const error2 = new Error("EventSource message size exceeded"); + error2.aborted = false; + return error2; + } var EventSourceStream = class extends Transform { /** * @type {eventSourceSettings} @@ -18359,6 +18386,13 @@ var require_eventsource_stream = __commonJS({ 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: void 0, event: void 0, @@ -18367,6 +18401,7 @@ var require_eventsource_stream = __commonJS({ }; /** * @param {object} options + * @param {number} [options.maxEventSize] * @param {eventSourceSettings} options.eventSourceSettings * @param {Function} [options.push] */ @@ -18374,6 +18409,10 @@ var require_eventsource_stream = __commonJS({ options.readableObjectMode = true; 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; } @@ -18389,6 +18428,10 @@ var require_eventsource_stream = __commonJS({ callback(); return; } + if (this.maxEventSize > 0 && this.chunks.length >= this.maxBufferedChunks && chunk[0] !== LF && chunk[0] !== CR) { + callback(createMaxEventSizeExceededError()); + return; + } this.chunks.push(chunk); if (this.checkBOM) { if (this.handleBOM()) { @@ -18425,18 +18468,32 @@ var require_eventsource_stream = __commonJS({ if (byte === CR) { this.crlfCheck = true; } - this.parseLine(this.readLine(), this.event); + try { + this.parseLine(this.readLine(), this.event); + } catch (error2) { + callback(error2); + return; + } this.consumeCurrentByte(); this.eventEndCheck = true; continue; } + if (this.maxEventSize > 0 && ++this.lineLength > this.maxEventSize + 7) { + callback(createMaxEventSizeExceededError()); + return; + } this.advanceCursor(); } callback(); } + _destroy(error2, callback) { + this.chunks.length = 0; + this.clearEvent(); + super._destroy(error2, callback); + } /** * @param {Buffer} line - * @param {EventStreamEvent} event + * @param {EventSourceStreamEvent} event */ parseLine(line, event) { if (line.length === 0) { @@ -18456,6 +18513,12 @@ var require_eventsource_stream = __commonJS({ } } 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 === void 0 ? 0 : 1) + valueBytes; + this.setEventFieldSize("data", dataSize); const value = line.toString("utf8", valueStart); if (event.data === void 0) { event.data = value; @@ -18463,27 +18526,38 @@ var require_eventsource_stream = __commonJS({ event.data += ` ${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; } 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 */ @@ -18510,6 +18584,12 @@ ${value}`; this.event.event = void 0; this.event.id = void 0; this.event.retry = void 0; + this.eventSize = 0; + this.dataLineCount = 0; + this.eventFieldSizes.data = 0; + this.eventFieldSizes.event = 0; + this.eventFieldSizes.id = 0; + this.eventFieldSizes.retry = 0; } hasPendingEvent() { return this.event.data !== void 0 || this.event.event !== void 0 || this.event.id !== void 0 || this.event.retry !== void 0; @@ -18534,13 +18614,15 @@ ${value}`; 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) { this.chunks.length = 0; @@ -18643,6 +18725,7 @@ var require_eventsource = __commonJS({ var { delay } = require_util8(); var { kEnumerableProperty } = require_util(); var { environmentSettingsObject } = require_util2(); + var { getGlobalDispatcher } = require_global2(); var experimentalWarned = false; var defaultReconnectionTime = 3e3; var CONNECTING = 0; @@ -18783,6 +18866,7 @@ var require_eventsource = __commonJS({ this.#state.origin = response.urlList[response.urlList.length - 1].origin; const eventSourceStream = new EventSourceStream({ eventSourceSettings: this.#state, + maxEventSize: this.#dispatcher.eventSourceOptions?.maxEventSize, push: (event) => { this.dispatchEvent(createFastMessageEvent( event.type, @@ -18915,7 +18999,8 @@ var require_eventsource = __commonJS({ { key: "dispatcher", // undici only - converter: webidl.converters.any + converter: webidl.converters.any, + defaultValue: () => getGlobalDispatcher() } ]); module.exports = { diff --git a/.github/actions/javascript/getPullRequestIncrementalChanges/index.js b/.github/actions/javascript/getPullRequestIncrementalChanges/index.js index e868a069ae7e..66c4c91063f2 100644 --- a/.github/actions/javascript/getPullRequestIncrementalChanges/index.js +++ b/.github/actions/javascript/getPullRequestIncrementalChanges/index.js @@ -2107,6 +2107,7 @@ var require_dispatcher = __commonJS({ var require_dispatcher_base = __commonJS({ "node_modules/undici/lib/dispatcher/dispatcher-base.js"(exports, module) { "use strict"; + var buffer = __require("node:buffer"); var Dispatcher = require_dispatcher(); var { ClientDestroyedError, @@ -2118,6 +2119,7 @@ var require_dispatcher_base = __commonJS({ var kOnClosed = /* @__PURE__ */ Symbol("onClosed"); var kInterceptedDispatch = /* @__PURE__ */ Symbol("Intercepted Dispatch"); var kWebSocketOptions = /* @__PURE__ */ Symbol("webSocketOptions"); + var kEventSourceOptions = /* @__PURE__ */ Symbol("eventSourceOptions"); var DispatcherBase = class extends Dispatcher { constructor(opts) { super(); @@ -2126,6 +2128,7 @@ var require_dispatcher_base = __commonJS({ this[kClosed] = false; this[kOnClosed] = []; this[kWebSocketOptions] = opts?.webSocket ?? {}; + this[kEventSourceOptions] = opts?.eventSource ?? {}; } get webSocketOptions() { return { @@ -2133,6 +2136,11 @@ var require_dispatcher_base = __commonJS({ maxPayloadSize: this[kWebSocketOptions].maxPayloadSize ?? 128 * 1024 * 1024 }; } + get eventSourceOptions() { + return { + maxEventSize: this[kEventSourceOptions].maxEventSize ?? buffer.kStringMaxLength + }; + } get destroyed() { return this[kDestroyed]; } @@ -6280,7 +6288,6 @@ var require_client_h1 = __commonJS({ socket[kSocketUsed] = false; socket[kParser] = new Parser(client, socket, llhttpInstance); addListener(socket, "error", function(err) { - assert(err.code !== "ERR_TLS_CERT_ALTNAME_INVALID"); const parser = this[kParser]; if (err.code === "ECONNRESET" && parser.statusCode && !parser.shouldKeepAlive) { const parserErr = parser.finish(); @@ -6964,7 +6971,6 @@ var require_client_h2 = __commonJS({ client[kHTTP2Session] = session; socket[kHTTP2Session] = session; util.addListener(socket, "error", function(err) { - assert(err.code !== "ERR_TLS_CERT_ALTNAME_INVALID"); this[kError] = err; this[kClient][kOnError](err); }); @@ -7023,7 +7029,6 @@ var require_client_h2 = __commonJS({ } } function onHttp2SessionError(err) { - assert(err.code !== "ERR_TLS_CERT_ALTNAME_INVALID"); this[kSocket][kError] = err; this[kClient][kOnError](err); } @@ -7717,9 +7722,10 @@ var require_client = __commonJS({ // h2 maxConcurrentStreams, allowH2, - webSocket + webSocket, + eventSource } = {}) { - super({ webSocket }); + super({ webSocket, eventSource }); if (keepAlive !== void 0) { throw new InvalidArgumentError("unsupported keepAlive, use pipelining=0 instead"); } @@ -8616,7 +8622,7 @@ var require_agent = __commonJS({ return opts && opts.connections === 1 ? new Client(origin, opts) : new Pool(origin, opts); } var Agent = class extends DispatcherBase { - constructor({ factory = defaultFactory, maxRedirections = 0, connect, ...options } = {}) { + constructor({ factory = defaultFactory, maxRedirections = 0, connect, tls, ...options } = {}) { if (typeof factory !== "function") { throw new InvalidArgumentError("factory must be a function."); } @@ -8630,8 +8636,11 @@ var require_agent = __commonJS({ if (connect && typeof connect !== "function") { connect = { ...connect }; } + if (tls && typeof tls !== "function") { + tls = { ...tls }; + } this[kInterceptors] = options.interceptors?.Agent && Array.isArray(options.interceptors.Agent) ? options.interceptors.Agent : [createRedirectInterceptor({ maxRedirections })]; - this[kOptions] = { ...util.deepClone(options), connect }; + this[kOptions] = { ...util.deepClone(options), connect, tls }; this[kOptions].interceptors = options.interceptors ? { ...options.interceptors } : void 0; this[kMaxRedirections] = maxRedirections; this[kFactory] = factory; @@ -14359,8 +14368,9 @@ var require_fetch = __commonJS({ } ); response.body = { stream, source: null, length: null }; - fetchParams.controller.onAborted = onAborted; - fetchParams.controller.on("terminated", onAborted); + if (!fetchParams.controller.resume) { + fetchParams.controller.on("terminated", onAborted); + } fetchParams.controller.resume = async () => { while (true) { let bytes; @@ -14460,7 +14470,6 @@ var require_fetch = __commonJS({ headersList.append(bufferToLowerCasedHeaderName(rawHeaders[i]), rawHeaders[i + 1].toString("latin1"), true); } location = headersList.get("location", true); - this.body = new Readable({ read: resume }); const decoders = []; const willFollow = location && request2.redirect === "follow" && redirectStatusSet.has(status); if (request2.method !== "HEAD" && request2.method !== "CONNECT" && !nullBodyStatus.includes(status) && !willFollow) { @@ -14468,7 +14477,7 @@ var require_fetch = __commonJS({ const codings = contentEncoding ? contentEncoding.toLowerCase().split(",") : []; const maxContentEncodings = 5; if (codings.length > maxContentEncodings) { - reject(new Error(`too many content-encodings in response: ${codings.length}, maximum allowed is ${maxContentEncodings}`)); + this.abort(new Error(`too many content-encodings in response: ${codings.length}, maximum allowed is ${maxContentEncodings}`)); return true; } for (let i = codings.length - 1; i >= 0; --i) { @@ -14498,6 +14507,7 @@ var require_fetch = __commonJS({ } } } + this.body = new Readable({ read: resume }); const onError = this.onError.bind(this); resolve({ status, @@ -14523,9 +14533,6 @@ var require_fetch = __commonJS({ if (this.abort) { fetchParams.controller.off("terminated", this.abort); } - if (fetchParams.controller.onAborted) { - fetchParams.controller.off("terminated", fetchParams.controller.onAborted); - } fetchParams.controller.ended = true; this.body.push(null); }, @@ -17599,6 +17606,16 @@ var require_receiver = __commonJS({ if (isControlFrame(this.#info.opcode)) { this.#loop = this.parseControlFrame(body); this.#state = parserStates.INFO; + const socket = this.ws[kResponse].socket; + if (this.#loop && socket.writableNeedDrain) { + this.#loop = false; + socket.once("drain", () => { + if (this.destroyed) return; + this.#loop = true; + this.run(callback); + }); + return; + } } else { if (!this.#info.compressed) { if (!this.writeFragments(body)) { @@ -18292,6 +18309,7 @@ var require_util8 = __commonJS({ var require_eventsource_stream = __commonJS({ "node_modules/undici/lib/web/eventsource/eventsource-stream.js"(exports, module) { "use strict"; + var buffer = __require("node:buffer"); var { Transform } = __require("node:stream"); var { isASCIINumber, isValidLastEventId } = require_util8(); var BOM = [239, 187, 191]; @@ -18299,24 +18317,28 @@ var require_eventsource_stream = __commonJS({ var CR = 13; var COLON = 58; var SPACE = 32; + var defaultMaxEventSize = buffer.kStringMaxLength; var DATA = Buffer.from("data"); var EVENT = Buffer.from("event"); var ID = Buffer.from("id"); var RETRY = Buffer.from("retry"); - function isASCIINumberBytes(buffer, start) { - if (start >= buffer.length) { + var minParserItems = 1024; + var maxParserItems = 131072; + var bytesPerParserItem = 128; + function isASCIINumberBytes(buffer2, start) { + if (start >= buffer2.length) { return false; } - for (let i = start; i < buffer.length; i++) { - if (buffer[i] < 48 || buffer[i] > 57) { + for (let i = start; i < buffer2.length; i++) { + if (buffer2[i] < 48 || buffer2[i] > 57) { return false; } } return true; } - function isValidLastEventIdBytes(buffer, start) { - for (let i = start; i < buffer.length; i++) { - if (buffer[i] === 0) { + function isValidLastEventIdBytes(buffer2, start) { + for (let i = start; i < buffer2.length; i++) { + if (buffer2[i] === 0) { return false; } } @@ -18333,6 +18355,11 @@ var require_eventsource_stream = __commonJS({ } return true; } + function createMaxEventSizeExceededError() { + const error3 = new Error("EventSource message size exceeded"); + error3.aborted = false; + return error3; + } var EventSourceStream = class extends Transform { /** * @type {eventSourceSettings} @@ -18359,6 +18386,13 @@ var require_eventsource_stream = __commonJS({ 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: void 0, event: void 0, @@ -18367,6 +18401,7 @@ var require_eventsource_stream = __commonJS({ }; /** * @param {object} options + * @param {number} [options.maxEventSize] * @param {eventSourceSettings} options.eventSourceSettings * @param {Function} [options.push] */ @@ -18374,6 +18409,10 @@ var require_eventsource_stream = __commonJS({ options.readableObjectMode = true; 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; } @@ -18389,6 +18428,10 @@ var require_eventsource_stream = __commonJS({ callback(); return; } + if (this.maxEventSize > 0 && this.chunks.length >= this.maxBufferedChunks && chunk[0] !== LF && chunk[0] !== CR) { + callback(createMaxEventSizeExceededError()); + return; + } this.chunks.push(chunk); if (this.checkBOM) { if (this.handleBOM()) { @@ -18425,18 +18468,32 @@ var require_eventsource_stream = __commonJS({ if (byte === CR) { this.crlfCheck = true; } - this.parseLine(this.readLine(), this.event); + try { + this.parseLine(this.readLine(), this.event); + } catch (error3) { + callback(error3); + return; + } this.consumeCurrentByte(); this.eventEndCheck = true; continue; } + if (this.maxEventSize > 0 && ++this.lineLength > this.maxEventSize + 7) { + callback(createMaxEventSizeExceededError()); + return; + } this.advanceCursor(); } callback(); } + _destroy(error3, callback) { + this.chunks.length = 0; + this.clearEvent(); + super._destroy(error3, callback); + } /** * @param {Buffer} line - * @param {EventStreamEvent} event + * @param {EventSourceStreamEvent} event */ parseLine(line, event) { if (line.length === 0) { @@ -18456,6 +18513,12 @@ var require_eventsource_stream = __commonJS({ } } 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 === void 0 ? 0 : 1) + valueBytes; + this.setEventFieldSize("data", dataSize); const value = line.toString("utf8", valueStart); if (event.data === void 0) { event.data = value; @@ -18463,27 +18526,38 @@ var require_eventsource_stream = __commonJS({ event.data += ` ${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; } 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 */ @@ -18510,6 +18584,12 @@ ${value}`; this.event.event = void 0; this.event.id = void 0; this.event.retry = void 0; + this.eventSize = 0; + this.dataLineCount = 0; + this.eventFieldSizes.data = 0; + this.eventFieldSizes.event = 0; + this.eventFieldSizes.id = 0; + this.eventFieldSizes.retry = 0; } hasPendingEvent() { return this.event.data !== void 0 || this.event.event !== void 0 || this.event.id !== void 0 || this.event.retry !== void 0; @@ -18534,13 +18614,15 @@ ${value}`; 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) { this.chunks.length = 0; @@ -18643,6 +18725,7 @@ var require_eventsource = __commonJS({ var { delay } = require_util8(); var { kEnumerableProperty } = require_util(); var { environmentSettingsObject } = require_util2(); + var { getGlobalDispatcher } = require_global2(); var experimentalWarned = false; var defaultReconnectionTime = 3e3; var CONNECTING = 0; @@ -18783,6 +18866,7 @@ var require_eventsource = __commonJS({ this.#state.origin = response.urlList[response.urlList.length - 1].origin; const eventSourceStream = new EventSourceStream({ eventSourceSettings: this.#state, + maxEventSize: this.#dispatcher.eventSourceOptions?.maxEventSize, push: (event) => { this.dispatchEvent(createFastMessageEvent( event.type, @@ -18915,7 +18999,8 @@ var require_eventsource = __commonJS({ { key: "dispatcher", // undici only - converter: webidl.converters.any + converter: webidl.converters.any, + defaultValue: () => getGlobalDispatcher() } ]); module.exports = { diff --git a/.github/actions/javascript/isAuthorizedContributor/index.js b/.github/actions/javascript/isAuthorizedContributor/index.js index d43a19fced4c..a3ebd67e72b2 100644 --- a/.github/actions/javascript/isAuthorizedContributor/index.js +++ b/.github/actions/javascript/isAuthorizedContributor/index.js @@ -2107,6 +2107,7 @@ var require_dispatcher = __commonJS({ var require_dispatcher_base = __commonJS({ "node_modules/undici/lib/dispatcher/dispatcher-base.js"(exports, module) { "use strict"; + var buffer = __require("node:buffer"); var Dispatcher = require_dispatcher(); var { ClientDestroyedError, @@ -2118,6 +2119,7 @@ var require_dispatcher_base = __commonJS({ var kOnClosed = /* @__PURE__ */ Symbol("onClosed"); var kInterceptedDispatch = /* @__PURE__ */ Symbol("Intercepted Dispatch"); var kWebSocketOptions = /* @__PURE__ */ Symbol("webSocketOptions"); + var kEventSourceOptions = /* @__PURE__ */ Symbol("eventSourceOptions"); var DispatcherBase = class extends Dispatcher { constructor(opts) { super(); @@ -2126,6 +2128,7 @@ var require_dispatcher_base = __commonJS({ this[kClosed] = false; this[kOnClosed] = []; this[kWebSocketOptions] = opts?.webSocket ?? {}; + this[kEventSourceOptions] = opts?.eventSource ?? {}; } get webSocketOptions() { return { @@ -2133,6 +2136,11 @@ var require_dispatcher_base = __commonJS({ maxPayloadSize: this[kWebSocketOptions].maxPayloadSize ?? 128 * 1024 * 1024 }; } + get eventSourceOptions() { + return { + maxEventSize: this[kEventSourceOptions].maxEventSize ?? buffer.kStringMaxLength + }; + } get destroyed() { return this[kDestroyed]; } @@ -6280,7 +6288,6 @@ var require_client_h1 = __commonJS({ socket[kSocketUsed] = false; socket[kParser] = new Parser(client, socket, llhttpInstance); addListener(socket, "error", function(err) { - assert(err.code !== "ERR_TLS_CERT_ALTNAME_INVALID"); const parser = this[kParser]; if (err.code === "ECONNRESET" && parser.statusCode && !parser.shouldKeepAlive) { const parserErr = parser.finish(); @@ -6964,7 +6971,6 @@ var require_client_h2 = __commonJS({ client[kHTTP2Session] = session; socket[kHTTP2Session] = session; util.addListener(socket, "error", function(err) { - assert(err.code !== "ERR_TLS_CERT_ALTNAME_INVALID"); this[kError] = err; this[kClient][kOnError](err); }); @@ -7023,7 +7029,6 @@ var require_client_h2 = __commonJS({ } } function onHttp2SessionError(err) { - assert(err.code !== "ERR_TLS_CERT_ALTNAME_INVALID"); this[kSocket][kError] = err; this[kClient][kOnError](err); } @@ -7717,9 +7722,10 @@ var require_client = __commonJS({ // h2 maxConcurrentStreams, allowH2, - webSocket + webSocket, + eventSource } = {}) { - super({ webSocket }); + super({ webSocket, eventSource }); if (keepAlive !== void 0) { throw new InvalidArgumentError("unsupported keepAlive, use pipelining=0 instead"); } @@ -8616,7 +8622,7 @@ var require_agent = __commonJS({ return opts && opts.connections === 1 ? new Client(origin, opts) : new Pool(origin, opts); } var Agent = class extends DispatcherBase { - constructor({ factory = defaultFactory, maxRedirections = 0, connect, ...options } = {}) { + constructor({ factory = defaultFactory, maxRedirections = 0, connect, tls, ...options } = {}) { if (typeof factory !== "function") { throw new InvalidArgumentError("factory must be a function."); } @@ -8630,8 +8636,11 @@ var require_agent = __commonJS({ if (connect && typeof connect !== "function") { connect = { ...connect }; } + if (tls && typeof tls !== "function") { + tls = { ...tls }; + } this[kInterceptors] = options.interceptors?.Agent && Array.isArray(options.interceptors.Agent) ? options.interceptors.Agent : [createRedirectInterceptor({ maxRedirections })]; - this[kOptions] = { ...util.deepClone(options), connect }; + this[kOptions] = { ...util.deepClone(options), connect, tls }; this[kOptions].interceptors = options.interceptors ? { ...options.interceptors } : void 0; this[kMaxRedirections] = maxRedirections; this[kFactory] = factory; @@ -14359,8 +14368,9 @@ var require_fetch = __commonJS({ } ); response.body = { stream, source: null, length: null }; - fetchParams.controller.onAborted = onAborted; - fetchParams.controller.on("terminated", onAborted); + if (!fetchParams.controller.resume) { + fetchParams.controller.on("terminated", onAborted); + } fetchParams.controller.resume = async () => { while (true) { let bytes; @@ -14460,7 +14470,6 @@ var require_fetch = __commonJS({ headersList.append(bufferToLowerCasedHeaderName(rawHeaders[i]), rawHeaders[i + 1].toString("latin1"), true); } location = headersList.get("location", true); - this.body = new Readable({ read: resume }); const decoders = []; const willFollow = location && request2.redirect === "follow" && redirectStatusSet.has(status); if (request2.method !== "HEAD" && request2.method !== "CONNECT" && !nullBodyStatus.includes(status) && !willFollow) { @@ -14468,7 +14477,7 @@ var require_fetch = __commonJS({ const codings = contentEncoding ? contentEncoding.toLowerCase().split(",") : []; const maxContentEncodings = 5; if (codings.length > maxContentEncodings) { - reject(new Error(`too many content-encodings in response: ${codings.length}, maximum allowed is ${maxContentEncodings}`)); + this.abort(new Error(`too many content-encodings in response: ${codings.length}, maximum allowed is ${maxContentEncodings}`)); return true; } for (let i = codings.length - 1; i >= 0; --i) { @@ -14498,6 +14507,7 @@ var require_fetch = __commonJS({ } } } + this.body = new Readable({ read: resume }); const onError = this.onError.bind(this); resolve({ status, @@ -14523,9 +14533,6 @@ var require_fetch = __commonJS({ if (this.abort) { fetchParams.controller.off("terminated", this.abort); } - if (fetchParams.controller.onAborted) { - fetchParams.controller.off("terminated", fetchParams.controller.onAborted); - } fetchParams.controller.ended = true; this.body.push(null); }, @@ -17599,6 +17606,16 @@ var require_receiver = __commonJS({ if (isControlFrame(this.#info.opcode)) { this.#loop = this.parseControlFrame(body); this.#state = parserStates.INFO; + const socket = this.ws[kResponse].socket; + if (this.#loop && socket.writableNeedDrain) { + this.#loop = false; + socket.once("drain", () => { + if (this.destroyed) return; + this.#loop = true; + this.run(callback); + }); + return; + } } else { if (!this.#info.compressed) { if (!this.writeFragments(body)) { @@ -18292,6 +18309,7 @@ var require_util8 = __commonJS({ var require_eventsource_stream = __commonJS({ "node_modules/undici/lib/web/eventsource/eventsource-stream.js"(exports, module) { "use strict"; + var buffer = __require("node:buffer"); var { Transform } = __require("node:stream"); var { isASCIINumber, isValidLastEventId } = require_util8(); var BOM = [239, 187, 191]; @@ -18299,24 +18317,28 @@ var require_eventsource_stream = __commonJS({ var CR = 13; var COLON = 58; var SPACE = 32; + var defaultMaxEventSize = buffer.kStringMaxLength; var DATA = Buffer.from("data"); var EVENT = Buffer.from("event"); var ID = Buffer.from("id"); var RETRY = Buffer.from("retry"); - function isASCIINumberBytes(buffer, start) { - if (start >= buffer.length) { + var minParserItems = 1024; + var maxParserItems = 131072; + var bytesPerParserItem = 128; + function isASCIINumberBytes(buffer2, start) { + if (start >= buffer2.length) { return false; } - for (let i = start; i < buffer.length; i++) { - if (buffer[i] < 48 || buffer[i] > 57) { + for (let i = start; i < buffer2.length; i++) { + if (buffer2[i] < 48 || buffer2[i] > 57) { return false; } } return true; } - function isValidLastEventIdBytes(buffer, start) { - for (let i = start; i < buffer.length; i++) { - if (buffer[i] === 0) { + function isValidLastEventIdBytes(buffer2, start) { + for (let i = start; i < buffer2.length; i++) { + if (buffer2[i] === 0) { return false; } } @@ -18333,6 +18355,11 @@ var require_eventsource_stream = __commonJS({ } return true; } + function createMaxEventSizeExceededError() { + const error2 = new Error("EventSource message size exceeded"); + error2.aborted = false; + return error2; + } var EventSourceStream = class extends Transform { /** * @type {eventSourceSettings} @@ -18359,6 +18386,13 @@ var require_eventsource_stream = __commonJS({ 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: void 0, event: void 0, @@ -18367,6 +18401,7 @@ var require_eventsource_stream = __commonJS({ }; /** * @param {object} options + * @param {number} [options.maxEventSize] * @param {eventSourceSettings} options.eventSourceSettings * @param {Function} [options.push] */ @@ -18374,6 +18409,10 @@ var require_eventsource_stream = __commonJS({ options.readableObjectMode = true; 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; } @@ -18389,6 +18428,10 @@ var require_eventsource_stream = __commonJS({ callback(); return; } + if (this.maxEventSize > 0 && this.chunks.length >= this.maxBufferedChunks && chunk[0] !== LF && chunk[0] !== CR) { + callback(createMaxEventSizeExceededError()); + return; + } this.chunks.push(chunk); if (this.checkBOM) { if (this.handleBOM()) { @@ -18425,18 +18468,32 @@ var require_eventsource_stream = __commonJS({ if (byte === CR) { this.crlfCheck = true; } - this.parseLine(this.readLine(), this.event); + try { + this.parseLine(this.readLine(), this.event); + } catch (error2) { + callback(error2); + return; + } this.consumeCurrentByte(); this.eventEndCheck = true; continue; } + if (this.maxEventSize > 0 && ++this.lineLength > this.maxEventSize + 7) { + callback(createMaxEventSizeExceededError()); + return; + } this.advanceCursor(); } callback(); } + _destroy(error2, callback) { + this.chunks.length = 0; + this.clearEvent(); + super._destroy(error2, callback); + } /** * @param {Buffer} line - * @param {EventStreamEvent} event + * @param {EventSourceStreamEvent} event */ parseLine(line, event) { if (line.length === 0) { @@ -18456,6 +18513,12 @@ var require_eventsource_stream = __commonJS({ } } 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 === void 0 ? 0 : 1) + valueBytes; + this.setEventFieldSize("data", dataSize); const value = line.toString("utf8", valueStart); if (event.data === void 0) { event.data = value; @@ -18463,27 +18526,38 @@ var require_eventsource_stream = __commonJS({ event.data += ` ${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; } 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 */ @@ -18510,6 +18584,12 @@ ${value}`; this.event.event = void 0; this.event.id = void 0; this.event.retry = void 0; + this.eventSize = 0; + this.dataLineCount = 0; + this.eventFieldSizes.data = 0; + this.eventFieldSizes.event = 0; + this.eventFieldSizes.id = 0; + this.eventFieldSizes.retry = 0; } hasPendingEvent() { return this.event.data !== void 0 || this.event.event !== void 0 || this.event.id !== void 0 || this.event.retry !== void 0; @@ -18534,13 +18614,15 @@ ${value}`; 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) { this.chunks.length = 0; @@ -18643,6 +18725,7 @@ var require_eventsource = __commonJS({ var { delay } = require_util8(); var { kEnumerableProperty } = require_util(); var { environmentSettingsObject } = require_util2(); + var { getGlobalDispatcher } = require_global2(); var experimentalWarned = false; var defaultReconnectionTime = 3e3; var CONNECTING = 0; @@ -18783,6 +18866,7 @@ var require_eventsource = __commonJS({ this.#state.origin = response.urlList[response.urlList.length - 1].origin; const eventSourceStream = new EventSourceStream({ eventSourceSettings: this.#state, + maxEventSize: this.#dispatcher.eventSourceOptions?.maxEventSize, push: (event) => { this.dispatchEvent(createFastMessageEvent( event.type, @@ -18915,7 +18999,8 @@ var require_eventsource = __commonJS({ { key: "dispatcher", // undici only - converter: webidl.converters.any + converter: webidl.converters.any, + defaultValue: () => getGlobalDispatcher() } ]); module.exports = { diff --git a/.github/actions/javascript/isDeployChecklistLocked/index.js b/.github/actions/javascript/isDeployChecklistLocked/index.js index 9cac857a61a8..e646925d3b70 100644 --- a/.github/actions/javascript/isDeployChecklistLocked/index.js +++ b/.github/actions/javascript/isDeployChecklistLocked/index.js @@ -28942,6 +28942,7 @@ var require_dispatcher = __commonJS({ var require_dispatcher_base = __commonJS({ "node_modules/undici/lib/dispatcher/dispatcher-base.js"(exports, module) { "use strict"; + var buffer = __require("node:buffer"); var Dispatcher = require_dispatcher(); var { ClientDestroyedError, @@ -28953,6 +28954,7 @@ var require_dispatcher_base = __commonJS({ var kOnClosed = /* @__PURE__ */ Symbol("onClosed"); var kInterceptedDispatch = /* @__PURE__ */ Symbol("Intercepted Dispatch"); var kWebSocketOptions = /* @__PURE__ */ Symbol("webSocketOptions"); + var kEventSourceOptions = /* @__PURE__ */ Symbol("eventSourceOptions"); var DispatcherBase = class extends Dispatcher { constructor(opts) { super(); @@ -28961,6 +28963,7 @@ var require_dispatcher_base = __commonJS({ this[kClosed] = false; this[kOnClosed] = []; this[kWebSocketOptions] = opts?.webSocket ?? {}; + this[kEventSourceOptions] = opts?.eventSource ?? {}; } get webSocketOptions() { return { @@ -28968,6 +28971,11 @@ var require_dispatcher_base = __commonJS({ maxPayloadSize: this[kWebSocketOptions].maxPayloadSize ?? 128 * 1024 * 1024 }; } + get eventSourceOptions() { + return { + maxEventSize: this[kEventSourceOptions].maxEventSize ?? buffer.kStringMaxLength + }; + } get destroyed() { return this[kDestroyed]; } @@ -33115,7 +33123,6 @@ var require_client_h1 = __commonJS({ socket[kSocketUsed] = false; socket[kParser] = new Parser(client, socket, llhttpInstance); addListener(socket, "error", function(err) { - assert(err.code !== "ERR_TLS_CERT_ALTNAME_INVALID"); const parser = this[kParser]; if (err.code === "ECONNRESET" && parser.statusCode && !parser.shouldKeepAlive) { const parserErr = parser.finish(); @@ -33799,7 +33806,6 @@ var require_client_h2 = __commonJS({ client[kHTTP2Session] = session; socket[kHTTP2Session] = session; util.addListener(socket, "error", function(err) { - assert(err.code !== "ERR_TLS_CERT_ALTNAME_INVALID"); this[kError] = err; this[kClient][kOnError](err); }); @@ -33858,7 +33864,6 @@ var require_client_h2 = __commonJS({ } } function onHttp2SessionError(err) { - assert(err.code !== "ERR_TLS_CERT_ALTNAME_INVALID"); this[kSocket][kError] = err; this[kClient][kOnError](err); } @@ -34552,9 +34557,10 @@ var require_client = __commonJS({ // h2 maxConcurrentStreams, allowH2, - webSocket + webSocket, + eventSource } = {}) { - super({ webSocket }); + super({ webSocket, eventSource }); if (keepAlive !== void 0) { throw new InvalidArgumentError("unsupported keepAlive, use pipelining=0 instead"); } @@ -35451,7 +35457,7 @@ var require_agent = __commonJS({ return opts && opts.connections === 1 ? new Client(origin, opts) : new Pool(origin, opts); } var Agent = class extends DispatcherBase { - constructor({ factory = defaultFactory, maxRedirections = 0, connect, ...options } = {}) { + constructor({ factory = defaultFactory, maxRedirections = 0, connect, tls, ...options } = {}) { if (typeof factory !== "function") { throw new InvalidArgumentError("factory must be a function."); } @@ -35465,8 +35471,11 @@ var require_agent = __commonJS({ if (connect && typeof connect !== "function") { connect = { ...connect }; } + if (tls && typeof tls !== "function") { + tls = { ...tls }; + } this[kInterceptors] = options.interceptors?.Agent && Array.isArray(options.interceptors.Agent) ? options.interceptors.Agent : [createRedirectInterceptor({ maxRedirections })]; - this[kOptions] = { ...util.deepClone(options), connect }; + this[kOptions] = { ...util.deepClone(options), connect, tls }; this[kOptions].interceptors = options.interceptors ? { ...options.interceptors } : void 0; this[kMaxRedirections] = maxRedirections; this[kFactory] = factory; @@ -41194,8 +41203,9 @@ var require_fetch = __commonJS({ } ); response.body = { stream, source: null, length: null }; - fetchParams.controller.onAborted = onAborted; - fetchParams.controller.on("terminated", onAborted); + if (!fetchParams.controller.resume) { + fetchParams.controller.on("terminated", onAborted); + } fetchParams.controller.resume = async () => { while (true) { let bytes; @@ -41295,7 +41305,6 @@ var require_fetch = __commonJS({ headersList.append(bufferToLowerCasedHeaderName(rawHeaders[i]), rawHeaders[i + 1].toString("latin1"), true); } location = headersList.get("location", true); - this.body = new Readable({ read: resume }); const decoders = []; const willFollow = location && request2.redirect === "follow" && redirectStatusSet.has(status); if (request2.method !== "HEAD" && request2.method !== "CONNECT" && !nullBodyStatus.includes(status) && !willFollow) { @@ -41303,7 +41312,7 @@ var require_fetch = __commonJS({ const codings = contentEncoding ? contentEncoding.toLowerCase().split(",") : []; const maxContentEncodings = 5; if (codings.length > maxContentEncodings) { - reject(new Error(`too many content-encodings in response: ${codings.length}, maximum allowed is ${maxContentEncodings}`)); + this.abort(new Error(`too many content-encodings in response: ${codings.length}, maximum allowed is ${maxContentEncodings}`)); return true; } for (let i = codings.length - 1; i >= 0; --i) { @@ -41333,6 +41342,7 @@ var require_fetch = __commonJS({ } } } + this.body = new Readable({ read: resume }); const onError = this.onError.bind(this); resolve({ status, @@ -41358,9 +41368,6 @@ var require_fetch = __commonJS({ if (this.abort) { fetchParams.controller.off("terminated", this.abort); } - if (fetchParams.controller.onAborted) { - fetchParams.controller.off("terminated", fetchParams.controller.onAborted); - } fetchParams.controller.ended = true; this.body.push(null); }, @@ -44434,6 +44441,16 @@ var require_receiver = __commonJS({ if (isControlFrame(this.#info.opcode)) { this.#loop = this.parseControlFrame(body); this.#state = parserStates.INFO; + const socket = this.ws[kResponse].socket; + if (this.#loop && socket.writableNeedDrain) { + this.#loop = false; + socket.once("drain", () => { + if (this.destroyed) return; + this.#loop = true; + this.run(callback); + }); + return; + } } else { if (!this.#info.compressed) { if (!this.writeFragments(body)) { @@ -45127,6 +45144,7 @@ var require_util8 = __commonJS({ var require_eventsource_stream = __commonJS({ "node_modules/undici/lib/web/eventsource/eventsource-stream.js"(exports, module) { "use strict"; + var buffer = __require("node:buffer"); var { Transform } = __require("node:stream"); var { isASCIINumber, isValidLastEventId } = require_util8(); var BOM = [239, 187, 191]; @@ -45134,24 +45152,28 @@ var require_eventsource_stream = __commonJS({ var CR = 13; var COLON = 58; var SPACE = 32; + var defaultMaxEventSize = buffer.kStringMaxLength; var DATA = Buffer.from("data"); var EVENT = Buffer.from("event"); var ID = Buffer.from("id"); var RETRY = Buffer.from("retry"); - function isASCIINumberBytes(buffer, start) { - if (start >= buffer.length) { + var minParserItems = 1024; + var maxParserItems = 131072; + var bytesPerParserItem = 128; + function isASCIINumberBytes(buffer2, start) { + if (start >= buffer2.length) { return false; } - for (let i = start; i < buffer.length; i++) { - if (buffer[i] < 48 || buffer[i] > 57) { + for (let i = start; i < buffer2.length; i++) { + if (buffer2[i] < 48 || buffer2[i] > 57) { return false; } } return true; } - function isValidLastEventIdBytes(buffer, start) { - for (let i = start; i < buffer.length; i++) { - if (buffer[i] === 0) { + function isValidLastEventIdBytes(buffer2, start) { + for (let i = start; i < buffer2.length; i++) { + if (buffer2[i] === 0) { return false; } } @@ -45168,6 +45190,11 @@ var require_eventsource_stream = __commonJS({ } return true; } + function createMaxEventSizeExceededError() { + const error2 = new Error("EventSource message size exceeded"); + error2.aborted = false; + return error2; + } var EventSourceStream = class extends Transform { /** * @type {eventSourceSettings} @@ -45194,6 +45221,13 @@ var require_eventsource_stream = __commonJS({ 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: void 0, event: void 0, @@ -45202,6 +45236,7 @@ var require_eventsource_stream = __commonJS({ }; /** * @param {object} options + * @param {number} [options.maxEventSize] * @param {eventSourceSettings} options.eventSourceSettings * @param {Function} [options.push] */ @@ -45209,6 +45244,10 @@ var require_eventsource_stream = __commonJS({ options.readableObjectMode = true; 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; } @@ -45224,6 +45263,10 @@ var require_eventsource_stream = __commonJS({ callback(); return; } + if (this.maxEventSize > 0 && this.chunks.length >= this.maxBufferedChunks && chunk[0] !== LF && chunk[0] !== CR) { + callback(createMaxEventSizeExceededError()); + return; + } this.chunks.push(chunk); if (this.checkBOM) { if (this.handleBOM()) { @@ -45260,18 +45303,32 @@ var require_eventsource_stream = __commonJS({ if (byte === CR) { this.crlfCheck = true; } - this.parseLine(this.readLine(), this.event); + try { + this.parseLine(this.readLine(), this.event); + } catch (error2) { + callback(error2); + return; + } this.consumeCurrentByte(); this.eventEndCheck = true; continue; } + if (this.maxEventSize > 0 && ++this.lineLength > this.maxEventSize + 7) { + callback(createMaxEventSizeExceededError()); + return; + } this.advanceCursor(); } callback(); } + _destroy(error2, callback) { + this.chunks.length = 0; + this.clearEvent(); + super._destroy(error2, callback); + } /** * @param {Buffer} line - * @param {EventStreamEvent} event + * @param {EventSourceStreamEvent} event */ parseLine(line, event) { if (line.length === 0) { @@ -45291,6 +45348,12 @@ var require_eventsource_stream = __commonJS({ } } 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 === void 0 ? 0 : 1) + valueBytes; + this.setEventFieldSize("data", dataSize); const value = line.toString("utf8", valueStart); if (event.data === void 0) { event.data = value; @@ -45298,27 +45361,38 @@ var require_eventsource_stream = __commonJS({ event.data += ` ${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; } 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 */ @@ -45345,6 +45419,12 @@ ${value}`; this.event.event = void 0; this.event.id = void 0; this.event.retry = void 0; + this.eventSize = 0; + this.dataLineCount = 0; + this.eventFieldSizes.data = 0; + this.eventFieldSizes.event = 0; + this.eventFieldSizes.id = 0; + this.eventFieldSizes.retry = 0; } hasPendingEvent() { return this.event.data !== void 0 || this.event.event !== void 0 || this.event.id !== void 0 || this.event.retry !== void 0; @@ -45369,13 +45449,15 @@ ${value}`; 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) { this.chunks.length = 0; @@ -45478,6 +45560,7 @@ var require_eventsource = __commonJS({ var { delay } = require_util8(); var { kEnumerableProperty } = require_util(); var { environmentSettingsObject } = require_util2(); + var { getGlobalDispatcher } = require_global2(); var experimentalWarned = false; var defaultReconnectionTime = 3e3; var CONNECTING = 0; @@ -45618,6 +45701,7 @@ var require_eventsource = __commonJS({ this.#state.origin = response.urlList[response.urlList.length - 1].origin; const eventSourceStream = new EventSourceStream({ eventSourceSettings: this.#state, + maxEventSize: this.#dispatcher.eventSourceOptions?.maxEventSize, push: (event) => { this.dispatchEvent(createFastMessageEvent( event.type, @@ -45750,7 +45834,8 @@ var require_eventsource = __commonJS({ { key: "dispatcher", // undici only - converter: webidl.converters.any + converter: webidl.converters.any, + defaultValue: () => getGlobalDispatcher() } ]); module.exports = { diff --git a/.github/actions/javascript/markPullRequestsAsDeployed/index.js b/.github/actions/javascript/markPullRequestsAsDeployed/index.js index 49325ea14f4f..3737b76f680d 100644 --- a/.github/actions/javascript/markPullRequestsAsDeployed/index.js +++ b/.github/actions/javascript/markPullRequestsAsDeployed/index.js @@ -2107,6 +2107,7 @@ var require_dispatcher = __commonJS({ var require_dispatcher_base = __commonJS({ "node_modules/undici/lib/dispatcher/dispatcher-base.js"(exports, module) { "use strict"; + var buffer = __require("node:buffer"); var Dispatcher = require_dispatcher(); var { ClientDestroyedError, @@ -2118,6 +2119,7 @@ var require_dispatcher_base = __commonJS({ var kOnClosed = /* @__PURE__ */ Symbol("onClosed"); var kInterceptedDispatch = /* @__PURE__ */ Symbol("Intercepted Dispatch"); var kWebSocketOptions = /* @__PURE__ */ Symbol("webSocketOptions"); + var kEventSourceOptions = /* @__PURE__ */ Symbol("eventSourceOptions"); var DispatcherBase = class extends Dispatcher { constructor(opts) { super(); @@ -2126,6 +2128,7 @@ var require_dispatcher_base = __commonJS({ this[kClosed] = false; this[kOnClosed] = []; this[kWebSocketOptions] = opts?.webSocket ?? {}; + this[kEventSourceOptions] = opts?.eventSource ?? {}; } get webSocketOptions() { return { @@ -2133,6 +2136,11 @@ var require_dispatcher_base = __commonJS({ maxPayloadSize: this[kWebSocketOptions].maxPayloadSize ?? 128 * 1024 * 1024 }; } + get eventSourceOptions() { + return { + maxEventSize: this[kEventSourceOptions].maxEventSize ?? buffer.kStringMaxLength + }; + } get destroyed() { return this[kDestroyed]; } @@ -6280,7 +6288,6 @@ var require_client_h1 = __commonJS({ socket[kSocketUsed] = false; socket[kParser] = new Parser(client, socket, llhttpInstance); addListener(socket, "error", function(err) { - assert(err.code !== "ERR_TLS_CERT_ALTNAME_INVALID"); const parser = this[kParser]; if (err.code === "ECONNRESET" && parser.statusCode && !parser.shouldKeepAlive) { const parserErr = parser.finish(); @@ -6964,7 +6971,6 @@ var require_client_h2 = __commonJS({ client[kHTTP2Session] = session; socket[kHTTP2Session] = session; util.addListener(socket, "error", function(err) { - assert(err.code !== "ERR_TLS_CERT_ALTNAME_INVALID"); this[kError] = err; this[kClient][kOnError](err); }); @@ -7023,7 +7029,6 @@ var require_client_h2 = __commonJS({ } } function onHttp2SessionError(err) { - assert(err.code !== "ERR_TLS_CERT_ALTNAME_INVALID"); this[kSocket][kError] = err; this[kClient][kOnError](err); } @@ -7717,9 +7722,10 @@ var require_client = __commonJS({ // h2 maxConcurrentStreams, allowH2, - webSocket + webSocket, + eventSource } = {}) { - super({ webSocket }); + super({ webSocket, eventSource }); if (keepAlive !== void 0) { throw new InvalidArgumentError("unsupported keepAlive, use pipelining=0 instead"); } @@ -8616,7 +8622,7 @@ var require_agent = __commonJS({ return opts && opts.connections === 1 ? new Client(origin, opts) : new Pool(origin, opts); } var Agent = class extends DispatcherBase { - constructor({ factory = defaultFactory, maxRedirections = 0, connect, ...options } = {}) { + constructor({ factory = defaultFactory, maxRedirections = 0, connect, tls, ...options } = {}) { if (typeof factory !== "function") { throw new InvalidArgumentError("factory must be a function."); } @@ -8630,8 +8636,11 @@ var require_agent = __commonJS({ if (connect && typeof connect !== "function") { connect = { ...connect }; } + if (tls && typeof tls !== "function") { + tls = { ...tls }; + } this[kInterceptors] = options.interceptors?.Agent && Array.isArray(options.interceptors.Agent) ? options.interceptors.Agent : [createRedirectInterceptor({ maxRedirections })]; - this[kOptions] = { ...util.deepClone(options), connect }; + this[kOptions] = { ...util.deepClone(options), connect, tls }; this[kOptions].interceptors = options.interceptors ? { ...options.interceptors } : void 0; this[kMaxRedirections] = maxRedirections; this[kFactory] = factory; @@ -14359,8 +14368,9 @@ var require_fetch = __commonJS({ } ); response.body = { stream, source: null, length: null }; - fetchParams.controller.onAborted = onAborted; - fetchParams.controller.on("terminated", onAborted); + if (!fetchParams.controller.resume) { + fetchParams.controller.on("terminated", onAborted); + } fetchParams.controller.resume = async () => { while (true) { let bytes; @@ -14460,7 +14470,6 @@ var require_fetch = __commonJS({ headersList.append(bufferToLowerCasedHeaderName(rawHeaders[i]), rawHeaders[i + 1].toString("latin1"), true); } location = headersList.get("location", true); - this.body = new Readable({ read: resume }); const decoders = []; const willFollow = location && request2.redirect === "follow" && redirectStatusSet.has(status); if (request2.method !== "HEAD" && request2.method !== "CONNECT" && !nullBodyStatus.includes(status) && !willFollow) { @@ -14468,7 +14477,7 @@ var require_fetch = __commonJS({ const codings = contentEncoding ? contentEncoding.toLowerCase().split(",") : []; const maxContentEncodings = 5; if (codings.length > maxContentEncodings) { - reject(new Error(`too many content-encodings in response: ${codings.length}, maximum allowed is ${maxContentEncodings}`)); + this.abort(new Error(`too many content-encodings in response: ${codings.length}, maximum allowed is ${maxContentEncodings}`)); return true; } for (let i = codings.length - 1; i >= 0; --i) { @@ -14498,6 +14507,7 @@ var require_fetch = __commonJS({ } } } + this.body = new Readable({ read: resume }); const onError = this.onError.bind(this); resolve({ status, @@ -14523,9 +14533,6 @@ var require_fetch = __commonJS({ if (this.abort) { fetchParams.controller.off("terminated", this.abort); } - if (fetchParams.controller.onAborted) { - fetchParams.controller.off("terminated", fetchParams.controller.onAborted); - } fetchParams.controller.ended = true; this.body.push(null); }, @@ -17599,6 +17606,16 @@ var require_receiver = __commonJS({ if (isControlFrame(this.#info.opcode)) { this.#loop = this.parseControlFrame(body); this.#state = parserStates.INFO; + const socket = this.ws[kResponse].socket; + if (this.#loop && socket.writableNeedDrain) { + this.#loop = false; + socket.once("drain", () => { + if (this.destroyed) return; + this.#loop = true; + this.run(callback); + }); + return; + } } else { if (!this.#info.compressed) { if (!this.writeFragments(body)) { @@ -18292,6 +18309,7 @@ var require_util8 = __commonJS({ var require_eventsource_stream = __commonJS({ "node_modules/undici/lib/web/eventsource/eventsource-stream.js"(exports, module) { "use strict"; + var buffer = __require("node:buffer"); var { Transform } = __require("node:stream"); var { isASCIINumber, isValidLastEventId } = require_util8(); var BOM = [239, 187, 191]; @@ -18299,24 +18317,28 @@ var require_eventsource_stream = __commonJS({ var CR = 13; var COLON = 58; var SPACE = 32; + var defaultMaxEventSize = buffer.kStringMaxLength; var DATA = Buffer.from("data"); var EVENT = Buffer.from("event"); var ID = Buffer.from("id"); var RETRY = Buffer.from("retry"); - function isASCIINumberBytes(buffer, start) { - if (start >= buffer.length) { + var minParserItems = 1024; + var maxParserItems = 131072; + var bytesPerParserItem = 128; + function isASCIINumberBytes(buffer2, start) { + if (start >= buffer2.length) { return false; } - for (let i = start; i < buffer.length; i++) { - if (buffer[i] < 48 || buffer[i] > 57) { + for (let i = start; i < buffer2.length; i++) { + if (buffer2[i] < 48 || buffer2[i] > 57) { return false; } } return true; } - function isValidLastEventIdBytes(buffer, start) { - for (let i = start; i < buffer.length; i++) { - if (buffer[i] === 0) { + function isValidLastEventIdBytes(buffer2, start) { + for (let i = start; i < buffer2.length; i++) { + if (buffer2[i] === 0) { return false; } } @@ -18333,6 +18355,11 @@ var require_eventsource_stream = __commonJS({ } return true; } + function createMaxEventSizeExceededError() { + const error2 = new Error("EventSource message size exceeded"); + error2.aborted = false; + return error2; + } var EventSourceStream = class extends Transform { /** * @type {eventSourceSettings} @@ -18359,6 +18386,13 @@ var require_eventsource_stream = __commonJS({ 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: void 0, event: void 0, @@ -18367,6 +18401,7 @@ var require_eventsource_stream = __commonJS({ }; /** * @param {object} options + * @param {number} [options.maxEventSize] * @param {eventSourceSettings} options.eventSourceSettings * @param {Function} [options.push] */ @@ -18374,6 +18409,10 @@ var require_eventsource_stream = __commonJS({ options.readableObjectMode = true; 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; } @@ -18389,6 +18428,10 @@ var require_eventsource_stream = __commonJS({ callback(); return; } + if (this.maxEventSize > 0 && this.chunks.length >= this.maxBufferedChunks && chunk[0] !== LF && chunk[0] !== CR) { + callback(createMaxEventSizeExceededError()); + return; + } this.chunks.push(chunk); if (this.checkBOM) { if (this.handleBOM()) { @@ -18425,18 +18468,32 @@ var require_eventsource_stream = __commonJS({ if (byte === CR) { this.crlfCheck = true; } - this.parseLine(this.readLine(), this.event); + try { + this.parseLine(this.readLine(), this.event); + } catch (error2) { + callback(error2); + return; + } this.consumeCurrentByte(); this.eventEndCheck = true; continue; } + if (this.maxEventSize > 0 && ++this.lineLength > this.maxEventSize + 7) { + callback(createMaxEventSizeExceededError()); + return; + } this.advanceCursor(); } callback(); } + _destroy(error2, callback) { + this.chunks.length = 0; + this.clearEvent(); + super._destroy(error2, callback); + } /** * @param {Buffer} line - * @param {EventStreamEvent} event + * @param {EventSourceStreamEvent} event */ parseLine(line, event) { if (line.length === 0) { @@ -18456,6 +18513,12 @@ var require_eventsource_stream = __commonJS({ } } 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 === void 0 ? 0 : 1) + valueBytes; + this.setEventFieldSize("data", dataSize); const value = line.toString("utf8", valueStart); if (event.data === void 0) { event.data = value; @@ -18463,27 +18526,38 @@ var require_eventsource_stream = __commonJS({ event.data += ` ${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; } 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 */ @@ -18510,6 +18584,12 @@ ${value}`; this.event.event = void 0; this.event.id = void 0; this.event.retry = void 0; + this.eventSize = 0; + this.dataLineCount = 0; + this.eventFieldSizes.data = 0; + this.eventFieldSizes.event = 0; + this.eventFieldSizes.id = 0; + this.eventFieldSizes.retry = 0; } hasPendingEvent() { return this.event.data !== void 0 || this.event.event !== void 0 || this.event.id !== void 0 || this.event.retry !== void 0; @@ -18534,13 +18614,15 @@ ${value}`; 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) { this.chunks.length = 0; @@ -18643,6 +18725,7 @@ var require_eventsource = __commonJS({ var { delay } = require_util8(); var { kEnumerableProperty } = require_util(); var { environmentSettingsObject } = require_util2(); + var { getGlobalDispatcher } = require_global2(); var experimentalWarned = false; var defaultReconnectionTime = 3e3; var CONNECTING = 0; @@ -18783,6 +18866,7 @@ var require_eventsource = __commonJS({ this.#state.origin = response.urlList[response.urlList.length - 1].origin; const eventSourceStream = new EventSourceStream({ eventSourceSettings: this.#state, + maxEventSize: this.#dispatcher.eventSourceOptions?.maxEventSize, push: (event) => { this.dispatchEvent(createFastMessageEvent( event.type, @@ -18915,7 +18999,8 @@ var require_eventsource = __commonJS({ { key: "dispatcher", // undici only - converter: webidl.converters.any + converter: webidl.converters.any, + defaultValue: () => getGlobalDispatcher() } ]); module.exports = { diff --git a/.github/actions/javascript/postOrReplaceComment/index.js b/.github/actions/javascript/postOrReplaceComment/index.js index 085163ad63f6..46073830b48c 100644 --- a/.github/actions/javascript/postOrReplaceComment/index.js +++ b/.github/actions/javascript/postOrReplaceComment/index.js @@ -2107,6 +2107,7 @@ var require_dispatcher = __commonJS({ var require_dispatcher_base = __commonJS({ "node_modules/undici/lib/dispatcher/dispatcher-base.js"(exports, module) { "use strict"; + var buffer = __require("node:buffer"); var Dispatcher = require_dispatcher(); var { ClientDestroyedError, @@ -2118,6 +2119,7 @@ var require_dispatcher_base = __commonJS({ var kOnClosed = /* @__PURE__ */ Symbol("onClosed"); var kInterceptedDispatch = /* @__PURE__ */ Symbol("Intercepted Dispatch"); var kWebSocketOptions = /* @__PURE__ */ Symbol("webSocketOptions"); + var kEventSourceOptions = /* @__PURE__ */ Symbol("eventSourceOptions"); var DispatcherBase = class extends Dispatcher { constructor(opts) { super(); @@ -2126,6 +2128,7 @@ var require_dispatcher_base = __commonJS({ this[kClosed] = false; this[kOnClosed] = []; this[kWebSocketOptions] = opts?.webSocket ?? {}; + this[kEventSourceOptions] = opts?.eventSource ?? {}; } get webSocketOptions() { return { @@ -2133,6 +2136,11 @@ var require_dispatcher_base = __commonJS({ maxPayloadSize: this[kWebSocketOptions].maxPayloadSize ?? 128 * 1024 * 1024 }; } + get eventSourceOptions() { + return { + maxEventSize: this[kEventSourceOptions].maxEventSize ?? buffer.kStringMaxLength + }; + } get destroyed() { return this[kDestroyed]; } @@ -6280,7 +6288,6 @@ var require_client_h1 = __commonJS({ socket[kSocketUsed] = false; socket[kParser] = new Parser(client, socket, llhttpInstance); addListener(socket, "error", function(err) { - assert(err.code !== "ERR_TLS_CERT_ALTNAME_INVALID"); const parser = this[kParser]; if (err.code === "ECONNRESET" && parser.statusCode && !parser.shouldKeepAlive) { const parserErr = parser.finish(); @@ -6964,7 +6971,6 @@ var require_client_h2 = __commonJS({ client[kHTTP2Session] = session; socket[kHTTP2Session] = session; util.addListener(socket, "error", function(err) { - assert(err.code !== "ERR_TLS_CERT_ALTNAME_INVALID"); this[kError] = err; this[kClient][kOnError](err); }); @@ -7023,7 +7029,6 @@ var require_client_h2 = __commonJS({ } } function onHttp2SessionError(err) { - assert(err.code !== "ERR_TLS_CERT_ALTNAME_INVALID"); this[kSocket][kError] = err; this[kClient][kOnError](err); } @@ -7717,9 +7722,10 @@ var require_client = __commonJS({ // h2 maxConcurrentStreams, allowH2, - webSocket + webSocket, + eventSource } = {}) { - super({ webSocket }); + super({ webSocket, eventSource }); if (keepAlive !== void 0) { throw new InvalidArgumentError("unsupported keepAlive, use pipelining=0 instead"); } @@ -8616,7 +8622,7 @@ var require_agent = __commonJS({ return opts && opts.connections === 1 ? new Client(origin, opts) : new Pool(origin, opts); } var Agent = class extends DispatcherBase { - constructor({ factory = defaultFactory, maxRedirections = 0, connect, ...options } = {}) { + constructor({ factory = defaultFactory, maxRedirections = 0, connect, tls, ...options } = {}) { if (typeof factory !== "function") { throw new InvalidArgumentError("factory must be a function."); } @@ -8630,8 +8636,11 @@ var require_agent = __commonJS({ if (connect && typeof connect !== "function") { connect = { ...connect }; } + if (tls && typeof tls !== "function") { + tls = { ...tls }; + } this[kInterceptors] = options.interceptors?.Agent && Array.isArray(options.interceptors.Agent) ? options.interceptors.Agent : [createRedirectInterceptor({ maxRedirections })]; - this[kOptions] = { ...util.deepClone(options), connect }; + this[kOptions] = { ...util.deepClone(options), connect, tls }; this[kOptions].interceptors = options.interceptors ? { ...options.interceptors } : void 0; this[kMaxRedirections] = maxRedirections; this[kFactory] = factory; @@ -14359,8 +14368,9 @@ var require_fetch = __commonJS({ } ); response.body = { stream, source: null, length: null }; - fetchParams.controller.onAborted = onAborted; - fetchParams.controller.on("terminated", onAborted); + if (!fetchParams.controller.resume) { + fetchParams.controller.on("terminated", onAborted); + } fetchParams.controller.resume = async () => { while (true) { let bytes; @@ -14460,7 +14470,6 @@ var require_fetch = __commonJS({ headersList.append(bufferToLowerCasedHeaderName(rawHeaders[i]), rawHeaders[i + 1].toString("latin1"), true); } location = headersList.get("location", true); - this.body = new Readable({ read: resume }); const decoders = []; const willFollow = location && request2.redirect === "follow" && redirectStatusSet.has(status); if (request2.method !== "HEAD" && request2.method !== "CONNECT" && !nullBodyStatus.includes(status) && !willFollow) { @@ -14468,7 +14477,7 @@ var require_fetch = __commonJS({ const codings = contentEncoding ? contentEncoding.toLowerCase().split(",") : []; const maxContentEncodings = 5; if (codings.length > maxContentEncodings) { - reject(new Error(`too many content-encodings in response: ${codings.length}, maximum allowed is ${maxContentEncodings}`)); + this.abort(new Error(`too many content-encodings in response: ${codings.length}, maximum allowed is ${maxContentEncodings}`)); return true; } for (let i = codings.length - 1; i >= 0; --i) { @@ -14498,6 +14507,7 @@ var require_fetch = __commonJS({ } } } + this.body = new Readable({ read: resume }); const onError = this.onError.bind(this); resolve({ status, @@ -14523,9 +14533,6 @@ var require_fetch = __commonJS({ if (this.abort) { fetchParams.controller.off("terminated", this.abort); } - if (fetchParams.controller.onAborted) { - fetchParams.controller.off("terminated", fetchParams.controller.onAborted); - } fetchParams.controller.ended = true; this.body.push(null); }, @@ -17599,6 +17606,16 @@ var require_receiver = __commonJS({ if (isControlFrame(this.#info.opcode)) { this.#loop = this.parseControlFrame(body); this.#state = parserStates.INFO; + const socket = this.ws[kResponse].socket; + if (this.#loop && socket.writableNeedDrain) { + this.#loop = false; + socket.once("drain", () => { + if (this.destroyed) return; + this.#loop = true; + this.run(callback); + }); + return; + } } else { if (!this.#info.compressed) { if (!this.writeFragments(body)) { @@ -18292,6 +18309,7 @@ var require_util8 = __commonJS({ var require_eventsource_stream = __commonJS({ "node_modules/undici/lib/web/eventsource/eventsource-stream.js"(exports, module) { "use strict"; + var buffer = __require("node:buffer"); var { Transform } = __require("node:stream"); var { isASCIINumber, isValidLastEventId } = require_util8(); var BOM = [239, 187, 191]; @@ -18299,24 +18317,28 @@ var require_eventsource_stream = __commonJS({ var CR = 13; var COLON = 58; var SPACE = 32; + var defaultMaxEventSize = buffer.kStringMaxLength; var DATA = Buffer.from("data"); var EVENT = Buffer.from("event"); var ID = Buffer.from("id"); var RETRY = Buffer.from("retry"); - function isASCIINumberBytes(buffer, start) { - if (start >= buffer.length) { + var minParserItems = 1024; + var maxParserItems = 131072; + var bytesPerParserItem = 128; + function isASCIINumberBytes(buffer2, start) { + if (start >= buffer2.length) { return false; } - for (let i = start; i < buffer.length; i++) { - if (buffer[i] < 48 || buffer[i] > 57) { + for (let i = start; i < buffer2.length; i++) { + if (buffer2[i] < 48 || buffer2[i] > 57) { return false; } } return true; } - function isValidLastEventIdBytes(buffer, start) { - for (let i = start; i < buffer.length; i++) { - if (buffer[i] === 0) { + function isValidLastEventIdBytes(buffer2, start) { + for (let i = start; i < buffer2.length; i++) { + if (buffer2[i] === 0) { return false; } } @@ -18333,6 +18355,11 @@ var require_eventsource_stream = __commonJS({ } return true; } + function createMaxEventSizeExceededError() { + const error2 = new Error("EventSource message size exceeded"); + error2.aborted = false; + return error2; + } var EventSourceStream = class extends Transform { /** * @type {eventSourceSettings} @@ -18359,6 +18386,13 @@ var require_eventsource_stream = __commonJS({ 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: void 0, event: void 0, @@ -18367,6 +18401,7 @@ var require_eventsource_stream = __commonJS({ }; /** * @param {object} options + * @param {number} [options.maxEventSize] * @param {eventSourceSettings} options.eventSourceSettings * @param {Function} [options.push] */ @@ -18374,6 +18409,10 @@ var require_eventsource_stream = __commonJS({ options.readableObjectMode = true; 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; } @@ -18389,6 +18428,10 @@ var require_eventsource_stream = __commonJS({ callback(); return; } + if (this.maxEventSize > 0 && this.chunks.length >= this.maxBufferedChunks && chunk[0] !== LF && chunk[0] !== CR) { + callback(createMaxEventSizeExceededError()); + return; + } this.chunks.push(chunk); if (this.checkBOM) { if (this.handleBOM()) { @@ -18425,18 +18468,32 @@ var require_eventsource_stream = __commonJS({ if (byte === CR) { this.crlfCheck = true; } - this.parseLine(this.readLine(), this.event); + try { + this.parseLine(this.readLine(), this.event); + } catch (error2) { + callback(error2); + return; + } this.consumeCurrentByte(); this.eventEndCheck = true; continue; } + if (this.maxEventSize > 0 && ++this.lineLength > this.maxEventSize + 7) { + callback(createMaxEventSizeExceededError()); + return; + } this.advanceCursor(); } callback(); } + _destroy(error2, callback) { + this.chunks.length = 0; + this.clearEvent(); + super._destroy(error2, callback); + } /** * @param {Buffer} line - * @param {EventStreamEvent} event + * @param {EventSourceStreamEvent} event */ parseLine(line, event) { if (line.length === 0) { @@ -18456,6 +18513,12 @@ var require_eventsource_stream = __commonJS({ } } 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 === void 0 ? 0 : 1) + valueBytes; + this.setEventFieldSize("data", dataSize); const value = line.toString("utf8", valueStart); if (event.data === void 0) { event.data = value; @@ -18463,27 +18526,38 @@ var require_eventsource_stream = __commonJS({ event.data += ` ${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; } 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 */ @@ -18510,6 +18584,12 @@ ${value}`; this.event.event = void 0; this.event.id = void 0; this.event.retry = void 0; + this.eventSize = 0; + this.dataLineCount = 0; + this.eventFieldSizes.data = 0; + this.eventFieldSizes.event = 0; + this.eventFieldSizes.id = 0; + this.eventFieldSizes.retry = 0; } hasPendingEvent() { return this.event.data !== void 0 || this.event.event !== void 0 || this.event.id !== void 0 || this.event.retry !== void 0; @@ -18534,13 +18614,15 @@ ${value}`; 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) { this.chunks.length = 0; @@ -18643,6 +18725,7 @@ var require_eventsource = __commonJS({ var { delay } = require_util8(); var { kEnumerableProperty } = require_util(); var { environmentSettingsObject } = require_util2(); + var { getGlobalDispatcher } = require_global2(); var experimentalWarned = false; var defaultReconnectionTime = 3e3; var CONNECTING = 0; @@ -18783,6 +18866,7 @@ var require_eventsource = __commonJS({ this.#state.origin = response.urlList[response.urlList.length - 1].origin; const eventSourceStream = new EventSourceStream({ eventSourceSettings: this.#state, + maxEventSize: this.#dispatcher.eventSourceOptions?.maxEventSize, push: (event) => { this.dispatchEvent(createFastMessageEvent( event.type, @@ -18915,7 +18999,8 @@ var require_eventsource = __commonJS({ { key: "dispatcher", // undici only - converter: webidl.converters.any + converter: webidl.converters.any, + defaultValue: () => getGlobalDispatcher() } ]); module.exports = { diff --git a/.github/actions/javascript/proposalPoliceComment/index.js b/.github/actions/javascript/proposalPoliceComment/index.js index acb06c2d64dd..d1dc1dd90787 100644 --- a/.github/actions/javascript/proposalPoliceComment/index.js +++ b/.github/actions/javascript/proposalPoliceComment/index.js @@ -2107,6 +2107,7 @@ var require_dispatcher = __commonJS({ var require_dispatcher_base = __commonJS({ "node_modules/undici/lib/dispatcher/dispatcher-base.js"(exports, module) { "use strict"; + var buffer = __require("node:buffer"); var Dispatcher = require_dispatcher(); var { ClientDestroyedError, @@ -2118,6 +2119,7 @@ var require_dispatcher_base = __commonJS({ var kOnClosed = /* @__PURE__ */ Symbol("onClosed"); var kInterceptedDispatch = /* @__PURE__ */ Symbol("Intercepted Dispatch"); var kWebSocketOptions = /* @__PURE__ */ Symbol("webSocketOptions"); + var kEventSourceOptions = /* @__PURE__ */ Symbol("eventSourceOptions"); var DispatcherBase = class extends Dispatcher { constructor(opts) { super(); @@ -2126,6 +2128,7 @@ var require_dispatcher_base = __commonJS({ this[kClosed] = false; this[kOnClosed] = []; this[kWebSocketOptions] = opts?.webSocket ?? {}; + this[kEventSourceOptions] = opts?.eventSource ?? {}; } get webSocketOptions() { return { @@ -2133,6 +2136,11 @@ var require_dispatcher_base = __commonJS({ maxPayloadSize: this[kWebSocketOptions].maxPayloadSize ?? 128 * 1024 * 1024 }; } + get eventSourceOptions() { + return { + maxEventSize: this[kEventSourceOptions].maxEventSize ?? buffer.kStringMaxLength + }; + } get destroyed() { return this[kDestroyed]; } @@ -6280,7 +6288,6 @@ var require_client_h1 = __commonJS({ socket[kSocketUsed] = false; socket[kParser] = new Parser(client, socket, llhttpInstance); addListener(socket, "error", function(err) { - assert(err.code !== "ERR_TLS_CERT_ALTNAME_INVALID"); const parser = this[kParser]; if (err.code === "ECONNRESET" && parser.statusCode && !parser.shouldKeepAlive) { const parserErr = parser.finish(); @@ -6964,7 +6971,6 @@ var require_client_h2 = __commonJS({ client[kHTTP2Session] = session; socket[kHTTP2Session] = session; util.addListener(socket, "error", function(err) { - assert(err.code !== "ERR_TLS_CERT_ALTNAME_INVALID"); this[kError] = err; this[kClient][kOnError](err); }); @@ -7023,7 +7029,6 @@ var require_client_h2 = __commonJS({ } } function onHttp2SessionError(err) { - assert(err.code !== "ERR_TLS_CERT_ALTNAME_INVALID"); this[kSocket][kError] = err; this[kClient][kOnError](err); } @@ -7717,9 +7722,10 @@ var require_client = __commonJS({ // h2 maxConcurrentStreams, allowH2, - webSocket + webSocket, + eventSource } = {}) { - super({ webSocket }); + super({ webSocket, eventSource }); if (keepAlive !== void 0) { throw new InvalidArgumentError("unsupported keepAlive, use pipelining=0 instead"); } @@ -8616,7 +8622,7 @@ var require_agent = __commonJS({ return opts && opts.connections === 1 ? new Client(origin, opts) : new Pool(origin, opts); } var Agent = class extends DispatcherBase { - constructor({ factory = defaultFactory, maxRedirections = 0, connect, ...options } = {}) { + constructor({ factory = defaultFactory, maxRedirections = 0, connect, tls, ...options } = {}) { if (typeof factory !== "function") { throw new InvalidArgumentError("factory must be a function."); } @@ -8630,8 +8636,11 @@ var require_agent = __commonJS({ if (connect && typeof connect !== "function") { connect = { ...connect }; } + if (tls && typeof tls !== "function") { + tls = { ...tls }; + } this[kInterceptors] = options.interceptors?.Agent && Array.isArray(options.interceptors.Agent) ? options.interceptors.Agent : [createRedirectInterceptor({ maxRedirections })]; - this[kOptions] = { ...util.deepClone(options), connect }; + this[kOptions] = { ...util.deepClone(options), connect, tls }; this[kOptions].interceptors = options.interceptors ? { ...options.interceptors } : void 0; this[kMaxRedirections] = maxRedirections; this[kFactory] = factory; @@ -14359,8 +14368,9 @@ var require_fetch = __commonJS({ } ); response.body = { stream, source: null, length: null }; - fetchParams.controller.onAborted = onAborted; - fetchParams.controller.on("terminated", onAborted); + if (!fetchParams.controller.resume) { + fetchParams.controller.on("terminated", onAborted); + } fetchParams.controller.resume = async () => { while (true) { let bytes; @@ -14460,7 +14470,6 @@ var require_fetch = __commonJS({ headersList.append(bufferToLowerCasedHeaderName(rawHeaders[i]), rawHeaders[i + 1].toString("latin1"), true); } location = headersList.get("location", true); - this.body = new Readable({ read: resume }); const decoders = []; const willFollow = location && request2.redirect === "follow" && redirectStatusSet.has(status); if (request2.method !== "HEAD" && request2.method !== "CONNECT" && !nullBodyStatus.includes(status) && !willFollow) { @@ -14468,7 +14477,7 @@ var require_fetch = __commonJS({ const codings = contentEncoding ? contentEncoding.toLowerCase().split(",") : []; const maxContentEncodings = 5; if (codings.length > maxContentEncodings) { - reject(new Error(`too many content-encodings in response: ${codings.length}, maximum allowed is ${maxContentEncodings}`)); + this.abort(new Error(`too many content-encodings in response: ${codings.length}, maximum allowed is ${maxContentEncodings}`)); return true; } for (let i = codings.length - 1; i >= 0; --i) { @@ -14498,6 +14507,7 @@ var require_fetch = __commonJS({ } } } + this.body = new Readable({ read: resume }); const onError = this.onError.bind(this); resolve({ status, @@ -14523,9 +14533,6 @@ var require_fetch = __commonJS({ if (this.abort) { fetchParams.controller.off("terminated", this.abort); } - if (fetchParams.controller.onAborted) { - fetchParams.controller.off("terminated", fetchParams.controller.onAborted); - } fetchParams.controller.ended = true; this.body.push(null); }, @@ -17599,6 +17606,16 @@ var require_receiver = __commonJS({ if (isControlFrame(this.#info.opcode)) { this.#loop = this.parseControlFrame(body); this.#state = parserStates.INFO; + const socket = this.ws[kResponse].socket; + if (this.#loop && socket.writableNeedDrain) { + this.#loop = false; + socket.once("drain", () => { + if (this.destroyed) return; + this.#loop = true; + this.run(callback); + }); + return; + } } else { if (!this.#info.compressed) { if (!this.writeFragments(body)) { @@ -18292,6 +18309,7 @@ var require_util8 = __commonJS({ var require_eventsource_stream = __commonJS({ "node_modules/undici/lib/web/eventsource/eventsource-stream.js"(exports, module) { "use strict"; + var buffer = __require("node:buffer"); var { Transform } = __require("node:stream"); var { isASCIINumber, isValidLastEventId } = require_util8(); var BOM = [239, 187, 191]; @@ -18299,24 +18317,28 @@ var require_eventsource_stream = __commonJS({ var CR = 13; var COLON = 58; var SPACE = 32; + var defaultMaxEventSize = buffer.kStringMaxLength; var DATA = Buffer.from("data"); var EVENT = Buffer.from("event"); var ID = Buffer.from("id"); var RETRY = Buffer.from("retry"); - function isASCIINumberBytes(buffer, start) { - if (start >= buffer.length) { + var minParserItems = 1024; + var maxParserItems = 131072; + var bytesPerParserItem = 128; + function isASCIINumberBytes(buffer2, start) { + if (start >= buffer2.length) { return false; } - for (let i = start; i < buffer.length; i++) { - if (buffer[i] < 48 || buffer[i] > 57) { + for (let i = start; i < buffer2.length; i++) { + if (buffer2[i] < 48 || buffer2[i] > 57) { return false; } } return true; } - function isValidLastEventIdBytes(buffer, start) { - for (let i = start; i < buffer.length; i++) { - if (buffer[i] === 0) { + function isValidLastEventIdBytes(buffer2, start) { + for (let i = start; i < buffer2.length; i++) { + if (buffer2[i] === 0) { return false; } } @@ -18333,6 +18355,11 @@ var require_eventsource_stream = __commonJS({ } return true; } + function createMaxEventSizeExceededError() { + const error2 = new Error("EventSource message size exceeded"); + error2.aborted = false; + return error2; + } var EventSourceStream = class extends Transform { /** * @type {eventSourceSettings} @@ -18359,6 +18386,13 @@ var require_eventsource_stream = __commonJS({ 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: void 0, event: void 0, @@ -18367,6 +18401,7 @@ var require_eventsource_stream = __commonJS({ }; /** * @param {object} options + * @param {number} [options.maxEventSize] * @param {eventSourceSettings} options.eventSourceSettings * @param {Function} [options.push] */ @@ -18374,6 +18409,10 @@ var require_eventsource_stream = __commonJS({ options.readableObjectMode = true; 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; } @@ -18389,6 +18428,10 @@ var require_eventsource_stream = __commonJS({ callback(); return; } + if (this.maxEventSize > 0 && this.chunks.length >= this.maxBufferedChunks && chunk[0] !== LF && chunk[0] !== CR) { + callback(createMaxEventSizeExceededError()); + return; + } this.chunks.push(chunk); if (this.checkBOM) { if (this.handleBOM()) { @@ -18425,18 +18468,32 @@ var require_eventsource_stream = __commonJS({ if (byte === CR) { this.crlfCheck = true; } - this.parseLine(this.readLine(), this.event); + try { + this.parseLine(this.readLine(), this.event); + } catch (error2) { + callback(error2); + return; + } this.consumeCurrentByte(); this.eventEndCheck = true; continue; } + if (this.maxEventSize > 0 && ++this.lineLength > this.maxEventSize + 7) { + callback(createMaxEventSizeExceededError()); + return; + } this.advanceCursor(); } callback(); } + _destroy(error2, callback) { + this.chunks.length = 0; + this.clearEvent(); + super._destroy(error2, callback); + } /** * @param {Buffer} line - * @param {EventStreamEvent} event + * @param {EventSourceStreamEvent} event */ parseLine(line, event) { if (line.length === 0) { @@ -18456,6 +18513,12 @@ var require_eventsource_stream = __commonJS({ } } 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 === void 0 ? 0 : 1) + valueBytes; + this.setEventFieldSize("data", dataSize); const value = line.toString("utf8", valueStart); if (event.data === void 0) { event.data = value; @@ -18463,27 +18526,38 @@ var require_eventsource_stream = __commonJS({ event.data += ` ${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; } 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 */ @@ -18510,6 +18584,12 @@ ${value}`; this.event.event = void 0; this.event.id = void 0; this.event.retry = void 0; + this.eventSize = 0; + this.dataLineCount = 0; + this.eventFieldSizes.data = 0; + this.eventFieldSizes.event = 0; + this.eventFieldSizes.id = 0; + this.eventFieldSizes.retry = 0; } hasPendingEvent() { return this.event.data !== void 0 || this.event.event !== void 0 || this.event.id !== void 0 || this.event.retry !== void 0; @@ -18534,13 +18614,15 @@ ${value}`; 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) { this.chunks.length = 0; @@ -18643,6 +18725,7 @@ var require_eventsource = __commonJS({ var { delay } = require_util8(); var { kEnumerableProperty } = require_util(); var { environmentSettingsObject } = require_util2(); + var { getGlobalDispatcher } = require_global2(); var experimentalWarned = false; var defaultReconnectionTime = 3e3; var CONNECTING = 0; @@ -18783,6 +18866,7 @@ var require_eventsource = __commonJS({ this.#state.origin = response.urlList[response.urlList.length - 1].origin; const eventSourceStream = new EventSourceStream({ eventSourceSettings: this.#state, + maxEventSize: this.#dispatcher.eventSourceOptions?.maxEventSize, push: (event) => { this.dispatchEvent(createFastMessageEvent( event.type, @@ -18915,7 +18999,8 @@ var require_eventsource = __commonJS({ { key: "dispatcher", // undici only - converter: webidl.converters.any + converter: webidl.converters.any, + defaultValue: () => getGlobalDispatcher() } ]); module.exports = { diff --git a/.github/actions/javascript/reopenIssueWithComment/index.js b/.github/actions/javascript/reopenIssueWithComment/index.js index 2fe118ee3e64..38f53ef884c8 100644 --- a/.github/actions/javascript/reopenIssueWithComment/index.js +++ b/.github/actions/javascript/reopenIssueWithComment/index.js @@ -2107,6 +2107,7 @@ var require_dispatcher = __commonJS({ var require_dispatcher_base = __commonJS({ "node_modules/undici/lib/dispatcher/dispatcher-base.js"(exports, module) { "use strict"; + var buffer = __require("node:buffer"); var Dispatcher = require_dispatcher(); var { ClientDestroyedError, @@ -2118,6 +2119,7 @@ var require_dispatcher_base = __commonJS({ var kOnClosed = /* @__PURE__ */ Symbol("onClosed"); var kInterceptedDispatch = /* @__PURE__ */ Symbol("Intercepted Dispatch"); var kWebSocketOptions = /* @__PURE__ */ Symbol("webSocketOptions"); + var kEventSourceOptions = /* @__PURE__ */ Symbol("eventSourceOptions"); var DispatcherBase = class extends Dispatcher { constructor(opts) { super(); @@ -2126,6 +2128,7 @@ var require_dispatcher_base = __commonJS({ this[kClosed] = false; this[kOnClosed] = []; this[kWebSocketOptions] = opts?.webSocket ?? {}; + this[kEventSourceOptions] = opts?.eventSource ?? {}; } get webSocketOptions() { return { @@ -2133,6 +2136,11 @@ var require_dispatcher_base = __commonJS({ maxPayloadSize: this[kWebSocketOptions].maxPayloadSize ?? 128 * 1024 * 1024 }; } + get eventSourceOptions() { + return { + maxEventSize: this[kEventSourceOptions].maxEventSize ?? buffer.kStringMaxLength + }; + } get destroyed() { return this[kDestroyed]; } @@ -6280,7 +6288,6 @@ var require_client_h1 = __commonJS({ socket[kSocketUsed] = false; socket[kParser] = new Parser(client, socket, llhttpInstance); addListener(socket, "error", function(err) { - assert(err.code !== "ERR_TLS_CERT_ALTNAME_INVALID"); const parser = this[kParser]; if (err.code === "ECONNRESET" && parser.statusCode && !parser.shouldKeepAlive) { const parserErr = parser.finish(); @@ -6964,7 +6971,6 @@ var require_client_h2 = __commonJS({ client[kHTTP2Session] = session; socket[kHTTP2Session] = session; util.addListener(socket, "error", function(err) { - assert(err.code !== "ERR_TLS_CERT_ALTNAME_INVALID"); this[kError] = err; this[kClient][kOnError](err); }); @@ -7023,7 +7029,6 @@ var require_client_h2 = __commonJS({ } } function onHttp2SessionError(err) { - assert(err.code !== "ERR_TLS_CERT_ALTNAME_INVALID"); this[kSocket][kError] = err; this[kClient][kOnError](err); } @@ -7717,9 +7722,10 @@ var require_client = __commonJS({ // h2 maxConcurrentStreams, allowH2, - webSocket + webSocket, + eventSource } = {}) { - super({ webSocket }); + super({ webSocket, eventSource }); if (keepAlive !== void 0) { throw new InvalidArgumentError("unsupported keepAlive, use pipelining=0 instead"); } @@ -8616,7 +8622,7 @@ var require_agent = __commonJS({ return opts && opts.connections === 1 ? new Client(origin, opts) : new Pool(origin, opts); } var Agent = class extends DispatcherBase { - constructor({ factory = defaultFactory, maxRedirections = 0, connect, ...options } = {}) { + constructor({ factory = defaultFactory, maxRedirections = 0, connect, tls, ...options } = {}) { if (typeof factory !== "function") { throw new InvalidArgumentError("factory must be a function."); } @@ -8630,8 +8636,11 @@ var require_agent = __commonJS({ if (connect && typeof connect !== "function") { connect = { ...connect }; } + if (tls && typeof tls !== "function") { + tls = { ...tls }; + } this[kInterceptors] = options.interceptors?.Agent && Array.isArray(options.interceptors.Agent) ? options.interceptors.Agent : [createRedirectInterceptor({ maxRedirections })]; - this[kOptions] = { ...util.deepClone(options), connect }; + this[kOptions] = { ...util.deepClone(options), connect, tls }; this[kOptions].interceptors = options.interceptors ? { ...options.interceptors } : void 0; this[kMaxRedirections] = maxRedirections; this[kFactory] = factory; @@ -14359,8 +14368,9 @@ var require_fetch = __commonJS({ } ); response.body = { stream, source: null, length: null }; - fetchParams.controller.onAborted = onAborted; - fetchParams.controller.on("terminated", onAborted); + if (!fetchParams.controller.resume) { + fetchParams.controller.on("terminated", onAborted); + } fetchParams.controller.resume = async () => { while (true) { let bytes; @@ -14460,7 +14470,6 @@ var require_fetch = __commonJS({ headersList.append(bufferToLowerCasedHeaderName(rawHeaders[i]), rawHeaders[i + 1].toString("latin1"), true); } location = headersList.get("location", true); - this.body = new Readable({ read: resume }); const decoders = []; const willFollow = location && request2.redirect === "follow" && redirectStatusSet.has(status); if (request2.method !== "HEAD" && request2.method !== "CONNECT" && !nullBodyStatus.includes(status) && !willFollow) { @@ -14468,7 +14477,7 @@ var require_fetch = __commonJS({ const codings = contentEncoding ? contentEncoding.toLowerCase().split(",") : []; const maxContentEncodings = 5; if (codings.length > maxContentEncodings) { - reject(new Error(`too many content-encodings in response: ${codings.length}, maximum allowed is ${maxContentEncodings}`)); + this.abort(new Error(`too many content-encodings in response: ${codings.length}, maximum allowed is ${maxContentEncodings}`)); return true; } for (let i = codings.length - 1; i >= 0; --i) { @@ -14498,6 +14507,7 @@ var require_fetch = __commonJS({ } } } + this.body = new Readable({ read: resume }); const onError = this.onError.bind(this); resolve({ status, @@ -14523,9 +14533,6 @@ var require_fetch = __commonJS({ if (this.abort) { fetchParams.controller.off("terminated", this.abort); } - if (fetchParams.controller.onAborted) { - fetchParams.controller.off("terminated", fetchParams.controller.onAborted); - } fetchParams.controller.ended = true; this.body.push(null); }, @@ -17599,6 +17606,16 @@ var require_receiver = __commonJS({ if (isControlFrame(this.#info.opcode)) { this.#loop = this.parseControlFrame(body); this.#state = parserStates.INFO; + const socket = this.ws[kResponse].socket; + if (this.#loop && socket.writableNeedDrain) { + this.#loop = false; + socket.once("drain", () => { + if (this.destroyed) return; + this.#loop = true; + this.run(callback); + }); + return; + } } else { if (!this.#info.compressed) { if (!this.writeFragments(body)) { @@ -18292,6 +18309,7 @@ var require_util8 = __commonJS({ var require_eventsource_stream = __commonJS({ "node_modules/undici/lib/web/eventsource/eventsource-stream.js"(exports, module) { "use strict"; + var buffer = __require("node:buffer"); var { Transform } = __require("node:stream"); var { isASCIINumber, isValidLastEventId } = require_util8(); var BOM = [239, 187, 191]; @@ -18299,24 +18317,28 @@ var require_eventsource_stream = __commonJS({ var CR = 13; var COLON = 58; var SPACE = 32; + var defaultMaxEventSize = buffer.kStringMaxLength; var DATA = Buffer.from("data"); var EVENT = Buffer.from("event"); var ID = Buffer.from("id"); var RETRY = Buffer.from("retry"); - function isASCIINumberBytes(buffer, start) { - if (start >= buffer.length) { + var minParserItems = 1024; + var maxParserItems = 131072; + var bytesPerParserItem = 128; + function isASCIINumberBytes(buffer2, start) { + if (start >= buffer2.length) { return false; } - for (let i = start; i < buffer.length; i++) { - if (buffer[i] < 48 || buffer[i] > 57) { + for (let i = start; i < buffer2.length; i++) { + if (buffer2[i] < 48 || buffer2[i] > 57) { return false; } } return true; } - function isValidLastEventIdBytes(buffer, start) { - for (let i = start; i < buffer.length; i++) { - if (buffer[i] === 0) { + function isValidLastEventIdBytes(buffer2, start) { + for (let i = start; i < buffer2.length; i++) { + if (buffer2[i] === 0) { return false; } } @@ -18333,6 +18355,11 @@ var require_eventsource_stream = __commonJS({ } return true; } + function createMaxEventSizeExceededError() { + const error2 = new Error("EventSource message size exceeded"); + error2.aborted = false; + return error2; + } var EventSourceStream = class extends Transform { /** * @type {eventSourceSettings} @@ -18359,6 +18386,13 @@ var require_eventsource_stream = __commonJS({ 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: void 0, event: void 0, @@ -18367,6 +18401,7 @@ var require_eventsource_stream = __commonJS({ }; /** * @param {object} options + * @param {number} [options.maxEventSize] * @param {eventSourceSettings} options.eventSourceSettings * @param {Function} [options.push] */ @@ -18374,6 +18409,10 @@ var require_eventsource_stream = __commonJS({ options.readableObjectMode = true; 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; } @@ -18389,6 +18428,10 @@ var require_eventsource_stream = __commonJS({ callback(); return; } + if (this.maxEventSize > 0 && this.chunks.length >= this.maxBufferedChunks && chunk[0] !== LF && chunk[0] !== CR) { + callback(createMaxEventSizeExceededError()); + return; + } this.chunks.push(chunk); if (this.checkBOM) { if (this.handleBOM()) { @@ -18425,18 +18468,32 @@ var require_eventsource_stream = __commonJS({ if (byte === CR) { this.crlfCheck = true; } - this.parseLine(this.readLine(), this.event); + try { + this.parseLine(this.readLine(), this.event); + } catch (error2) { + callback(error2); + return; + } this.consumeCurrentByte(); this.eventEndCheck = true; continue; } + if (this.maxEventSize > 0 && ++this.lineLength > this.maxEventSize + 7) { + callback(createMaxEventSizeExceededError()); + return; + } this.advanceCursor(); } callback(); } + _destroy(error2, callback) { + this.chunks.length = 0; + this.clearEvent(); + super._destroy(error2, callback); + } /** * @param {Buffer} line - * @param {EventStreamEvent} event + * @param {EventSourceStreamEvent} event */ parseLine(line, event) { if (line.length === 0) { @@ -18456,6 +18513,12 @@ var require_eventsource_stream = __commonJS({ } } 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 === void 0 ? 0 : 1) + valueBytes; + this.setEventFieldSize("data", dataSize); const value = line.toString("utf8", valueStart); if (event.data === void 0) { event.data = value; @@ -18463,27 +18526,38 @@ var require_eventsource_stream = __commonJS({ event.data += ` ${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; } 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 */ @@ -18510,6 +18584,12 @@ ${value}`; this.event.event = void 0; this.event.id = void 0; this.event.retry = void 0; + this.eventSize = 0; + this.dataLineCount = 0; + this.eventFieldSizes.data = 0; + this.eventFieldSizes.event = 0; + this.eventFieldSizes.id = 0; + this.eventFieldSizes.retry = 0; } hasPendingEvent() { return this.event.data !== void 0 || this.event.event !== void 0 || this.event.id !== void 0 || this.event.retry !== void 0; @@ -18534,13 +18614,15 @@ ${value}`; 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) { this.chunks.length = 0; @@ -18643,6 +18725,7 @@ var require_eventsource = __commonJS({ var { delay } = require_util8(); var { kEnumerableProperty } = require_util(); var { environmentSettingsObject } = require_util2(); + var { getGlobalDispatcher } = require_global2(); var experimentalWarned = false; var defaultReconnectionTime = 3e3; var CONNECTING = 0; @@ -18783,6 +18866,7 @@ var require_eventsource = __commonJS({ this.#state.origin = response.urlList[response.urlList.length - 1].origin; const eventSourceStream = new EventSourceStream({ eventSourceSettings: this.#state, + maxEventSize: this.#dispatcher.eventSourceOptions?.maxEventSize, push: (event) => { this.dispatchEvent(createFastMessageEvent( event.type, @@ -18915,7 +18999,8 @@ var require_eventsource = __commonJS({ { key: "dispatcher", // undici only - converter: webidl.converters.any + converter: webidl.converters.any, + defaultValue: () => getGlobalDispatcher() } ]); module.exports = { diff --git a/.github/actions/javascript/reviewerChecklist/index.js b/.github/actions/javascript/reviewerChecklist/index.js index 8e220a2cf59e..b861ce2f20ee 100644 --- a/.github/actions/javascript/reviewerChecklist/index.js +++ b/.github/actions/javascript/reviewerChecklist/index.js @@ -2107,6 +2107,7 @@ var require_dispatcher = __commonJS({ var require_dispatcher_base = __commonJS({ "node_modules/undici/lib/dispatcher/dispatcher-base.js"(exports, module) { "use strict"; + var buffer = __require("node:buffer"); var Dispatcher = require_dispatcher(); var { ClientDestroyedError, @@ -2118,6 +2119,7 @@ var require_dispatcher_base = __commonJS({ var kOnClosed = /* @__PURE__ */ Symbol("onClosed"); var kInterceptedDispatch = /* @__PURE__ */ Symbol("Intercepted Dispatch"); var kWebSocketOptions = /* @__PURE__ */ Symbol("webSocketOptions"); + var kEventSourceOptions = /* @__PURE__ */ Symbol("eventSourceOptions"); var DispatcherBase = class extends Dispatcher { constructor(opts) { super(); @@ -2126,6 +2128,7 @@ var require_dispatcher_base = __commonJS({ this[kClosed] = false; this[kOnClosed] = []; this[kWebSocketOptions] = opts?.webSocket ?? {}; + this[kEventSourceOptions] = opts?.eventSource ?? {}; } get webSocketOptions() { return { @@ -2133,6 +2136,11 @@ var require_dispatcher_base = __commonJS({ maxPayloadSize: this[kWebSocketOptions].maxPayloadSize ?? 128 * 1024 * 1024 }; } + get eventSourceOptions() { + return { + maxEventSize: this[kEventSourceOptions].maxEventSize ?? buffer.kStringMaxLength + }; + } get destroyed() { return this[kDestroyed]; } @@ -6280,7 +6288,6 @@ var require_client_h1 = __commonJS({ socket[kSocketUsed] = false; socket[kParser] = new Parser(client, socket, llhttpInstance); addListener(socket, "error", function(err) { - assert(err.code !== "ERR_TLS_CERT_ALTNAME_INVALID"); const parser = this[kParser]; if (err.code === "ECONNRESET" && parser.statusCode && !parser.shouldKeepAlive) { const parserErr = parser.finish(); @@ -6964,7 +6971,6 @@ var require_client_h2 = __commonJS({ client[kHTTP2Session] = session; socket[kHTTP2Session] = session; util.addListener(socket, "error", function(err) { - assert(err.code !== "ERR_TLS_CERT_ALTNAME_INVALID"); this[kError] = err; this[kClient][kOnError](err); }); @@ -7023,7 +7029,6 @@ var require_client_h2 = __commonJS({ } } function onHttp2SessionError(err) { - assert(err.code !== "ERR_TLS_CERT_ALTNAME_INVALID"); this[kSocket][kError] = err; this[kClient][kOnError](err); } @@ -7717,9 +7722,10 @@ var require_client = __commonJS({ // h2 maxConcurrentStreams, allowH2, - webSocket + webSocket, + eventSource } = {}) { - super({ webSocket }); + super({ webSocket, eventSource }); if (keepAlive !== void 0) { throw new InvalidArgumentError("unsupported keepAlive, use pipelining=0 instead"); } @@ -8616,7 +8622,7 @@ var require_agent = __commonJS({ return opts && opts.connections === 1 ? new Client(origin, opts) : new Pool(origin, opts); } var Agent = class extends DispatcherBase { - constructor({ factory = defaultFactory, maxRedirections = 0, connect, ...options } = {}) { + constructor({ factory = defaultFactory, maxRedirections = 0, connect, tls, ...options } = {}) { if (typeof factory !== "function") { throw new InvalidArgumentError("factory must be a function."); } @@ -8630,8 +8636,11 @@ var require_agent = __commonJS({ if (connect && typeof connect !== "function") { connect = { ...connect }; } + if (tls && typeof tls !== "function") { + tls = { ...tls }; + } this[kInterceptors] = options.interceptors?.Agent && Array.isArray(options.interceptors.Agent) ? options.interceptors.Agent : [createRedirectInterceptor({ maxRedirections })]; - this[kOptions] = { ...util.deepClone(options), connect }; + this[kOptions] = { ...util.deepClone(options), connect, tls }; this[kOptions].interceptors = options.interceptors ? { ...options.interceptors } : void 0; this[kMaxRedirections] = maxRedirections; this[kFactory] = factory; @@ -14359,8 +14368,9 @@ var require_fetch = __commonJS({ } ); response.body = { stream, source: null, length: null }; - fetchParams.controller.onAborted = onAborted; - fetchParams.controller.on("terminated", onAborted); + if (!fetchParams.controller.resume) { + fetchParams.controller.on("terminated", onAborted); + } fetchParams.controller.resume = async () => { while (true) { let bytes; @@ -14460,7 +14470,6 @@ var require_fetch = __commonJS({ headersList.append(bufferToLowerCasedHeaderName(rawHeaders[i]), rawHeaders[i + 1].toString("latin1"), true); } location = headersList.get("location", true); - this.body = new Readable({ read: resume }); const decoders = []; const willFollow = location && request2.redirect === "follow" && redirectStatusSet.has(status); if (request2.method !== "HEAD" && request2.method !== "CONNECT" && !nullBodyStatus.includes(status) && !willFollow) { @@ -14468,7 +14477,7 @@ var require_fetch = __commonJS({ const codings = contentEncoding ? contentEncoding.toLowerCase().split(",") : []; const maxContentEncodings = 5; if (codings.length > maxContentEncodings) { - reject(new Error(`too many content-encodings in response: ${codings.length}, maximum allowed is ${maxContentEncodings}`)); + this.abort(new Error(`too many content-encodings in response: ${codings.length}, maximum allowed is ${maxContentEncodings}`)); return true; } for (let i = codings.length - 1; i >= 0; --i) { @@ -14498,6 +14507,7 @@ var require_fetch = __commonJS({ } } } + this.body = new Readable({ read: resume }); const onError = this.onError.bind(this); resolve({ status, @@ -14523,9 +14533,6 @@ var require_fetch = __commonJS({ if (this.abort) { fetchParams.controller.off("terminated", this.abort); } - if (fetchParams.controller.onAborted) { - fetchParams.controller.off("terminated", fetchParams.controller.onAborted); - } fetchParams.controller.ended = true; this.body.push(null); }, @@ -17599,6 +17606,16 @@ var require_receiver = __commonJS({ if (isControlFrame(this.#info.opcode)) { this.#loop = this.parseControlFrame(body); this.#state = parserStates.INFO; + const socket = this.ws[kResponse].socket; + if (this.#loop && socket.writableNeedDrain) { + this.#loop = false; + socket.once("drain", () => { + if (this.destroyed) return; + this.#loop = true; + this.run(callback); + }); + return; + } } else { if (!this.#info.compressed) { if (!this.writeFragments(body)) { @@ -18292,6 +18309,7 @@ var require_util8 = __commonJS({ var require_eventsource_stream = __commonJS({ "node_modules/undici/lib/web/eventsource/eventsource-stream.js"(exports, module) { "use strict"; + var buffer = __require("node:buffer"); var { Transform } = __require("node:stream"); var { isASCIINumber, isValidLastEventId } = require_util8(); var BOM = [239, 187, 191]; @@ -18299,24 +18317,28 @@ var require_eventsource_stream = __commonJS({ var CR = 13; var COLON = 58; var SPACE = 32; + var defaultMaxEventSize = buffer.kStringMaxLength; var DATA = Buffer.from("data"); var EVENT = Buffer.from("event"); var ID = Buffer.from("id"); var RETRY = Buffer.from("retry"); - function isASCIINumberBytes(buffer, start) { - if (start >= buffer.length) { + var minParserItems = 1024; + var maxParserItems = 131072; + var bytesPerParserItem = 128; + function isASCIINumberBytes(buffer2, start) { + if (start >= buffer2.length) { return false; } - for (let i = start; i < buffer.length; i++) { - if (buffer[i] < 48 || buffer[i] > 57) { + for (let i = start; i < buffer2.length; i++) { + if (buffer2[i] < 48 || buffer2[i] > 57) { return false; } } return true; } - function isValidLastEventIdBytes(buffer, start) { - for (let i = start; i < buffer.length; i++) { - if (buffer[i] === 0) { + function isValidLastEventIdBytes(buffer2, start) { + for (let i = start; i < buffer2.length; i++) { + if (buffer2[i] === 0) { return false; } } @@ -18333,6 +18355,11 @@ var require_eventsource_stream = __commonJS({ } return true; } + function createMaxEventSizeExceededError() { + const error2 = new Error("EventSource message size exceeded"); + error2.aborted = false; + return error2; + } var EventSourceStream = class extends Transform { /** * @type {eventSourceSettings} @@ -18359,6 +18386,13 @@ var require_eventsource_stream = __commonJS({ 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: void 0, event: void 0, @@ -18367,6 +18401,7 @@ var require_eventsource_stream = __commonJS({ }; /** * @param {object} options + * @param {number} [options.maxEventSize] * @param {eventSourceSettings} options.eventSourceSettings * @param {Function} [options.push] */ @@ -18374,6 +18409,10 @@ var require_eventsource_stream = __commonJS({ options.readableObjectMode = true; 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; } @@ -18389,6 +18428,10 @@ var require_eventsource_stream = __commonJS({ callback(); return; } + if (this.maxEventSize > 0 && this.chunks.length >= this.maxBufferedChunks && chunk[0] !== LF && chunk[0] !== CR) { + callback(createMaxEventSizeExceededError()); + return; + } this.chunks.push(chunk); if (this.checkBOM) { if (this.handleBOM()) { @@ -18425,18 +18468,32 @@ var require_eventsource_stream = __commonJS({ if (byte === CR) { this.crlfCheck = true; } - this.parseLine(this.readLine(), this.event); + try { + this.parseLine(this.readLine(), this.event); + } catch (error2) { + callback(error2); + return; + } this.consumeCurrentByte(); this.eventEndCheck = true; continue; } + if (this.maxEventSize > 0 && ++this.lineLength > this.maxEventSize + 7) { + callback(createMaxEventSizeExceededError()); + return; + } this.advanceCursor(); } callback(); } + _destroy(error2, callback) { + this.chunks.length = 0; + this.clearEvent(); + super._destroy(error2, callback); + } /** * @param {Buffer} line - * @param {EventStreamEvent} event + * @param {EventSourceStreamEvent} event */ parseLine(line, event) { if (line.length === 0) { @@ -18456,6 +18513,12 @@ var require_eventsource_stream = __commonJS({ } } 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 === void 0 ? 0 : 1) + valueBytes; + this.setEventFieldSize("data", dataSize); const value = line.toString("utf8", valueStart); if (event.data === void 0) { event.data = value; @@ -18463,27 +18526,38 @@ var require_eventsource_stream = __commonJS({ event.data += ` ${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; } 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 */ @@ -18510,6 +18584,12 @@ ${value}`; this.event.event = void 0; this.event.id = void 0; this.event.retry = void 0; + this.eventSize = 0; + this.dataLineCount = 0; + this.eventFieldSizes.data = 0; + this.eventFieldSizes.event = 0; + this.eventFieldSizes.id = 0; + this.eventFieldSizes.retry = 0; } hasPendingEvent() { return this.event.data !== void 0 || this.event.event !== void 0 || this.event.id !== void 0 || this.event.retry !== void 0; @@ -18534,13 +18614,15 @@ ${value}`; 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) { this.chunks.length = 0; @@ -18643,6 +18725,7 @@ var require_eventsource = __commonJS({ var { delay } = require_util8(); var { kEnumerableProperty } = require_util(); var { environmentSettingsObject } = require_util2(); + var { getGlobalDispatcher } = require_global2(); var experimentalWarned = false; var defaultReconnectionTime = 3e3; var CONNECTING = 0; @@ -18783,6 +18866,7 @@ var require_eventsource = __commonJS({ this.#state.origin = response.urlList[response.urlList.length - 1].origin; const eventSourceStream = new EventSourceStream({ eventSourceSettings: this.#state, + maxEventSize: this.#dispatcher.eventSourceOptions?.maxEventSize, push: (event) => { this.dispatchEvent(createFastMessageEvent( event.type, @@ -18915,7 +18999,8 @@ var require_eventsource = __commonJS({ { key: "dispatcher", // undici only - converter: webidl.converters.any + converter: webidl.converters.any, + defaultValue: () => getGlobalDispatcher() } ]); module.exports = { diff --git a/.github/actions/javascript/validateReassureOutput/index.js b/.github/actions/javascript/validateReassureOutput/index.js index dd379f5b3565..48f1b5cdbadb 100644 --- a/.github/actions/javascript/validateReassureOutput/index.js +++ b/.github/actions/javascript/validateReassureOutput/index.js @@ -2107,6 +2107,7 @@ var require_dispatcher = __commonJS({ var require_dispatcher_base = __commonJS({ "node_modules/undici/lib/dispatcher/dispatcher-base.js"(exports, module) { "use strict"; + var buffer = __require("node:buffer"); var Dispatcher = require_dispatcher(); var { ClientDestroyedError, @@ -2118,6 +2119,7 @@ var require_dispatcher_base = __commonJS({ var kOnClosed = /* @__PURE__ */ Symbol("onClosed"); var kInterceptedDispatch = /* @__PURE__ */ Symbol("Intercepted Dispatch"); var kWebSocketOptions = /* @__PURE__ */ Symbol("webSocketOptions"); + var kEventSourceOptions = /* @__PURE__ */ Symbol("eventSourceOptions"); var DispatcherBase = class extends Dispatcher { constructor(opts) { super(); @@ -2126,6 +2128,7 @@ var require_dispatcher_base = __commonJS({ this[kClosed] = false; this[kOnClosed] = []; this[kWebSocketOptions] = opts?.webSocket ?? {}; + this[kEventSourceOptions] = opts?.eventSource ?? {}; } get webSocketOptions() { return { @@ -2133,6 +2136,11 @@ var require_dispatcher_base = __commonJS({ maxPayloadSize: this[kWebSocketOptions].maxPayloadSize ?? 128 * 1024 * 1024 }; } + get eventSourceOptions() { + return { + maxEventSize: this[kEventSourceOptions].maxEventSize ?? buffer.kStringMaxLength + }; + } get destroyed() { return this[kDestroyed]; } @@ -6280,7 +6288,6 @@ var require_client_h1 = __commonJS({ socket[kSocketUsed] = false; socket[kParser] = new Parser(client, socket, llhttpInstance); addListener(socket, "error", function(err) { - assert(err.code !== "ERR_TLS_CERT_ALTNAME_INVALID"); const parser = this[kParser]; if (err.code === "ECONNRESET" && parser.statusCode && !parser.shouldKeepAlive) { const parserErr = parser.finish(); @@ -6964,7 +6971,6 @@ var require_client_h2 = __commonJS({ client[kHTTP2Session] = session; socket[kHTTP2Session] = session; util.addListener(socket, "error", function(err) { - assert(err.code !== "ERR_TLS_CERT_ALTNAME_INVALID"); this[kError] = err; this[kClient][kOnError](err); }); @@ -7023,7 +7029,6 @@ var require_client_h2 = __commonJS({ } } function onHttp2SessionError(err) { - assert(err.code !== "ERR_TLS_CERT_ALTNAME_INVALID"); this[kSocket][kError] = err; this[kClient][kOnError](err); } @@ -7717,9 +7722,10 @@ var require_client = __commonJS({ // h2 maxConcurrentStreams, allowH2, - webSocket + webSocket, + eventSource } = {}) { - super({ webSocket }); + super({ webSocket, eventSource }); if (keepAlive !== void 0) { throw new InvalidArgumentError("unsupported keepAlive, use pipelining=0 instead"); } @@ -8616,7 +8622,7 @@ var require_agent = __commonJS({ return opts && opts.connections === 1 ? new Client(origin, opts) : new Pool(origin, opts); } var Agent = class extends DispatcherBase { - constructor({ factory = defaultFactory, maxRedirections = 0, connect, ...options } = {}) { + constructor({ factory = defaultFactory, maxRedirections = 0, connect, tls, ...options } = {}) { if (typeof factory !== "function") { throw new InvalidArgumentError("factory must be a function."); } @@ -8630,8 +8636,11 @@ var require_agent = __commonJS({ if (connect && typeof connect !== "function") { connect = { ...connect }; } + if (tls && typeof tls !== "function") { + tls = { ...tls }; + } this[kInterceptors] = options.interceptors?.Agent && Array.isArray(options.interceptors.Agent) ? options.interceptors.Agent : [createRedirectInterceptor({ maxRedirections })]; - this[kOptions] = { ...util.deepClone(options), connect }; + this[kOptions] = { ...util.deepClone(options), connect, tls }; this[kOptions].interceptors = options.interceptors ? { ...options.interceptors } : void 0; this[kMaxRedirections] = maxRedirections; this[kFactory] = factory; @@ -14359,8 +14368,9 @@ var require_fetch = __commonJS({ } ); response.body = { stream, source: null, length: null }; - fetchParams.controller.onAborted = onAborted; - fetchParams.controller.on("terminated", onAborted); + if (!fetchParams.controller.resume) { + fetchParams.controller.on("terminated", onAborted); + } fetchParams.controller.resume = async () => { while (true) { let bytes; @@ -14460,7 +14470,6 @@ var require_fetch = __commonJS({ headersList.append(bufferToLowerCasedHeaderName(rawHeaders[i]), rawHeaders[i + 1].toString("latin1"), true); } location = headersList.get("location", true); - this.body = new Readable({ read: resume }); const decoders = []; const willFollow = location && request.redirect === "follow" && redirectStatusSet.has(status); if (request.method !== "HEAD" && request.method !== "CONNECT" && !nullBodyStatus.includes(status) && !willFollow) { @@ -14468,7 +14477,7 @@ var require_fetch = __commonJS({ const codings = contentEncoding ? contentEncoding.toLowerCase().split(",") : []; const maxContentEncodings = 5; if (codings.length > maxContentEncodings) { - reject(new Error(`too many content-encodings in response: ${codings.length}, maximum allowed is ${maxContentEncodings}`)); + this.abort(new Error(`too many content-encodings in response: ${codings.length}, maximum allowed is ${maxContentEncodings}`)); return true; } for (let i = codings.length - 1; i >= 0; --i) { @@ -14498,6 +14507,7 @@ var require_fetch = __commonJS({ } } } + this.body = new Readable({ read: resume }); const onError = this.onError.bind(this); resolve({ status, @@ -14523,9 +14533,6 @@ var require_fetch = __commonJS({ if (this.abort) { fetchParams.controller.off("terminated", this.abort); } - if (fetchParams.controller.onAborted) { - fetchParams.controller.off("terminated", fetchParams.controller.onAborted); - } fetchParams.controller.ended = true; this.body.push(null); }, @@ -17599,6 +17606,16 @@ var require_receiver = __commonJS({ if (isControlFrame(this.#info.opcode)) { this.#loop = this.parseControlFrame(body); this.#state = parserStates.INFO; + const socket = this.ws[kResponse].socket; + if (this.#loop && socket.writableNeedDrain) { + this.#loop = false; + socket.once("drain", () => { + if (this.destroyed) return; + this.#loop = true; + this.run(callback); + }); + return; + } } else { if (!this.#info.compressed) { if (!this.writeFragments(body)) { @@ -18292,6 +18309,7 @@ var require_util8 = __commonJS({ var require_eventsource_stream = __commonJS({ "node_modules/undici/lib/web/eventsource/eventsource-stream.js"(exports, module) { "use strict"; + var buffer = __require("node:buffer"); var { Transform } = __require("node:stream"); var { isASCIINumber, isValidLastEventId } = require_util8(); var BOM = [239, 187, 191]; @@ -18299,24 +18317,28 @@ var require_eventsource_stream = __commonJS({ var CR = 13; var COLON = 58; var SPACE = 32; + var defaultMaxEventSize = buffer.kStringMaxLength; var DATA = Buffer.from("data"); var EVENT = Buffer.from("event"); var ID = Buffer.from("id"); var RETRY = Buffer.from("retry"); - function isASCIINumberBytes(buffer, start) { - if (start >= buffer.length) { + var minParserItems = 1024; + var maxParserItems = 131072; + var bytesPerParserItem = 128; + function isASCIINumberBytes(buffer2, start) { + if (start >= buffer2.length) { return false; } - for (let i = start; i < buffer.length; i++) { - if (buffer[i] < 48 || buffer[i] > 57) { + for (let i = start; i < buffer2.length; i++) { + if (buffer2[i] < 48 || buffer2[i] > 57) { return false; } } return true; } - function isValidLastEventIdBytes(buffer, start) { - for (let i = start; i < buffer.length; i++) { - if (buffer[i] === 0) { + function isValidLastEventIdBytes(buffer2, start) { + for (let i = start; i < buffer2.length; i++) { + if (buffer2[i] === 0) { return false; } } @@ -18333,6 +18355,11 @@ var require_eventsource_stream = __commonJS({ } return true; } + function createMaxEventSizeExceededError() { + const error2 = new Error("EventSource message size exceeded"); + error2.aborted = false; + return error2; + } var EventSourceStream = class extends Transform { /** * @type {eventSourceSettings} @@ -18359,6 +18386,13 @@ var require_eventsource_stream = __commonJS({ 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: void 0, event: void 0, @@ -18367,6 +18401,7 @@ var require_eventsource_stream = __commonJS({ }; /** * @param {object} options + * @param {number} [options.maxEventSize] * @param {eventSourceSettings} options.eventSourceSettings * @param {Function} [options.push] */ @@ -18374,6 +18409,10 @@ var require_eventsource_stream = __commonJS({ options.readableObjectMode = true; 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; } @@ -18389,6 +18428,10 @@ var require_eventsource_stream = __commonJS({ callback(); return; } + if (this.maxEventSize > 0 && this.chunks.length >= this.maxBufferedChunks && chunk[0] !== LF && chunk[0] !== CR) { + callback(createMaxEventSizeExceededError()); + return; + } this.chunks.push(chunk); if (this.checkBOM) { if (this.handleBOM()) { @@ -18425,18 +18468,32 @@ var require_eventsource_stream = __commonJS({ if (byte === CR) { this.crlfCheck = true; } - this.parseLine(this.readLine(), this.event); + try { + this.parseLine(this.readLine(), this.event); + } catch (error2) { + callback(error2); + return; + } this.consumeCurrentByte(); this.eventEndCheck = true; continue; } + if (this.maxEventSize > 0 && ++this.lineLength > this.maxEventSize + 7) { + callback(createMaxEventSizeExceededError()); + return; + } this.advanceCursor(); } callback(); } + _destroy(error2, callback) { + this.chunks.length = 0; + this.clearEvent(); + super._destroy(error2, callback); + } /** * @param {Buffer} line - * @param {EventStreamEvent} event + * @param {EventSourceStreamEvent} event */ parseLine(line, event) { if (line.length === 0) { @@ -18456,6 +18513,12 @@ var require_eventsource_stream = __commonJS({ } } 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 === void 0 ? 0 : 1) + valueBytes; + this.setEventFieldSize("data", dataSize); const value = line.toString("utf8", valueStart); if (event.data === void 0) { event.data = value; @@ -18463,27 +18526,38 @@ var require_eventsource_stream = __commonJS({ event.data += ` ${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; } 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 */ @@ -18510,6 +18584,12 @@ ${value}`; this.event.event = void 0; this.event.id = void 0; this.event.retry = void 0; + this.eventSize = 0; + this.dataLineCount = 0; + this.eventFieldSizes.data = 0; + this.eventFieldSizes.event = 0; + this.eventFieldSizes.id = 0; + this.eventFieldSizes.retry = 0; } hasPendingEvent() { return this.event.data !== void 0 || this.event.event !== void 0 || this.event.id !== void 0 || this.event.retry !== void 0; @@ -18534,13 +18614,15 @@ ${value}`; 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) { this.chunks.length = 0; @@ -18643,6 +18725,7 @@ var require_eventsource = __commonJS({ var { delay } = require_util8(); var { kEnumerableProperty } = require_util(); var { environmentSettingsObject } = require_util2(); + var { getGlobalDispatcher } = require_global2(); var experimentalWarned = false; var defaultReconnectionTime = 3e3; var CONNECTING = 0; @@ -18783,6 +18866,7 @@ var require_eventsource = __commonJS({ this.#state.origin = response.urlList[response.urlList.length - 1].origin; const eventSourceStream = new EventSourceStream({ eventSourceSettings: this.#state, + maxEventSize: this.#dispatcher.eventSourceOptions?.maxEventSize, push: (event) => { this.dispatchEvent(createFastMessageEvent( event.type, @@ -18915,7 +18999,8 @@ var require_eventsource = __commonJS({ { key: "dispatcher", // undici only - converter: webidl.converters.any + converter: webidl.converters.any, + defaultValue: () => getGlobalDispatcher() } ]); module.exports = { diff --git a/.github/actions/javascript/verifySignedCommits/index.js b/.github/actions/javascript/verifySignedCommits/index.js index d982728230d3..fdf7ab020b5f 100644 --- a/.github/actions/javascript/verifySignedCommits/index.js +++ b/.github/actions/javascript/verifySignedCommits/index.js @@ -2107,6 +2107,7 @@ var require_dispatcher = __commonJS({ var require_dispatcher_base = __commonJS({ "node_modules/undici/lib/dispatcher/dispatcher-base.js"(exports, module) { "use strict"; + var buffer = __require("node:buffer"); var Dispatcher = require_dispatcher(); var { ClientDestroyedError, @@ -2118,6 +2119,7 @@ var require_dispatcher_base = __commonJS({ var kOnClosed = /* @__PURE__ */ Symbol("onClosed"); var kInterceptedDispatch = /* @__PURE__ */ Symbol("Intercepted Dispatch"); var kWebSocketOptions = /* @__PURE__ */ Symbol("webSocketOptions"); + var kEventSourceOptions = /* @__PURE__ */ Symbol("eventSourceOptions"); var DispatcherBase = class extends Dispatcher { constructor(opts) { super(); @@ -2126,6 +2128,7 @@ var require_dispatcher_base = __commonJS({ this[kClosed] = false; this[kOnClosed] = []; this[kWebSocketOptions] = opts?.webSocket ?? {}; + this[kEventSourceOptions] = opts?.eventSource ?? {}; } get webSocketOptions() { return { @@ -2133,6 +2136,11 @@ var require_dispatcher_base = __commonJS({ maxPayloadSize: this[kWebSocketOptions].maxPayloadSize ?? 128 * 1024 * 1024 }; } + get eventSourceOptions() { + return { + maxEventSize: this[kEventSourceOptions].maxEventSize ?? buffer.kStringMaxLength + }; + } get destroyed() { return this[kDestroyed]; } @@ -6280,7 +6288,6 @@ var require_client_h1 = __commonJS({ socket[kSocketUsed] = false; socket[kParser] = new Parser(client, socket, llhttpInstance); addListener(socket, "error", function(err) { - assert(err.code !== "ERR_TLS_CERT_ALTNAME_INVALID"); const parser = this[kParser]; if (err.code === "ECONNRESET" && parser.statusCode && !parser.shouldKeepAlive) { const parserErr = parser.finish(); @@ -6964,7 +6971,6 @@ var require_client_h2 = __commonJS({ client[kHTTP2Session] = session; socket[kHTTP2Session] = session; util.addListener(socket, "error", function(err) { - assert(err.code !== "ERR_TLS_CERT_ALTNAME_INVALID"); this[kError] = err; this[kClient][kOnError](err); }); @@ -7023,7 +7029,6 @@ var require_client_h2 = __commonJS({ } } function onHttp2SessionError(err) { - assert(err.code !== "ERR_TLS_CERT_ALTNAME_INVALID"); this[kSocket][kError] = err; this[kClient][kOnError](err); } @@ -7717,9 +7722,10 @@ var require_client = __commonJS({ // h2 maxConcurrentStreams, allowH2, - webSocket + webSocket, + eventSource } = {}) { - super({ webSocket }); + super({ webSocket, eventSource }); if (keepAlive !== void 0) { throw new InvalidArgumentError("unsupported keepAlive, use pipelining=0 instead"); } @@ -8616,7 +8622,7 @@ var require_agent = __commonJS({ return opts && opts.connections === 1 ? new Client(origin, opts) : new Pool(origin, opts); } var Agent = class extends DispatcherBase { - constructor({ factory = defaultFactory, maxRedirections = 0, connect, ...options } = {}) { + constructor({ factory = defaultFactory, maxRedirections = 0, connect, tls, ...options } = {}) { if (typeof factory !== "function") { throw new InvalidArgumentError("factory must be a function."); } @@ -8630,8 +8636,11 @@ var require_agent = __commonJS({ if (connect && typeof connect !== "function") { connect = { ...connect }; } + if (tls && typeof tls !== "function") { + tls = { ...tls }; + } this[kInterceptors] = options.interceptors?.Agent && Array.isArray(options.interceptors.Agent) ? options.interceptors.Agent : [createRedirectInterceptor({ maxRedirections })]; - this[kOptions] = { ...util.deepClone(options), connect }; + this[kOptions] = { ...util.deepClone(options), connect, tls }; this[kOptions].interceptors = options.interceptors ? { ...options.interceptors } : void 0; this[kMaxRedirections] = maxRedirections; this[kFactory] = factory; @@ -14359,8 +14368,9 @@ var require_fetch = __commonJS({ } ); response.body = { stream, source: null, length: null }; - fetchParams.controller.onAborted = onAborted; - fetchParams.controller.on("terminated", onAborted); + if (!fetchParams.controller.resume) { + fetchParams.controller.on("terminated", onAborted); + } fetchParams.controller.resume = async () => { while (true) { let bytes; @@ -14460,7 +14470,6 @@ var require_fetch = __commonJS({ headersList.append(bufferToLowerCasedHeaderName(rawHeaders[i]), rawHeaders[i + 1].toString("latin1"), true); } location = headersList.get("location", true); - this.body = new Readable({ read: resume }); const decoders = []; const willFollow = location && request2.redirect === "follow" && redirectStatusSet.has(status); if (request2.method !== "HEAD" && request2.method !== "CONNECT" && !nullBodyStatus.includes(status) && !willFollow) { @@ -14468,7 +14477,7 @@ var require_fetch = __commonJS({ const codings = contentEncoding ? contentEncoding.toLowerCase().split(",") : []; const maxContentEncodings = 5; if (codings.length > maxContentEncodings) { - reject(new Error(`too many content-encodings in response: ${codings.length}, maximum allowed is ${maxContentEncodings}`)); + this.abort(new Error(`too many content-encodings in response: ${codings.length}, maximum allowed is ${maxContentEncodings}`)); return true; } for (let i = codings.length - 1; i >= 0; --i) { @@ -14498,6 +14507,7 @@ var require_fetch = __commonJS({ } } } + this.body = new Readable({ read: resume }); const onError = this.onError.bind(this); resolve({ status, @@ -14523,9 +14533,6 @@ var require_fetch = __commonJS({ if (this.abort) { fetchParams.controller.off("terminated", this.abort); } - if (fetchParams.controller.onAborted) { - fetchParams.controller.off("terminated", fetchParams.controller.onAborted); - } fetchParams.controller.ended = true; this.body.push(null); }, @@ -17599,6 +17606,16 @@ var require_receiver = __commonJS({ if (isControlFrame(this.#info.opcode)) { this.#loop = this.parseControlFrame(body); this.#state = parserStates.INFO; + const socket = this.ws[kResponse].socket; + if (this.#loop && socket.writableNeedDrain) { + this.#loop = false; + socket.once("drain", () => { + if (this.destroyed) return; + this.#loop = true; + this.run(callback); + }); + return; + } } else { if (!this.#info.compressed) { if (!this.writeFragments(body)) { @@ -18292,6 +18309,7 @@ var require_util8 = __commonJS({ var require_eventsource_stream = __commonJS({ "node_modules/undici/lib/web/eventsource/eventsource-stream.js"(exports, module) { "use strict"; + var buffer = __require("node:buffer"); var { Transform } = __require("node:stream"); var { isASCIINumber, isValidLastEventId } = require_util8(); var BOM = [239, 187, 191]; @@ -18299,24 +18317,28 @@ var require_eventsource_stream = __commonJS({ var CR = 13; var COLON = 58; var SPACE = 32; + var defaultMaxEventSize = buffer.kStringMaxLength; var DATA = Buffer.from("data"); var EVENT = Buffer.from("event"); var ID = Buffer.from("id"); var RETRY = Buffer.from("retry"); - function isASCIINumberBytes(buffer, start) { - if (start >= buffer.length) { + var minParserItems = 1024; + var maxParserItems = 131072; + var bytesPerParserItem = 128; + function isASCIINumberBytes(buffer2, start) { + if (start >= buffer2.length) { return false; } - for (let i = start; i < buffer.length; i++) { - if (buffer[i] < 48 || buffer[i] > 57) { + for (let i = start; i < buffer2.length; i++) { + if (buffer2[i] < 48 || buffer2[i] > 57) { return false; } } return true; } - function isValidLastEventIdBytes(buffer, start) { - for (let i = start; i < buffer.length; i++) { - if (buffer[i] === 0) { + function isValidLastEventIdBytes(buffer2, start) { + for (let i = start; i < buffer2.length; i++) { + if (buffer2[i] === 0) { return false; } } @@ -18333,6 +18355,11 @@ var require_eventsource_stream = __commonJS({ } return true; } + function createMaxEventSizeExceededError() { + const error2 = new Error("EventSource message size exceeded"); + error2.aborted = false; + return error2; + } var EventSourceStream = class extends Transform { /** * @type {eventSourceSettings} @@ -18359,6 +18386,13 @@ var require_eventsource_stream = __commonJS({ 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: void 0, event: void 0, @@ -18367,6 +18401,7 @@ var require_eventsource_stream = __commonJS({ }; /** * @param {object} options + * @param {number} [options.maxEventSize] * @param {eventSourceSettings} options.eventSourceSettings * @param {Function} [options.push] */ @@ -18374,6 +18409,10 @@ var require_eventsource_stream = __commonJS({ options.readableObjectMode = true; 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; } @@ -18389,6 +18428,10 @@ var require_eventsource_stream = __commonJS({ callback(); return; } + if (this.maxEventSize > 0 && this.chunks.length >= this.maxBufferedChunks && chunk[0] !== LF && chunk[0] !== CR) { + callback(createMaxEventSizeExceededError()); + return; + } this.chunks.push(chunk); if (this.checkBOM) { if (this.handleBOM()) { @@ -18425,18 +18468,32 @@ var require_eventsource_stream = __commonJS({ if (byte === CR) { this.crlfCheck = true; } - this.parseLine(this.readLine(), this.event); + try { + this.parseLine(this.readLine(), this.event); + } catch (error2) { + callback(error2); + return; + } this.consumeCurrentByte(); this.eventEndCheck = true; continue; } + if (this.maxEventSize > 0 && ++this.lineLength > this.maxEventSize + 7) { + callback(createMaxEventSizeExceededError()); + return; + } this.advanceCursor(); } callback(); } + _destroy(error2, callback) { + this.chunks.length = 0; + this.clearEvent(); + super._destroy(error2, callback); + } /** * @param {Buffer} line - * @param {EventStreamEvent} event + * @param {EventSourceStreamEvent} event */ parseLine(line, event) { if (line.length === 0) { @@ -18456,6 +18513,12 @@ var require_eventsource_stream = __commonJS({ } } 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 === void 0 ? 0 : 1) + valueBytes; + this.setEventFieldSize("data", dataSize); const value = line.toString("utf8", valueStart); if (event.data === void 0) { event.data = value; @@ -18463,27 +18526,38 @@ var require_eventsource_stream = __commonJS({ event.data += ` ${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; } 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 */ @@ -18510,6 +18584,12 @@ ${value}`; this.event.event = void 0; this.event.id = void 0; this.event.retry = void 0; + this.eventSize = 0; + this.dataLineCount = 0; + this.eventFieldSizes.data = 0; + this.eventFieldSizes.event = 0; + this.eventFieldSizes.id = 0; + this.eventFieldSizes.retry = 0; } hasPendingEvent() { return this.event.data !== void 0 || this.event.event !== void 0 || this.event.id !== void 0 || this.event.retry !== void 0; @@ -18534,13 +18614,15 @@ ${value}`; 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) { this.chunks.length = 0; @@ -18643,6 +18725,7 @@ var require_eventsource = __commonJS({ var { delay } = require_util8(); var { kEnumerableProperty } = require_util(); var { environmentSettingsObject } = require_util2(); + var { getGlobalDispatcher } = require_global2(); var experimentalWarned = false; var defaultReconnectionTime = 3e3; var CONNECTING = 0; @@ -18783,6 +18866,7 @@ var require_eventsource = __commonJS({ this.#state.origin = response.urlList[response.urlList.length - 1].origin; const eventSourceStream = new EventSourceStream({ eventSourceSettings: this.#state, + maxEventSize: this.#dispatcher.eventSourceOptions?.maxEventSize, push: (event) => { this.dispatchEvent(createFastMessageEvent( event.type, @@ -18915,7 +18999,8 @@ var require_eventsource = __commonJS({ { key: "dispatcher", // undici only - converter: webidl.converters.any + converter: webidl.converters.any, + defaultValue: () => getGlobalDispatcher() } ]); module.exports = { diff --git a/.github/actions/javascript/verifyStagingBuildsSucceeded/index.js b/.github/actions/javascript/verifyStagingBuildsSucceeded/index.js index d5508591a07b..b0cb37e480e2 100644 --- a/.github/actions/javascript/verifyStagingBuildsSucceeded/index.js +++ b/.github/actions/javascript/verifyStagingBuildsSucceeded/index.js @@ -2107,6 +2107,7 @@ var require_dispatcher = __commonJS({ var require_dispatcher_base = __commonJS({ "node_modules/undici/lib/dispatcher/dispatcher-base.js"(exports, module) { "use strict"; + var buffer = __require("node:buffer"); var Dispatcher = require_dispatcher(); var { ClientDestroyedError, @@ -2118,6 +2119,7 @@ var require_dispatcher_base = __commonJS({ var kOnClosed = /* @__PURE__ */ Symbol("onClosed"); var kInterceptedDispatch = /* @__PURE__ */ Symbol("Intercepted Dispatch"); var kWebSocketOptions = /* @__PURE__ */ Symbol("webSocketOptions"); + var kEventSourceOptions = /* @__PURE__ */ Symbol("eventSourceOptions"); var DispatcherBase = class extends Dispatcher { constructor(opts) { super(); @@ -2126,6 +2128,7 @@ var require_dispatcher_base = __commonJS({ this[kClosed] = false; this[kOnClosed] = []; this[kWebSocketOptions] = opts?.webSocket ?? {}; + this[kEventSourceOptions] = opts?.eventSource ?? {}; } get webSocketOptions() { return { @@ -2133,6 +2136,11 @@ var require_dispatcher_base = __commonJS({ maxPayloadSize: this[kWebSocketOptions].maxPayloadSize ?? 128 * 1024 * 1024 }; } + get eventSourceOptions() { + return { + maxEventSize: this[kEventSourceOptions].maxEventSize ?? buffer.kStringMaxLength + }; + } get destroyed() { return this[kDestroyed]; } @@ -6280,7 +6288,6 @@ var require_client_h1 = __commonJS({ socket[kSocketUsed] = false; socket[kParser] = new Parser(client, socket, llhttpInstance); addListener(socket, "error", function(err) { - assert(err.code !== "ERR_TLS_CERT_ALTNAME_INVALID"); const parser = this[kParser]; if (err.code === "ECONNRESET" && parser.statusCode && !parser.shouldKeepAlive) { const parserErr = parser.finish(); @@ -6964,7 +6971,6 @@ var require_client_h2 = __commonJS({ client[kHTTP2Session] = session; socket[kHTTP2Session] = session; util.addListener(socket, "error", function(err) { - assert(err.code !== "ERR_TLS_CERT_ALTNAME_INVALID"); this[kError] = err; this[kClient][kOnError](err); }); @@ -7023,7 +7029,6 @@ var require_client_h2 = __commonJS({ } } function onHttp2SessionError(err) { - assert(err.code !== "ERR_TLS_CERT_ALTNAME_INVALID"); this[kSocket][kError] = err; this[kClient][kOnError](err); } @@ -7717,9 +7722,10 @@ var require_client = __commonJS({ // h2 maxConcurrentStreams, allowH2, - webSocket + webSocket, + eventSource } = {}) { - super({ webSocket }); + super({ webSocket, eventSource }); if (keepAlive !== void 0) { throw new InvalidArgumentError("unsupported keepAlive, use pipelining=0 instead"); } @@ -8616,7 +8622,7 @@ var require_agent = __commonJS({ return opts && opts.connections === 1 ? new Client(origin, opts) : new Pool(origin, opts); } var Agent = class extends DispatcherBase { - constructor({ factory = defaultFactory, maxRedirections = 0, connect, ...options } = {}) { + constructor({ factory = defaultFactory, maxRedirections = 0, connect, tls, ...options } = {}) { if (typeof factory !== "function") { throw new InvalidArgumentError("factory must be a function."); } @@ -8630,8 +8636,11 @@ var require_agent = __commonJS({ if (connect && typeof connect !== "function") { connect = { ...connect }; } + if (tls && typeof tls !== "function") { + tls = { ...tls }; + } this[kInterceptors] = options.interceptors?.Agent && Array.isArray(options.interceptors.Agent) ? options.interceptors.Agent : [createRedirectInterceptor({ maxRedirections })]; - this[kOptions] = { ...util.deepClone(options), connect }; + this[kOptions] = { ...util.deepClone(options), connect, tls }; this[kOptions].interceptors = options.interceptors ? { ...options.interceptors } : void 0; this[kMaxRedirections] = maxRedirections; this[kFactory] = factory; @@ -14359,8 +14368,9 @@ var require_fetch = __commonJS({ } ); response.body = { stream, source: null, length: null }; - fetchParams.controller.onAborted = onAborted; - fetchParams.controller.on("terminated", onAborted); + if (!fetchParams.controller.resume) { + fetchParams.controller.on("terminated", onAborted); + } fetchParams.controller.resume = async () => { while (true) { let bytes; @@ -14460,7 +14470,6 @@ var require_fetch = __commonJS({ headersList.append(bufferToLowerCasedHeaderName(rawHeaders[i]), rawHeaders[i + 1].toString("latin1"), true); } location = headersList.get("location", true); - this.body = new Readable({ read: resume }); const decoders = []; const willFollow = location && request2.redirect === "follow" && redirectStatusSet.has(status); if (request2.method !== "HEAD" && request2.method !== "CONNECT" && !nullBodyStatus.includes(status) && !willFollow) { @@ -14468,7 +14477,7 @@ var require_fetch = __commonJS({ const codings = contentEncoding ? contentEncoding.toLowerCase().split(",") : []; const maxContentEncodings = 5; if (codings.length > maxContentEncodings) { - reject(new Error(`too many content-encodings in response: ${codings.length}, maximum allowed is ${maxContentEncodings}`)); + this.abort(new Error(`too many content-encodings in response: ${codings.length}, maximum allowed is ${maxContentEncodings}`)); return true; } for (let i = codings.length - 1; i >= 0; --i) { @@ -14498,6 +14507,7 @@ var require_fetch = __commonJS({ } } } + this.body = new Readable({ read: resume }); const onError = this.onError.bind(this); resolve({ status, @@ -14523,9 +14533,6 @@ var require_fetch = __commonJS({ if (this.abort) { fetchParams.controller.off("terminated", this.abort); } - if (fetchParams.controller.onAborted) { - fetchParams.controller.off("terminated", fetchParams.controller.onAborted); - } fetchParams.controller.ended = true; this.body.push(null); }, @@ -17599,6 +17606,16 @@ var require_receiver = __commonJS({ if (isControlFrame(this.#info.opcode)) { this.#loop = this.parseControlFrame(body); this.#state = parserStates.INFO; + const socket = this.ws[kResponse].socket; + if (this.#loop && socket.writableNeedDrain) { + this.#loop = false; + socket.once("drain", () => { + if (this.destroyed) return; + this.#loop = true; + this.run(callback); + }); + return; + } } else { if (!this.#info.compressed) { if (!this.writeFragments(body)) { @@ -18292,6 +18309,7 @@ var require_util8 = __commonJS({ var require_eventsource_stream = __commonJS({ "node_modules/undici/lib/web/eventsource/eventsource-stream.js"(exports, module) { "use strict"; + var buffer = __require("node:buffer"); var { Transform } = __require("node:stream"); var { isASCIINumber, isValidLastEventId } = require_util8(); var BOM = [239, 187, 191]; @@ -18299,24 +18317,28 @@ var require_eventsource_stream = __commonJS({ var CR = 13; var COLON = 58; var SPACE = 32; + var defaultMaxEventSize = buffer.kStringMaxLength; var DATA = Buffer.from("data"); var EVENT = Buffer.from("event"); var ID = Buffer.from("id"); var RETRY = Buffer.from("retry"); - function isASCIINumberBytes(buffer, start) { - if (start >= buffer.length) { + var minParserItems = 1024; + var maxParserItems = 131072; + var bytesPerParserItem = 128; + function isASCIINumberBytes(buffer2, start) { + if (start >= buffer2.length) { return false; } - for (let i = start; i < buffer.length; i++) { - if (buffer[i] < 48 || buffer[i] > 57) { + for (let i = start; i < buffer2.length; i++) { + if (buffer2[i] < 48 || buffer2[i] > 57) { return false; } } return true; } - function isValidLastEventIdBytes(buffer, start) { - for (let i = start; i < buffer.length; i++) { - if (buffer[i] === 0) { + function isValidLastEventIdBytes(buffer2, start) { + for (let i = start; i < buffer2.length; i++) { + if (buffer2[i] === 0) { return false; } } @@ -18333,6 +18355,11 @@ var require_eventsource_stream = __commonJS({ } return true; } + function createMaxEventSizeExceededError() { + const error2 = new Error("EventSource message size exceeded"); + error2.aborted = false; + return error2; + } var EventSourceStream = class extends Transform { /** * @type {eventSourceSettings} @@ -18359,6 +18386,13 @@ var require_eventsource_stream = __commonJS({ 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: void 0, event: void 0, @@ -18367,6 +18401,7 @@ var require_eventsource_stream = __commonJS({ }; /** * @param {object} options + * @param {number} [options.maxEventSize] * @param {eventSourceSettings} options.eventSourceSettings * @param {Function} [options.push] */ @@ -18374,6 +18409,10 @@ var require_eventsource_stream = __commonJS({ options.readableObjectMode = true; 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; } @@ -18389,6 +18428,10 @@ var require_eventsource_stream = __commonJS({ callback(); return; } + if (this.maxEventSize > 0 && this.chunks.length >= this.maxBufferedChunks && chunk[0] !== LF && chunk[0] !== CR) { + callback(createMaxEventSizeExceededError()); + return; + } this.chunks.push(chunk); if (this.checkBOM) { if (this.handleBOM()) { @@ -18425,18 +18468,32 @@ var require_eventsource_stream = __commonJS({ if (byte === CR) { this.crlfCheck = true; } - this.parseLine(this.readLine(), this.event); + try { + this.parseLine(this.readLine(), this.event); + } catch (error2) { + callback(error2); + return; + } this.consumeCurrentByte(); this.eventEndCheck = true; continue; } + if (this.maxEventSize > 0 && ++this.lineLength > this.maxEventSize + 7) { + callback(createMaxEventSizeExceededError()); + return; + } this.advanceCursor(); } callback(); } + _destroy(error2, callback) { + this.chunks.length = 0; + this.clearEvent(); + super._destroy(error2, callback); + } /** * @param {Buffer} line - * @param {EventStreamEvent} event + * @param {EventSourceStreamEvent} event */ parseLine(line, event) { if (line.length === 0) { @@ -18456,6 +18513,12 @@ var require_eventsource_stream = __commonJS({ } } 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 === void 0 ? 0 : 1) + valueBytes; + this.setEventFieldSize("data", dataSize); const value = line.toString("utf8", valueStart); if (event.data === void 0) { event.data = value; @@ -18463,27 +18526,38 @@ var require_eventsource_stream = __commonJS({ event.data += ` ${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; } 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 */ @@ -18510,6 +18584,12 @@ ${value}`; this.event.event = void 0; this.event.id = void 0; this.event.retry = void 0; + this.eventSize = 0; + this.dataLineCount = 0; + this.eventFieldSizes.data = 0; + this.eventFieldSizes.event = 0; + this.eventFieldSizes.id = 0; + this.eventFieldSizes.retry = 0; } hasPendingEvent() { return this.event.data !== void 0 || this.event.event !== void 0 || this.event.id !== void 0 || this.event.retry !== void 0; @@ -18534,13 +18614,15 @@ ${value}`; 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) { this.chunks.length = 0; @@ -18643,6 +18725,7 @@ var require_eventsource = __commonJS({ var { delay } = require_util8(); var { kEnumerableProperty } = require_util(); var { environmentSettingsObject } = require_util2(); + var { getGlobalDispatcher } = require_global2(); var experimentalWarned = false; var defaultReconnectionTime = 3e3; var CONNECTING = 0; @@ -18783,6 +18866,7 @@ var require_eventsource = __commonJS({ this.#state.origin = response.urlList[response.urlList.length - 1].origin; const eventSourceStream = new EventSourceStream({ eventSourceSettings: this.#state, + maxEventSize: this.#dispatcher.eventSourceOptions?.maxEventSize, push: (event) => { this.dispatchEvent(createFastMessageEvent( event.type, @@ -18915,7 +18999,8 @@ var require_eventsource = __commonJS({ { key: "dispatcher", // undici only - converter: webidl.converters.any + converter: webidl.converters.any, + defaultValue: () => getGlobalDispatcher() } ]); module.exports = { diff --git a/package-lock.json b/package-lock.json index f9fb702fa1ad..fff5743c0273 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4546,9 +4546,9 @@ } }, "node_modules/@cloudflare/workerd-darwin-64": { - "version": "1.20261019.1", - "resolved": "https://registry.npmjs.org/@cloudflare/workerd-darwin-64/-/workerd-darwin-64-1.20261019.1.tgz", - "integrity": "sha512-5ZILbAta/fBQvhmAYeCE7dKMMYIr7N9wJEX50fEGLKSIwGtvT0HzSfHNIK/O7cBQ4gHQ2WfIiPClvwcye6E0fA==", + "version": "1.20261023.1", + "resolved": "https://registry.npmjs.org/@cloudflare/workerd-darwin-64/-/workerd-darwin-64-1.20261023.1.tgz", + "integrity": "sha512-lsEx0i7nR0PNG/erUFFHmQmiidEhLfDE5uQmAL9421/y4/ycuxDDOSaxu3VGGYFFPK5sduyUeMmjIlX4CwOBFg==", "cpu": [ "x64" ], @@ -4563,9 +4563,9 @@ } }, "node_modules/@cloudflare/workerd-darwin-arm64": { - "version": "1.20261019.1", - "resolved": "https://registry.npmjs.org/@cloudflare/workerd-darwin-arm64/-/workerd-darwin-arm64-1.20261019.1.tgz", - "integrity": "sha512-cww2Ab6lVMxpTiEEjKmPI58p5EMo0vYTZSH+3WkqXJdQgc3ES66GuL247+U2B2YWajhhu2tqj7jySrXneU749g==", + "version": "1.20261023.1", + "resolved": "https://registry.npmjs.org/@cloudflare/workerd-darwin-arm64/-/workerd-darwin-arm64-1.20261023.1.tgz", + "integrity": "sha512-5e79fHgabdDD8EgmjOhJ1S+xMsf6DbC7fL7IgTBizMnzOp0P2isDn7pYmUxI9AJZE9FVQ4RUilH/I36YNg+GQQ==", "cpu": [ "arm64" ], @@ -4580,9 +4580,9 @@ } }, "node_modules/@cloudflare/workerd-linux-64": { - "version": "1.20261019.1", - "resolved": "https://registry.npmjs.org/@cloudflare/workerd-linux-64/-/workerd-linux-64-1.20261019.1.tgz", - "integrity": "sha512-4++VRi9vkQROYqrpZYOixIJuVDmujkwrT4kszsxNFlvcmsX6Mr2GumvxIN3gIixS3vJUh3Umdtkthqj5X0S3Xw==", + "version": "1.20261023.1", + "resolved": "https://registry.npmjs.org/@cloudflare/workerd-linux-64/-/workerd-linux-64-1.20261023.1.tgz", + "integrity": "sha512-VHQ6jKFSihjR2+x1buby8XTdBLLJztVnYiB7OLOTYO8aDXB+c1Rd2410PdgFuFYc4AgFEk6PCJLyCLL5L1KBnw==", "cpu": [ "x64" ], @@ -4597,9 +4597,9 @@ } }, "node_modules/@cloudflare/workerd-linux-arm64": { - "version": "1.20261019.1", - "resolved": "https://registry.npmjs.org/@cloudflare/workerd-linux-arm64/-/workerd-linux-arm64-1.20261019.1.tgz", - "integrity": "sha512-75PVtJOwfjScQ53sbLtQXI7D8yP1c21t+WEUPaYbqkzaz4ZqfR5wAd+zuWs8G5Q7kOj2SQIvEfY5Sn8Y+UVrnA==", + "version": "1.20261023.1", + "resolved": "https://registry.npmjs.org/@cloudflare/workerd-linux-arm64/-/workerd-linux-arm64-1.20261023.1.tgz", + "integrity": "sha512-ilpRHzfDN8YFRM5CLRKuFw40x/LJBS89yVdhdQmxehlVDuBqjKpJB++zPFbTgKRRFaNupgnXc8RHktXAIhgCmQ==", "cpu": [ "arm64" ], @@ -4614,9 +4614,9 @@ } }, "node_modules/@cloudflare/workerd-windows-64": { - "version": "1.20261019.1", - "resolved": "https://registry.npmjs.org/@cloudflare/workerd-windows-64/-/workerd-windows-64-1.20261019.1.tgz", - "integrity": "sha512-z49fvKTETMCnG6wnMcQwxx9CpryFceiKz04FRjq26EkhCyzRNJ6c3UXhyZz3r5f1CXnnBZc5DcU8ZouPkUJCqw==", + "version": "1.20261023.1", + "resolved": "https://registry.npmjs.org/@cloudflare/workerd-windows-64/-/workerd-windows-64-1.20261023.1.tgz", + "integrity": "sha512-279WLVjNsMycAwr0EZNiNEf0l2SY6NUtsN80NwZzbTHzakmiN+WSx4w38muxPm+PAU0oSPPAPXKVD+H6Hya8xw==", "cpu": [ "x64" ], @@ -35817,16 +35817,16 @@ } }, "node_modules/miniflare": { - "version": "5.20261019.2-beta", - "resolved": "https://registry.npmjs.org/miniflare/-/miniflare-5.20261019.2-beta.tgz", - "integrity": "sha512-QNgCA/axizZ7kv7RV3nwbRoz+w4watBlwIsyXjwgYHw4eSw5BrR1F2152s3Kz+Bzy/YxjKFHrZl3LzBRbPgYoQ==", + "version": "5.20261023.0-beta", + "resolved": "https://registry.npmjs.org/miniflare/-/miniflare-5.20261023.0-beta.tgz", + "integrity": "sha512-SHY8A98gCvmrnBLqABHRTSh3duAL1z+tHPRZu/tqxHFqVARrZ4oQis/ALYwp3XvzHvs6B/ff/CdcCafqP+cOFA==", "dev": true, "license": "MIT", "dependencies": { "@cspotcode/source-map-support": "0.8.1", "sharp": "0.35.5", - "undici": "7.29.1", - "workerd": "1.20261019.1", + "undici": "7.30.1", + "workerd": "1.20261023.1", "ws": "8.21.0", "youch": "4.1.0-beta.10" }, @@ -35835,9 +35835,9 @@ } }, "node_modules/miniflare/node_modules/undici": { - "version": "7.29.1", - "resolved": "https://registry.npmjs.org/undici/-/undici-7.29.1.tgz", - "integrity": "sha512-RYONW2MeafgYlkVOKYKkA/Ag7BmXqgIWCa8t1m0JcxrQg9pI9lEqRhAOruOBCbAohOa/gkCF+iPi9hrgvTzu6Q==", + "version": "7.30.1", + "resolved": "https://registry.npmjs.org/undici/-/undici-7.30.1.tgz", + "integrity": "sha512-03KrMbjIFDWQR5RNPrSw3bd1r12JpyFQl9/yxjUbJtqkjmllqC5lFjZh6ujeuJCKr8EOQvRW872Oy/az+nLYxg==", "dev": true, "license": "MIT", "engines": { @@ -43637,9 +43637,9 @@ "license": "MIT" }, "node_modules/undici": { - "version": "6.29.0", - "resolved": "https://registry.npmjs.org/undici/-/undici-6.29.0.tgz", - "integrity": "sha512-R+RODBqp6i2pPflGdq+xIOUkl+RNfGgHwoinecKu/JCuf2uO06cOKoDbI2P7Dn6KcswdKwrczbU6IYJ6K8X+wg==", + "version": "6.29.1", + "resolved": "https://registry.npmjs.org/undici/-/undici-6.29.1.tgz", + "integrity": "sha512-EvRlUt/QqAEvXdQeRMYUfwOQsfzpDztykrG2owGEE/rBOBoYv9uF39ZzsNDh4lTFHhTr2XOZjKkYgueD12ZmGA==", "license": "MIT", "engines": { "node": ">=18.17" @@ -44758,9 +44758,9 @@ } }, "node_modules/workerd": { - "version": "1.20261019.1", - "resolved": "https://registry.npmjs.org/workerd/-/workerd-1.20261019.1.tgz", - "integrity": "sha512-UUYRUq/7DmeCl11YriNbcVbjUZVLtt8uuCXFu+nz77hGFf8d4DEVXoCYtnA+MlBatE4+wxoj47DVqzK3xGBAiw==", + "version": "1.20261023.1", + "resolved": "https://registry.npmjs.org/workerd/-/workerd-1.20261023.1.tgz", + "integrity": "sha512-NeofJFyaYNpqKpFRJW3ApuonaerPd6/JWlfTtLDYf2A6ygqrDEFnYgEXmc0hhOxqnJsSM+kXJN6VebPojzRrsg==", "dev": true, "hasInstallScript": true, "license": "Apache-2.0", @@ -44771,17 +44771,17 @@ "node": ">=16" }, "optionalDependencies": { - "@cloudflare/workerd-darwin-64": "1.20261019.1", - "@cloudflare/workerd-darwin-arm64": "1.20261019.1", - "@cloudflare/workerd-linux-64": "1.20261019.1", - "@cloudflare/workerd-linux-arm64": "1.20261019.1", - "@cloudflare/workerd-windows-64": "1.20261019.1" + "@cloudflare/workerd-darwin-64": "1.20261023.1", + "@cloudflare/workerd-darwin-arm64": "1.20261023.1", + "@cloudflare/workerd-linux-64": "1.20261023.1", + "@cloudflare/workerd-linux-arm64": "1.20261023.1", + "@cloudflare/workerd-windows-64": "1.20261023.1" } }, "node_modules/wrangler": { - "version": "4.152.0", - "resolved": "https://registry.npmjs.org/wrangler/-/wrangler-4.152.0.tgz", - "integrity": "sha512-lmXTF1sCDEqBaEMpreGczvg/x3AIh1d/qxc4BN7utQ4jEDwdA4YG0L6kr3ev0TtVLHRb6QLySNAOAunwn+dHeA==", + "version": "4.153.0", + "resolved": "https://registry.npmjs.org/wrangler/-/wrangler-4.153.0.tgz", + "integrity": "sha512-Hn1AowKzZao/729rMpdpxBZt/RaKQNJ4GtKtHQcOrwT+J/GIq0iwl680+dhJyO00iSsXaCkxoNcLg3yVIwIvyw==", "dev": true, "license": "MIT OR Apache-2.0", "dependencies": { @@ -44789,10 +44789,10 @@ "@cloudflare/unenv-preset": "2.16.2", "blake3-wasm": "2.1.5", "esbuild": "0.28.2", - "miniflare": "5.20261019.2-beta", + "miniflare": "5.20261023.0-beta", "path-to-regexp": "6.3.0", "unenv": "2.0.0-rc.24", - "workerd": "1.20261019.1" + "workerd": "1.20261023.1" }, "bin": { "cf-wrangler": "bin/cf-wrangler.js", @@ -44806,7 +44806,7 @@ "fsevents": "2.3.3" }, "peerDependencies": { - "@cloudflare/workers-types": "^5.20261019.1" + "@cloudflare/workers-types": "^5.20261023.1" }, "peerDependenciesMeta": { "@cloudflare/workers-types": { @@ -45213,7 +45213,7 @@ "@types/node": "24.19.0", "@types/ws": "8.18.1", "typescript": "7.0.2", - "wrangler": "4.152.0", + "wrangler": "4.153.0", "ws": "8.21.0" } }, diff --git a/web/cloudflare-worker/package-lock.json b/web/cloudflare-worker/package-lock.json index c77eaf3468cc..4bcb930f7e15 100644 --- a/web/cloudflare-worker/package-lock.json +++ b/web/cloudflare-worker/package-lock.json @@ -11,7 +11,7 @@ "@types/node": "24.19.0", "@types/ws": "8.18.1", "typescript": "7.0.2", - "wrangler": "4.152.0", + "wrangler": "4.153.0", "ws": "8.21.0" } }, @@ -42,9 +42,9 @@ } }, "node_modules/@cloudflare/workerd-darwin-64": { - "version": "1.20261019.1", - "resolved": "https://registry.npmjs.org/@cloudflare/workerd-darwin-64/-/workerd-darwin-64-1.20261019.1.tgz", - "integrity": "sha512-5ZILbAta/fBQvhmAYeCE7dKMMYIr7N9wJEX50fEGLKSIwGtvT0HzSfHNIK/O7cBQ4gHQ2WfIiPClvwcye6E0fA==", + "version": "1.20261023.1", + "resolved": "https://registry.npmjs.org/@cloudflare/workerd-darwin-64/-/workerd-darwin-64-1.20261023.1.tgz", + "integrity": "sha512-lsEx0i7nR0PNG/erUFFHmQmiidEhLfDE5uQmAL9421/y4/ycuxDDOSaxu3VGGYFFPK5sduyUeMmjIlX4CwOBFg==", "cpu": [ "x64" ], @@ -59,9 +59,9 @@ } }, "node_modules/@cloudflare/workerd-darwin-arm64": { - "version": "1.20261019.1", - "resolved": "https://registry.npmjs.org/@cloudflare/workerd-darwin-arm64/-/workerd-darwin-arm64-1.20261019.1.tgz", - "integrity": "sha512-cww2Ab6lVMxpTiEEjKmPI58p5EMo0vYTZSH+3WkqXJdQgc3ES66GuL247+U2B2YWajhhu2tqj7jySrXneU749g==", + "version": "1.20261023.1", + "resolved": "https://registry.npmjs.org/@cloudflare/workerd-darwin-arm64/-/workerd-darwin-arm64-1.20261023.1.tgz", + "integrity": "sha512-5e79fHgabdDD8EgmjOhJ1S+xMsf6DbC7fL7IgTBizMnzOp0P2isDn7pYmUxI9AJZE9FVQ4RUilH/I36YNg+GQQ==", "cpu": [ "arm64" ], @@ -76,9 +76,9 @@ } }, "node_modules/@cloudflare/workerd-linux-64": { - "version": "1.20261019.1", - "resolved": "https://registry.npmjs.org/@cloudflare/workerd-linux-64/-/workerd-linux-64-1.20261019.1.tgz", - "integrity": "sha512-4++VRi9vkQROYqrpZYOixIJuVDmujkwrT4kszsxNFlvcmsX6Mr2GumvxIN3gIixS3vJUh3Umdtkthqj5X0S3Xw==", + "version": "1.20261023.1", + "resolved": "https://registry.npmjs.org/@cloudflare/workerd-linux-64/-/workerd-linux-64-1.20261023.1.tgz", + "integrity": "sha512-VHQ6jKFSihjR2+x1buby8XTdBLLJztVnYiB7OLOTYO8aDXB+c1Rd2410PdgFuFYc4AgFEk6PCJLyCLL5L1KBnw==", "cpu": [ "x64" ], @@ -93,9 +93,9 @@ } }, "node_modules/@cloudflare/workerd-linux-arm64": { - "version": "1.20261019.1", - "resolved": "https://registry.npmjs.org/@cloudflare/workerd-linux-arm64/-/workerd-linux-arm64-1.20261019.1.tgz", - "integrity": "sha512-75PVtJOwfjScQ53sbLtQXI7D8yP1c21t+WEUPaYbqkzaz4ZqfR5wAd+zuWs8G5Q7kOj2SQIvEfY5Sn8Y+UVrnA==", + "version": "1.20261023.1", + "resolved": "https://registry.npmjs.org/@cloudflare/workerd-linux-arm64/-/workerd-linux-arm64-1.20261023.1.tgz", + "integrity": "sha512-ilpRHzfDN8YFRM5CLRKuFw40x/LJBS89yVdhdQmxehlVDuBqjKpJB++zPFbTgKRRFaNupgnXc8RHktXAIhgCmQ==", "cpu": [ "arm64" ], @@ -110,9 +110,9 @@ } }, "node_modules/@cloudflare/workerd-windows-64": { - "version": "1.20261019.1", - "resolved": "https://registry.npmjs.org/@cloudflare/workerd-windows-64/-/workerd-windows-64-1.20261019.1.tgz", - "integrity": "sha512-z49fvKTETMCnG6wnMcQwxx9CpryFceiKz04FRjq26EkhCyzRNJ6c3UXhyZz3r5f1CXnnBZc5DcU8ZouPkUJCqw==", + "version": "1.20261023.1", + "resolved": "https://registry.npmjs.org/@cloudflare/workerd-windows-64/-/workerd-windows-64-1.20261023.1.tgz", + "integrity": "sha512-279WLVjNsMycAwr0EZNiNEf0l2SY6NUtsN80NwZzbTHzakmiN+WSx4w38muxPm+PAU0oSPPAPXKVD+H6Hya8xw==", "cpu": [ "x64" ], @@ -1713,16 +1713,16 @@ } }, "node_modules/miniflare": { - "version": "5.20261019.2-beta", - "resolved": "https://registry.npmjs.org/miniflare/-/miniflare-5.20261019.2-beta.tgz", - "integrity": "sha512-QNgCA/axizZ7kv7RV3nwbRoz+w4watBlwIsyXjwgYHw4eSw5BrR1F2152s3Kz+Bzy/YxjKFHrZl3LzBRbPgYoQ==", + "version": "5.20261023.0-beta", + "resolved": "https://registry.npmjs.org/miniflare/-/miniflare-5.20261023.0-beta.tgz", + "integrity": "sha512-SHY8A98gCvmrnBLqABHRTSh3duAL1z+tHPRZu/tqxHFqVARrZ4oQis/ALYwp3XvzHvs6B/ff/CdcCafqP+cOFA==", "dev": true, "license": "MIT", "dependencies": { "@cspotcode/source-map-support": "0.8.1", "sharp": "0.35.5", - "undici": "7.29.1", - "workerd": "1.20261019.1", + "undici": "7.30.1", + "workerd": "1.20261023.1", "ws": "8.21.0", "youch": "4.1.0-beta.10" }, @@ -1864,9 +1864,9 @@ } }, "node_modules/undici": { - "version": "7.29.1", - "resolved": "https://registry.npmjs.org/undici/-/undici-7.29.1.tgz", - "integrity": "sha512-RYONW2MeafgYlkVOKYKkA/Ag7BmXqgIWCa8t1m0JcxrQg9pI9lEqRhAOruOBCbAohOa/gkCF+iPi9hrgvTzu6Q==", + "version": "7.30.1", + "resolved": "https://registry.npmjs.org/undici/-/undici-7.30.1.tgz", + "integrity": "sha512-03KrMbjIFDWQR5RNPrSw3bd1r12JpyFQl9/yxjUbJtqkjmllqC5lFjZh6ujeuJCKr8EOQvRW872Oy/az+nLYxg==", "dev": true, "license": "MIT", "engines": { @@ -1891,9 +1891,9 @@ } }, "node_modules/workerd": { - "version": "1.20261019.1", - "resolved": "https://registry.npmjs.org/workerd/-/workerd-1.20261019.1.tgz", - "integrity": "sha512-UUYRUq/7DmeCl11YriNbcVbjUZVLtt8uuCXFu+nz77hGFf8d4DEVXoCYtnA+MlBatE4+wxoj47DVqzK3xGBAiw==", + "version": "1.20261023.1", + "resolved": "https://registry.npmjs.org/workerd/-/workerd-1.20261023.1.tgz", + "integrity": "sha512-NeofJFyaYNpqKpFRJW3ApuonaerPd6/JWlfTtLDYf2A6ygqrDEFnYgEXmc0hhOxqnJsSM+kXJN6VebPojzRrsg==", "dev": true, "hasInstallScript": true, "license": "Apache-2.0", @@ -1904,17 +1904,17 @@ "node": ">=16" }, "optionalDependencies": { - "@cloudflare/workerd-darwin-64": "1.20261019.1", - "@cloudflare/workerd-darwin-arm64": "1.20261019.1", - "@cloudflare/workerd-linux-64": "1.20261019.1", - "@cloudflare/workerd-linux-arm64": "1.20261019.1", - "@cloudflare/workerd-windows-64": "1.20261019.1" + "@cloudflare/workerd-darwin-64": "1.20261023.1", + "@cloudflare/workerd-darwin-arm64": "1.20261023.1", + "@cloudflare/workerd-linux-64": "1.20261023.1", + "@cloudflare/workerd-linux-arm64": "1.20261023.1", + "@cloudflare/workerd-windows-64": "1.20261023.1" } }, "node_modules/wrangler": { - "version": "4.152.0", - "resolved": "https://registry.npmjs.org/wrangler/-/wrangler-4.152.0.tgz", - "integrity": "sha512-lmXTF1sCDEqBaEMpreGczvg/x3AIh1d/qxc4BN7utQ4jEDwdA4YG0L6kr3ev0TtVLHRb6QLySNAOAunwn+dHeA==", + "version": "4.153.0", + "resolved": "https://registry.npmjs.org/wrangler/-/wrangler-4.153.0.tgz", + "integrity": "sha512-Hn1AowKzZao/729rMpdpxBZt/RaKQNJ4GtKtHQcOrwT+J/GIq0iwl680+dhJyO00iSsXaCkxoNcLg3yVIwIvyw==", "dev": true, "license": "MIT OR Apache-2.0", "dependencies": { @@ -1922,10 +1922,10 @@ "@cloudflare/unenv-preset": "2.16.2", "blake3-wasm": "2.1.5", "esbuild": "0.28.2", - "miniflare": "5.20261019.2-beta", + "miniflare": "5.20261023.0-beta", "path-to-regexp": "6.3.0", "unenv": "2.0.0-rc.24", - "workerd": "1.20261019.1" + "workerd": "1.20261023.1" }, "bin": { "cf-wrangler": "bin/cf-wrangler.js", @@ -1939,7 +1939,7 @@ "fsevents": "2.3.3" }, "peerDependencies": { - "@cloudflare/workers-types": "^5.20261019.1" + "@cloudflare/workers-types": "^5.20261023.1" }, "peerDependenciesMeta": { "@cloudflare/workers-types": { diff --git a/web/cloudflare-worker/package.json b/web/cloudflare-worker/package.json index c3321d790ce8..d31abc1df677 100644 --- a/web/cloudflare-worker/package.json +++ b/web/cloudflare-worker/package.json @@ -20,7 +20,7 @@ "@types/node": "24.19.0", "@types/ws": "8.18.1", "typescript": "7.0.2", - "wrangler": "4.152.0", + "wrangler": "4.153.0", "ws": "8.21.0" } }