10000 Use UTF-16 · oneNF/android-database-sqlcipher@665df4b · GitHub
[go: up one dir, main page]

Skip to content

Commit 665df4b

Browse files
Use UTF-16
1 parent d2d8328 commit 665df4b

6 files changed

+94
-66
lines changed

jni/net_sqlcipher_CursorWindow.cpp

Lines changed: 50 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,6 @@
1717
#undef LOG_TAG
1818
#define LOG_TAG "CursorWindow"
1919

20-
// #include <JNIHelp.h>
21-
// #include <android_runtime/AndroidRuntime.h>
22-
// #include <utils/Log.h>
23-
// #include "android_util_Binder.h"
24-
2520
#include <jni.h>
2621
#include <stdlib.h>
2722
#include <stdio.h>
@@ -32,7 +27,9 @@
3227
#include "jni_elements.h"
3328
#include "jni_exception.h"
3429
#include "sqlite3_exception.h"
35-
//#include <utils/String16.h>
30+
31+
#include <wchar.h>
32+
#include <stdlib.h>
3633

3734
namespace sqlcipher {
3835

@@ -170,9 +167,10 @@ LOG_WINDOW("Getting long for %d,%d from %p", row, column, window);
170167
#if WINDOW_STORAGE_UTF8
171168
return strtoll((char const *)window->offsetToPtr(field.data.buffer.offset), NULL, 0);
172169
#else
173-
String8 ascii((char16_t *) window->offsetToPtr(field.data.buffer.offset), size / 2);
174-
char const * str = ascii.string();
175-
return strtoll(str, NULL, 0);
170+
return strtoll((char const *)window->offsetToPtr(field.data.buffer.offset), NULL, 0);
171+
// String8 ascii((char16_t *) window->offsetToPtr(field.data.buffer.offset), size / 2);
172+
// char const * str = ascii.string();
173+
// return strtoll(str, NULL, 0);
176174
#endif
177175
} else {
178176
return 0;
@@ -308,42 +306,37 @@ LOG_WINDOW("Checking if column is a float for %d,%d from %p", row, column, windo
308306

309307
static jstring getString_native(JNIEnv* env, jobject object, jint row, jint column)
310308
{
309+
int i;
311310
int32_t err;
312311
CursorWindow * window = GET_WINDOW(env, object);
313-
LOG_WINDOW("Getting string for %d,%d from %p", row, column, window);
314-
312+
LOG_WINDOW("Getting string for %d,%d from %p", row, column, window);
315313
field_slot_t field;
316314
err = window->read_field_slot(row, column, &field);
317315
if (err != 0) {
318316
throwExceptionWithRowCol(env, row, column);
319317
return NULL;
320318
}
321-
322319
uint8_t type = field.type;
323-
if (type == FIELD_TYPE_STRING) {
324-
uint32_t size = field.data.buffer.size;
325-
if (size > 0) {
326-
return env->NewString((jchar const*)window->offsetToPtr(field.data.buffer.offset), size);
327-
// #if WINDOW_STORAGE_UTF8
328-
329-
// // std::wstring_convert<std::codecvt<char16_t,char,std::mbstate_t>,char16_t> convert;
330-
// // std::u16string utf16 = convert.from_bytes(window->offsetToPtr(field.data.buffer.offset));
331-
332-
// // Pass size - 1 since the UTF8 is null terminated and we don't want a null terminator on the UTF16 string
333-
// android::String16 utf16((char const *)window->offsetToPtr(field.data.buffer.offset), size - 1);
334-
// return env->NewString((jchar const *)utf16.string(), utf16.size());
335-
// #else
336-
// return env->NewString((jchar const *)window->offsetToPtr(field.data.buffer.offset), size / 2);
337-
// #endif
338-
} else {
339-
return env->NewStringUTF("");
340-
}
320+
jint size = (jint)field.data.buffer.size;
321+
if (type == FIELD_TYPE_NULL) {
322+
return NULL;
323+
} else if (type == FIELD_TYPE_BLOB) {
324+
throw_sqlite3_exception(env, "Unable to convert BLOB to string");
325+
return NULL;
326+
} else if (type == FIELD_TYPE_STRING) {
327+
jchar * buf = (jchar *)window->offsetToPtr(field.data.buffer.offset);
328+
jclass strClass = env->FindClass("java/lang/String");
329+
jmethodID ctorID = env->GetMethodID(strClass, "<init>", "([BLjava/lang/String;)V");
330+
jstring encoding = env->NewStringUTF("UTF-16LE");
331+
jbyteArray bytes = env->NewByteArray(size);
332+
env->SetByteArrayRegion(bytes, 0, size, (jbyte*)buf);
333+
return (jstring)env->NewObject(strClass, ctorID, bytes, encoding);
341334
} else if (type == FIELD_TYPE_INTEGER) {
342335
int64_t value;
343336
if (window->getLong(row, column, &value)) {
344-
char buf[32];
345-
snprintf(buf, sizeof(buf), "%lld", value);
346-
return env->NewStringUTF(buf);
337+
char buf[32];
338+
snprintf(buf, sizeof(buf), "%lld", value);
339+
return env->NewStringUTF((const char*)buf);
347340
}
348341
return NULL;
349342
} else if (type == FIELD_TYPE_FLOAT) {
@@ -354,14 +347,6 @@ LOG_WINDOW("Getting string for %d,%d from %p", row, column, window);
354347
return env->NewStringUTF(buf);
355348
}
356349
return NULL;
357-
} else if (type == FIELD_TYPE_NULL) {
358-
return NULL;
359-
} else if (type == FIELD_TYPE_BLOB) {
360-
throw_sqlite3_exception(env, "Unable to convert BLOB to string");
361-
return NULL;
362-
} else {
363-
throwUnknowTypeException(env, type);
364-
return NULL;
365350
}
366351
}
367352

@@ -410,12 +395,27 @@ LOG_WINDOW("Copying string for %d,%d from %p", row, column, window);
410395
uint32_t size = field.data.buffer.size;
411396
if (size > 0) {
412397

413-
if (size > bufferSize * 2 || dst == NULL) {
414-
newArray = env->NewCharArray(sizeCopied);
415-
memcpy(newArray, (jchar const *)window->offsetToPtr(field.data.buffer.offset), size);
398+
// std::string input = (const char*)window->offsetToPtr(field.data.buffer.offset);
399+
// std::wstring result = utf8_to_utf16(input);
400+
401+
jstring input = env->NewStringUTF((const char*)window->offsetToPtr(field.data.buffer.offset));
402+
const jchar* buffer = 10000 env->GetStringChars(input, JNI_FALSE);
403+
jstring result = env->NewString(buffer, size - 1);
404+
int32_t strSize = size - 1;
405+
if (strSize > bufferSize || dst == NULL) {
406+
newArray = env->NewCharArray(strSize);
407+
env->SetCharArrayRegion(newArray, 0, strSize, (jchar const *)result);
416408
} else {
417-
memcpy(dst, (jchar const *)window->offsetToPtr(field.data.buffer.offset), size);
409+
memcpy(dst, (jchar const *)result, strSize * 2);
418410
}
411+
sizeCopied = strSize;
412+
413+
// if (size > bufferSize * 2 || dst == NULL) {
414+
// newArray = env->NewCharArray(sizeCopied);
415+
// memcpy(newArray, (jchar const *)window->offsetToPtr(field.data.buffer.offset), size);
416+
// } else {
417+
// memcpy(dst, (jchar const *)window->offsetToPtr(field.data.buffer.offset), size);
418+
// }
419419

420420

421421
// #if WINDOW_STORAGE_UTF8
@@ -498,9 +498,10 @@ LOG_WINDOW("Getting double for %d,%d from %p", row, column, window);
498498
#if WINDOW_STORAGE_UTF8
499499
return strtod((char const *)window->offsetToPtr(field.data.buffer.offset), NULL);
500500
#else
501-
String8 ascii((char16_t *) window->offsetToPtr(field.data.buffer.offset), size / 2);
502-
char const * str = ascii.string();
503-
return strtod(str, NULL);
501+
return strtod((char const *)window->offsetToPtr(field.data.buffer.offset), NULL);
502+
// String8 ascii((char16_t *) window->offsetToPtr(field.data.buffer.offset), size / 2);
503+
// char const * str = ascii.string();
504+
// return strtod(str, NULL);
504505
#endif
505506
} else {
506507
return 0.0;
@@ -699,6 +700,7 @@ static JNINativeMethod sMethods[] =
699700
{"getBlob_native", "(II)[B", (void *)getBlob_native},
700701
{"isBlob_native", "(II)Z", (void *)isBlob_native},
701702
{"getString_native", "(II)Ljava/lang/String;", (void *)getString_native},
703+
//{"getString_native", "(II)[B", (void *)getString_native},
702704
{"copyStringToBuffer_native", "(IIILandroid/database/CharArrayBuffer;)[C", (void *)copyStringToBuffer_native},
703705
{"getDouble_native", "(II)D", (void *)getDouble_native},
704706
{"isNull_native", "(II)Z", (void *)isNull_native},

jni/net_sqlcipher_database_SQLiteDatabase.cpp

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,27 @@ int native_status(JNIEnv* env, jobject object, jint operation, jboolean reset)
154154
// if(keyUtf8 != 0) free(keyUtf8);
155155
// }
156156

157+
void native_key_char(JNIEnv* env, jobject object, jcharArray jKey) {
158+
int rc;
159+
int idx;
160+
LOGI("Entered native_key_char");
161+
sqlite3 *handle = (sqlite3 *)env->GetIntField(object, offset_db_handle);
162+
jchar *key = env->GetCharArrayElements(jKey, 0);
163+
jsize sz = env->GetArrayLength(jKey);
164+
char password[sz + 1];
165+
for(idx = 0; idx < sz; idx++){
166+
password[idx] = (char)key[idx];
167+
}
168+
password[sz] = '\0';
169+
if(sz > 0){
170+
rc = sqlite3_key(handle, password, sz);
171+
if(rc != SQLITE_OK){
172+
throw_sqlite3_exception(env, handle);
173+
}
174+
}
175+
env->ReleaseCharArrayElements(jKey, key, 0);
176+
}
177+
157178
void native_key_str(JNIEnv* env, jobject object, jstring jKey)
158179
{
159180
sqlite3 * handle = (sqlite3 *)env->GetIntField(object, offset_db_handle);
@@ -620,8 +641,8 @@ static JNINativeMethod sMethods[] =
620641
// {"setICURoot", "(Ljava/lang/String;)V", (void *)setICURoot},
621642
{"native_rawExecSQL", "(Ljava/lang/String;)V", (void *)native_rawExecSQL},
622643
{"native_status", "(IZ)I", (void *)native_status},
623-
// {"native_key", "([C)V", (void *)native_key_char},
624-
{"native_key", "(Ljava/lang/String;)V", (void *)native_key_str},
644+
{"native_key", "([C)V", (void *)native_key_char},
645+
//{"native_key", "(Ljava/lang/String;)V", (void *)native_key_str},
625646
// {"native_rekey", "([C)V", (void *)native_rekey_char},
626647
{"native_rekey", "(Ljava/lang/String;)V", (void *)native_rekey_str},
627648
};

jni/net_sqlcipher_database_SQLiteQuery.cpp

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -190,16 +190,8 @@ static jint native_fill_window(JNIEnv* env, jobject object, jobject javaWindow,
190190
int type = sqlite3_column_type(statement, i);
191191
if (type == SQLITE_TEXT) {
192192
// TEXT data
193-
#if WINDOW_STORAGE_UTF8
194-
uint8_t const * text = (uint8_t const *)sqlite3_column_text(statement, i);
195-
// SQLite does not include the NULL terminator in size, but does
196-
// ensure all strings are NULL terminated, so increase size by
197-
// one to make sure we store the terminator.
198-
size_t size = sqlite3_column_bytes(statement, i) + 1;
199-
#else
200193
uint8_t const * text = (uint8_t const *)sqlite3_column_text16(statement, i);
201194
size_t size = sqlite3_column_bytes16(statement, i);
202-
#endif
203195
int offset = window->alloc(size);
204196
if (!offset) {
205197
window->freeLastRow();

jni/net_sqlcipher_database_SQLiteStatement.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,8 +99,13 @@ static jstring native_1x1_string(JNIEnv* env, jobject object)
9999
// Handle the result
100100
if (err == SQLITE_ROW) {
101101
// No errors, read the data and return it
102-
char const * text = (char const *)sqlite3_column_text(statement, 0);
103-
value = env->NewStringUTF(text);
102+
//char const * text = (char const *)sqlite3_column_text(statement, 0);
103+
104+
const jchar *str = 0;
105+
jint strlength = 0;
106+
str = (const jchar*) sqlite3_column_text16(statement, 0);
107+
strlength = sqlite3_column_bytes16(statement, 0) / sizeof(jchar);
108+
value = str ? env->NewString(str, strlength) : NULL;
104109
} else {
105110
throw_sqlite3_exception_errcode(env, err, sqlite3_errmsg(handle));
106111
}

src/net/sqlcipher/CursorWindow.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@
2828
import android.util.Log;
2929
import android.util.SparseIntArray;
3030

31+
import java.io.UnsupportedEncodingException;
32+
import java.nio.charset.StandardCharsets;
33+
3134
/**
3235
* A buffer containing multiple cursor rows.
3336
*/
@@ -379,7 +382,7 @@ public boolean isString(int row, int col) {
379382
public String getString(int row, int col) {
380383
acquireReference();
381384
try {
382-
return getString_native(row - mStartPos, col);
385+
return getString_native(row - mStartPos, col);
383386
} finally {
384387
releaseReference();
385388
}
@@ -399,6 +402,7 @@ public String getString(int row, int col) {
399402
* {@link SQLiteException} is thrown.
400403
*/
401404
private native String getString_native(int row, int col);
405+
//private native byte[] getString_native(int row, int col);
402406

403407
/**
404408
* copy the text for the given field in the provided char array.

src/net/sqlcipher/database/SQLiteDatabase.java

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2327,7 +2327,7 @@ private void openDatabaseInternal(char[] password, SQLiteDatabaseHook databaseHo
23272327
databaseHook.preKey(this);
23282328
}
23292329

2330-
native_key(String.valueOf(password));
2330+
native_key(password);
23312331

23322332
if(databaseHook != null){
23332333
databaseHook.postKey(this);
@@ -2337,6 +2337,12 @@ private void openDatabaseInternal(char[] password, SQLiteDatabaseHook databaseHo
23372337
mTimeOpened = getTime();
23382338
}
23392339
try {
2340+
Cursor cursor = rawQuery("select count(*) from sqlite_master;", new String[]{});
2341+
if(cursor != null){
2342+
cursor.moveToFirst();
2343+
int count = cursor.getInt(0);
2344+
cursor.close();
2345+
}
23402346
//setLocale(Locale.getDefault());
23412347
} catch (RuntimeException e) {
23422348
Log.e(TAG, "Failed to setLocale() when constructing, closing the database", e);
@@ -2813,9 +2819,7 @@ private static ArrayList<Pair<String, String>> getAttachedDbs(SQLiteDatabase dbO
28132819

28142820
private native int native_status(int operation, boolean reset);
28152821

2816-
//private native void native_key(char[] key) throws SQLException;
2817-
private native void native_key(String key) throws SQLException;
2818-
2822+
private native void native_key(char[] key) throws SQLException;
2823+
28192824
private native void native_rekey(String key) throws SQLException;
2820-
//private native void native_rekey(char[] key) throws SQLException;
28212825
}

0 commit comments

Comments
 (0)
0