Class getField/Method returns NULL if type/args are unresolved.
These changes check that a field's type is resolved before returning it
through getDeclaredField, and that a method's return type and argument
types are resolved before returning it through getDeclaredMethods. This
fixes test failures in libcore MissingClassesTest.
(cherry picked from commit 1ae431a01516b6c91f031aff37c756b7e4f63dd1)
Change-Id: I6bd5601a975e677be6438b1efcb1b1f1ecde900c
diff --git a/src/java_lang_Class.cc b/src/java_lang_Class.cc
index 5c834f7..6cf7a2c 100644
--- a/src/java_lang_Class.cc
+++ b/src/java_lang_Class.cc
@@ -138,9 +138,15 @@
}
std::vector<Field*> fields;
+ FieldHelper fh;
for (size_t i = 0; i < c->NumInstanceFields(); ++i) {
Field* f = c->GetInstanceField(i);
+ fh.ChangeField(f);
if (IsVisibleField(f, publicOnly)) {
+ if (fh.GetType() == NULL) {
+ DCHECK(env->ExceptionOccurred());
+ return NULL;
+ }
fields.push_back(f);
}
if (env->ExceptionOccurred()) {
@@ -149,7 +155,12 @@
}
for (size_t i = 0; i < c->NumStaticFields(); ++i) {
Field* f = c->GetStaticField(i);
+ fh.ChangeField(f);
if (IsVisibleField(f, publicOnly)) {
+ if (fh.GetType() == NULL) {
+ DCHECK(env->ExceptionOccurred());
+ return NULL;
+ }
fields.push_back(f);
}
if (env->ExceptionOccurred()) {
@@ -174,15 +185,22 @@
}
static jobjectArray Class_getDeclaredMethods(JNIEnv* env, jclass javaClass, jboolean publicOnly) {
+ ScopedThreadStateChange tsc(Thread::Current(), Thread::kRunnable);
Class* c = DecodeClass(env, javaClass);
if (c == NULL) {
return NULL;
}
std::vector<Method*> methods;
+ MethodHelper mh;
for (size_t i = 0; i < c->NumVirtualMethods(); ++i) {
Method* m = c->GetVirtualMethod(i);
+ mh.ChangeMethod(m);
if (IsVisibleMethod(m, publicOnly)) {
+ if (mh.GetReturnType() == NULL || mh.GetParameterTypes() == NULL) {
+ DCHECK(env->ExceptionOccurred());
+ return NULL;
+ }
methods.push_back(m);
}
if (env->ExceptionOccurred()) {
@@ -191,7 +209,12 @@
}
for (size_t i = 0; i < c->NumDirectMethods(); ++i) {
Method* m = c->GetDirectMethod(i);
+ mh.ChangeMethod(m);
if (IsVisibleMethod(m, publicOnly)) {
+ if (mh.GetReturnType() == NULL || mh.GetParameterTypes() == NULL) {
+ DCHECK(env->ExceptionOccurred());
+ return NULL;
+ }
methods.push_back(m);
}
if (env->ExceptionOccurred()) {
@@ -283,6 +306,7 @@
}
static jobject Class_getDeclaredFieldNative(JNIEnv* env, jclass java_class, jobject jname) {
+ ScopedThreadStateChange tsc(Thread::Current(), Thread::kRunnable);
Class* c = DecodeClass(env, java_class);
if (c == NULL) {
return NULL;
@@ -296,6 +320,10 @@
Field* f = c->GetInstanceField(i);
fh.ChangeField(f);
if (name->Equals(fh.GetName())) {
+ if (fh.GetType() == NULL) {
+ DCHECK(env->ExceptionOccurred());
+ return NULL;
+ }
return AddLocalReference<jclass>(env, f);
}
}
@@ -303,6 +331,10 @@
Field* f = c->GetStaticField(i);
fh.ChangeField(f);
if (name->Equals(fh.GetName())) {
+ if (fh.GetType() == NULL) {
+ DCHECK(env->ExceptionOccurred());
+ return NULL;
+ }
return AddLocalReference<jclass>(env, f);
}
}