OSDN Git Service

Add null check to CheckVirtualMethod
authorMathieu Chartier <mathieuc@google.com>
Wed, 20 Aug 2014 19:09:38 +0000 (12:09 -0700)
committerMathieu Chartier <mathieuc@google.com>
Wed, 20 Aug 2014 19:37:32 +0000 (12:37 -0700)
There was a runtime SIGSEGV that should have been a check jni
failure.

Also added regression test.

Bug: 16320699
Change-Id: If6c8e73959cefb24e4703f1562cdddb343d86630

runtime/check_jni.cc
runtime/jni_internal_test.cc

index a530594..9036e3d 100644 (file)
@@ -353,7 +353,9 @@ class ScopedCheck {
       return;
     }
     mirror::Object* o = soa_.Decode<mirror::Object*>(java_object);
-    if (!o->InstanceOf(m->GetDeclaringClass())) {
+    if (o == nullptr) {
+      JniAbortF(function_name_, "can't call %s on null object", PrettyMethod(m).c_str());
+    } else if (!o->InstanceOf(m->GetDeclaringClass())) {
       JniAbortF(function_name_, "can't call %s on instance of %s",
                 PrettyMethod(m).c_str(), PrettyTypeOf(o).c_str());
     }
index da3080f..bb46321 100644 (file)
@@ -314,6 +314,22 @@ TEST_F(JniInternalTest, GetMethodID) {
   check_jni_abort_catcher.Check("sig == null");
 }
 
+TEST_F(JniInternalTest, CallVoidMethodNullReceiver) {
+  jclass jlobject = env_->FindClass("java/lang/Object");
+  jmethodID method;
+
+  // Check that GetMethodID for java.lang.NoSuchMethodError.<init>(String) finds the constructor.
+  method = env_->GetMethodID(jlobject, "<init>", "()V");
+  EXPECT_NE(nullptr, method);
+  EXPECT_FALSE(env_->ExceptionCheck());
+
+  // Null object to CallVoidMethod.
+  CheckJniAbortCatcher check_jni_abort_catcher;
+  method = env_->GetMethodID(nullptr, "<init>", "(Ljava/lang/String;)V");
+  env_->CallVoidMethod(nullptr, method);
+  check_jni_abort_catcher.Check("null");
+}
+
 TEST_F(JniInternalTest, GetStaticMethodID) {
   jclass jlobject = env_->FindClass("java/lang/Object");
   jclass jlnsme = env_->FindClass("java/lang/NoSuchMethodError");