From b414b730ae8916a36ed15f6027bcc5e463dde4b9 Mon Sep 17 00:00:00 2001 From: GCHQDeveloper581 <63102987+GCHQDeveloper581@users.noreply.github.com> Date: Wed, 25 Mar 2026 10:47:32 +0000 Subject: [PATCH 1/6] bump chromedriver to 146.0.6 --- package-lock.json | 26 ++++++++++++++++++-------- package.json | 2 +- 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/package-lock.json b/package-lock.json index 607aeca3fb..e4fce8f731 100644 --- a/package-lock.json +++ b/package-lock.json @@ -121,7 +121,7 @@ "autoprefixer": "^10.4.27", "babel-loader": "^10.1.1", "base64-loader": "^1.0.0", - "chromedriver": "^130.0.4", + "chromedriver": "^146.0.6", "cli-progress": "^3.12.0", "colors": "^1.4.0", "compression-webpack-plugin": "^11.1.0", @@ -6246,26 +6246,36 @@ } }, "node_modules/chromedriver": { - "version": "130.0.4", - "resolved": "https://registry.npmjs.org/chromedriver/-/chromedriver-130.0.4.tgz", - "integrity": "sha512-lpR+PWXszij1k4Ig3t338Zvll9HtCTiwoLM7n4pCCswALHxzmgwaaIFBh3rt9+5wRk9D07oFblrazrBxwaYYAQ==", + "version": "146.0.6", + "resolved": "https://registry.npmjs.org/chromedriver/-/chromedriver-146.0.6.tgz", + "integrity": "sha512-FIRi3hy0nRiyirK03etVXEpYTIodevFcvTBAM5ZCq+pX3w31jLm6JE8BVW1ypAVLvSp6HJDvboCcdgUroS3miw==", "dev": true, "hasInstallScript": true, "license": "Apache-2.0", "dependencies": { "@testim/chrome-version": "^1.1.4", - "axios": "^1.7.4", + "axios": "^1.13.5", "compare-versions": "^6.1.0", "extract-zip": "^2.0.1", - "proxy-agent": "^6.4.0", - "proxy-from-env": "^1.1.0", + "proxy-agent": "^6.5.0", + "proxy-from-env": "^2.0.0", "tcp-port-used": "^1.0.2" }, "bin": { "chromedriver": "bin/chromedriver" }, "engines": { - "node": ">=18" + "node": ">=20" + } + }, + "node_modules/chromedriver/node_modules/proxy-from-env": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-2.1.0.tgz", + "integrity": "sha512-cJ+oHTW1VAEa8cJslgmUZrc+sjRKgAKl3Zyse6+PV38hZe/V6Z14TbCuXcan9F9ghlz4QrFr2c92TNF82UkYHA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" } }, "node_modules/ci-info": { diff --git a/package.json b/package.json index fe3d7a196c..8dc668c89d 100644 --- a/package.json +++ b/package.json @@ -52,7 +52,7 @@ "autoprefixer": "^10.4.27", "babel-loader": "^10.1.1", "base64-loader": "^1.0.0", - "chromedriver": "^130.0.4", + "chromedriver": "^146.0.6", "cli-progress": "^3.12.0", "colors": "^1.4.0", "compression-webpack-plugin": "^11.1.0", From 046c89309b56e90e86bf6e227f67a70078b45ede Mon Sep 17 00:00:00 2001 From: GCHQDeveloper581 <63102987+GCHQDeveloper581@users.noreply.github.com> Date: Wed, 25 Mar 2026 11:56:53 +0000 Subject: [PATCH 2/6] Bump up to node 24 --- .github/workflows/master.yml | 2 +- .github/workflows/pull_requests.yml | 2 +- .github/workflows/releases.yml | 4 ++-- package-lock.json | 3 +++ package.json | 5 ++++- 5 files changed, 11 insertions(+), 5 deletions(-) diff --git a/.github/workflows/master.yml b/.github/workflows/master.yml index bcf10fb710..f5ff2692b5 100644 --- a/.github/workflows/master.yml +++ b/.github/workflows/master.yml @@ -21,7 +21,7 @@ jobs: - name: Set node version uses: actions/setup-node@v6 with: - node-version: '20.x' + node-version: '24' registry-url: "https://registry.npmjs.org" - name: Install diff --git a/.github/workflows/pull_requests.yml b/.github/workflows/pull_requests.yml index c34f357f3f..fb61835d50 100644 --- a/.github/workflows/pull_requests.yml +++ b/.github/workflows/pull_requests.yml @@ -17,7 +17,7 @@ jobs: - name: Set node version uses: actions/setup-node@v6 with: - node-version: '20.x' + node-version: '24' registry-url: "https://registry.npmjs.org" - name: Install diff --git a/.github/workflows/releases.yml b/.github/workflows/releases.yml index bf977c194f..5f900ca8e0 100644 --- a/.github/workflows/releases.yml +++ b/.github/workflows/releases.yml @@ -27,7 +27,7 @@ jobs: - name: Set node version uses: actions/setup-node@v6 with: - node-version: '20.x' + node-version: '24' registry-url: "https://registry.npmjs.org" - name: Install @@ -107,7 +107,7 @@ jobs: - name: Set node version uses: actions/setup-node@v6 with: - node-version: 18 + node-version: 24 registry-url: "https://registry.npmjs.org" - name: Install diff --git a/package-lock.json b/package-lock.json index e4fce8f731..152ce15590 100644 --- a/package-lock.json +++ b/package-lock.json @@ -160,6 +160,9 @@ "webpack-dev-server": "5.0.4", "webpack-node-externals": "^3.0.0", "worker-loader": "^3.0.8" + }, + "engines": { + "node": ">=24 <25" } }, "node_modules/@alexaltea/capstone-js": { diff --git a/package.json b/package.json index 8dc668c89d..4b200a0d66 100644 --- a/package.json +++ b/package.json @@ -36,7 +36,7 @@ "browserslist": [ "Chrome >= 50", "Firefox >= 38", - "node >= 22" + "node >= 24" ], "devDependencies": { "@babel/eslint-parser": "^7.28.6", @@ -207,5 +207,8 @@ "tag": "git tag -s \"v$(npm pkg get version | xargs)\" -m \"$(npm pkg get version | xargs)\" && echo \"Created v$(npm pkg get version | xargs), now check and push the tag\"", "getheapsize": "node -e 'console.log(`node heap limit = ${require(\"v8\").getHeapStatistics().heap_size_limit / (1024 * 1024)} Mb`)'", "setheapsize": "export NODE_OPTIONS=--max_old_space_size=2048" + }, + "engines": { + "node": ">=24 <25" } } From 82d3e883d737f9f67461732cb578871cf420dd15 Mon Sep 17 00:00:00 2001 From: GCHQDeveloper581 <63102987+GCHQDeveloper581@users.noreply.github.com> Date: Wed, 25 Mar 2026 12:02:28 +0000 Subject: [PATCH 3/6] remove no longer valid flag noexperimental-fetch --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 4b200a0d66..8012e7f117 100644 --- a/package.json +++ b/package.json @@ -194,8 +194,8 @@ "start": "npx grunt dev", "build": "npx grunt prod", "node": "npx grunt node", - "repl": "node --experimental-modules --experimental-json-modules --experimental-specifier-resolution=node --no-experimental-fetch --no-warnings src/node/repl.mjs", - "test": "npx grunt configTests && node --experimental-modules --experimental-json-modules --no-warnings --no-deprecation --openssl-legacy-provider --no-experimental-fetch tests/node/index.mjs && node --experimental-modules --experimental-json-modules --no-warnings --no-deprecation --openssl-legacy-provider --no-experimental-fetch --trace-uncaught tests/operations/index.mjs", + "repl": "node --experimental-modules --experimental-json-modules --experimental-specifier-resolution=node --no-warnings src/node/repl.mjs", + "test": "npx grunt configTests && node --experimental-modules --experimental-json-modules --no-warnings --no-deprecation --openssl-legacy-provider tests/node/index.mjs && node --experimental-modules --experimental-json-modules --no-warnings --no-deprecation --openssl-legacy-provider --trace-uncaught tests/operations/index.mjs", "testnodeconsumer": "npx grunt testnodeconsumer", "testui": "npx grunt testui", "testuidev": "npx nightwatch --env=dev", From e2c326ad545b176c23153685e03d05c332d96d43 Mon Sep 17 00:00:00 2001 From: Leon Zandman Date: Fri, 20 Mar 2026 19:58:19 +0100 Subject: [PATCH 4/6] Test fix: add WASM fetch polyfill for Node.js 22+ compatibility --- tests/lib/wasmFetchPolyfill.mjs | 29 +++++++++++++++++++++++++++++ tests/operations/index.mjs | 1 + 2 files changed, 30 insertions(+) create mode 100644 tests/lib/wasmFetchPolyfill.mjs diff --git a/tests/lib/wasmFetchPolyfill.mjs b/tests/lib/wasmFetchPolyfill.mjs new file mode 100644 index 0000000000..6ec6308d3b --- /dev/null +++ b/tests/lib/wasmFetchPolyfill.mjs @@ -0,0 +1,29 @@ +/** + * Polyfill for Node.js 22+ where globalThis.fetch is built-in but rejects + * bare filesystem paths. WASM libraries like argon2-browser call fetch() with + * an absolute path (e.g. "/path/to/argon2.wasm") expecting a browser-style + * fallback, but Node.js 22's fetch throws synchronously for non-URL strings. + * + * This wrapper intercepts such calls and serves the file via Node's fs module, + * returning a synthetic Response so the WASM module loads correctly. + */ + +import { readFile } from "fs/promises"; + +if (globalThis.fetch) { + const originalFetch = globalThis.fetch; + globalThis.fetch = async function patchedFetch(url, options) { + const urlStr = typeof url === "string" ? url + : url instanceof URL ? url.href + : String(url); + // Intercept bare filesystem paths (absolute POSIX or Windows) + if (urlStr.startsWith("/") || /^[A-Za-z]:[/\\]/.test(urlStr)) { + const buffer = await readFile(urlStr); + return new Response(buffer, { + status: 200, + headers: { "Content-Type": "application/wasm" }, + }); + } + return originalFetch(url, options); + }; +} diff --git a/tests/operations/index.mjs b/tests/operations/index.mjs index f030349d2a..59ff77c155 100644 --- a/tests/operations/index.mjs +++ b/tests/operations/index.mjs @@ -11,6 +11,7 @@ * @license Apache-2.0 */ +import "../lib/wasmFetchPolyfill.mjs"; import { setLongTestFailure, logTestReport } from "../lib/utils.mjs"; import TestRegister from "../lib/TestRegister.mjs"; From 899583b0ad0e800110e00edfd5bfee6a21c07d30 Mon Sep 17 00:00:00 2001 From: Leon Zandman Date: Fri, 20 Mar 2026 20:04:19 +0100 Subject: [PATCH 5/6] Fix linting. --- tests/lib/wasmFetchPolyfill.mjs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/tests/lib/wasmFetchPolyfill.mjs b/tests/lib/wasmFetchPolyfill.mjs index 6ec6308d3b..cc1a6a393d 100644 --- a/tests/lib/wasmFetchPolyfill.mjs +++ b/tests/lib/wasmFetchPolyfill.mjs @@ -13,9 +13,11 @@ import { readFile } from "fs/promises"; if (globalThis.fetch) { const originalFetch = globalThis.fetch; globalThis.fetch = async function patchedFetch(url, options) { - const urlStr = typeof url === "string" ? url - : url instanceof URL ? url.href - : String(url); + const urlStr = typeof url === "string" ? + url : + url instanceof URL ? + url.href : + String(url); // Intercept bare filesystem paths (absolute POSIX or Windows) if (urlStr.startsWith("/") || /^[A-Za-z]:[/\\]/.test(urlStr)) { const buffer = await readFile(urlStr); From 89352f38a15d9bf6261aa8c34e05db736041490f Mon Sep 17 00:00:00 2001 From: Leon Zandman Date: Sat, 28 Feb 2026 23:07:41 +0100 Subject: [PATCH 6/6] Replace worker-loader with Webpack 5 native worker syntax. --- package-lock.json | 68 +--------------------- package.json | 3 +- src/web/waiters/BackgroundWorkerWaiter.mjs | 4 +- src/web/waiters/InputWaiter.mjs | 6 +- src/web/waiters/OutputWaiter.mjs | 3 +- src/web/waiters/WorkerWaiter.mjs | 6 +- 6 files changed, 8 insertions(+), 82 deletions(-) diff --git a/package-lock.json b/package-lock.json index 152ce15590..4418888ce1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -158,8 +158,7 @@ "webpack": "^5.105.4", "webpack-bundle-analyzer": "^4.10.2", "webpack-dev-server": "5.0.4", - "webpack-node-externals": "^3.0.0", - "worker-loader": "^3.0.8" + "webpack-node-externals": "^3.0.0" }, "engines": { "node": ">=24 <25" @@ -4700,16 +4699,6 @@ "dev": true, "license": "MIT" }, - "node_modules/ajv-keywords": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", - "dev": true, - "license": "MIT", - "peerDependencies": { - "ajv": "^6.9.1" - } - }, "node_modules/ansi-align": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.1.tgz", @@ -12631,21 +12620,6 @@ "url": "https://opencollective.com/webpack" } }, - "node_modules/loader-utils": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", - "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", - "dev": true, - "license": "MIT", - "dependencies": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^2.1.2" - }, - "engines": { - "node": ">=8.9.0" - } - }, "node_modules/loader-utils-webpack-v4": { "name": "loader-utils", "version": "2.0.4", @@ -18423,46 +18397,6 @@ "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==", "license": "MIT" }, - "node_modules/worker-loader": { - "version": "3.0.8", - "resolved": "https://registry.npmjs.org/worker-loader/-/worker-loader-3.0.8.tgz", - "integrity": "sha512-XQyQkIFeRVC7f7uRhFdNMe/iJOdO6zxAaR3EWbDp45v3mDhrTi+++oswKNxShUNjPC/1xUp5DB29YKLhFo129g==", - "dev": true, - "license": "MIT", - "dependencies": { - "loader-utils": "^2.0.0", - "schema-utils": "^3.0.0" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^4.0.0 || ^5.0.0" - } - }, - "node_modules/worker-loader/node_modules/schema-utils": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", - "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, "node_modules/workerpool": { "version": "6.5.1", "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.5.1.tgz", diff --git a/package.json b/package.json index 8012e7f117..ebeaa5e219 100644 --- a/package.json +++ b/package.json @@ -89,8 +89,7 @@ "webpack": "^5.105.4", "webpack-bundle-analyzer": "^4.10.2", "webpack-dev-server": "5.0.4", - "webpack-node-externals": "^3.0.0", - "worker-loader": "^3.0.8" + "webpack-node-externals": "^3.0.0" }, "dependencies": { "@alexaltea/capstone-js": "^3.0.5", diff --git a/src/web/waiters/BackgroundWorkerWaiter.mjs b/src/web/waiters/BackgroundWorkerWaiter.mjs index 409c2bbb02..7565090daa 100644 --- a/src/web/waiters/BackgroundWorkerWaiter.mjs +++ b/src/web/waiters/BackgroundWorkerWaiter.mjs @@ -4,8 +4,6 @@ * @license Apache-2.0 */ -import ChefWorker from "worker-loader?inline=no-fallback!../../core/ChefWorker.js"; - /** * Waiter to handle conversations with a ChefWorker in the background. */ @@ -33,7 +31,7 @@ class BackgroundWorkerWaiter { */ registerChefWorker() { log.debug("Registering new background ChefWorker"); - this.chefWorker = new ChefWorker(); + this.chefWorker = new Worker(new URL("../../core/ChefWorker.js", import.meta.url)); this.chefWorker.addEventListener("message", this.handleChefMessage.bind(this)); this.chefWorker.postMessage({ action: "setLogPrefix", diff --git a/src/web/waiters/InputWaiter.mjs b/src/web/waiters/InputWaiter.mjs index 94663a0b2e..4e964e171c 100644 --- a/src/web/waiters/InputWaiter.mjs +++ b/src/web/waiters/InputWaiter.mjs @@ -5,8 +5,6 @@ * @license Apache-2.0 */ -import LoaderWorker from "worker-loader?inline=no-fallback!../workers/LoaderWorker.js"; -import InputWorker from "worker-loader?inline=no-fallback!../workers/InputWorker.mjs"; import Utils, {debounce} from "../../core/Utils.mjs"; import {toBase64} from "../../core/lib/Base64.mjs"; import cptable from "codepage"; @@ -359,7 +357,7 @@ class InputWaiter { } log.debug("Adding new InputWorker"); - this.inputWorker = new InputWorker(); + this.inputWorker = new Worker(new URL("../workers/InputWorker.mjs", import.meta.url)); this.inputWorker.postMessage({ action: "setLogLevel", data: log.getLevel() @@ -405,7 +403,7 @@ class InputWaiter { return -1; } log.debug(`Adding new LoaderWorker (${this.loaderWorkers.length + 1}/${this.maxWorkers}).`); - const newWorker = new LoaderWorker(); + const newWorker = new Worker(new URL("../workers/LoaderWorker.js", import.meta.url)); const workerId = this.workerId++; newWorker.addEventListener("message", this.handleLoaderMessage.bind(this)); newWorker.postMessage({ diff --git a/src/web/waiters/OutputWaiter.mjs b/src/web/waiters/OutputWaiter.mjs index 2b2cb0963c..881acaf0b4 100755 --- a/src/web/waiters/OutputWaiter.mjs +++ b/src/web/waiters/OutputWaiter.mjs @@ -10,7 +10,6 @@ import Dish from "../../core/Dish.mjs"; import {isUTF8, CHR_ENC_SIMPLE_REVERSE_LOOKUP} from "../../core/lib/ChrEnc.mjs"; import {detectFileType} from "../../core/lib/FileType.mjs"; import FileSaver from "file-saver"; -import ZipWorker from "worker-loader?inline=no-fallback!../workers/ZipWorker.mjs"; import { EditorView, @@ -987,7 +986,7 @@ class OutputWaiter { downloadButton.firstElementChild.innerHTML = "autorenew"; log.debug("Creating ZipWorker"); - this.zipWorker = new ZipWorker(); + this.zipWorker = new Worker(new URL("../workers/ZipWorker.mjs", import.meta.url)); this.zipWorker.postMessage({ action: "setLogLevel", data: log.getLevel() diff --git a/src/web/waiters/WorkerWaiter.mjs b/src/web/waiters/WorkerWaiter.mjs index 296aa9565f..f270323ea0 100644 --- a/src/web/waiters/WorkerWaiter.mjs +++ b/src/web/waiters/WorkerWaiter.mjs @@ -5,8 +5,6 @@ * @license Apache-2.0 */ -import ChefWorker from "worker-loader?inline=no-fallback!../../core/ChefWorker.js"; -import DishWorker from "worker-loader?inline=no-fallback!../workers/DishWorker.mjs"; import { debounce } from "../../core/Utils.mjs"; /** @@ -70,7 +68,7 @@ class WorkerWaiter { } log.debug("Adding new DishWorker"); - this.dishWorker.worker = new DishWorker(); + this.dishWorker.worker = new Worker(new URL("../workers/DishWorker.mjs", import.meta.url)); this.dishWorker.worker.addEventListener("message", this.handleDishMessage.bind(this)); this.dishWorker.worker.postMessage({ action: "setLogLevel", @@ -96,7 +94,7 @@ class WorkerWaiter { log.debug(`Adding new ChefWorker (${this.chefWorkers.length + 1}/${this.maxWorkers})`); // Create a new ChefWorker and send it the docURL - const newWorker = new ChefWorker(); + const newWorker = new Worker(new URL("../../core/ChefWorker.js", import.meta.url)); newWorker.addEventListener("message", this.handleChefMessage.bind(this)); newWorker.postMessage({ action: "setLogPrefix",