Skip to content

Commit a67db57

Browse files
JSap0914broofa
andauthored
fix(v7): align default seq formula in v7Bytes with updateV7State (#965)
--------- Co-authored-by: JSap0914 <JSap0914@users.noreply.github.com> Co-authored-by: Robert Kieffer <robert@broofa.com>
1 parent 7017780 commit a67db57

2 files changed

Lines changed: 43 additions & 3 deletions

File tree

‎src/test/v7.test.ts‎

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ describe('v7', () => {
173173
now: 2,
174174
expected: {
175175
msecs: 2, // time interval should update
176-
seq: 0x6c318c4, // sequence should be randomized
176+
seq: 0xcc318c4, // sequence should be randomized
177177
},
178178
},
179179
{
@@ -297,4 +297,40 @@ describe('v7', () => {
297297
assert.throws(() => v7({}, buf30, -1), RangeError);
298298
assert.throws(() => v7({}, buf30, 15), RangeError);
299299
});
300+
301+
test('default seq (no explicit seq option) is consistent with updateV7State formula', () => {
302+
// When v7() is called with random bytes and msecs but no explicit seq, the
303+
// default seq should use the same formula as updateV7State() –
304+
// ((rnds[6] & 0x7f) << 24) | (rnds[7] << 16) | (rnds[8] << 8) | rnds[9].
305+
//
306+
// Regression: the formula was `(rnds[6] * 0x7f) << 24`, which should have
307+
// been `(rnds[6] & 0x7f) << 24`, producing a seq inconsistent with
308+
// updateV7State.
309+
const rnds = Uint8Array.of(
310+
0x02,
311+
0x91,
312+
0x56,
313+
0xbe,
314+
0xc4,
315+
0xfb,
316+
0x02,
317+
0xc3,
318+
0x18,
319+
0xc4,
320+
0x6c,
321+
0x0c,
322+
0x0c,
323+
0x07,
324+
0x39,
325+
0x8f,
326+
);
327+
const state = updateV7State({}, RFC_MSECS, rnds);
328+
const uuidWithExplicitSeq = v7({
329+
random: rnds,
330+
msecs: RFC_MSECS,
331+
seq: state.seq,
332+
});
333+
const uuidWithDefaultSeq = v7({ random: rnds, msecs: RFC_MSECS });
334+
assert.strictEqual(uuidWithDefaultSeq, uuidWithExplicitSeq);
335+
});
300336
});

‎src/v7.ts‎

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ export function updateV7State(state: V7State, now: number, rnds: Uint8Array) {
5656

5757
if (now > state.msecs) {
5858
// Time has moved on! Pick a new random sequence number
59-
state.seq = (rnds[6] << 23) | (rnds[7] << 16) | (rnds[8] << 8) | rnds[9];
59+
state.seq = v7Sequence(rnds);
6060
state.msecs = now;
6161
} else {
6262
// Bump sequence counter w/ 32-bit rollover
@@ -97,7 +97,7 @@ function v7Bytes(
9797

9898
// Defaults
9999
msecs ??= Date.now();
100-
seq ??= ((rnds[6] * 0x7f) << 24) | (rnds[7] << 16) | (rnds[8] << 8) | rnds[9];
100+
seq ??= v7Sequence(rnds);
101101

102102
// byte 0-5: timestamp (48 bits)
103103
buf[offset++] = (msecs / 0x10000000000) & 0xff;
@@ -132,4 +132,8 @@ function v7Bytes(
132132
return buf;
133133
}
134134

135+
function v7Sequence(rnds: Uint8Array) {
136+
return ((rnds[6] & 0x7f) << 24) | (rnds[7] << 16) | (rnds[8] << 8) | rnds[9];
137+
}
138+
135139
export default v7;

0 commit comments

Comments
 (0)