narcissus icon indicating copy to clipboard operation
narcissus copied to clipboard

Problems for find static fields and methods

Open JaynLau opened this issue 11 months ago • 0 comments

// Find a method by name and signature. Signature should be of the form "(Z)[Ljava/lang/Class;"
JNIEXPORT jobject JNICALL Java_io_github_toolfactory_narcissus_Narcissus_findMethodInternal(JNIEnv *env, jclass ignored, jclass cls, jstring method_name, jstring sig, jboolean is_static) {
    if (argIsNull(env, cls) || argIsNull(env, method_name) || argIsNull(env, sig)) { return NULL; }
    const char* method_name_chars = (*env)->GetStringUTFChars(env, method_name, NULL);
    if (!method_name_chars || thrown(env)) { return NULL; }
    const char* sig_chars = (*env)->GetStringUTFChars(env, sig, NULL);
    if (!sig_chars || thrown(env)) { return NULL; }
    jmethodID methodID = (*env)->GetMethodID(env, cls, method_name_chars, sig_chars);
    (*env)->ReleaseStringUTFChars(env, sig, sig_chars);
    (*env)->ReleaseStringUTFChars(env, method_name, method_name_chars);
    if (!methodID) {
        return NULL;
    }
    return (*env)->ToReflectedMethod(env, cls, methodID, is_static ? JNI_TRUE : JNI_FALSE);
}

// Find a method by name and signature. Signature should be of the form "Ljava/lang/String;"
JNIEXPORT jobject JNICALL Java_io_github_toolfactory_narcissus_Narcissus_findFieldInternal(JNIEnv *env, jclass ignored, jclass cls, jstring field_name, jstring sig, jboolean is_static) {
    if (argIsNull(env, cls) || argIsNull(env, field_name) || argIsNull(env, sig)) { return NULL; }
    const char* field_name_chars = (*env)->GetStringUTFChars(env, field_name, NULL);
    if (!field_name_chars || thrown(env)) { return NULL; }
    const char* sig_chars = (*env)->GetStringUTFChars(env, sig, NULL);
    if (!sig_chars || thrown(env)) { return NULL; }
    jfieldID fieldID = (*env)->GetFieldID(env, cls, field_name_chars, sig_chars);
    (*env)->ReleaseStringUTFChars(env, sig, sig_chars);
    (*env)->ReleaseStringUTFChars(env, field_name, field_name_chars);
    if (!fieldID) {
        return NULL;
    }
    return (*env)->ToReflectedField(env, cls, fieldID, is_static ? JNI_TRUE : JNI_FALSE);
}

The code above in findMethodInternal and findFieldInternal dose not handle static method or field correctly.

jmethodID methodID = (*env)->GetMethodID(env, cls, method_name_chars, sig_chars); should be jmethodID methodID = is_static ? (*env)->GetStaticMethodID(env, cls, method_name_chars, sig_chars) : (*env)->GetMethodID(env, cls, method_name_chars, sig_chars);

jfieldID fieldID = (*env)->GetFieldID(env, cls, field_name_chars, sig_chars); should be jfieldID fieldID = is_static ? (*env)->GetStaticFieldID(env, cls, field_name_chars, sig_chars) : (*env)->GetFieldID(env, cls, field_name_chars, sig_chars);

In addition, it is best to add some unit tests to ensure that the code is robust.

JaynLau avatar Jan 10 '25 02:01 JaynLau