uuid/src/rng.ts : the random array is const. Every call will share the same random number. Subsequent call will update your old random code, so if you generated something important... good luck
The old code used to do a slice() which creates a new copy.
Might be unintentional. Although I have no idea how this would pass any tests, as you would think to test generating 2 randomnumbers and hope they are not the same.
Synchronous / serial calls:
import rng from './rng';
const a = rng();
console.log('a after first call: ', Array.from(a));
const b = rng();
console.log('a after second call:', Array.from(a));
console.log('b after second call:', Array.from(b));
console.log('a === b (same reference)? ', a === b);
console.log('a equals b (same contents)? ', a.every((v, i) => v === b[i]));
output: a after first call: [
101, 193, 125, 19, 142,
136, 181, 140, 209, 224,
176, 153, 179, 248, 246,
166
]
a after second call: [
4, 29, 48, 215, 162, 60,
64, 23, 78, 137, 2, 186,
230, 249, 70, 224
]
b after second call: [
4, 29, 48, 215, 162, 60,
64, 23, 78, 137, 2, 186,
230, 249, 70, 224
]
a === b (same reference)? true
a equals b (same contents)? true
and aynchronous calls: import rng from './rng';
async function getId() {
const bytes = rng();
await new Promise(r => setTimeout(r, 0)); // yield to the event loop
return Array.from(bytes);
}
const [id1, id2] = await Promise.all([getId(), getId()]);
console.log('id1:', id1);
console.log('id2:', id2);
console.log('identical?', id1.every((v, i) => v === id2[i]));
output: id1 captured: [
61, 116, 151, 35, 153,
75, 105, 15, 59, 235,
162, 215, 224, 115, 31,
122
]
id2 captured: [
13, 3, 84, 28, 22, 176,
160, 70, 67, 246, 1, 37,
38, 61, 171, 23
]
id1 after await: [
13, 3, 84, 28, 22, 176,
160, 70, 67, 246, 1, 37,
38, 61, 171, 23
]
id2 after await: [
13, 3, 84, 28, 22, 176,
160, 70, 67, 246, 1, 37,
38, 61, 171, 23
]
---
final id1: [
13, 3, 84, 28, 22, 176,
160, 70, 67, 246, 1, 37,
38, 61, 171, 23
]
final id2: [
13, 3, 84, 28, 22, 176,
160, 70, 67, 246, 1, 37,
38, 61, 171, 23
]
identical? trueYour test is more-or-less contrived to fail given the tradeoff to avoid repeated memory allocations but that doesn't say much about the actual usage in uuid generation since it's not exported for general purpose use.
Presumably they had some hot path somewhere where rng() is called in a loop and this optimization made sense with awareness that it could be misused as in your example breaking the contract ensuring randomness, which (hopefully) they're not actually doing anywhere.
Unless I'm missing something replacing the package over this with a less vetted implementation seems excessive and possibly even counterproductive.
became
https://github.com/uuidjs/uuid/blob/f2c235f93059325fa43e1106...
Welp.. time to patch and update everything again. Another day, another npm-package headache. Very odd()
Attack vector: call the rng(), and send the result somewhere. You now have now overwritten someone elses "random number" and know about it. The fun things you can do with those numbers!