Single quote (') in edittext makes my program crash - android

If I write something into an edittext that contains single quote (') my program crashes. With this edittext I can search for things in my database and some of them contain this single qoute (or apostrophe whatever name it has but the point is that it's about the single qoute). I assume it has some special functions and this is why it crashes. Is there any option to ignore its function or solve this problem somehow?
for example, an item in my database:
cv.put(KEY_NAME, "Jonh's idea");
cv.put(KEY_HOTNESS, "amazing");
cv.put(KEY_MONEY, "500");
ourDatabase.insert(DATABASE_TABLE, null, cv);
Then when I search for it with this method:
return ourDatabase.query(DATABASE_TABLE, new String[] {"_id", "idea_name",},
"idea_name like " + "'%" + qq + "%'", null, null, null, null);
where qq is given by the user (for example Jonh's idea), it crahses. And yes, I get syntax error.

Sounds like the ' is causing an SQL injection of some sort... the ' is causing a syntax error in your SQL statement. There are several things you might consider double checking:
rawQuery() will not protect you from SQL injections, so avoid using it (rather, use the query, insert, update, and delete methods instead).
Prefer formatting your selection and selectionArgs as follows (as it will protect you from SQL injections):
selection = "col_1 = ?";
selectionArgs = new String[] { "value_1" };
(note that the values in the String[] replace the ?s in the selection string).
Set an inputType on your EditText to prevent users from entering these characters in the first place (i.e. if you only want users to enter numbers, then set android:inputType="number").
Overall, as long as you correctly make use of the Android methods in the SQLiteDatabase class, you shouldn't run into any problems with SQL injections (Android does a good job at cleaning this up for you). That said, if you don't choose to make use of these special-purpose methods, then you should check the content of the String at runtime and protect against characters such as ', ;, ", etc. by escaping them.
You can refer to this post for more information:
Android Single Quote In SQL With a LIKE StateMent

You need to use the selectionArgs argument to escape the string (so that the single quote in it doesn't break the SQL). Try something like this:
return ourDatabase.query(DATABASE_TABLE, new String[] {"_id", "idea_name",}, "idea_name like ?", new String[] { "%" + qq + "%" }, null, null, null);

It seems like SQL-injection. U have to escape your input.

One more jugaad. You can replace ' with `. You won't have to recheck your code. Just modify the following:
String input = edittext.getText().toString();
if(input.contains("'"))
{
input = input.replace("'", "`");
}
//now proceed with the database operation ...
This will enable the user to input text like RD's jugaad to RD`s jugaad

Related

SQLite - Queries with non-English characters don't show any results

I'm using a SearchView widget and it works well, except for the fact the if the string I enter contains any non-English character the result is empty, even if it is clear that there ARE results
Example:
In the image shown above there are two results for the string "chu" but if I type "ñ" the ListView won't show any results and it's obvious that there are results.
This is what I've tried so far
public Cursor searchProductByDescription(String description) {
String where = PRODUCT_DESCRIPTION + " LIKE LOWER( ? ) ";
String[] whereArgs = { "%" + description + "%" };
this.openReadableDB();
Cursor cursor = db.query(PRODUCT_TABLE, null, where, whereArgs, null,
null, null);
if (cursor != null) {
cursor.moveToFirst();
}
this.closeDB();
return cursor;
}
I'm not sure if this is an issue related to the searchview widget or to SQLite.
I've seen a couple of question in which they suggest converting the string to LOWER o UPPER case, but this solution didn't work for me.
I'd really appreciate if you could help me here.
Thanks
LOWER() only knows how to lowercase ASCII characters. LIKE is also case insensitive only with ASCII characters. And ñ is not an ASCII character.
For a solution, consider the following:
Add another column to your table that you use for searches and use the original column only for display purposes.
Store data in this column in a normalized form such as NFC and with the case converted consistently to upper/lowercase. For example:
String stringToStore = Normalizer.normalize(originalString.toLowerCase(), Normalizer.Form.NFC);
Normalize your search strings similarly in code.
If you want to ignore accent e.g. have n also match ñ, use a slightly different approach to remove the accents.

What exactly is where?whereval in android sqlite?

There are two pieces of code,which i thought were similar ,but one gives me an error and one doesn't,so I have a few questions to ask
What exactly is "where","whereval"?
The below code gives me an error
String where = android.provider.MediaStore.Audio.Media.ALBUM
+ "="+img.get(position).Album;//here is the difference
Cursor cursor = managedQuery(
MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, columns,
where, null , orderBy);//whereval is null here
The below code doesn't give me any error
String where = android.provider.MediaStore.Audio.Media.ALBUM
+ "=?";here is the difference
String whereVal[] = {img.get(position).Album};here is the difference
Cursor cursor = managedQuery(
MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, columns,
where, whereVal , orderBy);//i have included whereVal
Please explain me the difference between the two pieces of code ??
Also how can i use two conditions in sqlite ??
In SQL, string literals are quoted 'like this'. If you insert a string literal in SQL without the quotes, you'll likely get an SQL syntax error. It's the same as in Java where "any string" without the quotes is unlikely to be valid Java code but it's valid as a string literal.
? is a placeholder for a literal. The SQL is compiled with the placeholder in place and the literal value is bound to the compiled statement. Think of it as a variable in programming languages. The value for the variable comes from the bind arguments. In Android Java sqlite wrapper, the bind args are supplied in the string array.
Further reading: http://www.sqlite.org/lang_expr.html#varparam - though the Android wrapper code adds some leaky abstractions on top of sqlite C API.
suppose i have to use the code1 to achieve the result that i am getting from code 2..what should be the syntax ??
Quote the string literal with '...':
String where = android.provider.MediaStore.Audio.Media.ALBUM
+ "='"+img.get(position).Album+"'";
Based on the comments you want a conjuction expression. Just add an AND between subexpressions, like
String where = "foo='bar' AND baz='xyzzy'";

Android - SimpleAdapter filter query, how to ignore accents?

I am currently using the ContentProvider for contacts to retrieve the contacts from the device and allowing the user to filter the results by typing into an EditText.
To do so I have set up a filter query on a SimpleAdapter as follows:
contactsAdapter.setFilterQueryProvider(new FilterQueryProvider() {
String[] PROJECTION = new String[] {
ContactsContract.Contacts._ID,
ContactsContract.Contacts.DISPLAY_NAME,
ContactsContract.Contacts.HAS_PHONE_NUMBER,
};
String sortOrder = ContactsContract.Contacts.DISPLAY_NAME + " COLLATE LOCALIZED COLLATE NOCASE ASC";
public Cursor runQuery(CharSequence constraint) {
String SELECTION = "LOWER(" + ContactsContract.Contacts.DISPLAY_NAME + ")"
+ " LIKE '" + constraint + "%' " + "and " + ContactsContract.Contacts.IN_VISIBLE_GROUP + " = '1'";
Cursor cur = managedQuery(ContactsContract.Contacts.CONTENT_URI,
PROJECTION, SELECTION, null, sortOrder);
return cur;
}
});
setListAdapter(contactsAdapter);
This works in most cases however when I have a contact with an accent (Example: Tést Cóntact) then I want the contact to show up even if the user types in Test Contact, currently it doesn't.
Also the case is not ignored in this case either whereas for standard characters it is, for example if I have a contact called Omar and search for omar it matches but if I have a contact called Ómar and search for ómar it doesn't match.
Does anyone know what I should be doing to implement the behavior I want to achieve?
I would see 2 options here :
Create a table that contains accent-less version of the contacts names and a reference to the actual contact Id
Replace accented caracters by ? in your search (which may result in not really user expected behaviour, but is so much simpler)
See my question Using COLLATE in Android SQLite - Locales is ignored in LIKE statement
Short answer - I think it's impossible to use the LIKE statement in Android SQLite and ignore accents. I solved it by making a new column in the database, where you store the same name without accents and in lower case. For example Column 1 stores "Tést Cóntact" - which is used for display and Column 2 stores "test contact" - which is used for using the LIKE statement.
Android 2.3 has a Normalizer class which will remove all accents from a string. If you are supporting lower Android API, then you may need to write your own normalizer somehow...
You can use the replace function to remove the accented characters. Look at this simple solution:
How to SQL compare columns when one has accented chars?

Android SQLite and Bind Variables Problem

I'm trying to do a relatively simple bitwise query operation with SQLite on Android. When I use bind variables, I get no data returned when I believe should get some rows back. If I hardcode the bind variable's value directly into the SQL, it works just fine. I'm thinking I have some silly syntax issue somewhere, but I just can't see it.
So this code works just fine:
String selection = new String(FLAGS + " & 2 = 2");
cursor = db.query(TABLE_NAME, ALL_COLUMNS, selection,
null, null, null, null, null );
This code however (using bind variables), returns no rows:
String selection = new String(FLAGS + " & ? = ?");
String[] selectionArgs = new String[]{"2", "2"};
cursor = db.query(TABLE_NAME, ALL_COLUMNS, selection,
selectionArgs, null, null, null, null );
They both result into a syntactically identical query being built when I inspect the cursor's mQuery property through the debugger. The latter does have the mBindArgs property populated correctly as well. I'm at a loss as to how this could be failing. There are no exceptions thrown or anything, it just doesn't return any rows.
I can take the failing query, and manually swap the question marks for the two's and paste it into the ADB SQLite command line interface and it works just fine as well.
If I am right the second query produces following condition:
& '2' = '2'
instead of
& 2 = 2
Try replacing & with AND
Make sure you have no ? characters in FLAG constant.
Besides what is a point of this logical condition?
I was facing the same problem as yours. As radek-k said, the query compares string.
One solution that may be performed is to use the following:
String selection = new String(FLAGS + " & ? = (0|?)");

SQLite LIKE alternative for REGEXP, Match Start of Any Word

It does not seem possible to use REGEXP in a SQLite query in Android. If it is possible, please point me in the right direction.
Is there a way to use a LIKE condition to query for an expression at the beginning of any word in the result?
Example:
Entries:
1. Minimum
2. Aluminum
3. Last Minute
Query:
"min"
Desired Result
(1) Minimum
(3) Last Minute
NOT
(2) Aluminum
This is basically my current code, which would return (2)Aluminum:
public Cursor search(String query) {
return mDb.query(TABLE, COLUMNS, KEY_NAME +" like ?", new String[] { "%"+query+"%" }, null, null, null);
}
Any help will be greatly appreciated!
It's somewhat of a hack, but...
foo LIKE 'bar%' OR foo LIKE '% bar%'
might work for your needs (finding "bar" at the beginning of a word in "foo"). If you also want punctuation to serve as word delimiters, you'd have to add OR clauses for that as well (hence why it's a hack).

Categories

Resources