Skip to content

Commit 62e3084

Browse files
HazATbillyvg
authored andcommitted
fix: uuidv4 fix for cloudflare (#8968)
1 parent 1e1c120 commit 62e3084

File tree

2 files changed

+38
-8
lines changed

2 files changed

+38
-8
lines changed

packages/utils/src/misc.ts

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,19 @@ export function uuid4(): string {
2525
const gbl = GLOBAL_OBJ as typeof GLOBAL_OBJ & CryptoGlobal;
2626
const crypto = gbl.crypto || gbl.msCrypto;
2727

28-
if (crypto && crypto.randomUUID) {
29-
return crypto.randomUUID().replace(/-/g, '');
28+
let getRandomByte = (): number => Math.random() * 16;
29+
try {
30+
if (crypto && crypto.randomUUID) {
31+
return crypto.randomUUID().replace(/-/g, '');
32+
}
33+
if (crypto && crypto.getRandomValues) {
34+
getRandomByte = () => crypto.getRandomValues(new Uint8Array(1))[0];
35+
}
36+
} catch (_) {
37+
// some runtimes can crash invoking crypto
38+
// https://github.com/getsentry/sentry-javascript/issues/8935
3039
}
3140

32-
const getRandomByte =
33-
crypto && crypto.getRandomValues ? () => crypto.getRandomValues(new Uint8Array(1))[0] : () => Math.random() * 16;
34-
3541
// http://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript/2117523#2117523
3642
// Concatenating the following numbers as strings results in '10000000100040008000100000000000'
3743
return (([1e7] as unknown as string) + 1e3 + 4e3 + 8e3 + 1e11).replace(/[018]/g, c =>

packages/utils/test/misc.test.ts

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -290,11 +290,12 @@ describe('checkOrSetAlreadyCaught()', () => {
290290
});
291291

292292
describe('uuid4 generation', () => {
293+
const uuid4Regex = /^[0-9A-F]{12}[4][0-9A-F]{3}[89AB][0-9A-F]{15}$/i;
293294
// Jest messes with the global object, so there is no global crypto object in any node version
294295
// For this reason we need to create our own crypto object for each test to cover all the code paths
295296
it('returns valid uuid v4 ids via Math.random', () => {
296297
for (let index = 0; index < 1_000; index++) {
297-
expect(uuid4()).toMatch(/^[0-9A-F]{12}[4][0-9A-F]{3}[89AB][0-9A-F]{15}$/i);
298+
expect(uuid4()).toMatch(uuid4Regex);
298299
}
299300
});
300301

@@ -305,7 +306,7 @@ describe('uuid4 generation', () => {
305306
(global as any).crypto = { getRandomValues: cryptoMod.getRandomValues };
306307

307308
for (let index = 0; index < 1_000; index++) {
308-
expect(uuid4()).toMatch(/^[0-9A-F]{12}[4][0-9A-F]{3}[89AB][0-9A-F]{15}$/i);
309+
expect(uuid4()).toMatch(uuid4Regex);
309310
}
310311
});
311312

@@ -316,7 +317,30 @@ describe('uuid4 generation', () => {
316317
(global as any).crypto = { randomUUID: cryptoMod.randomUUID };
317318

318319
for (let index = 0; index < 1_000; index++) {
319-
expect(uuid4()).toMatch(/^[0-9A-F]{12}[4][0-9A-F]{3}[89AB][0-9A-F]{15}$/i);
320+
expect(uuid4()).toMatch(uuid4Regex);
321+
}
322+
});
323+
324+
it("return valid uuid v4 even if crypto doesn't exists", () => {
325+
(global as any).crypto = { getRandomValues: undefined, randomUUID: undefined };
326+
327+
for (let index = 0; index < 1_000; index++) {
328+
expect(uuid4()).toMatch(uuid4Regex);
329+
}
330+
});
331+
332+
it('return valid uuid v4 even if crypto invoked causes an error', () => {
333+
(global as any).crypto = {
334+
getRandomValues: () => {
335+
throw new Error('yo');
336+
},
337+
randomUUID: () => {
338+
throw new Error('yo');
339+
},
340+
};
341+
342+
for (let index = 0; index < 1_000; index++) {
343+
expect(uuid4()).toMatch(uuid4Regex);
320344
}
321345
});
322346
});

0 commit comments

Comments
 (0)