Compare commits

..

3 Commits

Author SHA1 Message Date
Christian Clauss
c8ccba9717 Revert testing on Node.js v22 2024-05-01 19:39:13 +02:00
Christian Clauss
a3ec3afdf7 Add Node.js v22 2024-05-01 19:26:35 +02:00
Christian Clauss
09ec82e1e7 e2e-cache: Test current versions of Node.js 2024-04-08 08:20:30 +02:00
15 changed files with 133 additions and 590 deletions

View File

@@ -19,7 +19,7 @@ jobs:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
node-version: [18, 20, 22]
node-version: [18, 20]
steps:
- uses: actions/checkout@v4
- name: Clean global cache
@@ -42,11 +42,11 @@ jobs:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
node-version: [18, 20, 22]
node-version: [18, 20]
steps:
- uses: actions/checkout@v4
- name: Install pnpm
uses: pnpm/action-setup@v2
uses: pnpm/action-setup@v3
with:
version: 6.10.0
- name: Generate pnpm file
@@ -107,7 +107,7 @@ jobs:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
node-version: [18, 20, 22]
node-version: [18, 20]
steps:
- uses: actions/checkout@v4
- name: Update yarn
@@ -139,7 +139,7 @@ jobs:
name: Test yarn subprojects
strategy:
matrix:
node-version: [18, 20, 22]
node-version: [18, 20]
runs-on: ubuntu-latest
steps:
@@ -166,7 +166,7 @@ jobs:
name: Test yarn subprojects all locally managed
strategy:
matrix:
node-version: [18, 20, 22]
node-version: [18, 20]
runs-on: ubuntu-latest
steps:
@@ -193,7 +193,7 @@ jobs:
name: Test yarn subprojects some locally managed
strategy:
matrix:
node-version: [18, 20, 22]
node-version: [18, 20]
runs-on: ubuntu-latest
steps:
@@ -220,7 +220,7 @@ jobs:
name: Test yarn subprojects managed by git
strategy:
matrix:
node-version: [18, 20, 22]
node-version: [18, 20]
runs-on: ubuntu-latest
steps:

View File

@@ -1,22 +0,0 @@
name: 'Publish Immutable Action Version'
on:
release:
types: [created]
jobs:
publish:
runs-on: ubuntu-latest
permissions:
contents: read
id-token: write
packages: write
steps:
- name: Checking out
uses: actions/checkout@v4
- name: Publish
id: publish
uses: actions/publish-immutable-action@0.0.1
with:
github-token: ${{ secrets.GITHUB_TOKEN }}

View File

@@ -18,7 +18,7 @@ jobs:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
node-version: [18, 20, 22]
node-version: [10, 12, 14]
steps:
- uses: actions/checkout@v4
- name: Setup Node
@@ -34,7 +34,7 @@ jobs:
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest, macos-13]
os: [ubuntu-latest, windows-latest, macos-latest]
node-version: [lts/dubnium, lts/erbium, lts/fermium, lts/*, lts/-1]
steps:
- uses: actions/checkout@v4
@@ -43,7 +43,7 @@ jobs:
with:
node-version: ${{ matrix.node-version }}
check-latest: true
- if: runner.os != 'Windows' && runner.os != 'macOS'
- if: runner.os != 'Windows'
name: Verify node and npm
run: |
. "$NVM_DIR/nvm.sh"
@@ -83,7 +83,7 @@ jobs:
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
node-version:
[20.11.0-nightly202312211a0be537da, 21-nightly, 18.0.0-nightly]
[16.0.0-nightly20210420a0261d231c, 17-nightly, 18.0.0-nightly]
steps:
- uses: actions/checkout@v4
- name: Setup Node
@@ -103,7 +103,7 @@ jobs:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
node-version: [20.0.0-rc.1, 18.0.0-rc.2, 19.0.0-rc.0]
node-version: [16.0.0-rc.1, 18.0.0-rc.2, 19.0.0-rc.0]
steps:
- uses: actions/checkout@v4
- name: Setup Node
@@ -123,7 +123,7 @@ jobs:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
node-version: [18.20.0, 20.10.0, 22.0.0]
node-version: [10.15, 12.16.0, 14.2.0, 16.3.0]
steps:
- uses: actions/checkout@v4
- name: Setup Node
@@ -140,7 +140,7 @@ jobs:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
node-version: [18, 20, 22]
node-version: [10, 12, 14]
steps:
- uses: actions/checkout@v4
- name: Setup Node and check latest
@@ -167,7 +167,7 @@ jobs:
with:
node-version-file: '__tests__/data/${{ matrix.node-version-file }}'
- name: Verify node
run: __tests__/verify-node.sh 20
run: __tests__/verify-node.sh 14
version-file-volta:
runs-on: ${{ matrix.os }}
@@ -182,7 +182,7 @@ jobs:
with:
node-version-file: '__tests__/data/package-volta.json'
- name: Verify node
run: __tests__/verify-node.sh 20
run: __tests__/verify-node.sh 16
version-file-volta-extends:
runs-on: ${{ matrix.os }}
@@ -197,7 +197,7 @@ jobs:
with:
node-version-file: '__tests__/data/package-volta-extends.json'
- name: Verify node
run: __tests__/verify-node.sh 20
run: __tests__/verify-node.sh 16
node-dist:
runs-on: ${{ matrix.os }}
@@ -205,7 +205,7 @@ jobs:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
node-version: [17, 19]
node-version: [11, 13]
steps:
- uses: actions/checkout@v4
- name: Setup Node from dist
@@ -221,7 +221,7 @@ jobs:
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest, macos-13]
os: [ubuntu-latest, windows-latest, macos-latest]
steps:
- uses: actions/checkout@v4
# test old versions which didn't have npm and layout different
@@ -237,10 +237,10 @@ jobs:
runs-on: windows-latest
steps:
- uses: actions/checkout@v4
- name: Setup node 20 x86 from dist
- name: Setup node 14 x86 from dist
uses: ./
with:
node-version: '20'
node-version: '14'
architecture: 'x86'
- name: Verify node
run: __tests__/verify-arch.sh "ia32"

View File

@@ -1,6 +1,6 @@
---
name: undici
version: 5.28.4
version: 5.28.3
type: npm
summary: An HTTP/1.1 client, written from scratch for Node.js
homepage: https://undici.nodejs.org

View File

@@ -21,7 +21,7 @@ See [action.yml](action.yml)
- uses: actions/setup-node@v4
with:
# Version Spec of the version to use in SemVer notation.
# It also admits such aliases as lts/*, latest, nightly and canary builds
# It also emits such aliases as lts, latest, nightly and canary builds
# Examples: 12.x, 10.15.1, >=10.15.0, lts/Hydrogen, 16-nightly, latest, node
node-version: ''

View File

@@ -1 +1 @@
v20
v14

View File

@@ -1 +1 @@
nodejs 20.0.0
nodejs 14.0.0

View File

@@ -1 +1 @@
node 20.0.0
node 14.0.0

View File

@@ -3,6 +3,6 @@
"node": "^14.0.0"
},
"volta": {
"node": "20.0.0"
"node": "16.0.0"
}
}

View File

@@ -1,5 +1,5 @@
{
"engines": {
"node": "^20.0.0"
"node": "^14.0.0"
}
}

View File

@@ -60838,132 +60838,6 @@ function onConnectTimeout (socket) {
module.exports = buildConnector
/***/ }),
/***/ 4462:
/***/ ((module) => {
"use strict";
/** @type {Record<string, string | undefined>} */
const headerNameLowerCasedRecord = {}
// https://developer.mozilla.org/docs/Web/HTTP/Headers
const wellknownHeaderNames = [
'Accept',
'Accept-Encoding',
'Accept-Language',
'Accept-Ranges',
'Access-Control-Allow-Credentials',
'Access-Control-Allow-Headers',
'Access-Control-Allow-Methods',
'Access-Control-Allow-Origin',
'Access-Control-Expose-Headers',
'Access-Control-Max-Age',
'Access-Control-Request-Headers',
'Access-Control-Request-Method',
'Age',
'Allow',
'Alt-Svc',
'Alt-Used',
'Authorization',
'Cache-Control',
'Clear-Site-Data',
'Connection',
'Content-Disposition',
'Content-Encoding',
'Content-Language',
'Content-Length',
'Content-Location',
'Content-Range',
'Content-Security-Policy',
'Content-Security-Policy-Report-Only',
'Content-Type',
'Cookie',
'Cross-Origin-Embedder-Policy',
'Cross-Origin-Opener-Policy',
'Cross-Origin-Resource-Policy',
'Date',
'Device-Memory',
'Downlink',
'ECT',
'ETag',
'Expect',
'Expect-CT',
'Expires',
'Forwarded',
'From',
'Host',
'If-Match',
'If-Modified-Since',
'If-None-Match',
'If-Range',
'If-Unmodified-Since',
'Keep-Alive',
'Last-Modified',
'Link',
'Location',
'Max-Forwards',
'Origin',
'Permissions-Policy',
'Pragma',
'Proxy-Authenticate',
'Proxy-Authorization',
'RTT',
'Range',
'Referer',
'Referrer-Policy',
'Refresh',
'Retry-After',
'Sec-WebSocket-Accept',
'Sec-WebSocket-Extensions',
'Sec-WebSocket-Key',
'Sec-WebSocket-Protocol',
'Sec-WebSocket-Version',
'Server',
'Server-Timing',
'Service-Worker-Allowed',
'Service-Worker-Navigation-Preload',
'Set-Cookie',
'SourceMap',
'Strict-Transport-Security',
'Supports-Loading-Mode',
'TE',
'Timing-Allow-Origin',
'Trailer',
'Transfer-Encoding',
'Upgrade',
'Upgrade-Insecure-Requests',
'User-Agent',
'Vary',
'Via',
'WWW-Authenticate',
'X-Content-Type-Options',
'X-DNS-Prefetch-Control',
'X-Frame-Options',
'X-Permitted-Cross-Domain-Policies',
'X-Powered-By',
'X-Requested-With',
'X-XSS-Protection'
]
for (let i = 0; i < wellknownHeaderNames.length; ++i) {
const key = wellknownHeaderNames[i]
const lowerCasedKey = key.toLowerCase()
headerNameLowerCasedRecord[key] = headerNameLowerCasedRecord[lowerCasedKey] =
lowerCasedKey
}
// Note: object prototypes should not be able to be referenced. e.g. `Object#hasOwnProperty`.
Object.setPrototypeOf(headerNameLowerCasedRecord, null)
module.exports = {
wellknownHeaderNames,
headerNameLowerCasedRecord
}
/***/ }),
/***/ 8045:
@@ -61796,7 +61670,6 @@ const { InvalidArgumentError } = __nccwpck_require__(8045)
const { Blob } = __nccwpck_require__(4300)
const nodeUtil = __nccwpck_require__(3837)
const { stringify } = __nccwpck_require__(3477)
const { headerNameLowerCasedRecord } = __nccwpck_require__(4462)
const [nodeMajor, nodeMinor] = process.versions.node.split('.').map(v => Number(v))
@@ -62006,15 +61879,6 @@ function parseKeepAliveTimeout (val) {
return m ? parseInt(m[1], 10) * 1000 : null
}
/**
* Retrieves a header name and returns its lowercase value.
* @param {string | Buffer} value Header name
* @returns {string}
*/
function headerNameToString (value) {
return headerNameLowerCasedRecord[value] || value.toLowerCase()
}
function parseHeaders (headers, obj = {}) {
// For H2 support
if (!Array.isArray(headers)) return headers
@@ -62286,7 +62150,6 @@ module.exports = {
isIterable,
isAsyncIterable,
isDestroyed,
headerNameToString,
parseRawHeaders,
parseHeaders,
parseKeepAliveTimeout,
@@ -68934,18 +68797,14 @@ const { isBlobLike, toUSVString, ReadableStreamFrom } = __nccwpck_require__(3983
const assert = __nccwpck_require__(9491)
const { isUint8Array } = __nccwpck_require__(9830)
let supportedHashes = []
// https://nodejs.org/api/crypto.html#determining-if-crypto-support-is-unavailable
/** @type {import('crypto')|undefined} */
let crypto
try {
crypto = __nccwpck_require__(6113)
const possibleRelevantHashes = ['sha256', 'sha384', 'sha512']
supportedHashes = crypto.getHashes().filter((hash) => possibleRelevantHashes.includes(hash))
/* c8 ignore next 3 */
} catch {
}
function responseURL (response) {
@@ -69473,56 +69332,66 @@ function bytesMatch (bytes, metadataList) {
return true
}
// 3. If response is not eligible for integrity validation, return false.
// TODO
// 4. If parsedMetadata is the empty set, return true.
// 3. If parsedMetadata is the empty set, return true.
if (parsedMetadata.length === 0) {
return true
}
// 5. Let metadata be the result of getting the strongest
// 4. Let metadata be the result of getting the strongest
// metadata from parsedMetadata.
const strongest = getStrongestMetadata(parsedMetadata)
const metadata = filterMetadataListByAlgorithm(parsedMetadata, strongest)
const list = parsedMetadata.sort((c, d) => d.algo.localeCompare(c.algo))
// get the strongest algorithm
const strongest = list[0].algo
// get all entries that use the strongest algorithm; ignore weaker
const metadata = list.filter((item) => item.algo === strongest)
// 6. For each item in metadata:
// 5. For each item in metadata:
for (const item of metadata) {
// 1. Let algorithm be the alg component of item.
const algorithm = item.algo
// 2. Let expectedValue be the val component of item.
const expectedValue = item.hash
let expectedValue = item.hash
// See https://github.com/web-platform-tests/wpt/commit/e4c5cc7a5e48093220528dfdd1c4012dc3837a0e
// "be liberal with padding". This is annoying, and it's not even in the spec.
if (expectedValue.endsWith('==')) {
expectedValue = expectedValue.slice(0, -2)
}
// 3. Let actualValue be the result of applying algorithm to bytes.
let actualValue = crypto.createHash(algorithm).update(bytes).digest('base64')
if (actualValue[actualValue.length - 1] === '=') {
if (actualValue[actualValue.length - 2] === '=') {
actualValue = actualValue.slice(0, -2)
} else {
actualValue = actualValue.slice(0, -1)
}
if (actualValue.endsWith('==')) {
actualValue = actualValue.slice(0, -2)
}
// 4. If actualValue is a case-sensitive match for expectedValue,
// return true.
if (compareBase64Mixed(actualValue, expectedValue)) {
if (actualValue === expectedValue) {
return true
}
let actualBase64URL = crypto.createHash(algorithm).update(bytes).digest('base64url')
if (actualBase64URL.endsWith('==')) {
actualBase64URL = actualBase64URL.slice(0, -2)
}
if (actualBase64URL === expectedValue) {
return true
}
}
// 7. Return false.
// 6. Return false.
return false
}
// https://w3c.github.io/webappsec-subresource-integrity/#grammardef-hash-with-options
// https://www.w3.org/TR/CSP2/#source-list-syntax
// https://www.rfc-editor.org/rfc/rfc5234#appendix-B.1
const parseHashWithOptions = /(?<algo>sha256|sha384|sha512)-((?<hash>[A-Za-z0-9+/]+|[A-Za-z0-9_-]+)={0,2}(?:\s|$)( +[!-~]*)?)?/i
const parseHashWithOptions = /((?<algo>sha256|sha384|sha512)-(?<hash>[A-z0-9+/]{1}.*={0,2}))( +[\x21-\x7e]?)?/i
/**
* @see https://w3c.github.io/webappsec-subresource-integrity/#parse-metadata
@@ -69536,6 +69405,8 @@ function parseMetadata (metadata) {
// 2. Let empty be equal to true.
let empty = true
const supportedHashes = crypto.getHashes()
// 3. For each token returned by splitting metadata on spaces:
for (const token of metadata.split(' ')) {
// 1. Set empty to false.
@@ -69545,11 +69416,7 @@ function parseMetadata (metadata) {
const parsedToken = parseHashWithOptions.exec(token)
// 3. If token does not parse, continue to the next token.
if (
parsedToken === null ||
parsedToken.groups === undefined ||
parsedToken.groups.algo === undefined
) {
if (parsedToken === null || parsedToken.groups === undefined) {
// Note: Chromium blocks the request at this point, but Firefox
// gives a warning that an invalid integrity was given. The
// correct behavior is to ignore these, and subsequently not
@@ -69558,11 +69425,11 @@ function parseMetadata (metadata) {
}
// 4. Let algorithm be the hash-algo component of token.
const algorithm = parsedToken.groups.algo.toLowerCase()
const algorithm = parsedToken.groups.algo
// 5. If algorithm is a hash function recognized by the user
// agent, add the parsed token to result.
if (supportedHashes.includes(algorithm)) {
if (supportedHashes.includes(algorithm.toLowerCase())) {
result.push(parsedToken.groups)
}
}
@@ -69575,82 +69442,6 @@ function parseMetadata (metadata) {
return result
}
/**
* @param {{ algo: 'sha256' | 'sha384' | 'sha512' }[]} metadataList
*/
function getStrongestMetadata (metadataList) {
// Let algorithm be the algo component of the first item in metadataList.
// Can be sha256
let algorithm = metadataList[0].algo
// If the algorithm is sha512, then it is the strongest
// and we can return immediately
if (algorithm[3] === '5') {
return algorithm
}
for (let i = 1; i < metadataList.length; ++i) {
const metadata = metadataList[i]
// If the algorithm is sha512, then it is the strongest
// and we can break the loop immediately
if (metadata.algo[3] === '5') {
algorithm = 'sha512'
break
// If the algorithm is sha384, then a potential sha256 or sha384 is ignored
} else if (algorithm[3] === '3') {
continue
// algorithm is sha256, check if algorithm is sha384 and if so, set it as
// the strongest
} else if (metadata.algo[3] === '3') {
algorithm = 'sha384'
}
}
return algorithm
}
function filterMetadataListByAlgorithm (metadataList, algorithm) {
if (metadataList.length === 1) {
return metadataList
}
let pos = 0
for (let i = 0; i < metadataList.length; ++i) {
if (metadataList[i].algo === algorithm) {
metadataList[pos++] = metadataList[i]
}
}
metadataList.length = pos
return metadataList
}
/**
* Compares two base64 strings, allowing for base64url
* in the second string.
*
* @param {string} actualValue always base64
* @param {string} expectedValue base64 or base64url
* @returns {boolean}
*/
function compareBase64Mixed (actualValue, expectedValue) {
if (actualValue.length !== expectedValue.length) {
return false
}
for (let i = 0; i < actualValue.length; ++i) {
if (actualValue[i] !== expectedValue[i]) {
if (
(actualValue[i] === '+' && expectedValue[i] === '-') ||
(actualValue[i] === '/' && expectedValue[i] === '_')
) {
continue
}
return false
}
}
return true
}
// https://w3c.github.io/webappsec-upgrade-insecure-requests/#upgrade-request
function tryUpgradeRequestToAPotentiallyTrustworthyURL (request) {
// TODO
@@ -70066,8 +69857,7 @@ module.exports = {
urlHasHttpsScheme,
urlIsHttpHttpsScheme,
readAllBytes,
normalizeMethodRecord,
parseMetadata
normalizeMethodRecord
}
@@ -72154,17 +71944,12 @@ function parseLocation (statusCode, headers) {
// https://tools.ietf.org/html/rfc7231#section-6.4.4
function shouldRemoveHeader (header, removeContent, unknownOrigin) {
if (header.length === 4) {
return util.headerNameToString(header) === 'host'
}
if (removeContent && util.headerNameToString(header).startsWith('content-')) {
return true
}
if (unknownOrigin && (header.length === 13 || header.length === 6 || header.length === 19)) {
const name = util.headerNameToString(header)
return name === 'authorization' || name === 'cookie' || name === 'proxy-authorization'
}
return false
return (
(header.length === 4 && header.toString().toLowerCase() === 'host') ||
(removeContent && header.toString().toLowerCase().indexOf('content-') === 0) ||
(unknownOrigin && header.length === 13 && header.toString().toLowerCase() === 'authorization') ||
(unknownOrigin && header.length === 6 && header.toString().toLowerCase() === 'cookie')
)
}
// https://tools.ietf.org/html/rfc7231#section-6.4

305
dist/setup/index.js vendored
View File

@@ -69634,132 +69634,6 @@ function onConnectTimeout (socket) {
module.exports = buildConnector
/***/ }),
/***/ 4462:
/***/ ((module) => {
"use strict";
/** @type {Record<string, string | undefined>} */
const headerNameLowerCasedRecord = {}
// https://developer.mozilla.org/docs/Web/HTTP/Headers
const wellknownHeaderNames = [
'Accept',
'Accept-Encoding',
'Accept-Language',
'Accept-Ranges',
'Access-Control-Allow-Credentials',
'Access-Control-Allow-Headers',
'Access-Control-Allow-Methods',
'Access-Control-Allow-Origin',
'Access-Control-Expose-Headers',
'Access-Control-Max-Age',
'Access-Control-Request-Headers',
'Access-Control-Request-Method',
'Age',
'Allow',
'Alt-Svc',
'Alt-Used',
'Authorization',
'Cache-Control',
'Clear-Site-Data',
'Connection',
'Content-Disposition',
'Content-Encoding',
'Content-Language',
'Content-Length',
'Content-Location',
'Content-Range',
'Content-Security-Policy',
'Content-Security-Policy-Report-Only',
'Content-Type',
'Cookie',
'Cross-Origin-Embedder-Policy',
'Cross-Origin-Opener-Policy',
'Cross-Origin-Resource-Policy',
'Date',
'Device-Memory',
'Downlink',
'ECT',
'ETag',
'Expect',
'Expect-CT',
'Expires',
'Forwarded',
'From',
'Host',
'If-Match',
'If-Modified-Since',
'If-None-Match',
'If-Range',
'If-Unmodified-Since',
'Keep-Alive',
'Last-Modified',
'Link',
'Location',
'Max-Forwards',
'Origin',
'Permissions-Policy',
'Pragma',
'Proxy-Authenticate',
'Proxy-Authorization',
'RTT',
'Range',
'Referer',
'Referrer-Policy',
'Refresh',
'Retry-After',
'Sec-WebSocket-Accept',
'Sec-WebSocket-Extensions',
'Sec-WebSocket-Key',
'Sec-WebSocket-Protocol',
'Sec-WebSocket-Version',
'Server',
'Server-Timing',
'Service-Worker-Allowed',
'Service-Worker-Navigation-Preload',
'Set-Cookie',
'SourceMap',
'Strict-Transport-Security',
'Supports-Loading-Mode',
'TE',
'Timing-Allow-Origin',
'Trailer',
'Transfer-Encoding',
'Upgrade',
'Upgrade-Insecure-Requests',
'User-Agent',
'Vary',
'Via',
'WWW-Authenticate',
'X-Content-Type-Options',
'X-DNS-Prefetch-Control',
'X-Frame-Options',
'X-Permitted-Cross-Domain-Policies',
'X-Powered-By',
'X-Requested-With',
'X-XSS-Protection'
]
for (let i = 0; i < wellknownHeaderNames.length; ++i) {
const key = wellknownHeaderNames[i]
const lowerCasedKey = key.toLowerCase()
headerNameLowerCasedRecord[key] = headerNameLowerCasedRecord[lowerCasedKey] =
lowerCasedKey
}
// Note: object prototypes should not be able to be referenced. e.g. `Object#hasOwnProperty`.
Object.setPrototypeOf(headerNameLowerCasedRecord, null)
module.exports = {
wellknownHeaderNames,
headerNameLowerCasedRecord
}
/***/ }),
/***/ 8045:
@@ -70592,7 +70466,6 @@ const { InvalidArgumentError } = __nccwpck_require__(8045)
const { Blob } = __nccwpck_require__(4300)
const nodeUtil = __nccwpck_require__(3837)
const { stringify } = __nccwpck_require__(3477)
const { headerNameLowerCasedRecord } = __nccwpck_require__(4462)
const [nodeMajor, nodeMinor] = process.versions.node.split('.').map(v => Number(v))
@@ -70802,15 +70675,6 @@ function parseKeepAliveTimeout (val) {
return m ? parseInt(m[1], 10) * 1000 : null
}
/**
* Retrieves a header name and returns its lowercase value.
* @param {string | Buffer} value Header name
* @returns {string}
*/
function headerNameToString (value) {
return headerNameLowerCasedRecord[value] || value.toLowerCase()
}
function parseHeaders (headers, obj = {}) {
// For H2 support
if (!Array.isArray(headers)) return headers
@@ -71082,7 +70946,6 @@ module.exports = {
isIterable,
isAsyncIterable,
isDestroyed,
headerNameToString,
parseRawHeaders,
parseHeaders,
parseKeepAliveTimeout,
@@ -77730,18 +77593,14 @@ const { isBlobLike, toUSVString, ReadableStreamFrom } = __nccwpck_require__(3983
const assert = __nccwpck_require__(9491)
const { isUint8Array } = __nccwpck_require__(9830)
let supportedHashes = []
// https://nodejs.org/api/crypto.html#determining-if-crypto-support-is-unavailable
/** @type {import('crypto')|undefined} */
let crypto
try {
crypto = __nccwpck_require__(6113)
const possibleRelevantHashes = ['sha256', 'sha384', 'sha512']
supportedHashes = crypto.getHashes().filter((hash) => possibleRelevantHashes.includes(hash))
/* c8 ignore next 3 */
} catch {
}
function responseURL (response) {
@@ -78269,56 +78128,66 @@ function bytesMatch (bytes, metadataList) {
return true
}
// 3. If response is not eligible for integrity validation, return false.
// TODO
// 4. If parsedMetadata is the empty set, return true.
// 3. If parsedMetadata is the empty set, return true.
if (parsedMetadata.length === 0) {
return true
}
// 5. Let metadata be the result of getting the strongest
// 4. Let metadata be the result of getting the strongest
// metadata from parsedMetadata.
const strongest = getStrongestMetadata(parsedMetadata)
const metadata = filterMetadataListByAlgorithm(parsedMetadata, strongest)
const list = parsedMetadata.sort((c, d) => d.algo.localeCompare(c.algo))
// get the strongest algorithm
const strongest = list[0].algo
// get all entries that use the strongest algorithm; ignore weaker
const metadata = list.filter((item) => item.algo === strongest)
// 6. For each item in metadata:
// 5. For each item in metadata:
for (const item of metadata) {
// 1. Let algorithm be the alg component of item.
const algorithm = item.algo
// 2. Let expectedValue be the val component of item.
const expectedValue = item.hash
let expectedValue = item.hash
// See https://github.com/web-platform-tests/wpt/commit/e4c5cc7a5e48093220528dfdd1c4012dc3837a0e
// "be liberal with padding". This is annoying, and it's not even in the spec.
if (expectedValue.endsWith('==')) {
expectedValue = expectedValue.slice(0, -2)
}
// 3. Let actualValue be the result of applying algorithm to bytes.
let actualValue = crypto.createHash(algorithm).update(bytes).digest('base64')
if (actualValue[actualValue.length - 1] === '=') {
if (actualValue[actualValue.length - 2] === '=') {
actualValue = actualValue.slice(0, -2)
} else {
actualValue = actualValue.slice(0, -1)
}
if (actualValue.endsWith('==')) {
actualValue = actualValue.slice(0, -2)
}
// 4. If actualValue is a case-sensitive match for expectedValue,
// return true.
if (compareBase64Mixed(actualValue, expectedValue)) {
if (actualValue === expectedValue) {
return true
}
let actualBase64URL = crypto.createHash(algorithm).update(bytes).digest('base64url')
if (actualBase64URL.endsWith('==')) {
actualBase64URL = actualBase64URL.slice(0, -2)
}
if (actualBase64URL === expectedValue) {
return true
}
}
// 7. Return false.
// 6. Return false.
return false
}
// https://w3c.github.io/webappsec-subresource-integrity/#grammardef-hash-with-options
// https://www.w3.org/TR/CSP2/#source-list-syntax
// https://www.rfc-editor.org/rfc/rfc5234#appendix-B.1
const parseHashWithOptions = /(?<algo>sha256|sha384|sha512)-((?<hash>[A-Za-z0-9+/]+|[A-Za-z0-9_-]+)={0,2}(?:\s|$)( +[!-~]*)?)?/i
const parseHashWithOptions = /((?<algo>sha256|sha384|sha512)-(?<hash>[A-z0-9+/]{1}.*={0,2}))( +[\x21-\x7e]?)?/i
/**
* @see https://w3c.github.io/webappsec-subresource-integrity/#parse-metadata
@@ -78332,6 +78201,8 @@ function parseMetadata (metadata) {
// 2. Let empty be equal to true.
let empty = true
const supportedHashes = crypto.getHashes()
// 3. For each token returned by splitting metadata on spaces:
for (const token of metadata.split(' ')) {
// 1. Set empty to false.
@@ -78341,11 +78212,7 @@ function parseMetadata (metadata) {
const parsedToken = parseHashWithOptions.exec(token)
// 3. If token does not parse, continue to the next token.
if (
parsedToken === null ||
parsedToken.groups === undefined ||
parsedToken.groups.algo === undefined
) {
if (parsedToken === null || parsedToken.groups === undefined) {
// Note: Chromium blocks the request at this point, but Firefox
// gives a warning that an invalid integrity was given. The
// correct behavior is to ignore these, and subsequently not
@@ -78354,11 +78221,11 @@ function parseMetadata (metadata) {
}
// 4. Let algorithm be the hash-algo component of token.
const algorithm = parsedToken.groups.algo.toLowerCase()
const algorithm = parsedToken.groups.algo
// 5. If algorithm is a hash function recognized by the user
// agent, add the parsed token to result.
if (supportedHashes.includes(algorithm)) {
if (supportedHashes.includes(algorithm.toLowerCase())) {
result.push(parsedToken.groups)
}
}
@@ -78371,82 +78238,6 @@ function parseMetadata (metadata) {
return result
}
/**
* @param {{ algo: 'sha256' | 'sha384' | 'sha512' }[]} metadataList
*/
function getStrongestMetadata (metadataList) {
// Let algorithm be the algo component of the first item in metadataList.
// Can be sha256
let algorithm = metadataList[0].algo
// If the algorithm is sha512, then it is the strongest
// and we can return immediately
if (algorithm[3] === '5') {
return algorithm
}
for (let i = 1; i < metadataList.length; ++i) {
const metadata = metadataList[i]
// If the algorithm is sha512, then it is the strongest
// and we can break the loop immediately
if (metadata.algo[3] === '5') {
algorithm = 'sha512'
break
// If the algorithm is sha384, then a potential sha256 or sha384 is ignored
} else if (algorithm[3] === '3') {
continue
// algorithm is sha256, check if algorithm is sha384 and if so, set it as
// the strongest
} else if (metadata.algo[3] === '3') {
algorithm = 'sha384'
}
}
return algorithm
}
function filterMetadataListByAlgorithm (metadataList, algorithm) {
if (metadataList.length === 1) {
return metadataList
}
let pos = 0
for (let i = 0; i < metadataList.length; ++i) {
if (metadataList[i].algo === algorithm) {
metadataList[pos++] = metadataList[i]
}
}
metadataList.length = pos
return metadataList
}
/**
* Compares two base64 strings, allowing for base64url
* in the second string.
*
* @param {string} actualValue always base64
* @param {string} expectedValue base64 or base64url
* @returns {boolean}
*/
function compareBase64Mixed (actualValue, expectedValue) {
if (actualValue.length !== expectedValue.length) {
return false
}
for (let i = 0; i < actualValue.length; ++i) {
if (actualValue[i] !== expectedValue[i]) {
if (
(actualValue[i] === '+' && expectedValue[i] === '-') ||
(actualValue[i] === '/' && expectedValue[i] === '_')
) {
continue
}
return false
}
}
return true
}
// https://w3c.github.io/webappsec-upgrade-insecure-requests/#upgrade-request
function tryUpgradeRequestToAPotentiallyTrustworthyURL (request) {
// TODO
@@ -78862,8 +78653,7 @@ module.exports = {
urlHasHttpsScheme,
urlIsHttpHttpsScheme,
readAllBytes,
normalizeMethodRecord,
parseMetadata
normalizeMethodRecord
}
@@ -80950,17 +80740,12 @@ function parseLocation (statusCode, headers) {
// https://tools.ietf.org/html/rfc7231#section-6.4.4
function shouldRemoveHeader (header, removeContent, unknownOrigin) {
if (header.length === 4) {
return util.headerNameToString(header) === 'host'
}
if (removeContent && util.headerNameToString(header).startsWith('content-')) {
return true
}
if (unknownOrigin && (header.length === 13 || header.length === 6 || header.length === 19)) {
const name = util.headerNameToString(header)
return name === 'authorization' || name === 'cookie' || name === 'proxy-authorization'
}
return false
return (
(header.length === 4 && header.toString().toLowerCase() === 'host') ||
(removeContent && header.toString().toLowerCase().indexOf('content-') === 0) ||
(unknownOrigin && header.length === 13 && header.toString().toLowerCase() === 'authorization') ||
(unknownOrigin && header.length === 6 && header.toString().toLowerCase() === 'cookie')
)
}
// https://tools.ietf.org/html/rfc7231#section-6.4
@@ -93883,7 +93668,7 @@ class BaseDistribution {
}
throw err;
}
const toolPath = yield this.extractArchive(downloadPath, info, true);
const toolPath = yield this.extractArchive(downloadPath, info);
core.info('Done');
return toolPath;
});
@@ -93933,7 +93718,7 @@ class BaseDistribution {
return toolPath;
});
}
extractArchive(downloadPath, info, isOfficialArchive) {
extractArchive(downloadPath, info) {
return __awaiter(this, void 0, void 0, function* () {
//
// Extract
@@ -93948,7 +93733,7 @@ class BaseDistribution {
// on Windows runners without PowerShell Core.
//
// For default PowerShell Windows it should contain extension type to unpack it.
if (extension === '.zip' && isOfficialArchive) {
if (extension === '.zip') {
const renamedArchive = `${downloadPath}.zip`;
fs_1.default.renameSync(downloadPath, renamedArchive);
extPath = yield tc.extractZip(renamedArchive);
@@ -94186,7 +93971,7 @@ class OfficialBuilds extends base_distribution_1.default {
core.info(`Acquiring ${versionInfo.resolvedVersion} - ${versionInfo.arch} from ${versionInfo.downloadUrl}`);
downloadPath = yield tc.downloadTool(versionInfo.downloadUrl, undefined, this.nodeInfo.auth);
if (downloadPath) {
toolPath = yield this.extractArchive(downloadPath, versionInfo, false);
toolPath = yield this.extractArchive(downloadPath, versionInfo);
}
}
else {

28
package-lock.json generated
View File

@@ -2342,12 +2342,12 @@
}
},
"node_modules/braces": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
"integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
"integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
"dev": true,
"dependencies": {
"fill-range": "^7.1.1"
"fill-range": "^7.0.1"
},
"engines": {
"node": ">=8"
@@ -3201,9 +3201,9 @@
}
},
"node_modules/fill-range": {
"version": "7.1.1",
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
"integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
"version": "7.0.1",
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
"integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
"dev": true,
"dependencies": {
"to-regex-range": "^5.0.1"
@@ -4429,12 +4429,12 @@
}
},
"node_modules/micromatch": {
"version": "4.0.8",
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
"integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
"version": "4.0.5",
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz",
"integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==",
"dev": true,
"dependencies": {
"braces": "^3.0.3",
"braces": "^3.0.2",
"picomatch": "^2.3.1"
},
"engines": {
@@ -5431,9 +5431,9 @@
}
},
"node_modules/undici": {
"version": "5.28.4",
"resolved": "https://registry.npmjs.org/undici/-/undici-5.28.4.tgz",
"integrity": "sha512-72RFADWFqKmUb2hmmvNODKL3p9hcB6Gt2DOQMis1SEBaV6a4MH8soBvzg+95CYhCKPFedut2JY9bMfrDl9D23g==",
"version": "5.28.3",
"resolved": "https://registry.npmjs.org/undici/-/undici-5.28.3.tgz",
"integrity": "sha512-3ItfzbrhDlINjaP0duwnNsKpDQk3acHI3gVJ1z4fmwMK31k5G9OVIAMLSIaP6w4FaGkaAkN6zaQO9LUvZ1t7VA==",
"dependencies": {
"@fastify/busboy": "^2.0.0"
},

View File

@@ -150,7 +150,7 @@ export default abstract class BaseDistribution {
throw err;
}
const toolPath = await this.extractArchive(downloadPath, info, true);
const toolPath = await this.extractArchive(downloadPath, info);
core.info('Done');
return toolPath;
@@ -210,8 +210,7 @@ export default abstract class BaseDistribution {
protected async extractArchive(
downloadPath: string,
info: INodeVersionInfo | null,
isOfficialArchive?: boolean
info: INodeVersionInfo | null
) {
//
// Extract
@@ -226,7 +225,7 @@ export default abstract class BaseDistribution {
// on Windows runners without PowerShell Core.
//
// For default PowerShell Windows it should contain extension type to unpack it.
if (extension === '.zip' && isOfficialArchive) {
if (extension === '.zip') {
const renamedArchive = `${downloadPath}.zip`;
fs.renameSync(downloadPath, renamedArchive);
extPath = await tc.extractZip(renamedArchive);

View File

@@ -88,11 +88,7 @@ export default class OfficialBuilds extends BaseDistribution {
);
if (downloadPath) {
toolPath = await this.extractArchive(
downloadPath,
versionInfo,
false
);
toolPath = await this.extractArchive(downloadPath, versionInfo);
}
} else {
core.info(