diff --git a/CHANGELOG.md b/CHANGELOG.md index 36d8e6f8..112265c2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,11 @@ - Fixed typo in `Record.WithUnkownData()` -> `Record.WithUnknownData()`. +## v0.14.4 + +- Fixed concurrent map write pannic on `list.ExistInSliceWithRegex()` cache ([#2272](https://github.com/pocketbase/pocketbase/issues/2272)). + + ## v0.14.3 - Fixed Admin UI Logs `meta` visualization in Firefox ([#2221](https://github.com/pocketbase/pocketbase/issues/2221)). diff --git a/tools/list/list.go b/tools/list/list.go index ae796e31..63909a29 100644 --- a/tools/list/list.go +++ b/tools/list/list.go @@ -5,10 +5,11 @@ import ( "regexp" "strings" + "github.com/pocketbase/pocketbase/tools/store" "github.com/spf13/cast" ) -var cachedPatterns = map[string]*regexp.Regexp{} +var cachedPatterns = store.New[*regexp.Regexp](nil) // SubtractSlice returns a new slice with only the "base" elements // that don't exist in "subtract". @@ -56,15 +57,18 @@ func ExistInSliceWithRegex(str string, list []string) bool { } // check for regex match - pattern, ok := cachedPatterns[field] - if !ok { + pattern := cachedPatterns.Get(field) + if pattern == nil { var err error pattern, err = regexp.Compile(field) if err != nil { continue } // "cache" the pattern to avoid compiling it every time - cachedPatterns[field] = pattern + // (the limit size is arbitrary and it is there to prevent the cache growing too big) + // + // @todo consider replacing with TTL or LRU type cache + cachedPatterns.SetIfLessThanLimit(field, pattern, 5000) } if pattern != nil && pattern.MatchString(str) {