From fd42b4b3526a33338e6fa3f38ce332380139a860 Mon Sep 17 00:00:00 2001 From: Denton Gentry Date: Sat, 12 Mar 2022 17:46:52 -0800 Subject: [PATCH] java: format strings containing integers in ROOT locale. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We use strings to pass structured data from the JVM to Go. In a locale using Indian-Arabic numerals: ۰ ۱ ۲ ۳ ۴ ۵ ۶ ۷ ۸ ۹ the Java code will format decimal strings using Indian-Arabic glyphs. Go doesn't get a locale set automatically by the Android runtime, so it always parses strings in a default en-US `unable to parse "lo ١ ٦٥٥٣٦ true false true false false |": expected integer` Make the Java code format using the ROOT locale. These strings are purely internal to pass between the two runtimes, they are not shown to the user. Fixes https://github.com/tailscale/tailscale/issues/4156 Signed-off-by: Denton Gentry --- android/src/main/java/com/tailscale/ipn/App.java | 5 +++-- android/src/main/java/com/tailscale/ipn/DnsConfig.java | 3 ++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/android/src/main/java/com/tailscale/ipn/App.java b/android/src/main/java/com/tailscale/ipn/App.java index 658f38a..b1b268b 100644 --- a/android/src/main/java/com/tailscale/ipn/App.java +++ b/android/src/main/java/com/tailscale/ipn/App.java @@ -54,6 +54,7 @@ import java.security.GeneralSecurityException; import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.Locale; import androidx.core.app.NotificationCompat; import androidx.core.app.NotificationManagerCompat; @@ -373,7 +374,7 @@ public class App extends Application { try { // Android doesn't have a supportsBroadcast() but the Go net.Interface wants // one, so we say the interface has broadcast if it has multicast. - sb.append(String.format("%s %d %d %b %b %b %b %b |", nif.getName(), + sb.append(String.format(java.util.Locale.ROOT, "%s %d %d %b %b %b %b %b |", nif.getName(), nif.getIndex(), nif.getMTU(), nif.isUp(), nif.supportsMulticast(), nif.isLoopback(), nif.isPointToPoint(), nif.supportsMulticast())); @@ -381,7 +382,7 @@ public class App extends Application { // InterfaceAddress == hostname + "/" + IP String[] parts = ia.toString().split("/", 0); if (parts.length > 1) { - sb.append(String.format("%s/%d ", parts[1], ia.getNetworkPrefixLength())); + sb.append(String.format(java.util.Locale.ROOT, "%s/%d ", parts[1], ia.getNetworkPrefixLength())); } } } catch (Exception e) { diff --git a/android/src/main/java/com/tailscale/ipn/DnsConfig.java b/android/src/main/java/com/tailscale/ipn/DnsConfig.java index 7a9696a..7dc047d 100644 --- a/android/src/main/java/com/tailscale/ipn/DnsConfig.java +++ b/android/src/main/java/com/tailscale/ipn/DnsConfig.java @@ -19,6 +19,7 @@ import java.net.InetAddress; import java.util.ArrayList; import java.util.List; +import java.util.Locale; // Tailscale DNS Config retrieval // @@ -229,7 +230,7 @@ public class DnsConfig { String intToInetString(int hostAddress) { - return String.format("%d.%d.%d.%d", + return String.format(java.util.Locale.ROOT, "%d.%d.%d.%d", (byte)(0xff & hostAddress), (byte)(0xff & (hostAddress >> 8)), (byte)(0xff & (hostAddress >> 16)),