Add defensive check for result returned after JNI function calls
Summary: Added method which checks if value(methodId, fieldId, class ...) returned by JNI functions (getMethod, getField, getClass ...) is valid or not and throw exception if they are not valid ##Changelog: [Internal][Yoga] Add defensive check for result returned after JNI calls Reviewed By: astreet Differential Revision: D18745718 fbshipit-source-id: 2af26eda15fbe7834e1c9b274deeed4f106274ab
This commit is contained in:
committed by
Facebook Github Bot
parent
073f49d0d0
commit
ac8eb111a9
@@ -18,11 +18,11 @@ void registerNatives(
|
|||||||
size_t numMethods) {
|
size_t numMethods) {
|
||||||
jclass clazz = env->FindClass(className);
|
jclass clazz = env->FindClass(className);
|
||||||
|
|
||||||
assertNoPendingJniException(env);
|
assertNoPendingJniExceptionIf(env, !clazz);
|
||||||
|
|
||||||
env->RegisterNatives(clazz, methods, numMethods);
|
auto result = env->RegisterNatives(clazz, methods, numMethods);
|
||||||
|
|
||||||
assertNoPendingJniException(env);
|
assertNoPendingJniExceptionIf(env, result != JNI_OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
jmethodID getStaticMethodId(
|
jmethodID getStaticMethodId(
|
||||||
@@ -32,7 +32,7 @@ jmethodID getStaticMethodId(
|
|||||||
const char* methodDescriptor) {
|
const char* methodDescriptor) {
|
||||||
jmethodID methodId =
|
jmethodID methodId =
|
||||||
env->GetStaticMethodID(clazz, methodName, methodDescriptor);
|
env->GetStaticMethodID(clazz, methodName, methodDescriptor);
|
||||||
assertNoPendingJniException(env);
|
assertNoPendingJniExceptionIf(env, !methodId);
|
||||||
return methodId;
|
return methodId;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -42,7 +42,7 @@ jmethodID getMethodId(
|
|||||||
const char* methodName,
|
const char* methodName,
|
||||||
const char* methodDescriptor) {
|
const char* methodDescriptor) {
|
||||||
jmethodID methodId = env->GetMethodID(clazz, methodName, methodDescriptor);
|
jmethodID methodId = env->GetMethodID(clazz, methodName, methodDescriptor);
|
||||||
assertNoPendingJniException(env);
|
assertNoPendingJniExceptionIf(env, !methodId);
|
||||||
return methodId;
|
return methodId;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -52,7 +52,7 @@ jfieldID getFieldId(
|
|||||||
const char* fieldName,
|
const char* fieldName,
|
||||||
const char* fieldSignature) {
|
const char* fieldSignature) {
|
||||||
jfieldID fieldId = env->GetFieldID(clazz, fieldName, fieldSignature);
|
jfieldID fieldId = env->GetFieldID(clazz, fieldName, fieldSignature);
|
||||||
assertNoPendingJniException(env);
|
assertNoPendingJniExceptionIf(env, !fieldId);
|
||||||
return fieldId;
|
return fieldId;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -83,7 +83,7 @@ callStaticObjectMethod(JNIEnv* env, jclass clazz, jmethodID methodId, ...) {
|
|||||||
va_start(args, methodId);
|
va_start(args, methodId);
|
||||||
jobject result = env->CallStaticObjectMethodV(clazz, methodId, args);
|
jobject result = env->CallStaticObjectMethodV(clazz, methodId, args);
|
||||||
va_end(args);
|
va_end(args);
|
||||||
assertNoPendingJniException(env);
|
assertNoPendingJniExceptionIf(env, !result);
|
||||||
return make_local_ref(env, result);
|
return make_local_ref(env, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -76,6 +76,19 @@ void assertNoPendingJniException(JNIEnv* env) {
|
|||||||
throw YogaJniException(throwable);
|
throw YogaJniException(throwable);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void assertNoPendingJniExceptionIf(JNIEnv* env, bool condition) {
|
||||||
|
if (!condition) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (env->ExceptionCheck() == JNI_TRUE) {
|
||||||
|
assertNoPendingJniException(env);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw YogaJniException();
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace vanillajni
|
} // namespace vanillajni
|
||||||
} // namespace yoga
|
} // namespace yoga
|
||||||
} // namespace facebook
|
} // namespace facebook
|
||||||
|
@@ -47,6 +47,8 @@ void logErrorMessageAndDie(const char* message);
|
|||||||
*/
|
*/
|
||||||
void assertNoPendingJniException(JNIEnv* env);
|
void assertNoPendingJniException(JNIEnv* env);
|
||||||
|
|
||||||
|
void assertNoPendingJniExceptionIf(JNIEnv* env, bool condition);
|
||||||
|
|
||||||
} // namespace vanillajni
|
} // namespace vanillajni
|
||||||
} // namespace yoga
|
} // namespace yoga
|
||||||
} // namespace facebook
|
} // namespace facebook
|
||||||
|
Reference in New Issue
Block a user