]> git.codecow.com Git - nano25519.git/commitdiff
Patch endianness flag to test big-endian function paths.
authorChris Duncan <chris@codecow.com>
Sun, 27 Sep 2026 08:02:25 +0000 (01:02 -0700)
committerChris Duncan <chris@codecow.com>
Sun, 27 Sep 2026 08:02:25 +0000 (01:02 -0700)
package.json
test/big-endian.mjs [new file with mode: 0644]

index ce4c0137bb1349de24fb0e489ddd842a3c872a68..5e9d23efd228a71143e591acaf94d3a4947484ae 100644 (file)
                "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 (file)
index 0000000..d0dfc9b
--- /dev/null
@@ -0,0 +1,49 @@
+//! SPDX-FileCopyrightText: 2026 Chris Duncan <chris@codecow.com>
+//! 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
+       }
+})