narcissus
narcissus copied to clipboard
Problems for find static fields and methods
// 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.