Fix pool pollution, infinite loop #510
Open
+55
−17
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
When nanoid is called with a fractional value, there were a number of undesirable effects:
while (size--)
i
is initialized topoolOffset
,pool[i] & 63
->undefined & 63
->0
I chose
|0
to cast to a signed integer primarily because that has a slightly better outcome in the third case above: if the first call is negative (e.g.nanoid(-1)
) then Node will throw an error for an invalid Buffer size, rather than attempting to allocate a buffer of size2**32-1
. It's also more compact than>>>0
, which would be necessary to cast to an unsigned integer. I don't think there is a use case for generating ids longer than2**31-1
:)The browser code is structured in such a way that casting
size
incustomRandom
succinctly isn't readily feasible. I chose to cast it at the linelet j = step | 0
since casting defaultSize would not fix the infinite loop in all cases, and the other use of defaultSize is to define the step length which is already shown to be fractional and gets cast to an integer with~
anyway.As for the
nanoid
function,new Uint8Array(size)
ignores the fractional part, andsize
doesn't get used further - the function instead calls reduce over the typed array.In the Node/native async customAlphabet variant, I chose to convert the
id.length === size
check toid.length >= size
, which handles the fractional case and avoids the infinite loop;size
is not used for anything else there.