Skip to content

Commit 74f9f5a

Browse files
committed
Additional fixes and tests for ai#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.
1 parent 313a14e commit 74f9f5a

File tree

4 files changed

+28
-3
lines changed

4 files changed

+28
-3
lines changed

index.browser.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ export let customRandom = (alphabet, defaultSize, getRandom) => {
4040
while (j--) {
4141
// Adding `|| ''` refuses a random byte that exceeds the alphabet size.
4242
id += alphabet[bytes[j] & mask] || ''
43-
if (id.length === size) return id
43+
if (id.length >= size) return id
4444
}
4545
}
4646
}

index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ export function customRandom(alphabet, defaultSize, getRandom) {
5959
while (i--) {
6060
// Adding `|| ''` refuses a random byte that exceeds the alphabet size.
6161
id += alphabet[bytes[i] & mask] || ''
62-
if (id.length === size) return id
62+
if (id.length >= size) return id
6363
}
6464
}
6565
}

test/index.test.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,15 @@ for (let type of ['node', 'browser']) {
126126
equal(nanoidA(10), 'aaaaaaaaaa')
127127
})
128128

129+
test(`${type} / customAlphabet / avoids pool pollution, infinite loop`, () => {
130+
let ALPHABET = 'abcdefghijklmnopqrstuvwxyz'
131+
const nanoid2 = customAlphabet(ALPHABET)
132+
nanoid2(2.1)
133+
const second = nanoid2()
134+
const third = nanoid2()
135+
notEqual(second, third)
136+
})
137+
129138
test(`${type} / customRandom / supports generator`, () => {
130139
let sequence = [2, 255, 3, 7, 7, 7, 7, 7, 0, 1]
131140
function fakeRandom(size) {

test/non-secure.test.js

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { equal, match, ok } from 'node:assert'
1+
import { equal, match, ok, notEqual } from 'node:assert'
22
import { describe, test } from 'node:test'
33

44
import { urlAlphabet } from '../index.js'
@@ -57,6 +57,13 @@ describe('non secure', () => {
5757
ok(max - min <= 0.05)
5858
})
5959

60+
test('nanoid / avoids pool pollution, infinite loop', () => {
61+
nanoid(2.1)
62+
const second = nanoid()
63+
const third = nanoid()
64+
notEqual(second, third)
65+
})
66+
6067
test('customAlphabet / has options', () => {
6168
let nanoidA = customAlphabet('a', 5)
6269
equal(nanoidA(), 'aaaaa')
@@ -88,4 +95,13 @@ describe('non secure', () => {
8895
}
8996
ok(max - min <= 0.05)
9097
})
98+
99+
test('customAlphabet / avoids pool pollution, infinite loop', () => {
100+
let ALPHABET = 'abcdefghijklmnopqrstuvwxyz'
101+
let nanoid2 = customAlphabet(ALPHABET)
102+
nanoid2(2.1)
103+
const second = nanoid2()
104+
const third = nanoid2()
105+
notEqual(second, third)
106+
})
91107
})

0 commit comments

Comments
 (0)