Введенный пользователем апостроф сбоев Android-приложение (связано с SQL) - PullRequest
2 голосов
/ 22 сентября 2011

Мое приложение в настоящее время использует базу данных SQLite для хранения сообщений для пользователя. Однако если пользователь вводит апостроф в любое из полей, база данных падает. Я понимаю, что проблема в том, что SQLite использует апостроф в качестве разделителя кавычек (я помещаю одиночные апострофы вокруг сохраненного текста сообщения), но не могу придумать каких-либо хороших способов обойти это. Существует ли распространенная практика хранения строк с апострофами в базе данных SQLite?

Вот пример полученной мной ошибки:

java.lang.RuntimeException: Unable to resume activity {x.x.x.x/x.x.x.x.Main}: android.database.sqlite.SQLiteException: near "m": syntax error: , while compiling: SELECT title, contact_name, contact_number FROM contacts WHERE title='I'm at work'
at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3128)
at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3143)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2684)
at android.app.ActivityThread.access$2300(ActivityThread.java:125)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2033)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:123)
at android.app.ActivityThread.main(ActivityThread.java:4627)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:521)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:859)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:617)
at dalvik.system.NativeStart.main(Native Method)
Caused by: android.database.sqlite.SQLiteException: near "m": syntax error: , while compiling: SELECT title, contact_name, contact_number FROM contacts WHERE title='I'm at work'
at android.database.sqlite.SQLiteCompiledSql.native_compile(Native Method)
at android.database.sqlite.SQLiteCompiledSql.compile(SQLiteCompiledSql.java:91)
at android.database.sqlite.SQLiteCompiledSql.<init>(SQLiteCompiledSql.java:64)
at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java:80)
at android.database.sqlite.SQLiteQuery.<init>(SQLiteQuery.java:46)
at android.database.sqlite.SQLiteDirectCursorDriver.query(SQLiteDirectCursorDriver.java:42)
at android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1454)
at android.database.sqlite.SQLiteDatabase.queryWithFactory(SQLiteDatabase.java:1338)
at android.database.sqlite.SQLiteDatabase.query(SQLiteDatabase.java:1293)
at android.database.sqlite.SQLiteDatabase.query(SQLiteDatabase.java:1373)
... 19 more

Ответы [ 4 ]

10 голосов
/ 22 сентября 2011

См. этот вопрос - есть довольно много ответов, которые должны вам помочь.

В частности, речь идет об использовании DatabaseUtils.sqlEscapeString или:

uservalue = getText().tostring();
uservalue = uservalue.replace("'","\'");
//execute query...
3 голосов
/ 22 сентября 2011

Общие рекомендации по базам данных (и правила безопасного кодирования) помогают избежать этого, потому что то же самое, что вызывает вашу ошибку, может быть использовано для атак SQL INjection.Наиболее распространенные способы защиты (в порядке предпочтения согласно рекомендациям OWASP):

  1. Использование параметризованных хранимых процедур
  2. Использование параметризованных запросов, если механизм БД поддерживает это.В качестве последнего средства, избегайте строк (реализация зависит от механизма базы данных.)

SQLLite поддерживает опции 2 и 3.

На этой странице: http://www.sqlite.org/lang_expr.html

Строковая константа формируется путем заключения строки в одинарные кавычки (').Одиночная кавычка в строке может быть закодирована путем помещения двух одинарных кавычек в строку - как в Паскале.Экранирование в стиле C с использованием символа обратной косой черты не поддерживается, поскольку они не являются стандартными SQL.

, поэтому O'Brien будет введен как O''Brien в вашем выражении SQL.

И на этой странице вы можете использовать параметризованные запросы: http://www.sqlite.org/limits.html

INSERT INTO tab1 VALUES (?,?,?);

Затем используйте функции sqlite3_bind_XXXX (), чтобы связать ваши большие строковые значения с оператором SQL.Использование связывания избавляет от необходимости экранировать символы кавычек в строке, снижая риск атак с использованием SQL-инъекций.Он также работает быстрее, так как большую строку не нужно анализировать или копировать столько же.

0 голосов
/ 30 января 2017

Просто используйте стандартный API Android как

userInput = android.database.DatabaseUtils.sqlEscapeString(userInput);

Это решит вашу проблему.

0 голосов
/ 14 марта 2013

простейший код в одну строку:

String s = editText.getText().toString().replace("'","\'");
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...