mirror of
https://github.com/vercel-labs/scriptc.git
synced 2026-10-23 06:10:02 +08:00
createCipheriv, createDecipheriv, update(), setAAD() and setAuthTag() now read the value a typed-ref box holds when it is a string, view, ArrayBuffer or KeyObject. ERR_INVALID_ARG_TYPE names the class of a class instance that arrives through an untyped value, as Node does, instead of Object. An unknown output encoding that is not a string is rendered as Node's %s formats it (util.inspect at depth 0, or the object's own toString); a function, or an instance of a class that defines toString, throws a coded SC2020 error. Cipher programs link the inspect unit for that rendering. 5250 passes each argument through `any`, including class instances, records and arrays that Node rejects, and 5254 covers output encodings that are not strings from JavaScript.
103 lines
2.6 KiB
TypeScript
103 lines
2.6 KiB
TypeScript
import { execFile } from "node:child_process";
|
|
import { mkdir } from "node:fs/promises";
|
|
import { join } from "node:path";
|
|
import { promisify } from "node:util";
|
|
import { beforeAll, expect, test } from "vitest";
|
|
|
|
const execFileAsync = promisify(execFile);
|
|
const testDir = import.meta.dirname;
|
|
const bin = join(testDir, "build", "test_cipher");
|
|
const mbedtls = join(testDir, "../vendor/mbedtls");
|
|
|
|
const runtimeSources = [
|
|
"scr_shared.c",
|
|
"scr_bytes.c",
|
|
"scr_bytes.test.c",
|
|
"scr_bytes_io.c",
|
|
"scr_zlib.c",
|
|
"scr_lib.c",
|
|
"scr_hash.c",
|
|
"scr_string.c",
|
|
"scr_array.c",
|
|
"scr_map.c",
|
|
"scr_exception.c",
|
|
"scr_error.c",
|
|
"scr_number.c",
|
|
"scr_console.c",
|
|
"scr_closure.c",
|
|
"scr_ffi.c",
|
|
"scr_object.c",
|
|
"scr_union.c",
|
|
"scr_cycle.c",
|
|
"scr_alloc.c",
|
|
"scr_json.c",
|
|
"scr_inspect.c",
|
|
"scr_bigint.c",
|
|
"scr_async.c",
|
|
"scr_async_dyn.c",
|
|
"scr_child.c",
|
|
"scr_path.c",
|
|
"scr_url.c",
|
|
"scr_url_params.c",
|
|
];
|
|
|
|
// The AES, GCM, ChaCha20 and Poly1305 modules, and the generic cipher layer
|
|
// GCM is built on with the default configuration.
|
|
const mbedtlsSources = [
|
|
"aes.c",
|
|
"aesce.c",
|
|
"aesni.c",
|
|
"aria.c",
|
|
"camellia.c",
|
|
"ccm.c",
|
|
"chacha20.c",
|
|
"chachapoly.c",
|
|
"cipher.c",
|
|
"cipher_wrap.c",
|
|
"constant_time.c",
|
|
"des.c",
|
|
"gcm.c",
|
|
"nist_kw.c",
|
|
"platform_util.c",
|
|
"poly1305.c",
|
|
];
|
|
|
|
// Compiled once with ASan + the RC audit. test_cipher.c includes
|
|
// scr_cipher.c, moves contexts next to mbedTLS's GCM message and AAD
|
|
// limits, and checks that a failed update() or setAAD() returns no data
|
|
// and leaves every later call throwing, and that chacha20-poly1305
|
|
// decryption without a tag fails in final().
|
|
beforeAll(async () => {
|
|
await mkdir(join(testDir, "build"), { recursive: true });
|
|
await execFileAsync("clang", [
|
|
"-std=c11",
|
|
"-O1",
|
|
"-Wall",
|
|
"-Wextra",
|
|
"-Wno-missing-field-initializers",
|
|
"-fsanitize=address,undefined",
|
|
"-DSCR_RC_AUDIT",
|
|
"-I",
|
|
join(testDir, "../src"),
|
|
"-I",
|
|
join(mbedtls, "include"),
|
|
"-I",
|
|
join(mbedtls, "library"),
|
|
"-o",
|
|
bin,
|
|
join(testDir, "test_cipher.c"),
|
|
...runtimeSources.map((source) => join(testDir, "../src", source)),
|
|
...mbedtlsSources.map((source) => join(mbedtls, "library", source)),
|
|
"-Wno-deprecated-declarations",
|
|
"-lz",
|
|
...(process.platform === "linux" ? ["-D_GNU_SOURCE", "-lm"] : []),
|
|
]);
|
|
}, 300_000);
|
|
|
|
test("cipher runtime: backend failures retire the context", async () => {
|
|
const { stderr } = await execFileAsync(bin, [], {
|
|
env: { ...process.env, UBSAN_OPTIONS: "halt_on_error=1" },
|
|
});
|
|
expect(stderr.trim().split("\n").pop()).toMatch(/^(\d+)\/\1 cases passed$/);
|
|
});
|