Fix locale-dependent SQL in truncatedAttributesColumn()

Phillip Davis created

String.format with %d uses the default locale's numeral system.
On Persian (fa) locale this produces ۶۵۵۳۴ instead of 65534,
causing an SQLite error.

Extract the expression into truncatedAttributesColumn() so it
can be tested under a non-default locale, and replace
String.format with concatenation which always uses ASCII digits.

Change summary

src/main/java/eu/siacs/conversations/entities/Conversation.java                     | 11 
src/test/java/eu/siacs/conversations/entities/ConversationAllColumnsLocaleTest.java | 42 
2 files changed, 47 insertions(+), 6 deletions(-)

Detailed changes

src/main/java/eu/siacs/conversations/entities/Conversation.java 🔗

@@ -189,6 +189,10 @@ public class Conversation extends AbstractEntity
     public static final String MODE = "mode";
     public static final String ATTRIBUTES = "attributes";
 
+    static String truncatedAttributesColumn() {
+        return "SUBSTR(" + ATTRIBUTES + ", 0, " + (Short.MAX_VALUE << 1) + ") AS " + ATTRIBUTES;
+    }
+
     public static final String[] ALL_COLUMNS = new String[] {
         UUID,
         NAME,
@@ -198,12 +202,7 @@ public class Conversation extends AbstractEntity
         STATUS,
         CREATED,
         MODE,
-        String.format(
-            "SUBSTR(%s, 0, %d) AS %s",
-            ATTRIBUTES,
-            Short.MAX_VALUE << 1,
-            ATTRIBUTES
-        )
+        truncatedAttributesColumn()
     };
 
 

src/test/java/eu/siacs/conversations/entities/ConversationAllColumnsLocaleTest.java 🔗

@@ -0,0 +1,42 @@
+package eu.siacs.conversations.entities;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.Locale;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.annotation.Config;
+import org.robolectric.annotation.ConscryptMode;
+
+import android.os.Build;
+import eu.siacs.conversations.Conversations;
+
+@RunWith(RobolectricTestRunner.class)
+@Config(sdk = Build.VERSION_CODES.TIRAMISU, application = Conversations.class)
+@ConscryptMode(ConscryptMode.Mode.OFF)
+public class ConversationAllColumnsLocaleTest {
+    private Locale originalLocale;
+
+    @Before
+    public void setUp() {
+        originalLocale = Locale.getDefault();
+        Locale.setDefault(new Locale("fa"));
+    }
+
+    @After
+    public void tearDown() {
+        Locale.setDefault(originalLocale);
+    }
+
+    @Test
+    public void truncatedAttributesColumnUsesAsciiDigits() {
+        assertEquals(
+            "SUBSTR(attributes, 0, 65534) AS attributes",
+            Conversation.truncatedAttributesColumn()
+        );
+    }
+}