Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: ai/nanoid
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 3.3.7
Choose a base ref
...
head repository: ai/nanoid
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 3.3.8
Choose a head ref
  • 3 commits
  • 12 files changed
  • 2 contributors

Commits on Nov 26, 2024

  1. Fix pool pollution, infinite loop (#510)

    * Fix pool pollution, infinite loop
    
    When nanoid is called with a fractional value, there were a number
    of undesirable effects:
    - in browser and non-secure, the code infinite loops on `while (size--)`
    - in node, the value of poolOffset becomes fractional, causing calls to
      nanoid to return zeroes until the pool is next filled: when `i` is
      initialized to `poolOffset`, `pool[i] & 63` -> `undefined & 63` -> `0`
    - if the first call in node is a fractional argument, the initial buffer
      allocation fails with an error
    
    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
    size `2**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 than `2**31-1` :)
    
    The browser code is structured in such a way that casting `size` in
    `customRandom` succinctly isn't readily feasible. I chose to cast it
    at the line `let 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, and `size` 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 to `id.length >= size`, which handles
    the fractional case and avoids the infinite loop; `size` is not used
    for anything else there.
    
    * `const` -> `let`
    myndzi authored Nov 26, 2024
    Configuration menu
    Copy the full SHA
    d643045 View commit details
    Browse the repository at this point in the history
  2. Update size limit

    ai committed Nov 26, 2024
    Configuration menu
    Copy the full SHA
    4fe3495 View commit details
    Browse the repository at this point in the history
  3. Release 3.3.8 version

    ai committed Nov 26, 2024
    Configuration menu
    Copy the full SHA
    3044cd5 View commit details
    Browse the repository at this point in the history
Loading