fix: bound the spelling checker's word cache

The remembered answers are keyed on user input and never evicted: a
long session could grow the map without bound. Clear it at 10000 words
and let it refill - a script repeats the same words, so re-checks are
cheap.
This commit is contained in:
Kharec committed 2026-10-15 17:56:48 +02:00
1 parent 823c9f2d0f
commit b0bcb812b1
2 files changed
+38

No files matched your search

+9
View File
@@ -90,6 +90,12 @@ func (c *Checker) Add(word string) {
func normalize(w string) string { return strings.ReplaceAll(w, "’", "'") }
// cacheLimit bounds the remembered answers, which are keyed on user input:
// a long session of typos would grow the map forever otherwise. When full,
// the cache is cleared and refilled; a script repeats the same words, so
// re-checks are cheap.
const cacheLimit = 10000
// Check reports whether word is correct. Words with digits ("3rd", "R2D2")
// and single letters are always accepted.
func (c *Checker) Check(word string) bool {
@@ -104,6 +110,9 @@ func (c *Checker) Check(word string) bool {
}
ok, found := c.cache[word]
if !found {
if len(c.cache) >= cacheLimit {
clear(c.cache)
}
ok = c.dict.Check(word)
c.cache[word] = ok
}
+29
View File
@@ -180,6 +180,35 @@ func TestLatin1(t *testing.T) {
}
}
func TestCheckerCacheBound(t *testing.T) {
d, err := Parse([]byte("SET UTF-8\n"), []byte("1\nknown\n"))
if err != nil {
t.Fatal(err)
}
c := NewChecker(d, nil)
// letters encodes n in bijective base 26: distinct pure-letter words.
letters := func(n int) string {
var w []rune
for {
w = append([]rune{rune('a' + n%26)}, w...)
if n < 26 {
return string(w)
}
n = n/26 - 1
}
}
for i := range 2 * cacheLimit {
c.Check(letters(i))
}
if len(c.cache) > cacheLimit {
t.Errorf("cache holds %d words, limit %d", len(c.cache), cacheLimit)
}
// The answers are unchanged by a clear.
if !c.Check("known") || c.Check("knownn") {
t.Error("wrong answers after the cache cleared")
}
}
func TestWords(t *testing.T) {
got := Words("Élise's well-known R2D2, l’homme… 'quoted' x")
want := []Word{