2011-09-21 2 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 대표 마크입니다. 우 ~. – 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

하는 문자열 상수는 문자열을 작은 따옴표로 묶어서 형성합니다. ('). 문자열 내의 작은 따옴표는 파스칼에서와 같이 한 행에 작은 따옴표 두 개를 두어 인코딩 할 수 있습니다. 백 슬래시 문자를 사용하는 C 스타일 이스케이프는 표준 SQL이 아니기 때문에 지원되지 않습니다.

는 너무 O'Brien은 당신의 SQL 문에 O''Brien로 입력된다.

이 페이지 당 사용할 수있는 매개 변수가있는 쿼리 (???) TAB1 값으로 http://www.sqlite.org/limits.html

INSERT;

그런 다음 sqlite3_bind_XXXX() 함수를 사용하여 큰 문자열 값을 SQL 문에 바인딩하십시오. 바인딩을 사용하면 문자열에 이스케이프 인용 문자가 필요 없으므로 SQL 주입 공격의 위험을 줄일 수 있습니다. 큰 문자열은 을 구문 분석하거나 복사 할 필요가 없으므로 더 빠르게 실행됩니다.

+0

두 개의 작은 따옴표가 android SQLite 엔진에서 작동한다는 것이 확인 되었습니까? 나는 그것을 가능한 해결책으로 사용할 수 있습니다. –

+0

두 개의 작은 따옴표를 시도했지만 작동하지 않았습니다. – worked

0

하나 개의 라인 간단한 코드 :

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

그냥 그것은 당신의 문제를 해결할 수

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

로 안드로이드 표준 API를 사용합니다.

관련 문제