Repository navigation
fix(v1): preserve caller-owned random buffers - #980
sergioperezcheco wants to merge 4 commits into
Conversation
Copy generated node bytes before applying the multicast bit. Assisted-by: OpenAI gpt-6.1-sol Signed-off-by: sergioperezcheco <checo520@outlook.com>
|
Potentially it's faster to just modify the loop a bit to xor the value when assigning the output, that way you don't have to make a copy of the entire buffer. e.g. from // `node`
for (let n = 0; n < 6; ++n) {
buf[offset++] = node[n];
}to // Set multicast bit
// https://www.rfc-editor.org/rfc/rfc9562.html#section-6.10-3
buf[offset++] = node[0] | 0x01;
// `node`
for (let n = 1; n < 6; ++n) {
buf[offset++] = node[n];
}(this should only be done if |
|
Maybe something like: if (node == null) {
node = rnds.slice(10, 16);
// Set multicast bit
// https://www.rfc-editor.org/rfc/rfc9562.html#section-6.10-3
buf[offset++] = node[0] | 0x01;
} else {
buf[offset++] = node[0];
}
// `node`
for (let n = 1; n < 6; ++n) {
buf[offset++] = node[n];
} |
Address LinusU's review without copying caller-owned random bytes. Assisted-by: autonomous AI agent Signed-off-by: sergioperezcheco <checo520@outlook.com>
|
Changed in d28a601: the generated node now gets its multicast bit only when writing the first output byte, with no node-byte copy or input mutation. Explicit node bytes stay unchanged. The regression, full Node test suite, Node examples, lint, strict publint and an independent built-export replay pass on Node 22; I have not rerun the performance benchmark for this revision. |
There was a problem hiding this comment.
🟡 Changes recommended
Ordinary-array inputs now throw, and overlapping random/output views corrupt v1 node bytes.
2 open issues
What changed in this PR
This PR prevents v1/v6 node generation from modifying caller-owned random buffers while preserving multicast-bit behavior.
Changes:
- Set the multicast bit only when writing the generated node to output.
- Add regression coverage for random sources, buffer views, deterministic reuse, and explicit nodes.
| File | Description |
|---|---|
| src/v1.ts | Moves multicast-bit handling to output writes. |
| src/test/v1.test.ts | Tests input preservation across v1/v6 generation paths. |
Review effort: Balanced
| // `node` | ||
| for (let n = 0; n < 6; ++n) { | ||
| if (node == null) { | ||
| node = rnds.subarray(10, 16); |
| if (node == null) { | ||
| node = rnds.subarray(10, 16); | ||
|
|
||
| // Set multicast bit without modifying the random input | ||
| // https://www.rfc-editor.org/rfc/rfc9562.html#section-6.10-3 | ||
| buf[offset++] = node[0] | 0x01; | ||
| } else { | ||
| buf[offset++] = node[0]; | ||
| } | ||
| for (let n = 1; n < 6; ++n) { | ||
| buf[offset++] = node[n]; | ||
| } |
Preserve documented ordinary-array random sources using indexed reads. Capture node bytes before output writes can overwrite aliased inputs, without allocating another node array or changing explicit multicast bits. Assisted-by: Hermes Agent (Nous Research), gpt-6.1-sol Signed-off-by: Checo Tang <checo520@outlook.com>
|
Both findings are reproducible on a53ded9. The fix captures the six node bytes in scalar locals before any output writes and uses indexed reads instead of |

v1({ random: Buffer })andv6({ random: Buffer })must not mutate caller-owned random bytes when setting the generated node's multicast bit. Capture the six node bytes in scalar locals before writing the output, preserving ordinary-array random/rng inputs and correct bytes when random or explicit-node views overlap the output. This avoids allocating another node array, following LinusU's review; explicit node multicast bits are unchanged.Regression coverage includes Buffer/Uint8Array and ordinary-array sources, random/rng callbacks, input/output offsets and overlap, deterministic reuse, explicit nodes and separate output buffers. With the same final tests on Node 22/macOS, previous PR production gives 13 failures / 116 passes; the update gives 129 passes. Build, Node examples (ES modules/Jest/TypeScript), full Biome lint, direct changed-file formatting, strict publint and 140 built-export public checks pass. The unchanged
format:checkscript fails on both versions because Biome rejects--check; lint retains an informational schema-version mismatch. Node 20/24, BrowserStack, other operating systems, performance benchmarks and a fresh root frozen-lock install were not run for this revision. The earlier copy-implementation benchmark does not describe this revision.Prepared and checked with autonomous AI assistance through Hermes Agent; no human code review is claimed.