From 0daa00f68acc2f958ba19f73ddef700ce4049ab7 Mon Sep 17 00:00:00 2001 From: Kris Reeves Date: Tue, 26 Nov 2024 02:54:36 -0800 Subject: [PATCH] Additional fixes and tests for #508 (#509) * Additional fixes and tests for #508 I didn't fully understand the project and test structure, but while preparing the backport for v3 I gained a fuller understanding. The tests now exercise the customAlphabet code and the non-secure variant, and fix the infinite loop case in `customRandom` on both node and the browser. * `const` -> `let` * lint --- index.browser.js | 2 +- index.js | 2 +- test/index.test.js | 9 +++++++++ test/non-secure.test.js | 18 +++++++++++++++++- 4 files changed, 28 insertions(+), 3 deletions(-) diff --git a/index.browser.js b/index.browser.js index b8a1c8ce..4e242791 100644 --- a/index.browser.js +++ b/index.browser.js @@ -40,7 +40,7 @@ export let customRandom = (alphabet, defaultSize, getRandom) => { while (j--) { // Adding `|| ''` refuses a random byte that exceeds the alphabet size. id += alphabet[bytes[j] & mask] || '' - if (id.length === size) return id + if (id.length >= size) return id } } } diff --git a/index.js b/index.js index 468b1eb8..f21f1822 100644 --- a/index.js +++ b/index.js @@ -59,7 +59,7 @@ export function customRandom(alphabet, defaultSize, getRandom) { while (i--) { // Adding `|| ''` refuses a random byte that exceeds the alphabet size. id += alphabet[bytes[i] & mask] || '' - if (id.length === size) return id + if (id.length >= size) return id } } } diff --git a/test/index.test.js b/test/index.test.js index 6608e97a..d8577ed8 100644 --- a/test/index.test.js +++ b/test/index.test.js @@ -126,6 +126,15 @@ for (let type of ['node', 'browser']) { equal(nanoidA(10), 'aaaaaaaaaa') }) + test(`${type} / customAlphabet / avoids pool pollution, infinite loop`, () => { + let ALPHABET = 'abcdefghijklmnopqrstuvwxyz' + let nanoid2 = customAlphabet(ALPHABET) + nanoid2(2.1) + let second = nanoid2() + let third = nanoid2() + notEqual(second, third) + }) + test(`${type} / customRandom / supports generator`, () => { let sequence = [2, 255, 3, 7, 7, 7, 7, 7, 0, 1] function fakeRandom(size) { diff --git a/test/non-secure.test.js b/test/non-secure.test.js index 59144104..c7396340 100644 --- a/test/non-secure.test.js +++ b/test/non-secure.test.js @@ -1,4 +1,4 @@ -import { equal, match, ok } from 'node:assert' +import { equal, match, notEqual, ok } from 'node:assert' import { describe, test } from 'node:test' import { urlAlphabet } from '../index.js' @@ -57,6 +57,13 @@ describe('non secure', () => { ok(max - min <= 0.05) }) + test('nanoid / avoids pool pollution, infinite loop', () => { + nanoid(2.1) + let second = nanoid() + let third = nanoid() + notEqual(second, third) + }) + test('customAlphabet / has options', () => { let nanoidA = customAlphabet('a', 5) equal(nanoidA(), 'aaaaa') @@ -88,4 +95,13 @@ describe('non secure', () => { } ok(max - min <= 0.05) }) + + test('customAlphabet / avoids pool pollution, infinite loop', () => { + let ALPHABET = 'abcdefghijklmnopqrstuvwxyz' + let nanoid2 = customAlphabet(ALPHABET) + nanoid2(2.1) + let second = nanoid2() + let third = nanoid2() + notEqual(second, third) + }) })