Skip to content

Commit

Permalink
Fix infinite loop in rindexes with maxless data
Browse files Browse the repository at this point in the history
Verify that index is not undefined in isValidIndex()

Fixes a bug introduced in c29079d, when support for non-preallocated
data bound by ttl and/or maxSize was added.  When the pointer array is a
`number[]` instead of a `UintArray`, unset values will be `undefined`
rather than `0`, resulting in the situation where `index ===
this.keyMap.get(this.keyList[index])` is not a valid test for index
validity, since it can be `undefined` rather than always being
guaranteed to be a number.

Another way to fix this would be ensure that a previously unused spot in
the array is initialized to `0` when pointers are initialized.  However,
in performance critical cases, every set and get matters, and relying on
the initialized state of a UintArray saves that check in several hot
paths.  On the other hand, the test for `index === undefined` only has
to happen during iteration, which is much less likely to be performance
critical.

Fix: #278
  • Loading branch information
isaacs committed Mar 5, 2023
1 parent 078625c commit d5f0fde
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 1 deletion.
5 changes: 4 additions & 1 deletion index.js
Original file line number Diff line number Diff line change
Expand Up @@ -488,7 +488,10 @@ class LRUCache {
}

isValidIndex(index) {
return this.keyMap.get(this.keyList[index]) === index
return (
index !== undefined &&
this.keyMap.get(this.keyList[index]) === index
)
}

*entries() {
Expand Down
13 changes: 13 additions & 0 deletions test/reverse-iterate-delete-all.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// https://github.com/isaacs/node-lru-cache/issues/278
import t from 'tap'
import LRU from '../'
const lru = new LRU<string, string>({
maxSize:2,
sizeCalculation: () => 1,
});
lru.set('x', 'x')
lru.set('y', 'y')
for (const key of lru.rkeys()) {
lru.delete(key)
}
t.equal(lru.size, 0)

0 comments on commit d5f0fde

Please sign in to comment.