0

I have a free Android app that has spread beyond the original intended user base. I encountered an instance where this kind of String.format produced an invalid SQL string:

String sql = String.format ("SELECT name from customers where cust_id=%d", cust_id);

One situation that definitely caused a problem is where the user's localisation was for arabic, so the customer id was represented in arabic characters.

I fixed that particular problem like this:

String sql = String.format (Locale.ENGLISH, "SELECT name from customers where cust_id=%d", cust_id);

What delayed finding a solution was that, because it's a free app, most people don't report a problem- they just stop using the app: I only get to find out from crash logs. Furthermore, the nature of the localisation seemed to depend both on the selected language and also the version of Android... and the app is supported all the way back to V2.1. I have detected two different types just for arabic, and another (I haven't identified the language) that localised the digits to question marks.

My question is whether there will be a similar problem with statements that generate sql queries using concatenation, like this:

String sql = "SELECT name from customers where cust_id=" + cust_id;

The majority of my queries are like this, so it would be a big job to check and change. I can test it empirically on current versions, but how about previous and future ones?

JavaLatte
  • 378
  • 5
  • 18
  • See http://stackoverflow.com/questions/9159358/implicit-cast-to-string-tostring-and-int – Serg Aug 18 '16 at 12:34

2 Answers2

0

No string concatenation doesn't do any changes for localization, only String format does.

Ben
  • 1,285
  • 1
  • 9
  • 15
0

An integer does not save any localization information (because it is a primitive), the problem lies within your String.format call.

You used String.format like this:

String sql = String.format ("SELECT name from customers where cust_id=%d", cust_id);

The Android documentation says this:

String format (String format, Object... args)

Returns a formatted string using the specified format string and arguments. The locale always used is the one returned by Locale.getDefault().

Specifying no locale will always cause localization of the string to the default (which, in your customers' case, was Arabic). According to the Android documentation, there is also a second method declaration taking a locale:

String format (Locale l, String format, Object... args)

Returns a formatted string using the specified locale, format string, and arguments.

[...]If l is null then no localization is applied.

So your solution would be to modify your call:

String sql = String.format (null, "SELECT name from customers where cust_id=%d", cust_id);

Of course, you could also change your calls to simple string concatenation (which is probably the preferred way for SQL queries):

String sql = "SELECT name from customers where cust_id=" + cust_id;

Source: https://developer.android.com/reference/java/lang/String.html

techfly
  • 1,826
  • 3
  • 25
  • 31