diff --git a/index.browser.js b/index.browser.js index 9ec0a948..b8a1c8ce 100644 --- a/index.browser.js +++ b/index.browser.js @@ -47,11 +47,11 @@ export let customRandom = (alphabet, defaultSize, getRandom) => { } export let customAlphabet = (alphabet, size = 21) => - customRandom(alphabet, size, random) + customRandom(alphabet, size | 0, random) export let nanoid = (size = 21) => { let id = '' - let bytes = crypto.getRandomValues(new Uint8Array(size)) + let bytes = crypto.getRandomValues(new Uint8Array((size |= 0))) while (size--) { // Using the bitwise AND operator to "cap" the value of // the random byte from 255 to 63, in that way we can make sure diff --git a/index.js b/index.js index a1ce01c6..468b1eb8 100644 --- a/index.js +++ b/index.js @@ -25,8 +25,8 @@ function fillPool(bytes) { } export function random(bytes) { - // `-=` convert `bytes` to number to prevent `valueOf` abusing - fillPool((bytes -= 0)) + // `|=` convert `bytes` to number to prevent `valueOf` abusing and pool pollution + fillPool((bytes |= 0)) return pool.subarray(poolOffset - bytes, poolOffset) } @@ -70,8 +70,8 @@ export function customAlphabet(alphabet, size = 21) { } export function nanoid(size = 21) { - // `-=` convert `size` to number to prevent `valueOf` abusing - fillPool((size -= 0)) + // `|=` convert `size` to number to prevent `valueOf` abusing and pool pollution + fillPool((size |= 0)) let id = '' // We are reading directly from the random pool to avoid creating new array for (let i = poolOffset - size; i < poolOffset; i++) { diff --git a/non-secure/index.js b/non-secure/index.js index 78e522fa..3c3e43ba 100644 --- a/non-secure/index.js +++ b/non-secure/index.js @@ -11,7 +11,7 @@ export let customAlphabet = (alphabet, defaultSize = 21) => { return (size = defaultSize) => { let id = '' // A compact alternative for `for (var i = 0; i < step; i++)`. - let i = size + let i = size | 0 while (i--) { // `| 0` is more compact and faster than `Math.floor()`. id += alphabet[(Math.random() * alphabet.length) | 0] @@ -23,7 +23,7 @@ export let customAlphabet = (alphabet, defaultSize = 21) => { export let nanoid = (size = 21) => { let id = '' // A compact alternative for `for (var i = 0; i < step; i++)`. - let i = size + let i = size | 0 while (i--) { // `| 0` is more compact and faster than `Math.floor()`. id += urlAlphabet[(Math.random() * 64) | 0] diff --git a/test/index.test.js b/test/index.test.js index 6c64f23d..cd52b588 100644 --- a/test/index.test.js +++ b/test/index.test.js @@ -57,6 +57,13 @@ for (let type of ['node', 'browser']) { } }) + test(`avoids pool pollution, infinite loop`, () => { + nanoid(2.1) + const second = nanoid() + const third = nanoid() + notEqual(second, third) + }) + test(`has flat distribution`, () => { let COUNT = 100 * 1000 let LENGTH = nanoid().length