Skip to content

Commit 2b7bd93

Browse files
authored
fix collision by proxy number (#328)
1 parent 3b56634 commit 2b7bd93

File tree

2 files changed

+40
-2
lines changed

2 files changed

+40
-2
lines changed

index.js

+4-2
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@ let fillPool = bytes => {
2323
}
2424

2525
let random = bytes => {
26-
fillPool(bytes)
26+
// `-=` convert `bytes` to number to prevent `valueOf` abusing
27+
fillPool((bytes -= 0))
2728
return pool.subarray(poolOffset - bytes, poolOffset)
2829
}
2930

@@ -65,7 +66,8 @@ let customRandom = (alphabet, size, getRandom) => {
6566
let customAlphabet = (alphabet, size) => customRandom(alphabet, size, random)
6667

6768
let nanoid = (size = 21) => {
68-
fillPool(size)
69+
// `-=` convert `size` to number to prevent `valueOf` abusing
70+
fillPool((size -= 0))
6971
let id = ''
7072
// We are reading directly from the random pool to avoid creating new array
7173
for (let i = poolOffset - size; i < poolOffset; i++) {

test/index.test.js

+36
Original file line numberDiff line numberDiff line change
@@ -151,5 +151,41 @@ for (let type of ['node', 'browser']) {
151151
}
152152
})
153153
})
154+
155+
if (type === 'node') {
156+
describe('proxy number', () => {
157+
it('prevent collision', () => {
158+
let makeProxyNumberToReproducePreviousID = () => {
159+
let step = 0
160+
return {
161+
valueOf() {
162+
// "if (!pool || pool.length < bytes) {"
163+
if (step === 0) {
164+
step++
165+
return 0
166+
}
167+
// "} else if (poolOffset + bytes > pool.length) {"
168+
if (step === 1) {
169+
step++
170+
return -Infinity
171+
}
172+
// "poolOffset += bytes"
173+
if (step === 2) {
174+
step++
175+
return 0
176+
}
177+
178+
return 21
179+
}
180+
}
181+
}
182+
183+
let ID1 = nanoid()
184+
let ID2 = nanoid(makeProxyNumberToReproducePreviousID())
185+
186+
expect(ID1).not.toBe(ID2)
187+
})
188+
})
189+
}
154190
})
155191
}

0 commit comments

Comments
 (0)