From: Chris Duncan Date: Sun, 27 Sep 2026 08:02:25 +0000 (-0700) Subject: Patch endianness flag to test big-endian function paths. X-Git-Url: https://git.codecow.com/?a=commitdiff_plain;h=fdb67340546ef64f88f66b202c00868fc6ddecf1;p=nano25519.git Patch endianness flag to test big-endian function paths. --- diff --git a/package.json b/package.json index ce4c013..5e9d23e 100644 --- a/package.json +++ b/package.json @@ -36,8 +36,11 @@ "clean": "rm -rf {build,dist}", "compile": "node scripts/blake2b-gen.mjs && asc ./src/assembly/index.ts && tsc", "prepublishOnly": "npm run test:prod", - "test": "npm run build && node ./test/node.mjs", - "test:prod": "npm run build:prod && node ./test/node.mjs" + "test": "npm run build && npm run test:all", + "test:all": "npm run test:be && npm run test:le", + "test:be": "node --import ./test/big-endian.mjs ./test/node.mjs", + "test:le": "node ./test/node.mjs", + "test:prod": "npm run build:prod && npm run test:all" }, "devDependencies": { "@types/node": "26.2.0", diff --git a/test/big-endian.mjs b/test/big-endian.mjs new file mode 100644 index 0000000..d0dfc9b --- /dev/null +++ b/test/big-endian.mjs @@ -0,0 +1,49 @@ +//! SPDX-FileCopyrightText: 2026 Chris Duncan +//! SPDX-License-Identifier: GPL-3.0-or-later + +/** + * Preload that makes the package take its big-endian marshalling path on a + * little-endian host: `node --import ./test/big-endian.mjs ./test/node.mjs` + * + * The package probes byte order once, at load, by writing `1` into a + * `Uint32Array` and reading its first byte. This swaps the global constructor + * before the package captures it, so that one probe sees the big-endian layout + * and every other construction passes straight through to the real one. + * + * Forcing the path here is a faithful test of it, not an approximation: the + * big-endian path packs words from individual bytes with shifts, which gives + * the same result on either byte order. What this cannot cover is the probe + * itself, or V8's own wasm memory handling, on real big-endian hardware; for + * that, run the suite under s390x emulation. + */ + +const RealWords = globalThis.Uint32Array +let intercepted = 0 + +/** @this {unknown} */ +function Words (...args) { + if (new.target === undefined) { + return RealWords(...args) + } + const [a] = args + if (args.length === 1 && Array.isArray(a) && a.length === 1 && a[0] === 1) { + intercepted++ + // 1 laid out big-endian: the low byte comes last + return new RealWords([0x01000000]) + } + return new RealWords(...args) +} +Object.setPrototypeOf(Words, RealWords) +Words.prototype = RealWords.prototype +globalThis.Uint32Array = /** @type {Uint32ArrayConstructor} */ (/** @type {unknown} */ (Words)) + +console.log('\x1b[33mBIG-ENDIAN\x1b[0m: byte order probe forced, testing the big-endian marshalling path') + +// Without this, a change to the probe would silently fall back to the +// little-endian path, and this run would pass while testing nothing new. +process.on('exit', () => { + if (intercepted === 0) { + console.log('\x1b[31mFAIL\x1b[0m: big-endian preload never intercepted the byte order probe') + process.exitCode = 1 + } +})