Skip to content

Commit 9191ea1

Browse files
fix: resolve npm audit high severity vulnerabilities (actions#1350)
Bumps transitive dependencies to patched versions: - brace-expansion 5.0.8 -> 5.0.9 (GHSA-rgw5-rvv9-x895) - js-yaml 3.15.0 -> 3.15.1 (GHSA-5p4m-2wfm-xmqj) - undici 6.27.0 -> 6.28.0 (GHSA-8xcm-r25x-g524, GHSA-m8rv-5g2x-5cg5, GHSA-v3r7-h72x-cjcm) Refreshes .licenses/ cache for the updated packages and rebuilds dist/. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 8549b9f commit 9191ea1

5 files changed

Lines changed: 373 additions & 47 deletions

File tree

‎.licenses/npm/brace-expansion.dep.yml‎

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎.licenses/npm/undici.dep.yml‎

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎dist/cache-save/index.js‎

Lines changed: 166 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -16069,7 +16069,13 @@ function processHeader (request, key, val) {
1606916069
} else if (typeof val[i] === 'object') {
1607016070
throw new InvalidArgumentError(`invalid ${key} header`)
1607116071
} else {
16072-
arr.push(`${val[i]}`)
16072+
// Coerce primitives (and reject unsafe coercions such as functions
16073+
// with a crafted toString/Symbol.toPrimitive).
16074+
const str = `${val[i]}`
16075+
if (!isValidHeaderValue(str)) {
16076+
throw new InvalidArgumentError(`invalid ${key} header`)
16077+
}
16078+
arr.push(str)
1607316079
}
1607416080
}
1607516081
val = arr
@@ -16080,7 +16086,12 @@ function processHeader (request, key, val) {
1608016086
} else if (val === null) {
1608116087
val = ''
1608216088
} else {
16089+
// Coerce primitives (and reject unsafe coercions such as functions
16090+
// with a crafted toString/Symbol.toPrimitive).
1608316091
val = `${val}`
16092+
if (!isValidHeaderValue(val)) {
16093+
throw new InvalidArgumentError(`invalid ${key} header`)
16094+
}
1608416095
}
1608516096

1608616097
if (headerName === 'host') {
@@ -17452,6 +17463,7 @@ const {
1745217463
RequestContentLengthMismatchError,
1745317464
ResponseContentLengthMismatchError,
1745417465
RequestAbortedError,
17466+
InvalidArgumentError,
1745517467
HeadersTimeoutError,
1745617468
HeadersOverflowError,
1745717469
SocketError,
@@ -18435,8 +18447,16 @@ function writeH1 (client, request) {
1843518447
}
1843618448
body = bodyStream.stream
1843718449
contentLength = bodyStream.length
18438-
} else if (util.isBlobLike(body) && request.contentType == null && body.type) {
18439-
headers.push('content-type', body.type)
18450+
} else if (util.isBlobLike(body) && request.contentType == null) {
18451+
const contentType = body.type
18452+
if (contentType) {
18453+
const contentTypeValue = `${contentType}`
18454+
if (!util.isValidHeaderValue(contentTypeValue)) {
18455+
util.errorRequest(client, request, new InvalidArgumentError('invalid content-type header'))
18456+
return false
18457+
}
18458+
headers.push('content-type', contentTypeValue)
18459+
}
1844018460
}
1844118461

1844218462
if (body && typeof body.read === 'function') {
@@ -21909,6 +21929,28 @@ function calculateRetryAfterHeader (retryAfter) {
2190921929
return new Date(retryAfter).getTime() - current
2191021930
}
2191121931

21932+
function validatePartialResponseContentLength (headers, range, statusCode, retryCount) {
21933+
const contentLength = headers['content-length']
21934+
if (contentLength == null) {
21935+
return null
21936+
}
21937+
21938+
if (!Number.isFinite(range.start) || !Number.isFinite(range.end)) {
21939+
return null
21940+
}
21941+
21942+
const length = Number(contentLength)
21943+
const expectedLength = range.end - range.start + 1
21944+
if (!Number.isFinite(length) || length !== expectedLength) {
21945+
return new RequestRetryError('Content-Length mismatch', statusCode, {
21946+
headers,
21947+
data: { count: retryCount }
21948+
})
21949+
}
21950+
21951+
return null
21952+
}
21953+
2191221954
class RetryHandler {
2191321955
constructor (opts, handlers) {
2191421956
const { retryOptions, ...dispatchOpts } = opts
@@ -22123,6 +22165,12 @@ class RetryHandler {
2212322165
return false
2212422166
}
2212522167

22168+
const contentLengthError = validatePartialResponseContentLength(headers, contentRange, statusCode, this.retryCount)
22169+
if (contentLengthError != null) {
22170+
this.abort(contentLengthError)
22171+
return false
22172+
}
22173+
2212622174
const { start, size, end = size - 1 } = contentRange
2212722175

2212822176
assert(this.start === start, 'content-range mismatch')
@@ -22146,6 +22194,12 @@ class RetryHandler {
2214622194
)
2214722195
}
2214822196

22197+
const contentLengthError = validatePartialResponseContentLength(headers, range, statusCode, this.retryCount)
22198+
if (contentLengthError != null) {
22199+
this.abort(contentLengthError)
22200+
return false
22201+
}
22202+
2214922203
const { start, size, end = size - 1 } = range
2215022204
assert(
2215122205
start != null && Number.isFinite(start),
@@ -26390,7 +26444,7 @@ function validateCookiePath (path) {
2639026444

2639126445
if (
2639226446
code < 0x20 || // exclude CTLs (0-31)
26393-
code === 0x7F || // DEL
26447+
code > 0x7E || // exclude DEL and non-ascii
2639426448
code === 0x3B // ;
2639526449
) {
2639626450
throw new Error('Invalid cookie path')
@@ -26399,16 +26453,80 @@ function validateCookiePath (path) {
2639926453
}
2640026454

2640126455
/**
26402-
* I have no idea why these values aren't allowed to be honest,
26403-
* but Deno tests these. - Khafra
26456+
* <let-dig> ::= <letter> | <digit>
26457+
*
26458+
* <letter> ::= any one of the 52 alphabetic characters A through Z in
26459+
* upper case and a through z in lower case
26460+
*
26461+
* <digit> ::= any one of the ten digits 0 through 9r
26462+
*
26463+
* @see https://www.rfc-editor.org/rfc/rfc1034#section-3.5
26464+
* @param {number} code
26465+
*/
26466+
function isLetterOrDigit (code) {
26467+
return (
26468+
(code >= 0x30 && code <= 0x39) || // 0-9
26469+
(code >= 0x41 && code <= 0x5A) || // A-Z
26470+
(code >= 0x61 && code <= 0x7A) // a-z
26471+
)
26472+
}
26473+
26474+
/**
26475+
* Validates a cookie domain against the "preferred name syntax".
26476+
*
26477+
* <domain> ::= <subdomain> | " "
26478+
* <subdomain> ::= <label> | <subdomain> "." <label>
26479+
* <label> ::= <let-dig> [ [ <ldh-str> ] <let-dig> ]
26480+
* <ldh-str> ::= <let-dig-hyp> | <let-dig-hyp> <ldh-str>
26481+
* <let-dig-hyp> ::= <let-dig> | "-"
26482+
*
26483+
* @see https://www.rfc-editor.org/rfc/rfc1034#section-3.5
26484+
* @see https://www.rfc-editor.org/rfc/rfc1123#section-2.1
26485+
* @see https://www.rfc-editor.org/rfc/rfc1035#section-2.3.4
2640426486
* @param {string} domain
2640526487
*/
2640626488
function validateCookieDomain (domain) {
26407-
if (
26408-
domain.startsWith('-') ||
26409-
domain.endsWith('.') ||
26410-
domain.endsWith('-')
26411-
) {
26489+
// <domain> ::= <subdomain> | " "
26490+
if (domain === ' ') {
26491+
return
26492+
}
26493+
26494+
if (domain.length > 255) {
26495+
throw new Error('Invalid cookie domain')
26496+
}
26497+
26498+
let labelLength = 0
26499+
26500+
for (let i = 0; i < domain.length; ++i) {
26501+
const code = domain.charCodeAt(i)
26502+
26503+
if (code === 0x2E) {
26504+
if (labelLength === 0) {
26505+
throw new Error('Invalid cookie domain')
26506+
}
26507+
26508+
if (domain.charCodeAt(i - 1) === 0x2D) { // "-"
26509+
throw new Error('Invalid cookie domain')
26510+
}
26511+
26512+
labelLength = 0
26513+
continue
26514+
}
26515+
26516+
if (labelLength === 0 && !isLetterOrDigit(code)) {
26517+
throw new Error('Invalid cookie domain')
26518+
}
26519+
26520+
if (!isLetterOrDigit(code) && code !== 0x2D) { // "-"
26521+
throw new Error('Invalid cookie domain')
26522+
}
26523+
26524+
if (++labelLength > 63) {
26525+
throw new Error('Invalid cookie domain')
26526+
}
26527+
}
26528+
26529+
if (labelLength === 0 || domain.charCodeAt(domain.length - 1) === 0x2D) { // "-"
2641226530
throw new Error('Invalid cookie domain')
2641326531
}
2641426532
}
@@ -26551,7 +26669,13 @@ function stringify (cookie) {
2655126669

2655226670
const [key, ...value] = part.split('=')
2655326671

26554-
out.push(`${key.trim()}=${value.join('=')}`)
26672+
const trimmedKey = key.trim()
26673+
const joinedValue = value.join('=')
26674+
26675+
validateCookieName(trimmedKey)
26676+
validateCookieValue(joinedValue)
26677+
26678+
out.push(`${trimmedKey}=${joinedValue}`)
2655526679
}
2655626680

2655726681
return out.join('; ')
@@ -41084,7 +41208,7 @@ function combine(acc, pre, values, max, maxLength, dropEmpties) {
4108441208
}
4108541209
// The expansion values of a single numeric (`1..5`) or alphabetic (`a..e..2`)
4108641210
// sequence body.
41087-
function expandSequence(body, isAlphaSequence, max) {
41211+
function expandSequence(body, isAlphaSequence, max, maxLength) {
4108841212
const n = body.split(/\.\./);
4108941213
const N = [];
4109041214
// A sequence body always splits into two or three parts, but the compiler
@@ -41107,6 +41231,7 @@ function expandSequence(body, isAlphaSequence, max) {
4110741231
test = gte;
4110841232
}
4110941233
const pad = n.some(isPadded);
41234+
let length = 0;
4111041235
for (let i = x; test(i, y) && N.length < max; i += incr) {
4111141236
let c;
4111241237
if (isAlphaSequence) {
@@ -41130,7 +41255,10 @@ function expandSequence(body, isAlphaSequence, max) {
4113041255
}
4113141256
}
4113241257
}
41258+
if (length + c.length > maxLength)
41259+
break;
4113341260
N.push(c);
41261+
length += c.length;
4113441262
}
4113541263
return N;
4113641264
}
@@ -41184,7 +41312,7 @@ function expand_(str, max, maxLength, isTop) {
4118441312
}
4118541313
let values;
4118641314
if (isSequence) {
41187-
values = expandSequence(m.body, isAlphaSequence, max);
41315+
values = expandSequence(m.body, isAlphaSequence, max, maxLength);
4118841316
}
4118941317
else {
4119041318
let n = parseCommaParts(m.body);
@@ -41202,9 +41330,31 @@ function expand_(str, max, maxLength, isTop) {
4120241330
}
4120341331
/* c8 ignore stop */
4120441332
}
41333+
// Values that `combine` is going to drop as empty produce no result, so
41334+
// they must not count against `max` - otherwise `{a,,b}` with `max: 2`
41335+
// would stop at `['a', '']` and yield one result instead of two. Skipping
41336+
// them outright keeps `values` bounded while leaving `max` a bound on
41337+
// *kept* results.
41338+
let dropsEmpties = dropEmpties && !m.post.length && !pre;
41339+
for (let d = 0; dropsEmpties && d < acc.length; d++) {
41340+
if (acc[d]) {
41341+
dropsEmpties = false;
41342+
}
41343+
}
4120541344
values = [];
41206-
for (let j = 0; j < n.length; j++) {
41207-
values.push.apply(values, expand_(n[j], max, maxLength, false));
41345+
let valuesLength = 0;
41346+
outer: for (let j = 0; j < n.length; j++) {
41347+
const expanded = expand_(n[j], max, maxLength, false);
41348+
for (let k = 0; k < expanded.length; k++) {
41349+
const v = expanded[k];
41350+
if (dropsEmpties && !v)
41351+
continue;
41352+
if (values.length >= max || valuesLength + v.length > maxLength) {
41353+
break outer;
41354+
}
41355+
values.push(v);
41356+
valuesLength += v.length;
41357+
}
4120841358
}
4120941359
}
4121041360
acc = combine(acc, pre, values, max, maxLength, dropEmpties && !m.post.length);

0 commit comments

Comments
 (0)