diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 16cd1c3a..a2f6e3c3 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -29,8 +29,6 @@ updates: versions: [ '>=0.9.0' ] - dependency-name: 'bootstrap' versions: [ '>=5.0.0' ] - - dependency-name: 'cbor' - versions: [ '>=10.0.0' ] - dependency-name: 'eslint' versions: [ '>=10.0.0' ] - dependency-name: 'eslint-plugin-jsdoc' diff --git a/.github/workflows/master.yml b/.github/workflows/master.yml index f3c6f711..75f1e43b 100644 --- a/.github/workflows/master.yml +++ b/.github/workflows/master.yml @@ -15,13 +15,19 @@ jobs: contents: write pages: write runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + # Node 24 is the officially supported version; Node 26 is tested + # ahead of it becoming the active LTS release (see #2397) + node-version: [24, 26] steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - name: Set node version uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 with: - node-version: 24 + node-version: ${{ matrix.node-version }} registry-url: "https://registry.npmjs.org" - name: Install @@ -59,11 +65,11 @@ jobs: xvfb-run --server-args="-screen 0 1200x800x24" npx grunt testui - name: Prepare for GitHub Pages - if: success() + if: success() && matrix.node-version == 24 run: npx grunt copy:ghPages - name: Deploy to GitHub Pages - if: success() && github.ref == 'refs/heads/master' + if: success() && github.ref == 'refs/heads/master' && matrix.node-version == 24 uses: crazy-max/ghaction-github-pages@1d6ee9b181a81033a16bd707a1401afa978daab4 # v5.0.0 with: target_branch: gh-pages diff --git a/.github/workflows/pull_requests.yml b/.github/workflows/pull_requests.yml index 5ee27086..ac9e39a2 100644 --- a/.github/workflows/pull_requests.yml +++ b/.github/workflows/pull_requests.yml @@ -11,13 +11,19 @@ on: jobs: main: runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + # Node 24 is the officially supported version; Node 26 is tested + # ahead of it becoming the active LTS release (see #2397) + node-version: [24, 26] steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - name: Set node version uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 with: - node-version: 24 + node-version: ${{ matrix.node-version }} registry-url: "https://registry.npmjs.org" - name: Install @@ -38,7 +44,7 @@ jobs: run: npx grunt prod - name: Upload Build Artefact - if: success() + if: success() && matrix.node-version == 24 uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: zipped-build diff --git a/AGENTS.md b/AGENTS.md index 6459055a..4b332e12 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -13,7 +13,7 @@ Core principles for changes: ## Commands -CyberChef expects Node.js `>=24 <25`. +CyberChef expects Node.js `>=24 <27` (v24 is the officially supported version; v26 is also tested). - Install: `npm install` - Development server: `npm start` diff --git a/README.md b/README.md index f74b78a5..0c4b4a37 100755 --- a/README.md +++ b/README.md @@ -117,7 +117,7 @@ CyberChef is built to support ## Node.js support -CyberChef is built to fully support Node.js `v24`. For more information, see the ["Node API" wiki page](https://github.com/gchq/CyberChef/wiki/Node-API) +CyberChef is built to fully support Node.js `v24` and is also tested against Node.js `v26` ahead of it becoming the active LTS release. For more information, see the ["Node API" wiki page](https://github.com/gchq/CyberChef/wiki/Node-API) ## Security diff --git a/package-lock.json b/package-lock.json index 940f4086..833f6fa2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -29,7 +29,7 @@ "browserify-zlib": "^0.2.0", "bson": "^7.3.1", "buffer": "^6.0.3", - "cbor": "10.0.12", + "cbor2": "2.3.0", "chi-squared": "^1.1.0", "codepage": "^1.15.0", "crypto-api": "^0.8.5", @@ -165,7 +165,7 @@ "worker-loader": "^3.0.8" }, "engines": { - "node": ">=24 <25" + "node": ">=24 <27" } }, "node_modules/@alexaltea/capstone-js": { @@ -2665,6 +2665,15 @@ "node": ">=18" } }, + "node_modules/@cto.af/wtf8": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/@cto.af/wtf8/-/wtf8-0.0.5.tgz", + "integrity": "sha512-LfUFi+Vv4eDzj+XAtR89e3wwjXA/NZjUSwU5NhwbBrLecxPaBYFy3exCuc1j+D4UZeOVdqlsl8G7LmOt18V0tg==", + "license": "MIT", + "engines": { + "node": ">=20" + } + }, "node_modules/@discoveryjs/json-ext": { "version": "0.6.3", "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.6.3.tgz", @@ -6611,13 +6620,13 @@ ], "license": "CC-BY-4.0" }, - "node_modules/cbor": { - "version": "10.0.12", - "resolved": "https://registry.npmjs.org/cbor/-/cbor-10.0.12.tgz", - "integrity": "sha512-exQDevYd7ZQLP4moMQcZkKCVZsXLAtUSflObr3xTh4xzFIv/xBCdvCd6L259kQOUP2kcTC0jvC6PpZIf/WmRXA==", + "node_modules/cbor2": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/cbor2/-/cbor2-2.3.0.tgz", + "integrity": "sha512-76WB3hq8BoaGkMkBVJ27fW5LJU+qqDLEpgRNCG/SYKhODWXpVPOTD4UcUto3IEzYLA52nsvbhb0wabhHDn3qXg==", "license": "MIT", "dependencies": { - "nofilter": "^3.0.2" + "@cto.af/wtf8": "0.0.5" }, "engines": { "node": ">=20" @@ -14048,15 +14057,6 @@ "integrity": "sha512-qhfYgpoCSi37HLiViMlf94YqMQdvk3n3arI1uGbAWZK9NKCYRSI42W8lATeGloYGLYxb8us1C5rTvtsXjwdWQg==", "license": "ISC" }, - "node_modules/nofilter": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/nofilter/-/nofilter-3.1.0.tgz", - "integrity": "sha512-l2NNj07e9afPnhAhvgVrCD/oy2Ai1yfLpuo3EpiO1jFTsB4sFz6oIfAfSZyQzVpkZQ9xS8ZS5g1jCBgq4Hwo0g==", - "license": "MIT", - "engines": { - "node": ">=12.19" - } - }, "node_modules/nopt": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", diff --git a/package.json b/package.json index f8c2961e..f1af75a3 100644 --- a/package.json +++ b/package.json @@ -113,7 +113,7 @@ "browserify-zlib": "^0.2.0", "bson": "^7.3.1", "buffer": "^6.0.3", - "cbor": "10.0.12", + "cbor2": "2.3.0", "chi-squared": "^1.1.0", "codepage": "^1.15.0", "crypto-api": "^0.8.5", @@ -220,6 +220,6 @@ "setheapsize": "export NODE_OPTIONS=--max_old_space_size=2048" }, "engines": { - "node": ">=24 <25" + "node": ">=24 <27" } } diff --git a/src/core/operations/CBORDecode.mjs b/src/core/operations/CBORDecode.mjs index f4bda7c0..650a3a65 100644 --- a/src/core/operations/CBORDecode.mjs +++ b/src/core/operations/CBORDecode.mjs @@ -5,7 +5,7 @@ */ import Operation from "../Operation.mjs"; -import Cbor from "cbor"; +import { decode } from "cbor2"; /** * CBOR Decode operation @@ -33,7 +33,7 @@ class CBORDecode extends Operation { * @returns {JSON} */ run(input, args) { - return Cbor.decodeFirstSync(Buffer.from(input).toString("hex")); + return decode(new Uint8Array(input)); } } diff --git a/src/core/operations/CBOREncode.mjs b/src/core/operations/CBOREncode.mjs index c6e094a9..9a35adab 100644 --- a/src/core/operations/CBOREncode.mjs +++ b/src/core/operations/CBOREncode.mjs @@ -5,7 +5,8 @@ */ import Operation from "../Operation.mjs"; -import Cbor from "cbor"; +import { encode } from "cbor2"; +import { sortCoreDeterministic } from "cbor2/sorts"; /** * CBOR Encode operation @@ -33,7 +34,7 @@ class CBOREncode extends Operation { * @returns {ArrayBuffer} */ run(input, args) { - return new Uint8Array(Cbor.encodeCanonical(input)).buffer; + return new Uint8Array(encode(input, {sortKeys: sortCoreDeterministic})).buffer; } }