mirror of
https://github.com/golangci/golangci-lint-action.git
synced 2026-08-18 23:02:29 +00:00
chore: generate
This commit is contained in:
511
dist/post_run/index.js
generated
vendored
511
dist/post_run/index.js
generated
vendored
@@ -24514,20 +24514,6 @@ var escClose = '\0CLOSE'+Math.random()+'\0';
|
|||||||
var escComma = '\0COMMA'+Math.random()+'\0';
|
var escComma = '\0COMMA'+Math.random()+'\0';
|
||||||
var escPeriod = '\0PERIOD'+Math.random()+'\0';
|
var escPeriod = '\0PERIOD'+Math.random()+'\0';
|
||||||
|
|
||||||
var EXPANSION_MAX = 100000
|
|
||||||
|
|
||||||
// `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.
|
|
||||||
var EXPANSION_MAX_LENGTH = 4000000
|
|
||||||
|
|
||||||
function numeric(str) {
|
function numeric(str) {
|
||||||
return parseInt(str, 10) == str
|
return parseInt(str, 10) == str
|
||||||
? parseInt(str, 10)
|
? parseInt(str, 10)
|
||||||
@@ -24586,8 +24572,7 @@ function expandTop(str, options) {
|
|||||||
return [];
|
return [];
|
||||||
|
|
||||||
options = options || {};
|
options = options || {};
|
||||||
var max = options.max == null ? EXPANSION_MAX : options.max;
|
var max = options.max == null ? Infinity : options.max;
|
||||||
var maxLength = options.maxLength == null ? EXPANSION_MAX_LENGTH : options.maxLength;
|
|
||||||
|
|
||||||
// I don't know why Bash 4.3 does this, but it does.
|
// I don't know why Bash 4.3 does this, but it does.
|
||||||
// Anything starting with {} will have the first two bytes preserved
|
// Anything starting with {} will have the first two bytes preserved
|
||||||
@@ -24599,7 +24584,7 @@ function expandTop(str, options) {
|
|||||||
str = '\\{\\}' + str.substr(2);
|
str = '\\{\\}' + str.substr(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
return expand(escapeBraces(str), max, maxLength, true).map(unescapeBraces);
|
return expand(escapeBraces(str), max, true).map(unescapeBraces);
|
||||||
}
|
}
|
||||||
|
|
||||||
function identity(e) {
|
function identity(e) {
|
||||||
@@ -24620,270 +24605,106 @@ function gte(i, y) {
|
|||||||
return i >= y;
|
return i >= y;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build `{ acc[a] + pre + values[v] }` for every combination, capping the
|
function expand(str, max, isTop) {
|
||||||
// number of results at `max` and the total number of characters at `maxLength`.
|
var expansions = [];
|
||||||
// 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
|
var m = balanced('{', '}', str);
|
||||||
// are combined (CVE-2026-14257).
|
if (!m || /\$$/.test(m.pre)) return [str];
|
||||||
//
|
|
||||||
// `base[a]` is the length of the part of `acc[a]` that predates the current
|
var isNumericSequence = /^-?\d+\.\.-?\d+(?:\.\.-?\d+)?$/.test(m.body);
|
||||||
// empty-drop baseline (see `expand`). The matching baselines for the results
|
var isAlphaSequence = /^[a-zA-Z]\.\.[a-zA-Z](?:\.\.-?\d+)?$/.test(m.body);
|
||||||
// are appended to `outBase`, which the caller carries forward alongside them.
|
var isSequence = isNumericSequence || isAlphaSequence;
|
||||||
function combine(
|
var isOptions = m.body.indexOf(',') >= 0;
|
||||||
acc,
|
if (!isSequence && !isOptions) {
|
||||||
base,
|
// {a},b}
|
||||||
pre,
|
if (m.post.match(/,(?!,).*\}/)) {
|
||||||
values,
|
str = m.pre + '{' + m.body + escClose + m.post;
|
||||||
max,
|
return expand(str, max, true);
|
||||||
maxLength,
|
}
|
||||||
dropEmpties,
|
return [str];
|
||||||
outBase
|
}
|
||||||
) {
|
|
||||||
var out = []
|
var n;
|
||||||
var length = 0
|
if (isSequence) {
|
||||||
for (var a = 0; a < acc.length; a++) {
|
n = m.body.split(/\.\./);
|
||||||
for (var v = 0; v < values.length; v++) {
|
} else {
|
||||||
if (out.length >= max) return out
|
n = parseCommaParts(m.body);
|
||||||
var expansion = acc[a] + pre + values[v]
|
if (n.length === 1) {
|
||||||
// Bash drops empty results at the top level. Skip them before they count
|
// x{{a,b}}y ==> x{a}y x{b}y
|
||||||
// against `max`, so `max` bounds the number of *kept* results. "Empty"
|
n = expand(n[0], max, false).map(embrace);
|
||||||
// means "adds nothing past the baseline", not "empty overall".
|
if (n.length === 1) {
|
||||||
if (dropEmpties && expansion.length === base[a]) continue
|
var post = m.post.length
|
||||||
if (length + expansion.length > maxLength) return out
|
? expand(m.post, max, false)
|
||||||
out.push(expansion)
|
: [''];
|
||||||
outBase.push(base[a])
|
return post.map(function(p) {
|
||||||
length += expansion.length
|
return m.pre + n[0] + p;
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return out
|
|
||||||
}
|
|
||||||
|
|
||||||
// The expansion values of a single numeric (`1..5`) or alphabetic (`a..e..2`)
|
// at this point, n is the parts, and we know it's not a comma set
|
||||||
// sequence body.
|
// with a single entry.
|
||||||
function expandSequence(
|
|
||||||
body,
|
|
||||||
isAlphaSequence,
|
|
||||||
max,
|
|
||||||
maxLength
|
|
||||||
) {
|
|
||||||
var n = body.split(/\.\./)
|
|
||||||
var 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 */
|
|
||||||
var x = numeric(n[0])
|
|
||||||
var y = numeric(n[1])
|
|
||||||
var width = Math.max(n[0].length, n[1].length)
|
|
||||||
var incr =
|
|
||||||
n.length === 3 && n[2] !== undefined ?
|
|
||||||
Math.max(Math.abs(numeric(n[2])), 1)
|
|
||||||
: 1
|
|
||||||
var test = lte
|
|
||||||
var reverse = y < x
|
|
||||||
if (reverse) {
|
|
||||||
incr *= -1
|
|
||||||
test = gte
|
|
||||||
}
|
|
||||||
var pad = n.some(isPadded)
|
|
||||||
|
|
||||||
var length = 0
|
// no need to expand pre, since it is guaranteed to be free of brace-sets
|
||||||
for (var i = x; test(i, y) && N.length < max; i += incr) {
|
var pre = m.pre;
|
||||||
var c
|
var post = m.post.length
|
||||||
if (isAlphaSequence) {
|
? expand(m.post, max, false)
|
||||||
c = String.fromCharCode(i)
|
: [''];
|
||||||
if (c === '\\') {
|
|
||||||
c = ''
|
var N;
|
||||||
}
|
|
||||||
} else {
|
if (isSequence) {
|
||||||
c = String(i)
|
var x = numeric(n[0]);
|
||||||
if (pad) {
|
var y = numeric(n[1]);
|
||||||
var need = width - c.length
|
var width = Math.max(n[0].length, n[1].length)
|
||||||
if (need > 0) {
|
var incr = n.length == 3
|
||||||
var z = new Array(need + 1).join('0')
|
? Math.max(Math.abs(numeric(n[2])), 1)
|
||||||
if (i < 0) {
|
: 1;
|
||||||
c = '-' + z + c.slice(1)
|
var test = lte;
|
||||||
} else {
|
var reverse = y < x;
|
||||||
c = z + c
|
if (reverse) {
|
||||||
|
incr *= -1;
|
||||||
|
test = gte;
|
||||||
|
}
|
||||||
|
var pad = n.some(isPadded);
|
||||||
|
|
||||||
|
N = [];
|
||||||
|
|
||||||
|
for (var i = x; test(i, y); i += incr) {
|
||||||
|
var c;
|
||||||
|
if (isAlphaSequence) {
|
||||||
|
c = String.fromCharCode(i);
|
||||||
|
if (c === '\\')
|
||||||
|
c = '';
|
||||||
|
} else {
|
||||||
|
c = String(i);
|
||||||
|
if (pad) {
|
||||||
|
var need = width - c.length;
|
||||||
|
if (need > 0) {
|
||||||
|
var z = new Array(need + 1).join('0');
|
||||||
|
if (i < 0)
|
||||||
|
c = '-' + z + c.slice(1);
|
||||||
|
else
|
||||||
|
c = z + c;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
N.push(c);
|
||||||
}
|
}
|
||||||
if (length + c.length > maxLength) break
|
} else {
|
||||||
N.push(c)
|
N = concatMap(n, function(el) { return expand(el, max, false) });
|
||||||
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).
|
|
||||||
var acc = ['']
|
|
||||||
|
|
||||||
// Bash drops empty results, but only when the *first* group of the run 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).
|
|
||||||
//
|
|
||||||
// The old implementation recursed on `m.post`, so the drop tested only the
|
|
||||||
// expansion of the current call's substring. The `{a},b}` rewrite below turns
|
|
||||||
// `isTop` back on part-way through a string, starting a fresh such run, so
|
|
||||||
// the drop must ignore whatever `acc` already holds from earlier groups.
|
|
||||||
// `accBase[a]` records how much of `acc[a]` predates the current run;
|
|
||||||
// `combine` treats an expansion as empty when it adds nothing past that.
|
|
||||||
var accBase = [0]
|
|
||||||
var dropEmpties = false
|
|
||||||
var firstGroup = true
|
|
||||||
var nextBase
|
|
||||||
|
|
||||||
for (;;) {
|
|
||||||
var m = balanced('{', '}', str);
|
|
||||||
|
|
||||||
// No brace set left: the rest of the string is literal.
|
|
||||||
if (!m) {
|
|
||||||
return combine(acc, accBase, str, [''], max, maxLength, dropEmpties, [])
|
|
||||||
}
|
|
||||||
|
|
||||||
// no need to expand pre, since it is guaranteed to be free of brace-sets
|
|
||||||
var pre = m.pre;
|
|
||||||
|
|
||||||
// For compatibility reasons, `${` is not eligible for brace expansion, and
|
|
||||||
// on the 1.x line it suppresses expansion of the rest of the string too:
|
|
||||||
// the whole remainder is literal. The 2.x and 5.x lines instead keep
|
|
||||||
// expanding the tail, which is what bash does, but changing that here would
|
|
||||||
// be a breaking change for 1.x consumers. Routed through `combine` so the
|
|
||||||
// result is still bounded by `max` and `maxLength`.
|
|
||||||
if (/\$$/.test(pre)) {
|
|
||||||
return combine(acc, accBase, str, [''], max, maxLength, dropEmpties, [])
|
|
||||||
}
|
|
||||||
|
|
||||||
var isNumericSequence = /^-?\d+\.\.-?\d+(?:\.\.-?\d+)?$/.test(m.body);
|
|
||||||
var isAlphaSequence = /^[a-zA-Z]\.\.[a-zA-Z](?:\.\.-?\d+)?$/.test(m.body);
|
|
||||||
var isSequence = isNumericSequence || isAlphaSequence;
|
|
||||||
var isOptions = m.body.indexOf(',') >= 0;
|
|
||||||
if (!isSequence && !isOptions) {
|
|
||||||
// {a},b}
|
|
||||||
if (m.post.match(/,(?!,).*\}/)) {
|
|
||||||
str = m.pre + '{' + m.body + escClose + m.post;
|
|
||||||
// The rewritten string is expanded as if it were a fresh top-level one,
|
|
||||||
// so start a new empty-drop run: anchor the baseline at what `acc`
|
|
||||||
// holds now, and let the next expanding group decide whether to drop.
|
|
||||||
isTop = true
|
|
||||||
firstGroup = true
|
|
||||||
dropEmpties = false
|
|
||||||
accBase = []
|
|
||||||
for (var b = 0; b < acc.length; b++) {
|
|
||||||
accBase.push(acc[b].length)
|
|
||||||
}
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
// Nothing here expands, so the whole remaining string is literal.
|
|
||||||
return combine(
|
|
||||||
acc,
|
|
||||||
accBase,
|
|
||||||
pre + '{' + m.body + '}' + m.post,
|
|
||||||
[''],
|
|
||||||
max,
|
|
||||||
maxLength,
|
|
||||||
dropEmpties,
|
|
||||||
[]
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (firstGroup) {
|
|
||||||
dropEmpties = isTop && !isSequence
|
|
||||||
firstGroup = false
|
|
||||||
}
|
|
||||||
|
|
||||||
var values;
|
|
||||||
if (isSequence) {
|
|
||||||
values = expandSequence(m.body, isAlphaSequence, max, maxLength);
|
|
||||||
} else {
|
|
||||||
var 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);
|
|
||||||
//XXX is this necessary? Can't seem to hit it in tests.
|
|
||||||
/* c8 ignore start */
|
|
||||||
if (n.length === 1) {
|
|
||||||
nextBase = []
|
|
||||||
acc = combine(
|
|
||||||
acc,
|
|
||||||
accBase,
|
|
||||||
pre + n[0],
|
|
||||||
[''],
|
|
||||||
max,
|
|
||||||
maxLength,
|
|
||||||
dropEmpties && !m.post.length,
|
|
||||||
nextBase
|
|
||||||
)
|
|
||||||
accBase = nextBase
|
|
||||||
if (!m.post.length) break
|
|
||||||
str = m.post
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
/* c8 ignore stop */
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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. A value is dropped when it adds nothing past the
|
|
||||||
// baseline, which is what `combine` tests.
|
|
||||||
var dropsEmpties = dropEmpties && !m.post.length && !pre
|
|
||||||
for (var d = 0; dropsEmpties && d < acc.length; d++) {
|
|
||||||
if (acc[d].length !== accBase[d]) {
|
|
||||||
dropsEmpties = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
values = []
|
|
||||||
var valuesLength = 0
|
|
||||||
outer: for (var j = 0; j < n.length; j++) {
|
|
||||||
var expanded = expand(n[j], max, maxLength, false)
|
|
||||||
for (var k = 0; k < expanded.length; k++) {
|
|
||||||
var v = expanded[k]
|
|
||||||
if (dropsEmpties && !v) continue
|
|
||||||
if (values.length >= max || valuesLength + v.length > maxLength) {
|
|
||||||
break outer
|
|
||||||
}
|
|
||||||
values.push(v)
|
|
||||||
valuesLength += v.length
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
nextBase = []
|
|
||||||
acc = combine(
|
|
||||||
acc,
|
|
||||||
accBase,
|
|
||||||
pre,
|
|
||||||
values,
|
|
||||||
max,
|
|
||||||
maxLength,
|
|
||||||
dropEmpties && !m.post.length,
|
|
||||||
nextBase
|
|
||||||
)
|
|
||||||
accBase = nextBase
|
|
||||||
if (!m.post.length) break
|
|
||||||
str = m.post
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return acc
|
for (var j = 0; j < N.length; j++) {
|
||||||
|
for (var k = 0; k < post.length && expansions.length < max; k++) {
|
||||||
|
var expansion = pre + N[j] + post[k];
|
||||||
|
if (!isTop || isSequence || expansion)
|
||||||
|
expansions.push(expansion);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return expansions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -33971,7 +33792,13 @@ function processHeader (request, key, val) {
|
|||||||
} else if (typeof val[i] === 'object') {
|
} else if (typeof val[i] === 'object') {
|
||||||
throw new InvalidArgumentError(`invalid ${key} header`)
|
throw new InvalidArgumentError(`invalid ${key} header`)
|
||||||
} else {
|
} 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
|
val = arr
|
||||||
@@ -33982,7 +33809,12 @@ function processHeader (request, key, val) {
|
|||||||
} else if (val === null) {
|
} else if (val === null) {
|
||||||
val = ''
|
val = ''
|
||||||
} else {
|
} else {
|
||||||
|
// Coerce primitives (and reject unsafe coercions such as functions
|
||||||
|
// with a crafted toString/Symbol.toPrimitive).
|
||||||
val = `${val}`
|
val = `${val}`
|
||||||
|
if (!isValidHeaderValue(val)) {
|
||||||
|
throw new InvalidArgumentError(`invalid ${key} header`)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (headerName === 'host') {
|
if (headerName === 'host') {
|
||||||
@@ -35359,6 +35191,7 @@ const {
|
|||||||
RequestContentLengthMismatchError,
|
RequestContentLengthMismatchError,
|
||||||
ResponseContentLengthMismatchError,
|
ResponseContentLengthMismatchError,
|
||||||
RequestAbortedError,
|
RequestAbortedError,
|
||||||
|
InvalidArgumentError,
|
||||||
HeadersTimeoutError,
|
HeadersTimeoutError,
|
||||||
HeadersOverflowError,
|
HeadersOverflowError,
|
||||||
SocketError,
|
SocketError,
|
||||||
@@ -36342,8 +36175,16 @@ function writeH1 (client, request) {
|
|||||||
}
|
}
|
||||||
body = bodyStream.stream
|
body = bodyStream.stream
|
||||||
contentLength = bodyStream.length
|
contentLength = bodyStream.length
|
||||||
} else if (util.isBlobLike(body) && request.contentType == null && body.type) {
|
} else if (util.isBlobLike(body) && request.contentType == null) {
|
||||||
headers.push('content-type', body.type)
|
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') {
|
if (body && typeof body.read === 'function') {
|
||||||
@@ -39830,6 +39671,28 @@ function calculateRetryAfterHeader (retryAfter) {
|
|||||||
return new Date(retryAfter).getTime() - current
|
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 {
|
class RetryHandler {
|
||||||
constructor (opts, handlers) {
|
constructor (opts, handlers) {
|
||||||
const { retryOptions, ...dispatchOpts } = opts
|
const { retryOptions, ...dispatchOpts } = opts
|
||||||
@@ -40044,6 +39907,12 @@ class RetryHandler {
|
|||||||
return false
|
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
|
const { start, size, end = size - 1 } = contentRange
|
||||||
|
|
||||||
assert(this.start === start, 'content-range mismatch')
|
assert(this.start === start, 'content-range mismatch')
|
||||||
@@ -40067,6 +39936,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
|
const { start, size, end = size - 1 } = range
|
||||||
assert(
|
assert(
|
||||||
start != null && Number.isFinite(start),
|
start != null && Number.isFinite(start),
|
||||||
@@ -44338,7 +44213,7 @@ function validateCookiePath (path) {
|
|||||||
|
|
||||||
if (
|
if (
|
||||||
code < 0x20 || // exclude CTLs (0-31)
|
code < 0x20 || // exclude CTLs (0-31)
|
||||||
code === 0x7F || // DEL
|
code > 0x7E || // exclude DEL and non-ascii
|
||||||
code === 0x3B // ;
|
code === 0x3B // ;
|
||||||
) {
|
) {
|
||||||
throw new Error('Invalid cookie path')
|
throw new Error('Invalid cookie path')
|
||||||
@@ -44347,16 +44222,80 @@ function validateCookiePath (path) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* I have no idea why these values aren't allowed to be honest,
|
* <let-dig> ::= <letter> | <digit>
|
||||||
* but Deno tests these. - Khafra
|
*
|
||||||
|
* <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
|
* @param {string} domain
|
||||||
*/
|
*/
|
||||||
function validateCookieDomain (domain) {
|
function validateCookieDomain (domain) {
|
||||||
if (
|
// <domain> ::= <subdomain> | " "
|
||||||
domain.startsWith('-') ||
|
if (domain === ' ') {
|
||||||
domain.endsWith('.') ||
|
return
|
||||||
domain.endsWith('-')
|
}
|
||||||
) {
|
|
||||||
|
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')
|
throw new Error('Invalid cookie domain')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -44499,7 +44438,13 @@ function stringify (cookie) {
|
|||||||
|
|
||||||
const [key, ...value] = part.split('=')
|
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('; ')
|
return out.join('; ')
|
||||||
|
|||||||
511
dist/run/index.js
generated
vendored
511
dist/run/index.js
generated
vendored
@@ -24514,20 +24514,6 @@ var escClose = '\0CLOSE'+Math.random()+'\0';
|
|||||||
var escComma = '\0COMMA'+Math.random()+'\0';
|
var escComma = '\0COMMA'+Math.random()+'\0';
|
||||||
var escPeriod = '\0PERIOD'+Math.random()+'\0';
|
var escPeriod = '\0PERIOD'+Math.random()+'\0';
|
||||||
|
|
||||||
var EXPANSION_MAX = 100000
|
|
||||||
|
|
||||||
// `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.
|
|
||||||
var EXPANSION_MAX_LENGTH = 4000000
|
|
||||||
|
|
||||||
function numeric(str) {
|
function numeric(str) {
|
||||||
return parseInt(str, 10) == str
|
return parseInt(str, 10) == str
|
||||||
? parseInt(str, 10)
|
? parseInt(str, 10)
|
||||||
@@ -24586,8 +24572,7 @@ function expandTop(str, options) {
|
|||||||
return [];
|
return [];
|
||||||
|
|
||||||
options = options || {};
|
options = options || {};
|
||||||
var max = options.max == null ? EXPANSION_MAX : options.max;
|
var max = options.max == null ? Infinity : options.max;
|
||||||
var maxLength = options.maxLength == null ? EXPANSION_MAX_LENGTH : options.maxLength;
|
|
||||||
|
|
||||||
// I don't know why Bash 4.3 does this, but it does.
|
// I don't know why Bash 4.3 does this, but it does.
|
||||||
// Anything starting with {} will have the first two bytes preserved
|
// Anything starting with {} will have the first two bytes preserved
|
||||||
@@ -24599,7 +24584,7 @@ function expandTop(str, options) {
|
|||||||
str = '\\{\\}' + str.substr(2);
|
str = '\\{\\}' + str.substr(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
return expand(escapeBraces(str), max, maxLength, true).map(unescapeBraces);
|
return expand(escapeBraces(str), max, true).map(unescapeBraces);
|
||||||
}
|
}
|
||||||
|
|
||||||
function identity(e) {
|
function identity(e) {
|
||||||
@@ -24620,270 +24605,106 @@ function gte(i, y) {
|
|||||||
return i >= y;
|
return i >= y;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build `{ acc[a] + pre + values[v] }` for every combination, capping the
|
function expand(str, max, isTop) {
|
||||||
// number of results at `max` and the total number of characters at `maxLength`.
|
var expansions = [];
|
||||||
// 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
|
var m = balanced('{', '}', str);
|
||||||
// are combined (CVE-2026-14257).
|
if (!m || /\$$/.test(m.pre)) return [str];
|
||||||
//
|
|
||||||
// `base[a]` is the length of the part of `acc[a]` that predates the current
|
var isNumericSequence = /^-?\d+\.\.-?\d+(?:\.\.-?\d+)?$/.test(m.body);
|
||||||
// empty-drop baseline (see `expand`). The matching baselines for the results
|
var isAlphaSequence = /^[a-zA-Z]\.\.[a-zA-Z](?:\.\.-?\d+)?$/.test(m.body);
|
||||||
// are appended to `outBase`, which the caller carries forward alongside them.
|
var isSequence = isNumericSequence || isAlphaSequence;
|
||||||
function combine(
|
var isOptions = m.body.indexOf(',') >= 0;
|
||||||
acc,
|
if (!isSequence && !isOptions) {
|
||||||
base,
|
// {a},b}
|
||||||
pre,
|
if (m.post.match(/,(?!,).*\}/)) {
|
||||||
values,
|
str = m.pre + '{' + m.body + escClose + m.post;
|
||||||
max,
|
return expand(str, max, true);
|
||||||
maxLength,
|
}
|
||||||
dropEmpties,
|
return [str];
|
||||||
outBase
|
}
|
||||||
) {
|
|
||||||
var out = []
|
var n;
|
||||||
var length = 0
|
if (isSequence) {
|
||||||
for (var a = 0; a < acc.length; a++) {
|
n = m.body.split(/\.\./);
|
||||||
for (var v = 0; v < values.length; v++) {
|
} else {
|
||||||
if (out.length >= max) return out
|
n = parseCommaParts(m.body);
|
||||||
var expansion = acc[a] + pre + values[v]
|
if (n.length === 1) {
|
||||||
// Bash drops empty results at the top level. Skip them before they count
|
// x{{a,b}}y ==> x{a}y x{b}y
|
||||||
// against `max`, so `max` bounds the number of *kept* results. "Empty"
|
n = expand(n[0], max, false).map(embrace);
|
||||||
// means "adds nothing past the baseline", not "empty overall".
|
if (n.length === 1) {
|
||||||
if (dropEmpties && expansion.length === base[a]) continue
|
var post = m.post.length
|
||||||
if (length + expansion.length > maxLength) return out
|
? expand(m.post, max, false)
|
||||||
out.push(expansion)
|
: [''];
|
||||||
outBase.push(base[a])
|
return post.map(function(p) {
|
||||||
length += expansion.length
|
return m.pre + n[0] + p;
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return out
|
|
||||||
}
|
|
||||||
|
|
||||||
// The expansion values of a single numeric (`1..5`) or alphabetic (`a..e..2`)
|
// at this point, n is the parts, and we know it's not a comma set
|
||||||
// sequence body.
|
// with a single entry.
|
||||||
function expandSequence(
|
|
||||||
body,
|
|
||||||
isAlphaSequence,
|
|
||||||
max,
|
|
||||||
maxLength
|
|
||||||
) {
|
|
||||||
var n = body.split(/\.\./)
|
|
||||||
var 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 */
|
|
||||||
var x = numeric(n[0])
|
|
||||||
var y = numeric(n[1])
|
|
||||||
var width = Math.max(n[0].length, n[1].length)
|
|
||||||
var incr =
|
|
||||||
n.length === 3 && n[2] !== undefined ?
|
|
||||||
Math.max(Math.abs(numeric(n[2])), 1)
|
|
||||||
: 1
|
|
||||||
var test = lte
|
|
||||||
var reverse = y < x
|
|
||||||
if (reverse) {
|
|
||||||
incr *= -1
|
|
||||||
test = gte
|
|
||||||
}
|
|
||||||
var pad = n.some(isPadded)
|
|
||||||
|
|
||||||
var length = 0
|
// no need to expand pre, since it is guaranteed to be free of brace-sets
|
||||||
for (var i = x; test(i, y) && N.length < max; i += incr) {
|
var pre = m.pre;
|
||||||
var c
|
var post = m.post.length
|
||||||
if (isAlphaSequence) {
|
? expand(m.post, max, false)
|
||||||
c = String.fromCharCode(i)
|
: [''];
|
||||||
if (c === '\\') {
|
|
||||||
c = ''
|
var N;
|
||||||
}
|
|
||||||
} else {
|
if (isSequence) {
|
||||||
c = String(i)
|
var x = numeric(n[0]);
|
||||||
if (pad) {
|
var y = numeric(n[1]);
|
||||||
var need = width - c.length
|
var width = Math.max(n[0].length, n[1].length)
|
||||||
if (need > 0) {
|
var incr = n.length == 3
|
||||||
var z = new Array(need + 1).join('0')
|
? Math.max(Math.abs(numeric(n[2])), 1)
|
||||||
if (i < 0) {
|
: 1;
|
||||||
c = '-' + z + c.slice(1)
|
var test = lte;
|
||||||
} else {
|
var reverse = y < x;
|
||||||
c = z + c
|
if (reverse) {
|
||||||
|
incr *= -1;
|
||||||
|
test = gte;
|
||||||
|
}
|
||||||
|
var pad = n.some(isPadded);
|
||||||
|
|
||||||
|
N = [];
|
||||||
|
|
||||||
|
for (var i = x; test(i, y); i += incr) {
|
||||||
|
var c;
|
||||||
|
if (isAlphaSequence) {
|
||||||
|
c = String.fromCharCode(i);
|
||||||
|
if (c === '\\')
|
||||||
|
c = '';
|
||||||
|
} else {
|
||||||
|
c = String(i);
|
||||||
|
if (pad) {
|
||||||
|
var need = width - c.length;
|
||||||
|
if (need > 0) {
|
||||||
|
var z = new Array(need + 1).join('0');
|
||||||
|
if (i < 0)
|
||||||
|
c = '-' + z + c.slice(1);
|
||||||
|
else
|
||||||
|
c = z + c;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
N.push(c);
|
||||||
}
|
}
|
||||||
if (length + c.length > maxLength) break
|
} else {
|
||||||
N.push(c)
|
N = concatMap(n, function(el) { return expand(el, max, false) });
|
||||||
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).
|
|
||||||
var acc = ['']
|
|
||||||
|
|
||||||
// Bash drops empty results, but only when the *first* group of the run 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).
|
|
||||||
//
|
|
||||||
// The old implementation recursed on `m.post`, so the drop tested only the
|
|
||||||
// expansion of the current call's substring. The `{a},b}` rewrite below turns
|
|
||||||
// `isTop` back on part-way through a string, starting a fresh such run, so
|
|
||||||
// the drop must ignore whatever `acc` already holds from earlier groups.
|
|
||||||
// `accBase[a]` records how much of `acc[a]` predates the current run;
|
|
||||||
// `combine` treats an expansion as empty when it adds nothing past that.
|
|
||||||
var accBase = [0]
|
|
||||||
var dropEmpties = false
|
|
||||||
var firstGroup = true
|
|
||||||
var nextBase
|
|
||||||
|
|
||||||
for (;;) {
|
|
||||||
var m = balanced('{', '}', str);
|
|
||||||
|
|
||||||
// No brace set left: the rest of the string is literal.
|
|
||||||
if (!m) {
|
|
||||||
return combine(acc, accBase, str, [''], max, maxLength, dropEmpties, [])
|
|
||||||
}
|
|
||||||
|
|
||||||
// no need to expand pre, since it is guaranteed to be free of brace-sets
|
|
||||||
var pre = m.pre;
|
|
||||||
|
|
||||||
// For compatibility reasons, `${` is not eligible for brace expansion, and
|
|
||||||
// on the 1.x line it suppresses expansion of the rest of the string too:
|
|
||||||
// the whole remainder is literal. The 2.x and 5.x lines instead keep
|
|
||||||
// expanding the tail, which is what bash does, but changing that here would
|
|
||||||
// be a breaking change for 1.x consumers. Routed through `combine` so the
|
|
||||||
// result is still bounded by `max` and `maxLength`.
|
|
||||||
if (/\$$/.test(pre)) {
|
|
||||||
return combine(acc, accBase, str, [''], max, maxLength, dropEmpties, [])
|
|
||||||
}
|
|
||||||
|
|
||||||
var isNumericSequence = /^-?\d+\.\.-?\d+(?:\.\.-?\d+)?$/.test(m.body);
|
|
||||||
var isAlphaSequence = /^[a-zA-Z]\.\.[a-zA-Z](?:\.\.-?\d+)?$/.test(m.body);
|
|
||||||
var isSequence = isNumericSequence || isAlphaSequence;
|
|
||||||
var isOptions = m.body.indexOf(',') >= 0;
|
|
||||||
if (!isSequence && !isOptions) {
|
|
||||||
// {a},b}
|
|
||||||
if (m.post.match(/,(?!,).*\}/)) {
|
|
||||||
str = m.pre + '{' + m.body + escClose + m.post;
|
|
||||||
// The rewritten string is expanded as if it were a fresh top-level one,
|
|
||||||
// so start a new empty-drop run: anchor the baseline at what `acc`
|
|
||||||
// holds now, and let the next expanding group decide whether to drop.
|
|
||||||
isTop = true
|
|
||||||
firstGroup = true
|
|
||||||
dropEmpties = false
|
|
||||||
accBase = []
|
|
||||||
for (var b = 0; b < acc.length; b++) {
|
|
||||||
accBase.push(acc[b].length)
|
|
||||||
}
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
// Nothing here expands, so the whole remaining string is literal.
|
|
||||||
return combine(
|
|
||||||
acc,
|
|
||||||
accBase,
|
|
||||||
pre + '{' + m.body + '}' + m.post,
|
|
||||||
[''],
|
|
||||||
max,
|
|
||||||
maxLength,
|
|
||||||
dropEmpties,
|
|
||||||
[]
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (firstGroup) {
|
|
||||||
dropEmpties = isTop && !isSequence
|
|
||||||
firstGroup = false
|
|
||||||
}
|
|
||||||
|
|
||||||
var values;
|
|
||||||
if (isSequence) {
|
|
||||||
values = expandSequence(m.body, isAlphaSequence, max, maxLength);
|
|
||||||
} else {
|
|
||||||
var 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);
|
|
||||||
//XXX is this necessary? Can't seem to hit it in tests.
|
|
||||||
/* c8 ignore start */
|
|
||||||
if (n.length === 1) {
|
|
||||||
nextBase = []
|
|
||||||
acc = combine(
|
|
||||||
acc,
|
|
||||||
accBase,
|
|
||||||
pre + n[0],
|
|
||||||
[''],
|
|
||||||
max,
|
|
||||||
maxLength,
|
|
||||||
dropEmpties && !m.post.length,
|
|
||||||
nextBase
|
|
||||||
)
|
|
||||||
accBase = nextBase
|
|
||||||
if (!m.post.length) break
|
|
||||||
str = m.post
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
/* c8 ignore stop */
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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. A value is dropped when it adds nothing past the
|
|
||||||
// baseline, which is what `combine` tests.
|
|
||||||
var dropsEmpties = dropEmpties && !m.post.length && !pre
|
|
||||||
for (var d = 0; dropsEmpties && d < acc.length; d++) {
|
|
||||||
if (acc[d].length !== accBase[d]) {
|
|
||||||
dropsEmpties = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
values = []
|
|
||||||
var valuesLength = 0
|
|
||||||
outer: for (var j = 0; j < n.length; j++) {
|
|
||||||
var expanded = expand(n[j], max, maxLength, false)
|
|
||||||
for (var k = 0; k < expanded.length; k++) {
|
|
||||||
var v = expanded[k]
|
|
||||||
if (dropsEmpties && !v) continue
|
|
||||||
if (values.length >= max || valuesLength + v.length > maxLength) {
|
|
||||||
break outer
|
|
||||||
}
|
|
||||||
values.push(v)
|
|
||||||
valuesLength += v.length
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
nextBase = []
|
|
||||||
acc = combine(
|
|
||||||
acc,
|
|
||||||
accBase,
|
|
||||||
pre,
|
|
||||||
values,
|
|
||||||
max,
|
|
||||||
maxLength,
|
|
||||||
dropEmpties && !m.post.length,
|
|
||||||
nextBase
|
|
||||||
)
|
|
||||||
accBase = nextBase
|
|
||||||
if (!m.post.length) break
|
|
||||||
str = m.post
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return acc
|
for (var j = 0; j < N.length; j++) {
|
||||||
|
for (var k = 0; k < post.length && expansions.length < max; k++) {
|
||||||
|
var expansion = pre + N[j] + post[k];
|
||||||
|
if (!isTop || isSequence || expansion)
|
||||||
|
expansions.push(expansion);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return expansions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -33971,7 +33792,13 @@ function processHeader (request, key, val) {
|
|||||||
} else if (typeof val[i] === 'object') {
|
} else if (typeof val[i] === 'object') {
|
||||||
throw new InvalidArgumentError(`invalid ${key} header`)
|
throw new InvalidArgumentError(`invalid ${key} header`)
|
||||||
} else {
|
} 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
|
val = arr
|
||||||
@@ -33982,7 +33809,12 @@ function processHeader (request, key, val) {
|
|||||||
} else if (val === null) {
|
} else if (val === null) {
|
||||||
val = ''
|
val = ''
|
||||||
} else {
|
} else {
|
||||||
|
// Coerce primitives (and reject unsafe coercions such as functions
|
||||||
|
// with a crafted toString/Symbol.toPrimitive).
|
||||||
val = `${val}`
|
val = `${val}`
|
||||||
|
if (!isValidHeaderValue(val)) {
|
||||||
|
throw new InvalidArgumentError(`invalid ${key} header`)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (headerName === 'host') {
|
if (headerName === 'host') {
|
||||||
@@ -35359,6 +35191,7 @@ const {
|
|||||||
RequestContentLengthMismatchError,
|
RequestContentLengthMismatchError,
|
||||||
ResponseContentLengthMismatchError,
|
ResponseContentLengthMismatchError,
|
||||||
RequestAbortedError,
|
RequestAbortedError,
|
||||||
|
InvalidArgumentError,
|
||||||
HeadersTimeoutError,
|
HeadersTimeoutError,
|
||||||
HeadersOverflowError,
|
HeadersOverflowError,
|
||||||
SocketError,
|
SocketError,
|
||||||
@@ -36342,8 +36175,16 @@ function writeH1 (client, request) {
|
|||||||
}
|
}
|
||||||
body = bodyStream.stream
|
body = bodyStream.stream
|
||||||
contentLength = bodyStream.length
|
contentLength = bodyStream.length
|
||||||
} else if (util.isBlobLike(body) && request.contentType == null && body.type) {
|
} else if (util.isBlobLike(body) && request.contentType == null) {
|
||||||
headers.push('content-type', body.type)
|
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') {
|
if (body && typeof body.read === 'function') {
|
||||||
@@ -39830,6 +39671,28 @@ function calculateRetryAfterHeader (retryAfter) {
|
|||||||
return new Date(retryAfter).getTime() - current
|
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 {
|
class RetryHandler {
|
||||||
constructor (opts, handlers) {
|
constructor (opts, handlers) {
|
||||||
const { retryOptions, ...dispatchOpts } = opts
|
const { retryOptions, ...dispatchOpts } = opts
|
||||||
@@ -40044,6 +39907,12 @@ class RetryHandler {
|
|||||||
return false
|
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
|
const { start, size, end = size - 1 } = contentRange
|
||||||
|
|
||||||
assert(this.start === start, 'content-range mismatch')
|
assert(this.start === start, 'content-range mismatch')
|
||||||
@@ -40067,6 +39936,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
|
const { start, size, end = size - 1 } = range
|
||||||
assert(
|
assert(
|
||||||
start != null && Number.isFinite(start),
|
start != null && Number.isFinite(start),
|
||||||
@@ -44338,7 +44213,7 @@ function validateCookiePath (path) {
|
|||||||
|
|
||||||
if (
|
if (
|
||||||
code < 0x20 || // exclude CTLs (0-31)
|
code < 0x20 || // exclude CTLs (0-31)
|
||||||
code === 0x7F || // DEL
|
code > 0x7E || // exclude DEL and non-ascii
|
||||||
code === 0x3B // ;
|
code === 0x3B // ;
|
||||||
) {
|
) {
|
||||||
throw new Error('Invalid cookie path')
|
throw new Error('Invalid cookie path')
|
||||||
@@ -44347,16 +44222,80 @@ function validateCookiePath (path) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* I have no idea why these values aren't allowed to be honest,
|
* <let-dig> ::= <letter> | <digit>
|
||||||
* but Deno tests these. - Khafra
|
*
|
||||||
|
* <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
|
* @param {string} domain
|
||||||
*/
|
*/
|
||||||
function validateCookieDomain (domain) {
|
function validateCookieDomain (domain) {
|
||||||
if (
|
// <domain> ::= <subdomain> | " "
|
||||||
domain.startsWith('-') ||
|
if (domain === ' ') {
|
||||||
domain.endsWith('.') ||
|
return
|
||||||
domain.endsWith('-')
|
}
|
||||||
) {
|
|
||||||
|
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')
|
throw new Error('Invalid cookie domain')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -44499,7 +44438,13 @@ function stringify (cookie) {
|
|||||||
|
|
||||||
const [key, ...value] = part.split('=')
|
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('; ')
|
return out.join('; ')
|
||||||
|
|||||||
Reference in New Issue
Block a user