https://bugs.kde.org/show_bug.cgi?id=461070

--- Comment #14 from Maciej Stanczew <maciej.stancze...@gmail.com> ---
Created attachment 160781
  --> https://bugs.kde.org/attachment.cgi?id=160781&action=edit
sensors: Correctly handle the return value of QCollator::compare

I think I have found the root cause for this issue: it's in libksysguard, and
was introduced with the fix to bug #440310.

First, I located the place in the code which is impacted by changing between
en_US and C locales: it's the Compare structure in SensorTreeModel.cpp, and its
use as a comparator in an std::map in SensorTreeItem:
> std::map<QString, std::unique_ptr<SensorTreeItem>, Compare> children;

After adding some debug logs I noticed a weird behavior. Calls to Compare()
seemed ok with en_US, but with the C locale I was getting a 'false' result
regardless of the order of arguments:
> # with LC_COLLATE=en_US.UTF-8
> Compare("cpu", "lmsensors") = true
> Compare("lmsensors", "cpu") = false
> # with LC_COLLATE=C.UTF-8
> Compare("cpu", "lmsensors") = false
> Compare("lmsensors", "cpu") = false

Adding more information to the logs revealed the cause of this behavior:
> # with LC_COLLATE=en_US.UTF-8
> Compare("cpu", "lmsensors") = true, collator->compare() = -1
> Compare("lmsensors", "cpu") = false, collator->compare() = 1
> # with LC_COLLATE=C.UTF-8
> Compare("cpu", "lmsensors") = false, collator->compare() = -9
> Compare("lmsensors", "cpu") = false, collator->compare() = 9

We can see that with the C locale, 'collator->compare()' returns the
lexicographical difference between characters (e.g. 'c' - 'l' = -9), and with
en_US it squashes the value to -1. And since the code in Compare only checks
against -1, all the other negative values are not handled correctly:
> return collator->compare(first, second) == -1;

Documentation about QCollator::compare() doesn't restrict the return value to
[-1, 0, 1]:
> Returns an integer less than, equal to, or greater than zero depending on 
> whether s1 sorts before, with or after s2.

Thus comparing the returned value against -1 is based on an incorrect
assumption, which just happens to work with most locales, but breaks with the C
locale.

If I'm not missing anything, the fix should be easy enough: change "== -1" to
"< 0". I have prepared a patch based on 5.27.7 and tested it on my setup, and I
get correct sensor list even with 'LC_COLLATE=C.UTF-8'.

-- 
You are receiving this mail because:
You are watching all bug changes.

Reply via email to