The vulnerable functions were identified by analyzing the changes in commit 'ae1075df9e7c1917ad164ea7954ab15920c0beff', which addresses the vulnerability. The core issue is the handling of fractional numeric inputs for 'size' or 'bytes' parameters in various functions across different nanoid implementations (browser, Node.js, async, non-secure).
The patches primarily involve:
- Casting the input 'size' or derived values ('step', 'i', 'j') to integers using a bitwise OR with zero (e.g.,
size |= 0, step | 0). This prevents fractional values from causing issues in loops like while (size--) or array indexing/allocations.
- Modifying loop exit conditions (e.g.,
id.length === size to id.length >= size) to correctly handle cases where 'size' might be fractional and an exact match is impossible for an integer length.
The identified functions are those where these changes were made, indicating they were previously susceptible to the described problems: infinite loops (in browser/non-secure contexts due to while (fractional_value--)), predictable output/zeroes (in Node.js due to fractional poolOffset after fillPool is called with a fractional size), or buffer allocation errors (in Node.js if fillPool receives a problematic fractional size).
Functions like customAlphabet are included if they either directly contained such a loop or condition, or if they served as an entry point that passed a fractional value to another vulnerable internal function (like random in index.js) that was subsequently patched.