Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c5bb8d8d authored by Mike Lockwood's avatar Mike Lockwood
Browse files

Clean up error handling in custom sqlite function dispatching



Change-Id: I54036bb5defd8c887a9b878e012f0b1d4afe9966
Signed-off-by: default avatarMike Lockwood <lockwood@android.com>
parent bc9151bc
Loading
Loading
Loading
Loading
+21 −11
Original line number Diff line number Diff line
@@ -63,6 +63,7 @@ enum {

static jfieldID offset_db_handle;
static jmethodID method_custom_function_callback;
static jclass string_class = NULL;

static char *createStr(const char *path, short extra) {
    int len = strlen(path) + extra;
@@ -394,27 +395,36 @@ static void custom_function_callback(sqlite3_context * context, int argc, sqlite
        LOGE("custom_function_callback cannot call into Java on this thread");
        return;
    }
    // get global ref to CustomFunction object from our user data
    jobject function = (jobject)sqlite3_user_data(context);

    // pack up the arguments into a string array
    jobjectArray strArray = env->NewObjectArray(argc, env->FindClass("java/lang/String"), NULL);
    if (!strArray) {
        jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
        return;
    }
    if (!string_class)
        string_class = (jclass)env->NewGlobalRef(env->FindClass("java/lang/String"));
    jobjectArray strArray = env->NewObjectArray(argc, string_class, NULL);
    if (!strArray)
        goto done;
    for (int i = 0; i < argc; i++) {
        char* arg = (char *)sqlite3_value_text(argv[i]);
        jobject obj = env->NewStringUTF(arg);
        if (!obj) {
            jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
        if (!arg) {
            LOGE("NULL argument in custom_function_callback.  This should not happen.");
            return;
        }
        jobject obj = env->NewStringUTF(arg);
        if (!obj)
            goto done;
        env->SetObjectArrayElement(strArray, i, obj);
        env->DeleteLocalRef(obj);
    }

    // get global ref to CustomFunction object from our user data
    jobject function = (jobject)sqlite3_user_data(context);
    env->CallVoidMethod(function, method_custom_function_callback, strArray);

done:
    if (env->ExceptionCheck()) {
        LOGE("An exception was thrown by custom sqlite3 function.");
        LOGE_EX(env);
        env->ExceptionClear();
    }
}

static jint native_addCustomFunction(JNIEnv* env, jobject object,
@@ -423,7 +433,7 @@ static jint native_addCustomFunction(JNIEnv* env, jobject object,
    sqlite3 * handle = (sqlite3 *)env->GetIntField(object, offset_db_handle);
    char const *nameStr = env->GetStringUTFChars(name, NULL);
    jobject ref = env->NewGlobalRef(function);
    LOGD("native_addCustomFunction %s ref: %d", nameStr, ref);
    LOGD("native_addCustomFunction %s ref: %p", nameStr, ref);
    int err = sqlite3_create_function(handle, nameStr, numArgs, SQLITE_UTF8,
            (void *)ref, custom_function_callback, NULL, NULL);
    env->ReleaseStringUTFChars(name, nameStr);