mirror of
https://github.com/actions/setup-python.git
synced 2026-10-10 16:43:08 +01:00
Compare commits
3 Commits
dependabot
...
dependabot
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1fa030f173 | ||
|
|
bb4b67e4f6 | ||
|
|
f4c8249567 |
2
.licenses/npm/brace-expansion.dep.yml
generated
2
.licenses/npm/brace-expansion.dep.yml
generated
@@ -1,6 +1,6 @@
|
||||
---
|
||||
name: brace-expansion
|
||||
version: 5.0.9
|
||||
version: 5.0.12
|
||||
type: npm
|
||||
summary: Brace expansion as known from sh/bash
|
||||
homepage:
|
||||
|
||||
@@ -5,9 +5,9 @@ description = ""
|
||||
authors = ["Your Name <you@example.com>"]
|
||||
|
||||
[tool.poetry.dependencies]
|
||||
python = ">=3.9,<3.14"
|
||||
python = ">=3.9,<3.15"
|
||||
flake8 = "^4.0.1"
|
||||
pyinstaller = "6.10.0"
|
||||
pyinstaller = "6.16.0"
|
||||
setuptools = ">=78.1.1"
|
||||
packaging = ">=22.0,<26"
|
||||
|
||||
|
||||
94
dist/cache-save/index.js
vendored
94
dist/cache-save/index.js
vendored
@@ -41078,7 +41078,7 @@ exports.range = range;
|
||||
|
||||
|
||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||
exports.EXPANSION_MAX_LENGTH = exports.EXPANSION_MAX = void 0;
|
||||
exports.EXPANSION_MAX_REWRITES = exports.EXPANSION_MAX_DEPTH = exports.EXPANSION_MAX_LENGTH = exports.EXPANSION_MAX = void 0;
|
||||
exports.expand = expand;
|
||||
const balanced_match_1 = __nccwpck_require__(2649);
|
||||
const escSlash = '\0SLASH' + Math.random() + '\0';
|
||||
@@ -41108,6 +41108,24 @@ exports.EXPANSION_MAX = 100_000;
|
||||
// realistic expansion (100k results hitting `EXPANSION_MAX` measure ~1M
|
||||
// characters) so legitimate input is unaffected.
|
||||
exports.EXPANSION_MAX_LENGTH = 4_000_000;
|
||||
// `expand_` recurses once per level of brace *nesting* - both when expanding a
|
||||
// set's comma members and when re-wrapping a set whose body is a single part.
|
||||
// The CVE-2026-14257 fix made the *tail* iterative (recursion on `m.post`, one
|
||||
// level per chained group), which left nesting depth unbounded: about 3,100
|
||||
// levels of `{{{...a,b...}}}` - only ~6KB of input - exhausted the native stack
|
||||
// and crashed the process. `EXPANSION_MAX_DEPTH` bounds how deep the parser
|
||||
// will follow nesting. It sits far above any realistic pattern and well below
|
||||
// the depth at which the stack runs out.
|
||||
exports.EXPANSION_MAX_DEPTH = 1_000;
|
||||
// Bash keeps a quirk where a brace group followed by a comma set still expands
|
||||
// (`{a},b}`). The parser implements it by rewriting the string and restarting
|
||||
// the scan, absorbing one `}` per pass. `n` trailing braces therefore cost `n`
|
||||
// full passes over a string that itself grows by one `escClose` sentinel each
|
||||
// time - quadratic in `n`, with a ~26x constant from the sentinel's length.
|
||||
// 128KB of `'{a}' + '}'.repeat(n) + ',z}'` blocked the event loop for 27
|
||||
// seconds to produce two results. `EXPANSION_MAX_REWRITES` bounds how many
|
||||
// times the scan may restart. Real `{a},b}` input needs a handful.
|
||||
exports.EXPANSION_MAX_REWRITES = 1_000;
|
||||
function numeric(str) {
|
||||
return !isNaN(str) ? parseInt(str, 10) : str.charCodeAt(0);
|
||||
}
|
||||
@@ -41127,37 +41145,52 @@ function unescapeBraces(str) {
|
||||
.replace(escCommaPattern, ',')
|
||||
.replace(escPeriodPattern, '.');
|
||||
}
|
||||
// Like `target.push(...items)` but doesn't overflow the stack
|
||||
function pushAll(target, items) {
|
||||
for (let i = 0; i < items.length; i++) {
|
||||
target.push(items[i]);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Basically just str.split(","), but handling cases
|
||||
* where we have nested braced sections, which should be
|
||||
* treated as individual members, like {a,{b,c},d}
|
||||
*/
|
||||
function parseCommaParts(str) {
|
||||
if (!str) {
|
||||
return [''];
|
||||
}
|
||||
const parts = [];
|
||||
const m = (0, balanced_match_1.balanced)('{', '}', str);
|
||||
if (!m) {
|
||||
return str.split(',');
|
||||
// Walk the brace groups iteratively. Recursing on `post` once per group let a
|
||||
// chain of them exhaust the stack - the parsing-side counterpart to
|
||||
// the `expand_` overflow fixed for CVE-2026-14257, and not something `max` or
|
||||
// `maxLength` can bound, since it happens before expansion.
|
||||
//
|
||||
// The part the next chunk continues
|
||||
let carry = '';
|
||||
for (;;) {
|
||||
const m = (0, balanced_match_1.balanced)('{', '}', str);
|
||||
if (!m) {
|
||||
const tail = str.split(',');
|
||||
tail[0] = carry + tail[0];
|
||||
pushAll(parts, tail);
|
||||
return parts;
|
||||
}
|
||||
const { pre, body, post } = m;
|
||||
const p = pre.split(',');
|
||||
p[0] = carry + p[0];
|
||||
p[p.length - 1] += '{' + body + '}';
|
||||
if (!post.length) {
|
||||
pushAll(parts, p);
|
||||
return parts;
|
||||
}
|
||||
carry = p.pop();
|
||||
pushAll(parts, p);
|
||||
str = post;
|
||||
}
|
||||
const { pre, body, post } = m;
|
||||
const p = pre.split(',');
|
||||
p[p.length - 1] += '{' + body + '}';
|
||||
const postParts = parseCommaParts(post);
|
||||
if (post.length) {
|
||||
;
|
||||
p[p.length - 1] += postParts.shift();
|
||||
p.push.apply(p, postParts);
|
||||
}
|
||||
parts.push.apply(parts, p);
|
||||
return parts;
|
||||
}
|
||||
function expand(str, options = {}) {
|
||||
if (!str) {
|
||||
return [];
|
||||
}
|
||||
const { max = exports.EXPANSION_MAX, maxLength = exports.EXPANSION_MAX_LENGTH } = options;
|
||||
const { max = exports.EXPANSION_MAX, maxLength = exports.EXPANSION_MAX_LENGTH, maxDepth = exports.EXPANSION_MAX_DEPTH, maxRewrites = exports.EXPANSION_MAX_REWRITES, } = 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,
|
||||
@@ -41167,7 +41200,7 @@ function expand(str, options = {}) {
|
||||
if (str.slice(0, 2) === '{}') {
|
||||
str = '\\{\\}' + str.slice(2);
|
||||
}
|
||||
return expand_(escapeBraces(str), max, maxLength, true).map(unescapeBraces);
|
||||
return expand_(escapeBraces(str), max, maxLength, maxDepth, 0, maxRewrites, true).map(unescapeBraces);
|
||||
}
|
||||
function embrace(str) {
|
||||
return '{' + str + '}';
|
||||
@@ -41262,7 +41295,13 @@ function expandSequence(body, isAlphaSequence, max, maxLength) {
|
||||
}
|
||||
return N;
|
||||
}
|
||||
function expand_(str, max, maxLength, isTop) {
|
||||
function expand_(str, max, maxLength, maxDepth, depth, maxRewrites, isTop) {
|
||||
// Too deeply nested to keep following: treat the rest as literal, the same
|
||||
// way a group that cannot expand is already handled. Truncating rather than
|
||||
// throwing keeps `expand` total, matching `max` and `maxLength`.
|
||||
if (depth > maxDepth) {
|
||||
return [str];
|
||||
}
|
||||
// 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
|
||||
@@ -41274,6 +41313,9 @@ function expand_(str, max, maxLength, isTop) {
|
||||
// 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).
|
||||
// How many times the `{a},b}` rewrite below has restarted the scan. Each pass
|
||||
// re-reads the whole string, so leaving this unbounded is quadratic.
|
||||
let rewrites = 0;
|
||||
let dropEmpties = false;
|
||||
let firstGroup = true;
|
||||
for (;;) {
|
||||
@@ -41298,7 +41340,8 @@ function expand_(str, max, maxLength, isTop) {
|
||||
const isOptions = m.body.indexOf(',') >= 0;
|
||||
if (!isSequence && !isOptions) {
|
||||
// {a},b}
|
||||
if (m.post.match(/,(?!,).*\}/)) {
|
||||
if (rewrites < maxRewrites && m.post.match(/,(?!,).*\}/)) {
|
||||
rewrites++;
|
||||
str = m.pre + '{' + m.body + escClose + m.post;
|
||||
isTop = true;
|
||||
continue;
|
||||
@@ -41318,7 +41361,7 @@ function expand_(str, max, maxLength, isTop) {
|
||||
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, maxLength, false).map(embrace);
|
||||
n = expand_(n[0], max, maxLength, maxDepth, depth + 1, maxRewrites, false).map(embrace);
|
||||
//XXX is this necessary? Can't seem to hit it in tests.
|
||||
/* c8 ignore start */
|
||||
if (n.length === 1) {
|
||||
@@ -41344,12 +41387,13 @@ function expand_(str, max, maxLength, isTop) {
|
||||
values = [];
|
||||
let valuesLength = 0;
|
||||
outer: for (let j = 0; j < n.length; j++) {
|
||||
const expanded = expand_(n[j], max, maxLength, false);
|
||||
const expanded = expand_(n[j], max, maxLength, maxDepth, depth + 1, maxRewrites, 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) {
|
||||
if (values.length >= max ||
|
||||
valuesLength + v.length > maxLength) {
|
||||
break outer;
|
||||
}
|
||||
values.push(v);
|
||||
|
||||
186
dist/setup/index.js
vendored
186
dist/setup/index.js
vendored
@@ -41078,7 +41078,7 @@ exports.range = range;
|
||||
|
||||
|
||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||
exports.EXPANSION_MAX_LENGTH = exports.EXPANSION_MAX = void 0;
|
||||
exports.EXPANSION_MAX_REWRITES = exports.EXPANSION_MAX_DEPTH = exports.EXPANSION_MAX_LENGTH = exports.EXPANSION_MAX = void 0;
|
||||
exports.expand = expand;
|
||||
const balanced_match_1 = __nccwpck_require__(2649);
|
||||
const escSlash = '\0SLASH' + Math.random() + '\0';
|
||||
@@ -41108,6 +41108,24 @@ exports.EXPANSION_MAX = 100_000;
|
||||
// realistic expansion (100k results hitting `EXPANSION_MAX` measure ~1M
|
||||
// characters) so legitimate input is unaffected.
|
||||
exports.EXPANSION_MAX_LENGTH = 4_000_000;
|
||||
// `expand_` recurses once per level of brace *nesting* - both when expanding a
|
||||
// set's comma members and when re-wrapping a set whose body is a single part.
|
||||
// The CVE-2026-14257 fix made the *tail* iterative (recursion on `m.post`, one
|
||||
// level per chained group), which left nesting depth unbounded: about 3,100
|
||||
// levels of `{{{...a,b...}}}` - only ~6KB of input - exhausted the native stack
|
||||
// and crashed the process. `EXPANSION_MAX_DEPTH` bounds how deep the parser
|
||||
// will follow nesting. It sits far above any realistic pattern and well below
|
||||
// the depth at which the stack runs out.
|
||||
exports.EXPANSION_MAX_DEPTH = 1_000;
|
||||
// Bash keeps a quirk where a brace group followed by a comma set still expands
|
||||
// (`{a},b}`). The parser implements it by rewriting the string and restarting
|
||||
// the scan, absorbing one `}` per pass. `n` trailing braces therefore cost `n`
|
||||
// full passes over a string that itself grows by one `escClose` sentinel each
|
||||
// time - quadratic in `n`, with a ~26x constant from the sentinel's length.
|
||||
// 128KB of `'{a}' + '}'.repeat(n) + ',z}'` blocked the event loop for 27
|
||||
// seconds to produce two results. `EXPANSION_MAX_REWRITES` bounds how many
|
||||
// times the scan may restart. Real `{a},b}` input needs a handful.
|
||||
exports.EXPANSION_MAX_REWRITES = 1_000;
|
||||
function numeric(str) {
|
||||
return !isNaN(str) ? parseInt(str, 10) : str.charCodeAt(0);
|
||||
}
|
||||
@@ -41127,37 +41145,52 @@ function unescapeBraces(str) {
|
||||
.replace(escCommaPattern, ',')
|
||||
.replace(escPeriodPattern, '.');
|
||||
}
|
||||
// Like `target.push(...items)` but doesn't overflow the stack
|
||||
function pushAll(target, items) {
|
||||
for (let i = 0; i < items.length; i++) {
|
||||
target.push(items[i]);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Basically just str.split(","), but handling cases
|
||||
* where we have nested braced sections, which should be
|
||||
* treated as individual members, like {a,{b,c},d}
|
||||
*/
|
||||
function parseCommaParts(str) {
|
||||
if (!str) {
|
||||
return [''];
|
||||
}
|
||||
const parts = [];
|
||||
const m = (0, balanced_match_1.balanced)('{', '}', str);
|
||||
if (!m) {
|
||||
return str.split(',');
|
||||
// Walk the brace groups iteratively. Recursing on `post` once per group let a
|
||||
// chain of them exhaust the stack - the parsing-side counterpart to
|
||||
// the `expand_` overflow fixed for CVE-2026-14257, and not something `max` or
|
||||
// `maxLength` can bound, since it happens before expansion.
|
||||
//
|
||||
// The part the next chunk continues
|
||||
let carry = '';
|
||||
for (;;) {
|
||||
const m = (0, balanced_match_1.balanced)('{', '}', str);
|
||||
if (!m) {
|
||||
const tail = str.split(',');
|
||||
tail[0] = carry + tail[0];
|
||||
pushAll(parts, tail);
|
||||
return parts;
|
||||
}
|
||||
const { pre, body, post } = m;
|
||||
const p = pre.split(',');
|
||||
p[0] = carry + p[0];
|
||||
p[p.length - 1] += '{' + body + '}';
|
||||
if (!post.length) {
|
||||
pushAll(parts, p);
|
||||
return parts;
|
||||
}
|
||||
carry = p.pop();
|
||||
pushAll(parts, p);
|
||||
str = post;
|
||||
}
|
||||
const { pre, body, post } = m;
|
||||
const p = pre.split(',');
|
||||
p[p.length - 1] += '{' + body + '}';
|
||||
const postParts = parseCommaParts(post);
|
||||
if (post.length) {
|
||||
;
|
||||
p[p.length - 1] += postParts.shift();
|
||||
p.push.apply(p, postParts);
|
||||
}
|
||||
parts.push.apply(parts, p);
|
||||
return parts;
|
||||
}
|
||||
function expand(str, options = {}) {
|
||||
if (!str) {
|
||||
return [];
|
||||
}
|
||||
const { max = exports.EXPANSION_MAX, maxLength = exports.EXPANSION_MAX_LENGTH } = options;
|
||||
const { max = exports.EXPANSION_MAX, maxLength = exports.EXPANSION_MAX_LENGTH, maxDepth = exports.EXPANSION_MAX_DEPTH, maxRewrites = exports.EXPANSION_MAX_REWRITES, } = 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,
|
||||
@@ -41167,7 +41200,7 @@ function expand(str, options = {}) {
|
||||
if (str.slice(0, 2) === '{}') {
|
||||
str = '\\{\\}' + str.slice(2);
|
||||
}
|
||||
return expand_(escapeBraces(str), max, maxLength, true).map(unescapeBraces);
|
||||
return expand_(escapeBraces(str), max, maxLength, maxDepth, 0, maxRewrites, true).map(unescapeBraces);
|
||||
}
|
||||
function embrace(str) {
|
||||
return '{' + str + '}';
|
||||
@@ -41262,7 +41295,13 @@ function expandSequence(body, isAlphaSequence, max, maxLength) {
|
||||
}
|
||||
return N;
|
||||
}
|
||||
function expand_(str, max, maxLength, isTop) {
|
||||
function expand_(str, max, maxLength, maxDepth, depth, maxRewrites, isTop) {
|
||||
// Too deeply nested to keep following: treat the rest as literal, the same
|
||||
// way a group that cannot expand is already handled. Truncating rather than
|
||||
// throwing keeps `expand` total, matching `max` and `maxLength`.
|
||||
if (depth > maxDepth) {
|
||||
return [str];
|
||||
}
|
||||
// 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
|
||||
@@ -41274,6 +41313,9 @@ function expand_(str, max, maxLength, isTop) {
|
||||
// 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).
|
||||
// How many times the `{a},b}` rewrite below has restarted the scan. Each pass
|
||||
// re-reads the whole string, so leaving this unbounded is quadratic.
|
||||
let rewrites = 0;
|
||||
let dropEmpties = false;
|
||||
let firstGroup = true;
|
||||
for (;;) {
|
||||
@@ -41298,7 +41340,8 @@ function expand_(str, max, maxLength, isTop) {
|
||||
const isOptions = m.body.indexOf(',') >= 0;
|
||||
if (!isSequence && !isOptions) {
|
||||
// {a},b}
|
||||
if (m.post.match(/,(?!,).*\}/)) {
|
||||
if (rewrites < maxRewrites && m.post.match(/,(?!,).*\}/)) {
|
||||
rewrites++;
|
||||
str = m.pre + '{' + m.body + escClose + m.post;
|
||||
isTop = true;
|
||||
continue;
|
||||
@@ -41318,7 +41361,7 @@ function expand_(str, max, maxLength, isTop) {
|
||||
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, maxLength, false).map(embrace);
|
||||
n = expand_(n[0], max, maxLength, maxDepth, depth + 1, maxRewrites, false).map(embrace);
|
||||
//XXX is this necessary? Can't seem to hit it in tests.
|
||||
/* c8 ignore start */
|
||||
if (n.length === 1) {
|
||||
@@ -41344,12 +41387,13 @@ function expand_(str, max, maxLength, isTop) {
|
||||
values = [];
|
||||
let valuesLength = 0;
|
||||
outer: for (let j = 0; j < n.length; j++) {
|
||||
const expanded = expand_(n[j], max, maxLength, false);
|
||||
const expanded = expand_(n[j], max, maxLength, maxDepth, depth + 1, maxRewrites, 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) {
|
||||
if (values.length >= max ||
|
||||
valuesLength + v.length > maxLength) {
|
||||
break outer;
|
||||
}
|
||||
values.push(v);
|
||||
@@ -100326,6 +100370,24 @@ const EXPANSION_MAX = 100_000;
|
||||
// realistic expansion (100k results hitting `EXPANSION_MAX` measure ~1M
|
||||
// characters) so legitimate input is unaffected.
|
||||
const EXPANSION_MAX_LENGTH = 4_000_000;
|
||||
// `expand_` recurses once per level of brace *nesting* - both when expanding a
|
||||
// set's comma members and when re-wrapping a set whose body is a single part.
|
||||
// The CVE-2026-14257 fix made the *tail* iterative (recursion on `m.post`, one
|
||||
// level per chained group), which left nesting depth unbounded: about 3,100
|
||||
// levels of `{{{...a,b...}}}` - only ~6KB of input - exhausted the native stack
|
||||
// and crashed the process. `EXPANSION_MAX_DEPTH` bounds how deep the parser
|
||||
// will follow nesting. It sits far above any realistic pattern and well below
|
||||
// the depth at which the stack runs out.
|
||||
const EXPANSION_MAX_DEPTH = 1_000;
|
||||
// Bash keeps a quirk where a brace group followed by a comma set still expands
|
||||
// (`{a},b}`). The parser implements it by rewriting the string and restarting
|
||||
// the scan, absorbing one `}` per pass. `n` trailing braces therefore cost `n`
|
||||
// full passes over a string that itself grows by one `escClose` sentinel each
|
||||
// time - quadratic in `n`, with a ~26x constant from the sentinel's length.
|
||||
// 128KB of `'{a}' + '}'.repeat(n) + ',z}'` blocked the event loop for 27
|
||||
// seconds to produce two results. `EXPANSION_MAX_REWRITES` bounds how many
|
||||
// times the scan may restart. Real `{a},b}` input needs a handful.
|
||||
const EXPANSION_MAX_REWRITES = 1_000;
|
||||
function numeric(str) {
|
||||
return !isNaN(str) ? parseInt(str, 10) : str.charCodeAt(0);
|
||||
}
|
||||
@@ -100345,37 +100407,52 @@ function unescapeBraces(str) {
|
||||
.replace(escCommaPattern, ',')
|
||||
.replace(escPeriodPattern, '.');
|
||||
}
|
||||
// Like `target.push(...items)` but doesn't overflow the stack
|
||||
function pushAll(target, items) {
|
||||
for (let i = 0; i < items.length; i++) {
|
||||
target.push(items[i]);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Basically just str.split(","), but handling cases
|
||||
* where we have nested braced sections, which should be
|
||||
* treated as individual members, like {a,{b,c},d}
|
||||
*/
|
||||
function parseCommaParts(str) {
|
||||
if (!str) {
|
||||
return [''];
|
||||
}
|
||||
const parts = [];
|
||||
const m = balanced('{', '}', str);
|
||||
if (!m) {
|
||||
return str.split(',');
|
||||
// Walk the brace groups iteratively. Recursing on `post` once per group let a
|
||||
// chain of them exhaust the stack - the parsing-side counterpart to
|
||||
// the `expand_` overflow fixed for CVE-2026-14257, and not something `max` or
|
||||
// `maxLength` can bound, since it happens before expansion.
|
||||
//
|
||||
// The part the next chunk continues
|
||||
let carry = '';
|
||||
for (;;) {
|
||||
const m = balanced('{', '}', str);
|
||||
if (!m) {
|
||||
const tail = str.split(',');
|
||||
tail[0] = carry + tail[0];
|
||||
pushAll(parts, tail);
|
||||
return parts;
|
||||
}
|
||||
const { pre, body, post } = m;
|
||||
const p = pre.split(',');
|
||||
p[0] = carry + p[0];
|
||||
p[p.length - 1] += '{' + body + '}';
|
||||
if (!post.length) {
|
||||
pushAll(parts, p);
|
||||
return parts;
|
||||
}
|
||||
carry = p.pop();
|
||||
pushAll(parts, p);
|
||||
str = post;
|
||||
}
|
||||
const { pre, body, post } = m;
|
||||
const p = pre.split(',');
|
||||
p[p.length - 1] += '{' + body + '}';
|
||||
const postParts = parseCommaParts(post);
|
||||
if (post.length) {
|
||||
;
|
||||
p[p.length - 1] += postParts.shift();
|
||||
p.push.apply(p, postParts);
|
||||
}
|
||||
parts.push.apply(parts, p);
|
||||
return parts;
|
||||
}
|
||||
function expand(str, options = {}) {
|
||||
if (!str) {
|
||||
return [];
|
||||
}
|
||||
const { max = EXPANSION_MAX, maxLength = EXPANSION_MAX_LENGTH } = options;
|
||||
const { max = EXPANSION_MAX, maxLength = EXPANSION_MAX_LENGTH, maxDepth = EXPANSION_MAX_DEPTH, maxRewrites = EXPANSION_MAX_REWRITES, } = 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,
|
||||
@@ -100385,7 +100462,7 @@ function expand(str, options = {}) {
|
||||
if (str.slice(0, 2) === '{}') {
|
||||
str = '\\{\\}' + str.slice(2);
|
||||
}
|
||||
return expand_(escapeBraces(str), max, maxLength, true).map(unescapeBraces);
|
||||
return expand_(escapeBraces(str), max, maxLength, maxDepth, 0, maxRewrites, true).map(unescapeBraces);
|
||||
}
|
||||
function embrace(str) {
|
||||
return '{' + str + '}';
|
||||
@@ -100480,7 +100557,13 @@ function expandSequence(body, isAlphaSequence, max, maxLength) {
|
||||
}
|
||||
return N;
|
||||
}
|
||||
function expand_(str, max, maxLength, isTop) {
|
||||
function expand_(str, max, maxLength, maxDepth, depth, maxRewrites, isTop) {
|
||||
// Too deeply nested to keep following: treat the rest as literal, the same
|
||||
// way a group that cannot expand is already handled. Truncating rather than
|
||||
// throwing keeps `expand` total, matching `max` and `maxLength`.
|
||||
if (depth > maxDepth) {
|
||||
return [str];
|
||||
}
|
||||
// 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
|
||||
@@ -100492,6 +100575,9 @@ function expand_(str, max, maxLength, isTop) {
|
||||
// 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).
|
||||
// How many times the `{a},b}` rewrite below has restarted the scan. Each pass
|
||||
// re-reads the whole string, so leaving this unbounded is quadratic.
|
||||
let rewrites = 0;
|
||||
let dropEmpties = false;
|
||||
let firstGroup = true;
|
||||
for (;;) {
|
||||
@@ -100516,7 +100602,8 @@ function expand_(str, max, maxLength, isTop) {
|
||||
const isOptions = m.body.indexOf(',') >= 0;
|
||||
if (!isSequence && !isOptions) {
|
||||
// {a},b}
|
||||
if (m.post.match(/,(?!,).*\}/)) {
|
||||
if (rewrites < maxRewrites && m.post.match(/,(?!,).*\}/)) {
|
||||
rewrites++;
|
||||
str = m.pre + '{' + m.body + escClose + m.post;
|
||||
isTop = true;
|
||||
continue;
|
||||
@@ -100536,7 +100623,7 @@ function expand_(str, max, maxLength, isTop) {
|
||||
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, maxLength, false).map(embrace);
|
||||
n = expand_(n[0], max, maxLength, maxDepth, depth + 1, maxRewrites, false).map(embrace);
|
||||
//XXX is this necessary? Can't seem to hit it in tests.
|
||||
/* c8 ignore start */
|
||||
if (n.length === 1) {
|
||||
@@ -100562,12 +100649,13 @@ function expand_(str, max, maxLength, isTop) {
|
||||
values = [];
|
||||
let valuesLength = 0;
|
||||
outer: for (let j = 0; j < n.length; j++) {
|
||||
const expanded = expand_(n[j], max, maxLength, false);
|
||||
const expanded = expand_(n[j], max, maxLength, maxDepth, depth + 1, maxRewrites, 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) {
|
||||
if (values.length >= max ||
|
||||
valuesLength + v.length > maxLength) {
|
||||
break outer;
|
||||
}
|
||||
values.push(v);
|
||||
|
||||
18
package-lock.json
generated
18
package-lock.json
generated
@@ -34,7 +34,7 @@
|
||||
"globals": "^17.7.0",
|
||||
"jest": "^30.4.2",
|
||||
"prettier": "^3.8.4",
|
||||
"ts-jest": "^29.4.13",
|
||||
"ts-jest": "^29.4.11",
|
||||
"typescript": "^6.0.3"
|
||||
},
|
||||
"engines": {
|
||||
@@ -2793,9 +2793,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/brace-expansion": {
|
||||
"version": "5.0.9",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.9.tgz",
|
||||
"integrity": "sha512-ScQ4IuvIEF1TMlP7Zt+vjJ//9zlPb2SDcxWxM3bk8s6t6GGdJ7KO1dCcTidOPJKePW30LE/2cT7wCyPho9/Wxg==",
|
||||
"version": "5.0.12",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.12.tgz",
|
||||
"integrity": "sha512-YovQ3rzhaLMIrDjNDMkNS01tea93qhEhG5xy8f6+R0l+dw3Ki+5sCoIoI942iuLZTHWogWktgwVDhU09iNEimQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"balanced-match": "^4.0.2"
|
||||
@@ -6023,9 +6023,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/ts-jest": {
|
||||
"version": "29.4.13",
|
||||
"resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.4.13.tgz",
|
||||
"integrity": "sha512-rUQG+Ar95cNQf//KvsSjvabLpCTbwk+vKGWkAgiKFugqVwmOpGR7n7xa3S68/AB21Wn0KNhIAVxmxrUsz0L1AQ==",
|
||||
"version": "29.4.11",
|
||||
"resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.4.11.tgz",
|
||||
"integrity": "sha512-IrFl7l9AuB/qrNw5quqvAv/hmKMb8dhWOH4jQOGo0Oq8tCeo1O86/iTFG1FaRimgUkF13l4PcepO8ATFT6Ns4g==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
@@ -6035,7 +6035,7 @@
|
||||
"json5": "^2.2.3",
|
||||
"lodash.memoize": "^4.1.2",
|
||||
"make-error": "^1.3.6",
|
||||
"semver": "^7.8.5",
|
||||
"semver": "^7.8.0",
|
||||
"type-fest": "^4.41.0",
|
||||
"yargs-parser": "^21.1.1"
|
||||
},
|
||||
@@ -6046,7 +6046,7 @@
|
||||
"node": "^14.15.0 || ^16.10.0 || ^18.0.0 || >=20.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@babel/core": ">=7.0.0-beta.0 <9",
|
||||
"@babel/core": ">=7.0.0-beta.0 <8",
|
||||
"@jest/transform": "^29.0.0 || ^30.0.0",
|
||||
"@jest/types": "^29.0.0 || ^30.0.0",
|
||||
"babel-jest": "^29.0.0 || ^30.0.0",
|
||||
|
||||
@@ -57,7 +57,7 @@
|
||||
"globals": "^17.7.0",
|
||||
"jest": "^30.4.2",
|
||||
"prettier": "^3.8.4",
|
||||
"ts-jest": "^29.4.13",
|
||||
"ts-jest": "^29.4.11",
|
||||
"typescript": "^6.0.3"
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user