From 742fae6fc61201d14d303d0610b917d92c836f92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Erik=20Pedersen?= Date: Mon, 29 May 2023 11:50:29 +0200 Subject: [PATCH] Fix potential deadlock in ByParam Fixes #11039 --- langs/language.go | 11 +++++++++++ resources/page/pages_sort.go | 6 ++---- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/langs/language.go b/langs/language.go index 4e089606c7b..51cae734da4 100644 --- a/langs/language.go +++ b/langs/language.go @@ -181,3 +181,14 @@ type Collator struct { func (c *Collator) CompareStrings(a, b string) int { return c.c.CompareString(a, b) } + +// CompareStrings compares a and b using the Collator in l. +// It returns -1 if a < b, 1 if a > b and 0 if a == b. +// Note that the Collator is not thread safe, so you may want +// to acquire a lock on it before calling this method. +func CompareStrings(l *Language, a, b string) int { + l.collator.Lock() + defer l.collator.Unlock() + return l.collator.CompareStrings(a, b) + +} diff --git a/resources/page/pages_sort.go b/resources/page/pages_sort.go index b9b905cc227..7731e3e8055 100644 --- a/resources/page/pages_sort.go +++ b/resources/page/pages_sort.go @@ -372,9 +372,6 @@ func (p Pages) ByParam(paramsKey any) Pages { paramsKeyStr := cast.ToString(paramsKey) key := "pageSort.ByParam." + paramsKeyStr - stringLess, close := collatorStringLess(p[0]) - defer close() - paramsKeyComparator := func(p1, p2 Page) bool { v1, _ := p1.Param(paramsKeyStr) v2, _ := p2.Param(paramsKeyStr) @@ -403,7 +400,8 @@ func (p Pages) ByParam(paramsKey any) Pages { s1 := cast.ToString(v1) s2 := cast.ToString(v2) - return stringLess(s1, s2) + // Hold the lock as short as possible, see #11039. + return langs.CompareStrings(p1.CurrentSection().Language(), s1, s2) < 0 }