Bump js-yaml, brace-expansion, and undici to latest releases (#958)

* Bump js-yaml from 5.1.0 to 5.2.2

Bumps [js-yaml](https://github.com/nodeca/js-yaml) from 5.1.0 to 5.2.2.
- [Changelog](https://github.com/nodeca/js-yaml/blob/master/CHANGELOG.md)
- [Commits](https://github.com/nodeca/js-yaml/compare/5.1.0...5.2.2)

---
updated-dependencies:
- dependency-name: js-yaml
  dependency-version: 5.2.2
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>

* chore: update dependency files for js-yaml, undici, and brace-expansion

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: chiranjib-swain <chiranjib-swain@github.com>
This commit is contained in:
dependabot[bot]
2026-08-06 15:02:16 -05:00
committed by GitHub
co-authored by dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> chiranjib-swain
parent b7a8804475
commit 2c2a2313b2
6 changed files with 387 additions and 160 deletions
+366 -139
View File
@@ -5703,7 +5703,13 @@ function processHeader (request, key, val) {
} else if (typeof val[i] === 'object') {
throw new InvalidArgumentError(`invalid ${key} header`)
} else {
arr.push(`${val[i]}`)
// Coerce primitives (and reject unsafe coercions such as functions
// with a crafted toString/Symbol.toPrimitive).
const str = `${val[i]}`
if (!isValidHeaderValue(str)) {
throw new InvalidArgumentError(`invalid ${key} header`)
}
arr.push(str)
}
}
val = arr
@@ -5714,7 +5720,12 @@ function processHeader (request, key, val) {
} else if (val === null) {
val = ''
} else {
// Coerce primitives (and reject unsafe coercions such as functions
// with a crafted toString/Symbol.toPrimitive).
val = `${val}`
if (!isValidHeaderValue(val)) {
throw new InvalidArgumentError(`invalid ${key} header`)
}
}
if (headerName === 'host') {
@@ -7086,6 +7097,7 @@ const {
RequestContentLengthMismatchError,
ResponseContentLengthMismatchError,
RequestAbortedError,
InvalidArgumentError,
HeadersTimeoutError,
HeadersOverflowError,
SocketError,
@@ -8069,8 +8081,16 @@ function writeH1 (client, request) {
}
body = bodyStream.stream
contentLength = bodyStream.length
} else if (util.isBlobLike(body) && request.contentType == null && body.type) {
headers.push('content-type', body.type)
} else if (util.isBlobLike(body) && request.contentType == null) {
const contentType = body.type
if (contentType) {
const contentTypeValue = `${contentType}`
if (!util.isValidHeaderValue(contentTypeValue)) {
util.errorRequest(client, request, new InvalidArgumentError('invalid content-type header'))
return false
}
headers.push('content-type', contentTypeValue)
}
}
if (body && typeof body.read === 'function') {
@@ -11543,6 +11563,28 @@ function calculateRetryAfterHeader (retryAfter) {
return new Date(retryAfter).getTime() - current
}
function validatePartialResponseContentLength (headers, range, statusCode, retryCount) {
const contentLength = headers['content-length']
if (contentLength == null) {
return null
}
if (!Number.isFinite(range.start) || !Number.isFinite(range.end)) {
return null
}
const length = Number(contentLength)
const expectedLength = range.end - range.start + 1
if (!Number.isFinite(length) || length !== expectedLength) {
return new RequestRetryError('Content-Length mismatch', statusCode, {
headers,
data: { count: retryCount }
})
}
return null
}
class RetryHandler {
constructor (opts, handlers) {
const { retryOptions, ...dispatchOpts } = opts
@@ -11757,6 +11799,12 @@ class RetryHandler {
return false
}
const contentLengthError = validatePartialResponseContentLength(headers, contentRange, statusCode, this.retryCount)
if (contentLengthError != null) {
this.abort(contentLengthError)
return false
}
const { start, size, end = size - 1 } = contentRange
assert(this.start === start, 'content-range mismatch')
@@ -11780,6 +11828,12 @@ class RetryHandler {
)
}
const contentLengthError = validatePartialResponseContentLength(headers, range, statusCode, this.retryCount)
if (contentLengthError != null) {
this.abort(contentLengthError)
return false
}
const { start, size, end = size - 1 } = range
assert(
start != null && Number.isFinite(start),
@@ -16024,7 +16078,7 @@ function validateCookiePath (path) {
if (
code < 0x20 || // exclude CTLs (0-31)
code === 0x7F || // DEL
code > 0x7E || // exclude DEL and non-ascii
code === 0x3B // ;
) {
throw new Error('Invalid cookie path')
@@ -16033,16 +16087,80 @@ function validateCookiePath (path) {
}
/**
* I have no idea why these values aren't allowed to be honest,
* but Deno tests these. - Khafra
* <let-dig> ::= <letter> | <digit>
*
* <letter> ::= any one of the 52 alphabetic characters A through Z in
* upper case and a through z in lower case
*
* <digit> ::= any one of the ten digits 0 through 9r
*
* @see https://www.rfc-editor.org/rfc/rfc1034#section-3.5
* @param {number} code
*/
function isLetterOrDigit (code) {
return (
(code >= 0x30 && code <= 0x39) || // 0-9
(code >= 0x41 && code <= 0x5A) || // A-Z
(code >= 0x61 && code <= 0x7A) // a-z
)
}
/**
* Validates a cookie domain against the "preferred name syntax".
*
* <domain> ::= <subdomain> | " "
* <subdomain> ::= <label> | <subdomain> "." <label>
* <label> ::= <let-dig> [ [ <ldh-str> ] <let-dig> ]
* <ldh-str> ::= <let-dig-hyp> | <let-dig-hyp> <ldh-str>
* <let-dig-hyp> ::= <let-dig> | "-"
*
* @see https://www.rfc-editor.org/rfc/rfc1034#section-3.5
* @see https://www.rfc-editor.org/rfc/rfc1123#section-2.1
* @see https://www.rfc-editor.org/rfc/rfc1035#section-2.3.4
* @param {string} domain
*/
function validateCookieDomain (domain) {
if (
domain.startsWith('-') ||
domain.endsWith('.') ||
domain.endsWith('-')
) {
// <domain> ::= <subdomain> | " "
if (domain === ' ') {
return
}
if (domain.length > 255) {
throw new Error('Invalid cookie domain')
}
let labelLength = 0
for (let i = 0; i < domain.length; ++i) {
const code = domain.charCodeAt(i)
if (code === 0x2E) {
if (labelLength === 0) {
throw new Error('Invalid cookie domain')
}
if (domain.charCodeAt(i - 1) === 0x2D) { // "-"
throw new Error('Invalid cookie domain')
}
labelLength = 0
continue
}
if (labelLength === 0 && !isLetterOrDigit(code)) {
throw new Error('Invalid cookie domain')
}
if (!isLetterOrDigit(code) && code !== 0x2D) { // "-"
throw new Error('Invalid cookie domain')
}
if (++labelLength > 63) {
throw new Error('Invalid cookie domain')
}
}
if (labelLength === 0 || domain.charCodeAt(domain.length - 1) === 0x2D) { // "-"
throw new Error('Invalid cookie domain')
}
}
@@ -16185,7 +16303,13 @@ function stringify (cookie) {
const [key, ...value] = part.split('=')
out.push(`${key.trim()}=${value.join('=')}`)
const trimmedKey = key.trim()
const joinedValue = value.join('=')
validateCookieName(trimmedKey)
validateCookieValue(joinedValue)
out.push(`${trimmedKey}=${joinedValue}`)
}
return out.join('; ')
@@ -38125,7 +38249,7 @@ const getContent = async (client, repoPath) => {
};
;// CONCATENATED MODULE: ./node_modules/js-yaml/dist/js-yaml.mjs
/*! js-yaml 5.1.0 https://github.com/nodeca/js-yaml @license MIT */
/*! js-yaml 5.2.2 https://github.com/nodeca/js-yaml @license MIT */
//#region src/tag.ts
var NOT_RESOLVED = Symbol("NOT_RESOLVED");
var MERGE_KEY = Symbol("MERGE_KEY");
@@ -38367,7 +38491,7 @@ var intCoreTag = defineScalarTag("tag:yaml.org,2002:int", {
..."0123456789"
],
resolve: resolveYamlInteger$2,
identify: (object) => Object.prototype.toString.call(object) === "[object Number]" && object % 1 === 0 && !Object.is(object, -0),
identify: (object) => Number.isInteger(object) && !Object.is(object, -0) && object.toString(10).indexOf("e") < 0,
represent: (object) => object.toString(10)
});
//#endregion
@@ -38397,7 +38521,7 @@ var intJsonTag = defineScalarTag("tag:yaml.org,2002:int", {
implicit: true,
implicitFirstChars: ["-", ..."0123456789"],
resolve: resolveYamlInteger$1,
identify: (object) => Object.prototype.toString.call(object) === "[object Number]" && object % 1 === 0 && !Object.is(object, -0),
identify: (object) => Number.isInteger(object) && !Object.is(object, -0) && object.toString(10).indexOf("e") < 0,
represent: (object) => object.toString(10)
});
//#endregion
@@ -38433,7 +38557,7 @@ var intYaml11Tag = defineScalarTag("tag:yaml.org,2002:int", {
..."0123456789"
],
resolve: resolveYamlInteger,
identify: (object) => Object.prototype.toString.call(object) === "[object Number]" && object % 1 === 0 && !Object.is(object, -0),
identify: (object) => Number.isInteger(object) && !Object.is(object, -0) && object.toString(10).indexOf("e") < 0,
represent: (object) => object.toString(10)
});
//#endregion
@@ -38468,7 +38592,7 @@ var floatCoreTag = defineScalarTag("tag:yaml.org,2002:float", {
..."0123456789"
],
resolve: resolveYamlFloat$2,
identify: (object) => Object.prototype.toString.call(object) === "[object Number]" && (object % 1 !== 0 || Object.is(object, -0)),
identify: (object) => typeof object === "number" && (!Number.isInteger(object) || Object.is(object, -0) || object.toString(10).indexOf("e") >= 0),
represent: representYamlFloat$2
});
//#endregion
@@ -38503,7 +38627,7 @@ var floatJsonTag = defineScalarTag("tag:yaml.org,2002:float", {
implicit: true,
implicitFirstChars: ["-", ..."0123456789"],
resolve: resolveYamlFloat$1,
identify: (object) => Object.prototype.toString.call(object) === "[object Number]" && (object % 1 !== 0 || Object.is(object, -0)),
identify: (object) => typeof object === "number" && (!Number.isInteger(object) || Object.is(object, -0) || object.toString(10).indexOf("e") >= 0),
represent: representYamlFloat$1
});
//#endregion
@@ -38542,7 +38666,7 @@ var floatYaml11Tag = defineScalarTag("tag:yaml.org,2002:float", {
..."0123456789"
],
resolve: resolveYamlFloat,
identify: (object) => Object.prototype.toString.call(object) === "[object Number]" && (object % 1 !== 0 || Object.is(object, -0)),
identify: (object) => typeof object === "number" && (!Number.isInteger(object) || Object.is(object, -0) || object.toString(10).indexOf("e") >= 0),
represent: representYamlFloat
});
//#endregion
@@ -38630,18 +38754,40 @@ var seqTag = defineSequenceTag("tag:yaml.org,2002:seq", {
identify: Array.isArray
});
//#endregion
//#region src/common/object.ts
function js_yaml_isPlainObject(data) {
if (data === null || typeof data !== "object" || Array.isArray(data)) return false;
const prototype = Object.getPrototypeOf(data);
return prototype === null || prototype === Object.prototype;
}
function pick(object, keys) {
const result = {};
for (const key of keys) if (object[key] !== void 0) result[key] = object[key];
return result;
}
//#endregion
//#region src/tag/sequence/omap.ts
var omapTag = defineSequenceTag("tag:yaml.org,2002:omap", {
create: () => [],
addItem: (container, item) => {
if (Object.prototype.toString.call(item) !== "[object Object]") return "cannot resolve an ordered map item";
const object = item;
const itemKeys = Object.keys(object);
if (itemKeys.length !== 1) return "cannot resolve an ordered map item";
for (const existing of container) if (Object.prototype.hasOwnProperty.call(existing, itemKeys[0])) return "cannot resolve an ordered map item";
container.push(object);
create: () => ({
list: [],
seen: /* @__PURE__ */ new Set()
}),
addItem: (carrier, item) => {
let key;
if (item instanceof Map) {
if (item.size !== 1) return "cannot resolve an ordered map item";
key = item.keys().next().value;
} else if (js_yaml_isPlainObject(item)) {
const itemKeys = Object.keys(item);
if (itemKeys.length !== 1) return "cannot resolve an ordered map item";
key = itemKeys[0];
} else return "cannot resolve an ordered map item";
if (carrier.seen.has(key)) return "duplicate key in ordered map";
carrier.seen.add(key);
carrier.list.push(item);
return "";
}
},
finalize: (carrier) => carrier.list
});
//#endregion
//#region src/tag/sequence/pairs.ts
@@ -38662,18 +38808,6 @@ var pairsTag = defineSequenceTag("tag:yaml.org,2002:pairs", {
}
});
//#endregion
//#region src/common/object.ts
function js_yaml_isPlainObject(data) {
if (data === null || typeof data !== "object" || Array.isArray(data)) return false;
const prototype = Object.getPrototypeOf(data);
return prototype === null || prototype === Object.prototype;
}
function pick(object, keys) {
const result = {};
for (const key of keys) if (object[key] !== void 0) result[key] = object[key];
return result;
}
//#endregion
//#region src/tag/mapping/map.ts
var mapTag = defineMappingTag("tag:yaml.org,2002:map", {
create: () => ({}),
@@ -39263,7 +39397,8 @@ var DEFAULT_CONSTRUCTOR_OPTIONS = {
filename: "",
schema: CORE_SCHEMA,
json: false,
maxMergeSeqLength: 20
maxTotalMergeKeys: 1e4,
maxAliases: -1
};
function eventPosition$1(event) {
if ("tagStart" in event && event.tagStart !== NO_RANGE$2) return event.tagStart;
@@ -39351,6 +39486,7 @@ function isMappingTag(tag) {
}
function mergeKeys(state, frame, source, sourceTag) {
for (const sourceKey of sourceTag.keys(source)) {
if (state.maxTotalMergeKeys !== -1 && ++state.totalMergeKeys > state.maxTotalMergeKeys) throwError$1(state, `merge keys exceeded maxTotalMergeKeys (${state.maxTotalMergeKeys})`);
if (frame.tag.has(frame.value, sourceKey)) continue;
const err = frame.tag.addPair(frame.value, sourceKey, sourceTag.get(source, sourceKey));
if (err) throwError$1(state, err);
@@ -39360,14 +39496,8 @@ function mergeKeys(state, frame, source, sourceTag) {
function mergeSource(state, frame, source, sourceTag) {
state.position = frame.keyPosition;
if (isMappingTag(sourceTag)) mergeKeys(state, frame, source, sourceTag);
else if (sourceTag.nodeKind === "sequence" && Array.isArray(source)) {
const seen = /* @__PURE__ */ new Set();
for (const element of source) {
if (seen.has(element)) continue;
seen.add(element);
mergeKeys(state, frame, element, frame.tag);
}
} else throwError$1(state, "cannot merge mappings; the provided source object is unacceptable");
else if (sourceTag.nodeKind === "sequence" && Array.isArray(source)) for (const element of source) mergeKeys(state, frame, element, frame.tag);
else throwError$1(state, "cannot merge mappings; the provided source object is unacceptable");
}
function addMappingValue(state, frame, key, value, tag) {
state.position = frame.keyPosition;
@@ -39388,7 +39518,6 @@ function addValue(state, value, tag) {
} else if (frame.kind === "sequence") {
if (frame.merge) {
if (!isMappingTag(tag)) throwError$1(state, "cannot merge mappings; the provided source object is unacceptable");
if (frame.index >= state.maxMergeSeqLength) throwError$1(state, `merge sequence length exceeded maxMergeSeqLength (${state.maxMergeSeqLength})`);
}
const err = frame.tag.addItem(frame.value, value, frame.index++);
if (err) throwError$1(state, err);
@@ -39425,7 +39554,9 @@ function constructFromEvents(events, options) {
position: 0,
frames: [],
anchors: /* @__PURE__ */ new Map(),
tagHandlers: Object.create(null)
tagHandlers: Object.create(null),
totalMergeKeys: 0,
aliasCount: 0
};
while (state.eventIndex < state.events.length) {
const event = state.events[state.eventIndex++];
@@ -39433,6 +39564,7 @@ function constructFromEvents(events, options) {
switch (event.type) {
case 1:
state.anchors = /* @__PURE__ */ new Map();
state.aliasCount = 0;
state.tagHandlers = Object.create(null);
for (const directive of event.directives) if (directive.kind === "tag") state.tagHandlers[directive.handle] = directive.prefix;
state.frames.push({
@@ -39483,6 +39615,7 @@ function constructFromEvents(events, options) {
break;
}
case 5: {
if (state.maxAliases !== -1 && ++state.aliasCount > state.maxAliases) throwError$1(state, `aliases exceeded maxAliases (${state.maxAliases})`);
const name = state.source.slice(event.anchorStart, event.anchorEnd);
const anchor = state.anchors.get(name);
if (!anchor) throwError$1(state, `unidentified alias "${name}"`);
@@ -39557,6 +39690,17 @@ function addMappingEvent(state, start, anchorStart, anchorEnd, tagStart, tagEnd,
style
});
}
function insertFlowPairMappingEvent(state, snapshot) {
state.events.splice(snapshot.eventsLength, 0, {
type: 3,
start: snapshot.position,
anchorStart: NO_RANGE$1,
anchorEnd: NO_RANGE$1,
tagStart: NO_RANGE$1,
tagEnd: NO_RANGE$1,
style: 2
});
}
function addScalarEvent(state, valueStart, valueEnd, anchorStart, anchorEnd, tagStart, tagEnd, style, chomping = 1, indent = -1, fast = false) {
state.events.push({
type: 4,
@@ -40000,12 +40144,8 @@ function readFlowCollection(state, nodeIndent, props) {
state.position++;
skipFlowSeparationSpace(state, nodeIndent);
if (!isMapping) {
restoreState(state, entryStart);
addMappingEvent(state, entryStart.position, NO_RANGE$1, NO_RANGE$1, NO_RANGE$1, NO_RANGE$1, 2);
if (!parseNode(state, nodeIndent, CONTEXT_FLOW_IN, false, true)) addEmptyScalarEvent(state);
skipFlowSeparationSpace(state, nodeIndent);
state.position++;
skipFlowSeparationSpace(state, nodeIndent);
insertFlowPairMappingEvent(state, entryStart);
if (!keyWasRead) addEmptyScalarEvent(state);
} else if (!keyWasRead) addEmptyScalarEvent(state);
if (!parseNode(state, nodeIndent, CONTEXT_FLOW_IN, false, true)) addEmptyScalarEvent(state);
skipFlowSeparationSpace(state, nodeIndent);
@@ -40015,9 +40155,8 @@ function readFlowCollection(state, nodeIndent, props) {
addEmptyScalarEvent(state);
} else if (isMapping) addEmptyScalarEvent(state);
else if (isPair) {
restoreState(state, entryStart);
addMappingEvent(state, entryStart.position, NO_RANGE$1, NO_RANGE$1, NO_RANGE$1, NO_RANGE$1, 2);
parseNode(state, nodeIndent, CONTEXT_FLOW_IN, false, true);
insertFlowPairMappingEvent(state, entryStart);
if (!keyWasRead) addEmptyScalarEvent(state);
addEmptyScalarEvent(state);
addPopEvent(state);
}
@@ -40672,7 +40811,7 @@ function isNsCharOrWhitespace(c) {
function isPlainSafe(c, prev, inblock) {
const cIsNsCharOrWhitespace = isNsCharOrWhitespace(c);
const cIsNsChar = cIsNsCharOrWhitespace && !isWhitespace(c);
return (inblock ? cIsNsCharOrWhitespace : cIsNsCharOrWhitespace && c !== CHAR_COMMA && c !== CHAR_LEFT_SQUARE_BRACKET && c !== CHAR_RIGHT_SQUARE_BRACKET && c !== CHAR_LEFT_CURLY_BRACKET && c !== CHAR_RIGHT_CURLY_BRACKET) && c !== CHAR_SHARP && !(prev === CHAR_COLON && !cIsNsChar) || isNsCharOrWhitespace(prev) && !isWhitespace(prev) && c === CHAR_SHARP || prev === CHAR_COLON && cIsNsChar;
return (inblock ? cIsNsCharOrWhitespace : cIsNsCharOrWhitespace && c !== CHAR_COMMA && c !== CHAR_LEFT_SQUARE_BRACKET && c !== CHAR_RIGHT_SQUARE_BRACKET && c !== CHAR_LEFT_CURLY_BRACKET && c !== CHAR_RIGHT_CURLY_BRACKET) && c !== CHAR_SHARP && !(prev === CHAR_COLON && !cIsNsChar) || isNsCharOrWhitespace(prev) && !isWhitespace(prev) && c === CHAR_SHARP || prev === CHAR_COLON && cIsNsChar && (inblock || c !== CHAR_COMMA && c !== CHAR_LEFT_SQUARE_BRACKET && c !== CHAR_RIGHT_SQUARE_BRACKET && c !== CHAR_LEFT_CURLY_BRACKET && c !== CHAR_RIGHT_CURLY_BRACKET);
}
function isPlainSafeFirst(c) {
return isPrintable(c) && c !== CHAR_BOM && !isWhitespace(c) && c !== CHAR_MINUS && c !== CHAR_QUESTION && c !== CHAR_COLON && c !== CHAR_COMMA && c !== CHAR_LEFT_SQUARE_BRACKET && c !== CHAR_RIGHT_SQUARE_BRACKET && c !== CHAR_LEFT_CURLY_BRACKET && c !== CHAR_RIGHT_CURLY_BRACKET && c !== CHAR_SHARP && c !== CHAR_AMPERSAND && c !== CHAR_ASTERISK && c !== CHAR_EXCLAMATION && c !== CHAR_VERTICAL_LINE && c !== CHAR_EQUALS && c !== CHAR_GREATER_THAN && c !== CHAR_SINGLE_QUOTE && c !== CHAR_DOUBLE_QUOTE && c !== CHAR_PERCENT && c !== CHAR_COMMERCIAL_AT && c !== CHAR_GRAVE_ACCENT;
@@ -41325,6 +41464,17 @@ const closePattern = /\\}/g;
const commaPattern = /\\,/g;
const periodPattern = /\\\./g;
const EXPANSION_MAX = 100_000;
// `EXPANSION_MAX` caps the *number* of expansions, but not their length. An
// input like `'{a,b}'.repeat(1500)` stays under that count - its output is
// truncated to 100k results - while making every result ~1500 characters
// long. The result set, and the intermediate arrays built while combining
// brace sets, then grow large enough to exhaust memory and crash the process
// (CVE-2026-14257). `EXPANSION_MAX_LENGTH` bounds the total number of
// characters the accumulator may hold at any point, so memory stays flat no
// matter how many brace groups are chained. The limit sits well above any
// realistic expansion (100k results hitting `EXPANSION_MAX` measure ~1M
// characters) so legitimate input is unaffected.
const EXPANSION_MAX_LENGTH = 4_000_000;
function numeric(str) {
return !isNaN(str) ? parseInt(str, 10) : str.charCodeAt(0);
}
@@ -41374,7 +41524,7 @@ function esm_expand(str, options = {}) {
if (!str) {
return [];
}
const { max = EXPANSION_MAX } = options;
const { max = EXPANSION_MAX, maxLength = EXPANSION_MAX_LENGTH } = options;
// I don't know why Bash 4.3 does this, but it does.
// Anything starting with {} will have the first two bytes preserved
// but *only* at the top level, so {},a}b will not expand to anything,
@@ -41384,7 +41534,7 @@ function esm_expand(str, options = {}) {
if (str.slice(0, 2) === '{}') {
str = '\\{\\}' + str.slice(2);
}
return expand_(escapeBraces(str), max, true).map(unescapeBraces);
return expand_(escapeBraces(str), max, maxLength, true).map(unescapeBraces);
}
function embrace(str) {
return '{' + str + '}';
@@ -41398,22 +41548,117 @@ function lte(i, y) {
function gte(i, y) {
return i >= y;
}
function expand_(str, max, isTop) {
/** @type {string[]} */
const expansions = [];
const m = balanced('{', '}', str);
if (!m)
return [str];
// no need to expand pre, since it is guaranteed to be free of brace-sets
const pre = m.pre;
const post = m.post.length ? expand_(m.post, max, false) : [''];
if (/\$$/.test(m.pre)) {
for (let k = 0; k < post.length && k < max; k++) {
const expansion = pre + '{' + m.body + '}' + post[k];
expansions.push(expansion);
// Build `{ acc[a] + pre + values[v] }` for every combination, capping the
// number of results at `max` and the total number of characters at `maxLength`.
// This is the one place output grows, so bounding it here keeps the single
// accumulator - and therefore memory - flat regardless of how many brace groups
// are combined (CVE-2026-14257).
function combine(acc, pre, values, max, maxLength, dropEmpties) {
const out = [];
let length = 0;
for (let a = 0; a < acc.length; a++) {
for (let v = 0; v < values.length; v++) {
if (out.length >= max)
return out;
const expansion = acc[a] + pre + values[v];
// Bash drops empty results at the top level. Skip them before they count
// against `max`, so `max` bounds the number of *kept* results.
if (dropEmpties && !expansion)
continue;
if (length + expansion.length > maxLength)
return out;
out.push(expansion);
length += expansion.length;
}
}
else {
return out;
}
// The expansion values of a single numeric (`1..5`) or alphabetic (`a..e..2`)
// sequence body.
function expandSequence(body, isAlphaSequence, max, maxLength) {
const n = body.split(/\.\./);
const N = [];
// A sequence body always splits into two or three parts, but the compiler
// can't know that.
/* c8 ignore start */
if (n[0] === undefined || n[1] === undefined) {
return N;
}
/* c8 ignore stop */
const x = numeric(n[0]);
const y = numeric(n[1]);
const width = Math.max(n[0].length, n[1].length);
let incr = n.length === 3 && n[2] !== undefined ?
Math.max(Math.abs(numeric(n[2])), 1)
: 1;
let test = lte;
const reverse = y < x;
if (reverse) {
incr *= -1;
test = gte;
}
const pad = n.some(isPadded);
let length = 0;
for (let i = x; test(i, y) && N.length < max; i += incr) {
let c;
if (isAlphaSequence) {
c = String.fromCharCode(i);
if (c === '\\') {
c = '';
}
}
else {
c = String(i);
if (pad) {
const need = width - c.length;
if (need > 0) {
const z = new Array(need + 1).join('0');
if (i < 0) {
c = '-' + z + c.slice(1);
}
else {
c = z + c;
}
}
}
}
if (length + c.length > maxLength)
break;
N.push(c);
length += c.length;
}
return N;
}
function expand_(str, max, maxLength, isTop) {
// Consume the string's top-level brace groups left to right, threading a
// running set of combined prefixes (`acc`). Expanding the tail iteratively -
// rather than recursing on `m.post` once per group - keeps the native stack
// depth constant, so deeply chained input (`'{a,b}'.repeat(3000)`) can no
// longer overflow the stack, and leaves a single accumulator whose size
// `maxLength` bounds directly (CVE-2026-14257).
let acc = [''];
// Bash drops empty results, but only when the *first* top-level group is a
// comma set - a sequence like `{a..\}` may legitimately yield ''. The drop
// is on the final strings, so it is applied to whichever `combine` produces
// them (the one with no brace set left in the tail).
let dropEmpties = false;
let firstGroup = true;
for (;;) {
const m = balanced('{', '}', str);
// No brace set left: the rest of the string is literal.
if (!m) {
return combine(acc, str, [''], max, maxLength, dropEmpties);
}
// no need to expand pre, since it is guaranteed to be free of brace-sets
const pre = m.pre;
if (/\$$/.test(pre)) {
acc = combine(acc, pre + '{' + m.body + '}', [''], max, maxLength, dropEmpties && !m.post.length);
firstGroup = false;
if (!m.post.length)
break;
str = m.post;
continue;
}
const isNumericSequence = /^-?\d+\.\.-?\d+(?:\.\.-?\d+)?$/.test(m.body);
const isAlphaSequence = /^[a-zA-Z]\.\.[a-zA-Z](?:\.\.-?\d+)?$/.test(m.body);
const isSequence = isNumericSequence || isAlphaSequence;
@@ -41422,87 +41667,69 @@ function expand_(str, max, isTop) {
// {a},b}
if (m.post.match(/,(?!,).*\}/)) {
str = m.pre + '{' + m.body + escClose + m.post;
return expand_(str, max, true);
isTop = true;
continue;
}
return [str];
// Nothing here expands, so the whole remaining string is literal.
return combine(acc, pre + '{' + m.body + '}' + m.post, [''], max, maxLength, dropEmpties);
}
let n;
if (firstGroup) {
dropEmpties = isTop && !isSequence;
firstGroup = false;
}
let values;
if (isSequence) {
n = m.body.split(/\.\./);
values = expandSequence(m.body, isAlphaSequence, max, maxLength);
}
else {
n = parseCommaParts(m.body);
let n = parseCommaParts(m.body);
if (n.length === 1 && n[0] !== undefined) {
// x{{a,b}}y ==> x{a}y x{b}y
n = expand_(n[0], max, false).map(embrace);
n = expand_(n[0], max, maxLength, false).map(embrace);
//XXX is this necessary? Can't seem to hit it in tests.
/* c8 ignore start */
if (n.length === 1) {
return post.map(p => m.pre + n[0] + p);
acc = combine(acc, pre + n[0], [''], max, maxLength, dropEmpties && !m.post.length);
if (!m.post.length)
break;
str = m.post;
continue;
}
/* c8 ignore stop */
}
}
// at this point, n is the parts, and we know it's not a comma set
// with a single entry.
let N;
if (isSequence && n[0] !== undefined && n[1] !== undefined) {
const x = numeric(n[0]);
const y = numeric(n[1]);
const width = Math.max(n[0].length, n[1].length);
let incr = n.length === 3 && n[2] !== undefined ?
Math.max(Math.abs(numeric(n[2])), 1)
: 1;
let test = lte;
const reverse = y < x;
if (reverse) {
incr *= -1;
test = gte;
// Values that `combine` is going to drop as empty produce no result, so
// they must not count against `max` - otherwise `{a,,b}` with `max: 2`
// would stop at `['a', '']` and yield one result instead of two. Skipping
// them outright keeps `values` bounded while leaving `max` a bound on
// *kept* results.
let dropsEmpties = dropEmpties && !m.post.length && !pre;
for (let d = 0; dropsEmpties && d < acc.length; d++) {
if (acc[d]) {
dropsEmpties = false;
}
}
const pad = n.some(isPadded);
N = [];
for (let i = x; test(i, y) && N.length < max; i += incr) {
let c;
if (isAlphaSequence) {
c = String.fromCharCode(i);
if (c === '\\') {
c = '';
values = [];
let valuesLength = 0;
outer: for (let j = 0; j < n.length; j++) {
const expanded = expand_(n[j], max, maxLength, false);
for (let k = 0; k < expanded.length; k++) {
const v = expanded[k];
if (dropsEmpties && !v)
continue;
if (values.length >= max || valuesLength + v.length > maxLength) {
break outer;
}
}
else {
c = String(i);
if (pad) {
const need = width - c.length;
if (need > 0) {
const z = new Array(need + 1).join('0');
if (i < 0) {
c = '-' + z + c.slice(1);
}
else {
c = z + c;
}
}
}
}
N.push(c);
}
}
else {
N = [];
for (let j = 0; j < n.length; j++) {
N.push.apply(N, expand_(n[j], max, false));
}
}
for (let j = 0; j < N.length; j++) {
for (let k = 0; k < post.length && expansions.length < max; k++) {
const expansion = pre + N[j] + post[k];
if (!isTop || isSequence || expansion) {
expansions.push(expansion);
values.push(v);
valuesLength += v.length;
}
}
}
acc = combine(acc, pre, values, max, maxLength, dropEmpties && !m.post.length);
if (!m.post.length)
break;
str = m.post;
}
return expansions;
return acc;
}
//# sourceMappingURL=index.js.map
;// CONCATENATED MODULE: ./node_modules/minimatch/dist/esm/assert-valid-pattern.js