2011-09-21 3 views
2

私のアプリケーションは現在SQLiteデータベースを利用してユーザのメッセージを保存しています。ただし、いずれかのフィールドにアポストロフィを入力すると、データベースがクラッシュします。私はこの問題がSQLiteの引用符区切り文字としてアポストロフィを使用していることに起因していることを認識しています(メッセージテキストの前後に単一のアポストロフィを配置します)。 SQLiteデータベースにアポストロフィを使用して文字列を格納する方法はありますか?ユーザ入力のアポストロフィがクラッシュアンドロイドアプリ(SQL関連)

は、ここで私が受信したエラーの例です:

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 

答えて

10

this質問を参照してください - あなたを助ける必要があり、かなりの数の答えがあります。

は、具体的には、DatabaseUtils.sqlEscapeStringかを使用しての話:これに対して

uservalue = getText().tostring(); 
uservalue = uservalue.replace("'","\'"); 
//execute query... 
+0

リンクありがとうございます。私はどこでも同じような質問を探しましたが、私は "一重引用符"ではなく "アポストロフィ"を探していました。 –

+0

恐ろしい:)問題はありません - このupvoteは私の> 2000 repマークです。ウーホー。 – Jack

+2

DatabaseUtils.sqlEscapeStringが私にとって最も簡単な解決策でした。FTW –

3

一般的なデータベースのガイドライン(および安全なコーディングガイドライン)ヘルプprventがあなたのエラーを引き起こしている同じことがSQLインジェクション攻撃に悪用される可能性があるため。最も一般的な防御は(OWASPガイドラインに従って優先順に)次のとおりです。

  1. 利用が格納parmeterized手順
  2. 使用パラメータ化クエリDBエンジンがサポートしている場合。最後の手段として
  3. 、エスケープ文字列(データベースエンジンに実装dependednt。)

SQLLiteはこのページから、オプション2と3

サポートしています。http://www.sqlite.org/lang_expr.html

文字列を定数は、文字列を一重引用符で囲むことによって形成されます ( ')。文字列内の一重引用符は、二重引用符を行内に2つ入れることでエンコードすることができます(Pascalのように)。バックスラッシュ文字を使用するCスタイルのエスケープは、標準SQLではないためサポートされていません。

したがってO'Brienは、SQLステートメントにO''Brienと入力されます。

そして、このページごとに、あなたはパラメータ化クエリを使用することができます(???、)TAB1のVALUES INTO http://www.sqlite.org/limits.html

INSERTを。

次に、sqlite3_bind_XXXX()関数を使用して、大きな文字列 の値をSQLステートメントにバインドします。バインドを使用すると、 文字列のエスケープ文字が不要になり、SQL 注入攻撃の危険性が軽減されます。大きな文字列の場合は、 を解析したりコピーする必要はありません。

+0

2つのシングルクォートがアンドロイドSQLiteエンジンで動作することが確認されましたか?私はそれを実行可能な解決策として使用することができます。 –

+0

2つのシングルクォートを試しました...うまくいきませんでした。 – worked

0

1行の最も簡単なコード:

String s = editText.getText().toString().replace("'","\'"); 
0

ちょうどそれがあなたの問題を解決します

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

としてアンドロイドの標準的なAPIを使用しています。

関連する問題