From 45e20d8c9e5e3b570cf927eed97923661e9eb440 Mon Sep 17 00:00:00 2001 From: David Perez Date: Wed, 20 Aug 2025 15:20:03 -0500 Subject: [PATCH] PM-17755: Fix comparator inconsistency based on Locale (#5762) --- .../SpecialCharWithPrecedenceComparator.kt | 5 +-- ...SpecialCharWithPrecedenceComparatorTest.kt | 35 ++++++++++++++++++- 2 files changed, 37 insertions(+), 3 deletions(-) diff --git a/core/src/main/kotlin/com/bitwarden/core/data/repository/util/SpecialCharWithPrecedenceComparator.kt b/core/src/main/kotlin/com/bitwarden/core/data/repository/util/SpecialCharWithPrecedenceComparator.kt index 3fcfd8e382..a30a810a6c 100644 --- a/core/src/main/kotlin/com/bitwarden/core/data/repository/util/SpecialCharWithPrecedenceComparator.kt +++ b/core/src/main/kotlin/com/bitwarden/core/data/repository/util/SpecialCharWithPrecedenceComparator.kt @@ -38,8 +38,9 @@ private fun compareCharsSpecialCharsWithPrecedence(c1: Char, c2: Char): Int { } else -> { - val upperCaseStr1 = c1.toString().uppercase(Locale.getDefault()) - val upperCaseStr2 = c2.toString().uppercase(Locale.getDefault()) + // Use Locale.ROOT for consistent, locale-insensitive comparison + val upperCaseStr1 = c1.toString().uppercase(Locale.ROOT) + val upperCaseStr2 = c2.toString().uppercase(Locale.ROOT) upperCaseStr1.compareTo(upperCaseStr2) } } diff --git a/core/src/test/kotlin/com/bitwarden/core/data/repository/util/SpecialCharWithPrecedenceComparatorTest.kt b/core/src/test/kotlin/com/bitwarden/core/data/repository/util/SpecialCharWithPrecedenceComparatorTest.kt index 892c643a5f..00293930fb 100644 --- a/core/src/test/kotlin/com/bitwarden/core/data/repository/util/SpecialCharWithPrecedenceComparatorTest.kt +++ b/core/src/test/kotlin/com/bitwarden/core/data/repository/util/SpecialCharWithPrecedenceComparatorTest.kt @@ -1,10 +1,25 @@ package com.bitwarden.core.data.repository.util -import org.junit.Test +import org.junit.jupiter.api.AfterEach import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.Test +import java.util.Locale class SpecialCharWithPrecedenceComparatorTest { + private lateinit var defaultLocale: Locale + + @BeforeEach + fun setup() { + defaultLocale = Locale.getDefault() + } + + @AfterEach + fun tearDown() { + Locale.setDefault(defaultLocale) + } + @Test fun `Sorting with comparator should return expected result of sorted string`() { val unsortedList = listOf( @@ -41,4 +56,22 @@ class SpecialCharWithPrecedenceComparatorTest { unsortedList.sortedWith(SpecialCharWithPrecedenceComparator), ) } + + @Test + fun `comparator should return consistent values across locales`() { + val unsortedList = listOf("i", "z", "j") + val sortedList = listOf("i", "j", "z") + val locales = listOf( + Locale.forLanguageTag("tr-TR"), + Locale.US, + ) + + locales.forEach { locale -> + Locale.setDefault(locale) + assertEquals( + sortedList, + unsortedList.sortedWith(SpecialCharWithPrecedenceComparator), + ) + } + } }