1 /* 2 * Copyright (C) 2011 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include "jni_internal.h" 18 19 #include "android-base/stringprintf.h" 20 21 #include "art_method-inl.h" 22 #include "common_compiler_test.h" 23 #include "indirect_reference_table.h" 24 #include "java_vm_ext.h" 25 #include "jni_env_ext.h" 26 #include "mirror/string-inl.h" 27 #include "nativehelper/scoped_local_ref.h" 28 #include "scoped_thread_state_change-inl.h" 29 30 namespace art { 31 32 using android::base::StringPrintf; 33 34 // TODO: Convert to CommonRuntimeTest. Currently MakeExecutable is used. 35 class JniInternalTest : public CommonCompilerTest { 36 protected: 37 virtual void SetUp() { 38 CommonCompilerTest::SetUp(); 39 40 vm_ = Runtime::Current()->GetJavaVM(); 41 42 // Turn on -verbose:jni for the JNI tests. 43 // gLogVerbosity.jni = true; 44 45 vm_->AttachCurrentThread(&env_, nullptr); 46 47 ScopedLocalRef<jclass> aioobe(env_, 48 env_->FindClass("java/lang/ArrayIndexOutOfBoundsException")); 49 CHECK(aioobe.get() != nullptr); 50 aioobe_ = reinterpret_cast<jclass>(env_->NewGlobalRef(aioobe.get())); 51 52 ScopedLocalRef<jclass> ase(env_, env_->FindClass("java/lang/ArrayStoreException")); 53 CHECK(ase.get() != nullptr); 54 ase_ = reinterpret_cast<jclass>(env_->NewGlobalRef(ase.get())); 55 56 ScopedLocalRef<jclass> sioobe(env_, 57 env_->FindClass("java/lang/StringIndexOutOfBoundsException")); 58 CHECK(sioobe.get() != nullptr); 59 sioobe_ = reinterpret_cast<jclass>(env_->NewGlobalRef(sioobe.get())); 60 } 61 62 void ExpectException(jclass exception_class) { 63 ScopedObjectAccess soa(env_); 64 EXPECT_TRUE(env_->ExceptionCheck()) 65 << mirror::Class::PrettyDescriptor(soa.Decode<mirror::Class>(exception_class)); 66 jthrowable exception = env_->ExceptionOccurred(); 67 EXPECT_NE(nullptr, exception); 68 env_->ExceptionClear(); 69 EXPECT_TRUE(env_->IsInstanceOf(exception, exception_class)); 70 } 71 72 void CleanUpJniEnv() { 73 if (aioobe_ != nullptr) { 74 env_->DeleteGlobalRef(aioobe_); 75 aioobe_ = nullptr; 76 } 77 if (ase_ != nullptr) { 78 env_->DeleteGlobalRef(ase_); 79 ase_ = nullptr; 80 } 81 if (sioobe_ != nullptr) { 82 env_->DeleteGlobalRef(sioobe_); 83 sioobe_ = nullptr; 84 } 85 } 86 87 virtual void TearDown() OVERRIDE { 88 CleanUpJniEnv(); 89 CommonCompilerTest::TearDown(); 90 } 91 92 jclass GetPrimitiveClass(char descriptor) { 93 ScopedObjectAccess soa(env_); 94 mirror::Class* c = class_linker_->FindPrimitiveClass(descriptor); 95 CHECK(c != nullptr); 96 return soa.AddLocalReference<jclass>(c); 97 } 98 99 void ExpectClassFound(const char* name) { 100 EXPECT_NE(env_->FindClass(name), nullptr) << name; 101 EXPECT_FALSE(env_->ExceptionCheck()) << name; 102 } 103 104 void ExpectClassNotFound(const char* name, bool check_jni, const char* check_jni_msg, 105 CheckJniAbortCatcher* abort_catcher) { 106 EXPECT_EQ(env_->FindClass(name), nullptr) << name; 107 if (!check_jni || check_jni_msg == nullptr) { 108 EXPECT_TRUE(env_->ExceptionCheck()) << name; 109 env_->ExceptionClear(); 110 } else { 111 abort_catcher->Check(check_jni_msg); 112 } 113 } 114 115 void FindClassTest(bool check_jni) { 116 bool old_check_jni = vm_->SetCheckJniEnabled(check_jni); 117 CheckJniAbortCatcher check_jni_abort_catcher; 118 119 // Null argument is always an abort. 120 env_->FindClass(nullptr); 121 check_jni_abort_catcher.Check(check_jni ? "non-nullable const char* was NULL" 122 : "name == null"); 123 124 // Reference types... 125 ExpectClassFound("java/lang/String"); 126 // ...for arrays too, where you must include "L;". 127 ExpectClassFound("[Ljava/lang/String;"); 128 // Primitive arrays are okay too, if the primitive type is valid. 129 ExpectClassFound("[C"); 130 131 // But primitive types aren't allowed... 132 ExpectClassNotFound("C", check_jni, nullptr, &check_jni_abort_catcher); 133 ExpectClassNotFound("V", check_jni, nullptr, &check_jni_abort_catcher); 134 ExpectClassNotFound("K", check_jni, nullptr, &check_jni_abort_catcher); 135 136 if (check_jni) { 137 // Check JNI will reject invalid class names as aborts but without pending exceptions. 138 EXPECT_EQ(env_->FindClass("java.lang.String"), nullptr); 139 EXPECT_FALSE(env_->ExceptionCheck()); 140 check_jni_abort_catcher.Check("illegal class name 'java.lang.String'"); 141 142 EXPECT_EQ(env_->FindClass("[Ljava.lang.String;"), nullptr); 143 EXPECT_FALSE(env_->ExceptionCheck()); 144 check_jni_abort_catcher.Check("illegal class name '[Ljava.lang.String;'"); 145 } else { 146 // Without check JNI we're tolerant and replace '.' with '/'. 147 ExpectClassFound("java.lang.String"); 148 ExpectClassFound("[Ljava.lang.String;"); 149 } 150 151 ExpectClassNotFound("Ljava.lang.String;", check_jni, "illegal class name 'Ljava.lang.String;'", 152 &check_jni_abort_catcher); 153 ExpectClassNotFound("[java.lang.String", check_jni, "illegal class name '[java.lang.String'", 154 &check_jni_abort_catcher); 155 156 // You can't include the "L;" in a JNI class descriptor. 157 ExpectClassNotFound("Ljava/lang/String;", check_jni, "illegal class name 'Ljava/lang/String;'", 158 &check_jni_abort_catcher); 159 160 // But you must include it for an array of any reference type. 161 ExpectClassNotFound("[java/lang/String", check_jni, "illegal class name '[java/lang/String'", 162 &check_jni_abort_catcher); 163 164 ExpectClassNotFound("[K", check_jni, "illegal class name '[K'", &check_jni_abort_catcher); 165 166 // Void arrays aren't allowed. 167 ExpectClassNotFound("[V", check_jni, "illegal class name '[V'", &check_jni_abort_catcher); 168 169 EXPECT_EQ(check_jni, vm_->SetCheckJniEnabled(old_check_jni)); 170 } 171 172 void GetFieldIdBadArgumentTest(bool check_jni) { 173 bool old_check_jni = vm_->SetCheckJniEnabled(check_jni); 174 CheckJniAbortCatcher check_jni_abort_catcher; 175 176 jclass c = env_->FindClass("java/lang/String"); 177 ASSERT_NE(c, nullptr); 178 179 jfieldID fid = env_->GetFieldID(nullptr, "count", "I"); 180 EXPECT_EQ(nullptr, fid); 181 check_jni_abort_catcher.Check(check_jni ? "GetFieldID received NULL jclass" 182 : "java_class == null"); 183 fid = env_->GetFieldID(c, nullptr, "I"); 184 EXPECT_EQ(nullptr, fid); 185 check_jni_abort_catcher.Check(check_jni ? "non-nullable const char* was NULL" 186 : "name == null"); 187 fid = env_->GetFieldID(c, "count", nullptr); 188 EXPECT_EQ(nullptr, fid); 189 check_jni_abort_catcher.Check(check_jni ? "non-nullable const char* was NULL" 190 : "sig == null"); 191 192 EXPECT_EQ(check_jni, vm_->SetCheckJniEnabled(old_check_jni)); 193 } 194 195 void GetStaticFieldIdBadArgumentTest(bool check_jni) { 196 bool old_check_jni = vm_->SetCheckJniEnabled(check_jni); 197 CheckJniAbortCatcher check_jni_abort_catcher; 198 199 jclass c = env_->FindClass("java/lang/String"); 200 ASSERT_NE(c, nullptr); 201 202 jfieldID fid = env_->GetStaticFieldID(nullptr, "CASE_INSENSITIVE_ORDER", "Ljava/util/Comparator;"); 203 EXPECT_EQ(nullptr, fid); 204 check_jni_abort_catcher.Check(check_jni ? "GetStaticFieldID received NULL jclass" 205 : "java_class == null"); 206 fid = env_->GetStaticFieldID(c, nullptr, "Ljava/util/Comparator;"); 207 EXPECT_EQ(nullptr, fid); 208 check_jni_abort_catcher.Check(check_jni ? "non-nullable const char* was NULL" 209 : "name == null"); 210 fid = env_->GetStaticFieldID(c, "CASE_INSENSITIVE_ORDER", nullptr); 211 EXPECT_EQ(nullptr, fid); 212 check_jni_abort_catcher.Check(check_jni ? "non-nullable const char* was NULL" 213 : "sig == null"); 214 215 EXPECT_EQ(check_jni, vm_->SetCheckJniEnabled(old_check_jni)); 216 } 217 218 void GetMethodIdBadArgumentTest(bool check_jni) { 219 bool old_check_jni = vm_->SetCheckJniEnabled(check_jni); 220 CheckJniAbortCatcher check_jni_abort_catcher; 221 222 jmethodID method = env_->GetMethodID(nullptr, "<init>", "(Ljava/lang/String;)V"); 223 EXPECT_EQ(nullptr, method); 224 check_jni_abort_catcher.Check(check_jni ? "GetMethodID received NULL jclass" 225 : "java_class == null"); 226 jclass jlnsme = env_->FindClass("java/lang/NoSuchMethodError"); 227 ASSERT_TRUE(jlnsme != nullptr); 228 method = env_->GetMethodID(jlnsme, nullptr, "(Ljava/lang/String;)V"); 229 EXPECT_EQ(nullptr, method); 230 check_jni_abort_catcher.Check(check_jni ? "non-nullable const char* was NULL" 231 : "name == null"); 232 method = env_->GetMethodID(jlnsme, "<init>", nullptr); 233 EXPECT_EQ(nullptr, method); 234 check_jni_abort_catcher.Check(check_jni ? "non-nullable const char* was NULL" 235 : "sig == null"); 236 237 EXPECT_EQ(check_jni, vm_->SetCheckJniEnabled(old_check_jni)); 238 } 239 240 void GetStaticMethodIdBadArgumentTest(bool check_jni) { 241 bool old_check_jni = vm_->SetCheckJniEnabled(check_jni); 242 CheckJniAbortCatcher check_jni_abort_catcher; 243 244 jmethodID method = env_->GetStaticMethodID(nullptr, "valueOf", "(I)Ljava/lang/String;"); 245 EXPECT_EQ(nullptr, method); 246 check_jni_abort_catcher.Check(check_jni ? "GetStaticMethodID received NULL jclass" 247 : "java_class == null"); 248 jclass jlstring = env_->FindClass("java/lang/String"); 249 method = env_->GetStaticMethodID(jlstring, nullptr, "(I)Ljava/lang/String;"); 250 EXPECT_EQ(nullptr, method); 251 check_jni_abort_catcher.Check(check_jni ? "non-nullable const char* was NULL" 252 : "name == null"); 253 method = env_->GetStaticMethodID(jlstring, "valueOf", nullptr); 254 EXPECT_EQ(nullptr, method); 255 check_jni_abort_catcher.Check(check_jni ? "non-nullable const char* was NULL" 256 : "sig == null"); 257 258 EXPECT_EQ(check_jni, vm_->SetCheckJniEnabled(old_check_jni)); 259 } 260 261 void GetFromReflectedField_ToReflectedFieldBadArgumentTest(bool check_jni) { 262 bool old_check_jni = vm_->SetCheckJniEnabled(check_jni); 263 CheckJniAbortCatcher check_jni_abort_catcher; 264 265 jclass c = env_->FindClass("java/lang/String"); 266 ASSERT_NE(c, nullptr); 267 jfieldID fid = env_->GetFieldID(c, "count", "I"); 268 ASSERT_NE(fid, nullptr); 269 270 // Check class argument for null argument, not checked in non-check JNI. 271 jobject field = env_->ToReflectedField(nullptr, fid, JNI_FALSE); 272 if (check_jni) { 273 EXPECT_EQ(field, nullptr); 274 check_jni_abort_catcher.Check("ToReflectedField received NULL jclass"); 275 } else { 276 EXPECT_NE(field, nullptr); 277 } 278 279 field = env_->ToReflectedField(c, nullptr, JNI_FALSE); 280 EXPECT_EQ(field, nullptr); 281 check_jni_abort_catcher.Check(check_jni ? "jfieldID was NULL" 282 : "fid == null"); 283 284 fid = env_->FromReflectedField(nullptr); 285 ASSERT_EQ(fid, nullptr); 286 check_jni_abort_catcher.Check(check_jni ? "expected non-null java.lang.reflect.Field" 287 : "jlr_field == null"); 288 289 EXPECT_EQ(check_jni, vm_->SetCheckJniEnabled(old_check_jni)); 290 } 291 292 void GetFromReflectedMethod_ToReflectedMethodBadArgumentTest(bool check_jni) { 293 bool old_check_jni = vm_->SetCheckJniEnabled(check_jni); 294 CheckJniAbortCatcher check_jni_abort_catcher; 295 296 jclass c = env_->FindClass("java/lang/String"); 297 ASSERT_NE(c, nullptr); 298 jmethodID mid = env_->GetMethodID(c, "<init>", "()V"); 299 ASSERT_NE(mid, nullptr); 300 301 // Check class argument for null argument, not checked in non-check JNI. 302 jobject method = env_->ToReflectedMethod(nullptr, mid, JNI_FALSE); 303 if (check_jni) { 304 EXPECT_EQ(method, nullptr); 305 check_jni_abort_catcher.Check("ToReflectedMethod received NULL jclass"); 306 } else { 307 EXPECT_NE(method, nullptr); 308 } 309 310 method = env_->ToReflectedMethod(c, nullptr, JNI_FALSE); 311 EXPECT_EQ(method, nullptr); 312 check_jni_abort_catcher.Check(check_jni ? "jmethodID was NULL" 313 : "mid == null"); 314 mid = env_->FromReflectedMethod(method); 315 ASSERT_EQ(mid, nullptr); 316 check_jni_abort_catcher.Check(check_jni ? "expected non-null method" : "jlr_method == null"); 317 318 EXPECT_EQ(check_jni, vm_->SetCheckJniEnabled(old_check_jni)); 319 } 320 321 void RegisterAndUnregisterNativesBadArguments(bool check_jni, 322 CheckJniAbortCatcher* check_jni_abort_catcher) { 323 bool old_check_jni = vm_->SetCheckJniEnabled(check_jni); 324 // Passing a class of null is a failure. 325 { 326 JNINativeMethod methods[] = { }; 327 EXPECT_EQ(env_->RegisterNatives(nullptr, methods, 0), JNI_ERR); 328 check_jni_abort_catcher->Check(check_jni ? "RegisterNatives received NULL jclass" 329 : "java_class == null"); 330 } 331 332 // Passing methods as null is a failure. 333 jclass jlobject = env_->FindClass("java/lang/Object"); 334 EXPECT_EQ(env_->RegisterNatives(jlobject, nullptr, 1), JNI_ERR); 335 check_jni_abort_catcher->Check("methods == null"); 336 337 // Unregisters null is a failure. 338 EXPECT_EQ(env_->UnregisterNatives(nullptr), JNI_ERR); 339 check_jni_abort_catcher->Check(check_jni ? "UnregisterNatives received NULL jclass" 340 : "java_class == null"); 341 342 EXPECT_EQ(check_jni, vm_->SetCheckJniEnabled(old_check_jni)); 343 } 344 345 346 void GetPrimitiveArrayElementsOfWrongType(bool check_jni) { 347 bool old_check_jni = vm_->SetCheckJniEnabled(check_jni); 348 CheckJniAbortCatcher jni_abort_catcher; 349 350 jbooleanArray array = env_->NewBooleanArray(10); 351 jboolean is_copy; 352 EXPECT_EQ(env_->GetByteArrayElements(reinterpret_cast<jbyteArray>(array), &is_copy), nullptr); 353 jni_abort_catcher.Check( 354 check_jni ? "incompatible array type boolean[] expected byte[]" 355 : "attempt to get byte primitive array elements with an object of type boolean[]"); 356 EXPECT_EQ(env_->GetShortArrayElements(reinterpret_cast<jshortArray>(array), &is_copy), nullptr); 357 jni_abort_catcher.Check( 358 check_jni ? "incompatible array type boolean[] expected short[]" 359 : "attempt to get short primitive array elements with an object of type boolean[]"); 360 EXPECT_EQ(env_->GetCharArrayElements(reinterpret_cast<jcharArray>(array), &is_copy), nullptr); 361 jni_abort_catcher.Check( 362 check_jni ? "incompatible array type boolean[] expected char[]" 363 : "attempt to get char primitive array elements with an object of type boolean[]"); 364 EXPECT_EQ(env_->GetIntArrayElements(reinterpret_cast<jintArray>(array), &is_copy), nullptr); 365 jni_abort_catcher.Check( 366 check_jni ? "incompatible array type boolean[] expected int[]" 367 : "attempt to get int primitive array elements with an object of type boolean[]"); 368 EXPECT_EQ(env_->GetLongArrayElements(reinterpret_cast<jlongArray>(array), &is_copy), nullptr); 369 jni_abort_catcher.Check( 370 check_jni ? "incompatible array type boolean[] expected long[]" 371 : "attempt to get long primitive array elements with an object of type boolean[]"); 372 EXPECT_EQ(env_->GetFloatArrayElements(reinterpret_cast<jfloatArray>(array), &is_copy), nullptr); 373 jni_abort_catcher.Check( 374 check_jni ? "incompatible array type boolean[] expected float[]" 375 : "attempt to get float primitive array elements with an object of type boolean[]"); 376 EXPECT_EQ(env_->GetDoubleArrayElements(reinterpret_cast<jdoubleArray>(array), &is_copy), nullptr); 377 jni_abort_catcher.Check( 378 check_jni ? "incompatible array type boolean[] expected double[]" 379 : "attempt to get double primitive array elements with an object of type boolean[]"); 380 jbyteArray array2 = env_->NewByteArray(10); 381 EXPECT_EQ(env_->GetBooleanArrayElements(reinterpret_cast<jbooleanArray>(array2), &is_copy), 382 nullptr); 383 jni_abort_catcher.Check( 384 check_jni ? "incompatible array type byte[] expected boolean[]" 385 : "attempt to get boolean primitive array elements with an object of type byte[]"); 386 jobject object = env_->NewStringUTF("Test String"); 387 EXPECT_EQ(env_->GetBooleanArrayElements(reinterpret_cast<jbooleanArray>(object), &is_copy), 388 nullptr); 389 jni_abort_catcher.Check( 390 check_jni ? "jarray argument has non-array type: java.lang.String" 391 : "attempt to get boolean primitive array elements with an object of type java.lang.String"); 392 393 EXPECT_EQ(check_jni, vm_->SetCheckJniEnabled(old_check_jni)); 394 } 395 396 void ReleasePrimitiveArrayElementsOfWrongType(bool check_jni) { 397 bool old_check_jni = vm_->SetCheckJniEnabled(check_jni); 398 CheckJniAbortCatcher jni_abort_catcher; 399 { 400 jbooleanArray array = env_->NewBooleanArray(10); 401 ASSERT_TRUE(array != nullptr); 402 jboolean is_copy; 403 jboolean* elements = env_->GetBooleanArrayElements(array, &is_copy); 404 ASSERT_TRUE(elements != nullptr); 405 env_->ReleaseByteArrayElements(reinterpret_cast<jbyteArray>(array), 406 reinterpret_cast<jbyte*>(elements), 0); 407 jni_abort_catcher.Check( 408 check_jni ? "incompatible array type boolean[] expected byte[]" 409 : "attempt to release byte primitive array elements with an object of type boolean[]"); 410 env_->ReleaseShortArrayElements(reinterpret_cast<jshortArray>(array), 411 reinterpret_cast<jshort*>(elements), 0); 412 jni_abort_catcher.Check( 413 check_jni ? "incompatible array type boolean[] expected short[]" 414 : "attempt to release short primitive array elements with an object of type boolean[]"); 415 env_->ReleaseCharArrayElements(reinterpret_cast<jcharArray>(array), 416 reinterpret_cast<jchar*>(elements), 0); 417 jni_abort_catcher.Check( 418 check_jni ? "incompatible array type boolean[] expected char[]" 419 : "attempt to release char primitive array elements with an object of type boolean[]"); 420 env_->ReleaseIntArrayElements(reinterpret_cast<jintArray>(array), 421 reinterpret_cast<jint*>(elements), 0); 422 jni_abort_catcher.Check( 423 check_jni ? "incompatible array type boolean[] expected int[]" 424 : "attempt to release int primitive array elements with an object of type boolean[]"); 425 env_->ReleaseLongArrayElements(reinterpret_cast<jlongArray>(array), 426 reinterpret_cast<jlong*>(elements), 0); 427 jni_abort_catcher.Check( 428 check_jni ? "incompatible array type boolean[] expected long[]" 429 : "attempt to release long primitive array elements with an object of type boolean[]"); 430 env_->ReleaseFloatArrayElements(reinterpret_cast<jfloatArray>(array), 431 reinterpret_cast<jfloat*>(elements), 0); 432 jni_abort_catcher.Check( 433 check_jni ? "incompatible array type boolean[] expected float[]" 434 : "attempt to release float primitive array elements with an object of type boolean[]"); 435 env_->ReleaseDoubleArrayElements(reinterpret_cast<jdoubleArray>(array), 436 reinterpret_cast<jdouble*>(elements), 0); 437 jni_abort_catcher.Check( 438 check_jni ? "incompatible array type boolean[] expected double[]" 439 : "attempt to release double primitive array elements with an object of type boolean[]"); 440 441 // Don't leak the elements array. 442 env_->ReleaseBooleanArrayElements(array, elements, 0); 443 } 444 { 445 jbyteArray array = env_->NewByteArray(10); 446 jboolean is_copy; 447 jbyte* elements = env_->GetByteArrayElements(array, &is_copy); 448 449 env_->ReleaseBooleanArrayElements(reinterpret_cast<jbooleanArray>(array), 450 reinterpret_cast<jboolean*>(elements), 0); 451 jni_abort_catcher.Check( 452 check_jni ? "incompatible array type byte[] expected boolean[]" 453 : "attempt to release boolean primitive array elements with an object of type byte[]"); 454 jobject object = env_->NewStringUTF("Test String"); 455 env_->ReleaseBooleanArrayElements(reinterpret_cast<jbooleanArray>(object), 456 reinterpret_cast<jboolean*>(elements), 0); 457 jni_abort_catcher.Check( 458 check_jni ? "jarray argument has non-array type: java.lang.String" 459 : "attempt to release boolean primitive array elements with an object of type " 460 "java.lang.String"); 461 462 // Don't leak the elements array. 463 env_->ReleaseByteArrayElements(array, elements, 0); 464 } 465 EXPECT_EQ(check_jni, vm_->SetCheckJniEnabled(old_check_jni)); 466 } 467 468 void GetReleasePrimitiveArrayCriticalOfWrongType(bool check_jni) { 469 bool old_check_jni = vm_->SetCheckJniEnabled(check_jni); 470 CheckJniAbortCatcher jni_abort_catcher; 471 472 jobject object = env_->NewStringUTF("Test String"); 473 jboolean is_copy; 474 void* elements = env_->GetPrimitiveArrayCritical(reinterpret_cast<jarray>(object), &is_copy); 475 jni_abort_catcher.Check(check_jni ? "jarray argument has non-array type: java.lang.String" 476 : "expected primitive array, given java.lang.String"); 477 env_->ReleasePrimitiveArrayCritical(reinterpret_cast<jarray>(object), elements, 0); 478 jni_abort_catcher.Check(check_jni ? "jarray argument has non-array type: java.lang.String" 479 : "expected primitive array, given java.lang.String"); 480 481 EXPECT_EQ(check_jni, vm_->SetCheckJniEnabled(old_check_jni)); 482 } 483 484 void GetPrimitiveArrayRegionElementsOfWrongType(bool check_jni) { 485 bool old_check_jni = vm_->SetCheckJniEnabled(check_jni); 486 CheckJniAbortCatcher jni_abort_catcher; 487 constexpr size_t kLength = 10; 488 jbooleanArray array = env_->NewBooleanArray(kLength); 489 ASSERT_TRUE(array != nullptr); 490 jboolean elements[kLength]; 491 env_->GetByteArrayRegion(reinterpret_cast<jbyteArray>(array), 0, kLength, 492 reinterpret_cast<jbyte*>(elements)); 493 jni_abort_catcher.Check( 494 check_jni ? "incompatible array type boolean[] expected byte[]" 495 : "attempt to get region of byte primitive array elements with an object of type boolean[]"); 496 env_->GetShortArrayRegion(reinterpret_cast<jshortArray>(array), 0, kLength, 497 reinterpret_cast<jshort*>(elements)); 498 jni_abort_catcher.Check( 499 check_jni ? "incompatible array type boolean[] expected short[]" 500 : "attempt to get region of short primitive array elements with an object of type boolean[]"); 501 env_->GetCharArrayRegion(reinterpret_cast<jcharArray>(array), 0, kLength, 502 reinterpret_cast<jchar*>(elements)); 503 jni_abort_catcher.Check( 504 check_jni ? "incompatible array type boolean[] expected char[]" 505 : "attempt to get region of char primitive array elements with an object of type boolean[]"); 506 env_->GetIntArrayRegion(reinterpret_cast<jintArray>(array), 0, kLength, 507 reinterpret_cast<jint*>(elements)); 508 jni_abort_catcher.Check( 509 check_jni ? "incompatible array type boolean[] expected int[]" 510 : "attempt to get region of int primitive array elements with an object of type boolean[]"); 511 env_->GetLongArrayRegion(reinterpret_cast<jlongArray>(array), 0, kLength, 512 reinterpret_cast<jlong*>(elements)); 513 jni_abort_catcher.Check( 514 check_jni ? "incompatible array type boolean[] expected long[]" 515 : "attempt to get region of long primitive array elements with an object of type boolean[]"); 516 env_->GetFloatArrayRegion(reinterpret_cast<jfloatArray>(array), 0, kLength, 517 reinterpret_cast<jfloat*>(elements)); 518 jni_abort_catcher.Check( 519 check_jni ? "incompatible array type boolean[] expected float[]" 520 : "attempt to get region of float primitive array elements with an object of type boolean[]"); 521 env_->GetDoubleArrayRegion(reinterpret_cast<jdoubleArray>(array), 0, kLength, 522 reinterpret_cast<jdouble*>(elements)); 523 jni_abort_catcher.Check( 524 check_jni ? "incompatible array type boolean[] expected double[]" 525 : "attempt to get region of double primitive array elements with an object of type boolean[]"); 526 jbyteArray array2 = env_->NewByteArray(10); 527 env_->GetBooleanArrayRegion(reinterpret_cast<jbooleanArray>(array2), 0, kLength, 528 reinterpret_cast<jboolean*>(elements)); 529 jni_abort_catcher.Check( 530 check_jni ? "incompatible array type byte[] expected boolean[]" 531 : "attempt to get region of boolean primitive array elements with an object of type byte[]"); 532 jobject object = env_->NewStringUTF("Test String"); 533 env_->GetBooleanArrayRegion(reinterpret_cast<jbooleanArray>(object), 0, kLength, 534 reinterpret_cast<jboolean*>(elements)); 535 jni_abort_catcher.Check(check_jni ? "jarray argument has non-array type: java.lang.String" 536 : "attempt to get region of boolean primitive array elements with an object of type " 537 "java.lang.String"); 538 539 EXPECT_EQ(check_jni, vm_->SetCheckJniEnabled(old_check_jni)); 540 } 541 542 void SetPrimitiveArrayRegionElementsOfWrongType(bool check_jni) { 543 bool old_check_jni = vm_->SetCheckJniEnabled(check_jni); 544 CheckJniAbortCatcher jni_abort_catcher; 545 constexpr size_t kLength = 10; 546 jbooleanArray array = env_->NewBooleanArray(kLength); 547 ASSERT_TRUE(array != nullptr); 548 jboolean elements[kLength]; 549 env_->SetByteArrayRegion(reinterpret_cast<jbyteArray>(array), 0, kLength, 550 reinterpret_cast<jbyte*>(elements)); 551 jni_abort_catcher.Check( 552 check_jni ? "incompatible array type boolean[] expected byte[]" 553 : "attempt to set region of byte primitive array elements with an object of type boolean[]"); 554 env_->SetShortArrayRegion(reinterpret_cast<jshortArray>(array), 0, kLength, 555 reinterpret_cast<jshort*>(elements)); 556 jni_abort_catcher.Check( 557 check_jni ? "incompatible array type boolean[] expected short[]" 558 : "attempt to set region of short primitive array elements with an object of type boolean[]"); 559 env_->SetCharArrayRegion(reinterpret_cast<jcharArray>(array), 0, kLength, 560 reinterpret_cast<jchar*>(elements)); 561 jni_abort_catcher.Check( 562 check_jni ? "incompatible array type boolean[] expected char[]" 563 : "attempt to set region of char primitive array elements with an object of type boolean[]"); 564 env_->SetIntArrayRegion(reinterpret_cast<jintArray>(array), 0, kLength, 565 reinterpret_cast<jint*>(elements)); 566 jni_abort_catcher.Check( 567 check_jni ? "incompatible array type boolean[] expected int[]" 568 : "attempt to set region of int primitive array elements with an object of type boolean[]"); 569 env_->SetLongArrayRegion(reinterpret_cast<jlongArray>(array), 0, kLength, 570 reinterpret_cast<jlong*>(elements)); 571 jni_abort_catcher.Check( 572 check_jni ? "incompatible array type boolean[] expected long[]" 573 : "attempt to set region of long primitive array elements with an object of type boolean[]"); 574 env_->SetFloatArrayRegion(reinterpret_cast<jfloatArray>(array), 0, kLength, 575 reinterpret_cast<jfloat*>(elements)); 576 jni_abort_catcher.Check( 577 check_jni ? "incompatible array type boolean[] expected float[]" 578 : "attempt to set region of float primitive array elements with an object of type boolean[]"); 579 env_->SetDoubleArrayRegion(reinterpret_cast<jdoubleArray>(array), 0, kLength, 580 reinterpret_cast<jdouble*>(elements)); 581 jni_abort_catcher.Check( 582 check_jni ? "incompatible array type boolean[] expected double[]" 583 : "attempt to set region of double primitive array elements with an object of type boolean[]"); 584 jbyteArray array2 = env_->NewByteArray(10); 585 env_->SetBooleanArrayRegion(reinterpret_cast<jbooleanArray>(array2), 0, kLength, 586 reinterpret_cast<jboolean*>(elements)); 587 jni_abort_catcher.Check( 588 check_jni ? "incompatible array type byte[] expected boolean[]" 589 : "attempt to set region of boolean primitive array elements with an object of type byte[]"); 590 jobject object = env_->NewStringUTF("Test String"); 591 env_->SetBooleanArrayRegion(reinterpret_cast<jbooleanArray>(object), 0, kLength, 592 reinterpret_cast<jboolean*>(elements)); 593 jni_abort_catcher.Check(check_jni ? "jarray argument has non-array type: java.lang.String" 594 : "attempt to set region of boolean primitive array elements with an object of type " 595 "java.lang.String"); 596 EXPECT_EQ(check_jni, vm_->SetCheckJniEnabled(old_check_jni)); 597 } 598 599 void NewObjectArrayBadArguments(bool check_jni) { 600 bool old_check_jni = vm_->SetCheckJniEnabled(check_jni); 601 CheckJniAbortCatcher jni_abort_catcher; 602 603 jclass element_class = env_->FindClass("java/lang/String"); 604 ASSERT_NE(element_class, nullptr); 605 606 env_->NewObjectArray(-1, element_class, nullptr); 607 jni_abort_catcher.Check(check_jni ? "negative jsize: -1" : "negative array length: -1"); 608 609 env_->NewObjectArray(std::numeric_limits<jint>::min(), element_class, nullptr); 610 jni_abort_catcher.Check(check_jni ? "negative jsize: -2147483648" 611 : "negative array length: -2147483648"); 612 613 EXPECT_EQ(check_jni, vm_->SetCheckJniEnabled(old_check_jni)); 614 } 615 616 void SetUpForTest(bool direct, const char* method_name, const char* method_sig, 617 void* native_fnptr) { 618 // Initialize class loader and set generic JNI entrypoint. 619 // Note: this code is adapted from the jni_compiler_test, and taken with minimal modifications. 620 if (!runtime_->IsStarted()) { 621 { 622 ScopedObjectAccess soa(Thread::Current()); 623 class_loader_ = LoadDex("MyClassNatives"); 624 StackHandleScope<1> hs(soa.Self()); 625 Handle<mirror::ClassLoader> loader( 626 hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader_))); 627 mirror::Class* c = class_linker_->FindClass(soa.Self(), "LMyClassNatives;", loader); 628 const auto pointer_size = class_linker_->GetImagePointerSize(); 629 ArtMethod* method = c->FindClassMethod(method_name, method_sig, pointer_size); 630 ASSERT_TRUE(method != nullptr) << method_name << " " << method_sig; 631 ASSERT_EQ(direct, method->IsDirect()); 632 method->SetEntryPointFromQuickCompiledCode(class_linker_->GetRuntimeQuickGenericJniStub()); 633 } 634 // Start runtime. 635 Thread::Current()->TransitionFromSuspendedToRunnable(); 636 bool started = runtime_->Start(); 637 CHECK(started); 638 } 639 // JNI operations after runtime start. 640 env_ = Thread::Current()->GetJniEnv(); 641 jklass_ = env_->FindClass("MyClassNatives"); 642 ASSERT_TRUE(jklass_ != nullptr) << method_name << " " << method_sig; 643 644 if (direct) { 645 jmethod_ = env_->GetStaticMethodID(jklass_, method_name, method_sig); 646 } else { 647 jmethod_ = env_->GetMethodID(jklass_, method_name, method_sig); 648 } 649 ASSERT_TRUE(jmethod_ != nullptr) << method_name << " " << method_sig; 650 651 if (native_fnptr != nullptr) { 652 JNINativeMethod methods[] = { { method_name, method_sig, native_fnptr } }; 653 ASSERT_EQ(JNI_OK, env_->RegisterNatives(jklass_, methods, 1)) 654 << method_name << " " << method_sig; 655 } else { 656 env_->UnregisterNatives(jklass_); 657 } 658 659 jmethodID constructor = env_->GetMethodID(jklass_, "<init>", "()V"); 660 jobj_ = env_->NewObject(jklass_, constructor); 661 ASSERT_TRUE(jobj_ != nullptr) << method_name << " " << method_sig; 662 } 663 664 JavaVMExt* vm_; 665 JNIEnv* env_; 666 jclass aioobe_; 667 jclass ase_; 668 jclass sioobe_; 669 670 jclass jklass_; 671 jobject jobj_; 672 jobject class_loader_; 673 jmethodID jmethod_; 674 }; 675 676 TEST_F(JniInternalTest, AllocObject) { 677 jclass c = env_->FindClass("java/lang/String"); 678 ASSERT_NE(c, nullptr); 679 jobject o = env_->AllocObject(c); 680 ASSERT_NE(o, nullptr); 681 682 // We have an instance of the class we asked for... 683 ASSERT_TRUE(env_->IsInstanceOf(o, c)); 684 // ...whose fields haven't been initialized because 685 // we didn't call a constructor. 686 // Even with string compression empty string has `count == 0`. 687 ASSERT_EQ(0, env_->GetIntField(o, env_->GetFieldID(c, "count", "I"))); 688 } 689 690 TEST_F(JniInternalTest, GetVersion) { 691 ASSERT_EQ(JNI_VERSION_1_6, env_->GetVersion()); 692 } 693 694 TEST_F(JniInternalTest, FindClass) { 695 // This tests leads to warnings in the log. 696 ScopedLogSeverity sls(LogSeverity::ERROR); 697 698 FindClassTest(false); 699 FindClassTest(true); 700 } 701 702 TEST_F(JniInternalTest, GetFieldID) { 703 jclass jlnsfe = env_->FindClass("java/lang/NoSuchFieldError"); 704 ASSERT_NE(jlnsfe, nullptr); 705 jclass c = env_->FindClass("java/lang/String"); 706 ASSERT_NE(c, nullptr); 707 708 // Wrong type. 709 jfieldID fid = env_->GetFieldID(c, "count", "J"); 710 EXPECT_EQ(nullptr, fid); 711 ExpectException(jlnsfe); 712 713 // Wrong type where type doesn't exist. 714 fid = env_->GetFieldID(c, "count", "Lrod/jane/freddy;"); 715 EXPECT_EQ(nullptr, fid); 716 ExpectException(jlnsfe); 717 718 // Wrong name. 719 fid = env_->GetFieldID(c, "Count", "I"); 720 EXPECT_EQ(nullptr, fid); 721 ExpectException(jlnsfe); 722 723 // Good declared field lookup. 724 fid = env_->GetFieldID(c, "count", "I"); 725 EXPECT_NE(nullptr, fid); 726 EXPECT_FALSE(env_->ExceptionCheck()); 727 728 // Good superclass field lookup. 729 c = env_->FindClass("java/lang/StringBuilder"); 730 fid = env_->GetFieldID(c, "count", "I"); 731 EXPECT_NE(nullptr, fid); 732 EXPECT_NE(fid, nullptr); 733 EXPECT_FALSE(env_->ExceptionCheck()); 734 735 // Not instance. 736 fid = env_->GetFieldID(c, "CASE_INSENSITIVE_ORDER", "Ljava/util/Comparator;"); 737 EXPECT_EQ(nullptr, fid); 738 ExpectException(jlnsfe); 739 740 // Bad arguments. 741 GetFieldIdBadArgumentTest(false); 742 GetFieldIdBadArgumentTest(true); 743 } 744 745 TEST_F(JniInternalTest, GetStaticFieldID) { 746 jclass jlnsfe = env_->FindClass("java/lang/NoSuchFieldError"); 747 ASSERT_NE(jlnsfe, nullptr); 748 jclass c = env_->FindClass("java/lang/String"); 749 ASSERT_NE(c, nullptr); 750 751 // Wrong type. 752 jfieldID fid = env_->GetStaticFieldID(c, "CASE_INSENSITIVE_ORDER", "J"); 753 EXPECT_EQ(nullptr, fid); 754 ExpectException(jlnsfe); 755 756 // Wrong type where type doesn't exist. 757 fid = env_->GetStaticFieldID(c, "CASE_INSENSITIVE_ORDER", "Lrod/jane/freddy;"); 758 EXPECT_EQ(nullptr, fid); 759 ExpectException(jlnsfe); 760 761 // Wrong name. 762 fid = env_->GetStaticFieldID(c, "cASE_INSENSITIVE_ORDER", "Ljava/util/Comparator;"); 763 EXPECT_EQ(nullptr, fid); 764 ExpectException(jlnsfe); 765 766 // Good declared field lookup. 767 fid = env_->GetStaticFieldID(c, "CASE_INSENSITIVE_ORDER", "Ljava/util/Comparator;"); 768 EXPECT_NE(nullptr, fid); 769 EXPECT_NE(fid, nullptr); 770 EXPECT_FALSE(env_->ExceptionCheck()); 771 772 // Not static. 773 fid = env_->GetStaticFieldID(c, "count", "I"); 774 EXPECT_EQ(nullptr, fid); 775 ExpectException(jlnsfe); 776 777 // Bad arguments. 778 GetStaticFieldIdBadArgumentTest(false); 779 GetStaticFieldIdBadArgumentTest(true); 780 } 781 782 TEST_F(JniInternalTest, GetMethodID) { 783 jclass jlobject = env_->FindClass("java/lang/Object"); 784 jclass jlstring = env_->FindClass("java/lang/String"); 785 jclass jlnsme = env_->FindClass("java/lang/NoSuchMethodError"); 786 jclass jncrbc = env_->FindClass("java/nio/channels/ReadableByteChannel"); 787 788 // Sanity check that no exceptions are pending. 789 ASSERT_FALSE(env_->ExceptionCheck()); 790 791 // Check that java.lang.Object.foo() doesn't exist and NoSuchMethodError is 792 // a pending exception. 793 jmethodID method = env_->GetMethodID(jlobject, "foo", "()V"); 794 EXPECT_EQ(nullptr, method); 795 ExpectException(jlnsme); 796 797 // Check that java.lang.Object.equals() does exist. 798 method = env_->GetMethodID(jlobject, "equals", "(Ljava/lang/Object;)Z"); 799 EXPECT_NE(nullptr, method); 800 EXPECT_FALSE(env_->ExceptionCheck()); 801 802 // Check that GetMethodID for java.lang.String.valueOf(int) fails as the 803 // method is static. 804 method = env_->GetMethodID(jlstring, "valueOf", "(I)Ljava/lang/String;"); 805 EXPECT_EQ(nullptr, method); 806 ExpectException(jlnsme); 807 808 // Check that GetMethodID for java.lang.NoSuchMethodError.<init>(String) finds the constructor. 809 method = env_->GetMethodID(jlnsme, "<init>", "(Ljava/lang/String;)V"); 810 EXPECT_NE(nullptr, method); 811 EXPECT_FALSE(env_->ExceptionCheck()); 812 813 // Check that GetMethodID can find a interface method inherited from another interface. 814 method = env_->GetMethodID(jncrbc, "close", "()V"); 815 EXPECT_NE(nullptr, method); 816 EXPECT_FALSE(env_->ExceptionCheck()); 817 818 // Bad arguments. 819 GetMethodIdBadArgumentTest(false); 820 GetMethodIdBadArgumentTest(true); 821 } 822 823 TEST_F(JniInternalTest, CallVoidMethodNullReceiver) { 824 jclass jlobject = env_->FindClass("java/lang/Object"); 825 jmethodID method; 826 827 // Check that GetMethodID for java.lang.NoSuchMethodError.<init>(String) finds the constructor. 828 method = env_->GetMethodID(jlobject, "<init>", "()V"); 829 EXPECT_NE(nullptr, method); 830 EXPECT_FALSE(env_->ExceptionCheck()); 831 832 // Null object to CallVoidMethod. 833 CheckJniAbortCatcher check_jni_abort_catcher; 834 env_->CallVoidMethod(nullptr, method); 835 check_jni_abort_catcher.Check("null"); 836 } 837 838 TEST_F(JniInternalTest, CallVarArgMethodBadPrimitive) { 839 // Check that bad primitive values cause check JNI to abort when 840 // passed out-of-range primitive value var args. As var args can't 841 // differentiate type sizes less than an int, and this isn't 842 // corrected by JNI, this helps ensure JNI code is valid. 843 #define DoCall(boxed_type, shorty, c_type, bad_value) \ 844 { \ 845 jclass prim_class = env_->FindClass("java/lang/" #boxed_type); \ 846 jmethodID method = env_->GetStaticMethodID(prim_class, "valueOf", \ 847 "(" #shorty ")Ljava/lang/" #boxed_type ";"); \ 848 EXPECT_NE(nullptr, method); \ 849 EXPECT_FALSE(env_->ExceptionCheck()); \ 850 CheckJniAbortCatcher check_jni_abort_catcher; \ 851 env_->CallStaticObjectMethod(prim_class, method, bad_value); \ 852 check_jni_abort_catcher.Check("unexpected " #c_type " value: " #bad_value); \ 853 } 854 855 DoCall(Boolean, Z, jboolean, 2); 856 DoCall(Byte, B, jbyte, 128); 857 DoCall(Byte, B, jbyte, -129); 858 DoCall(Short, S, jshort, 32768); 859 DoCall(Short, S, jshort, -32769); 860 DoCall(Character, C, jchar, 65536); 861 DoCall(Character, C, jchar, -1); 862 #undef DoCall 863 } 864 865 TEST_F(JniInternalTest, CallJValueMethodBadPrimitive) { 866 // Check that bad primitive values, passed as jvalues, cause check 867 // JNI to abort. Unlike with var args, sizes less than an int should 868 // be truncated or sign extended and not cause an abort except for 869 // jbooleans that are passed as bytes. 870 #define DoFailCall(boxed_type, shorty, c_type, bad_value) \ 871 { \ 872 jclass prim_class = env_->FindClass("java/lang/" #boxed_type); \ 873 jmethodID method = env_->GetStaticMethodID(prim_class, "valueOf", \ 874 "(" #shorty ")Ljava/lang/" #boxed_type ";"); \ 875 EXPECT_NE(nullptr, method); \ 876 EXPECT_FALSE(env_->ExceptionCheck()); \ 877 CheckJniAbortCatcher check_jni_abort_catcher; \ 878 jvalue jval; \ 879 jval.i = bad_value; \ 880 env_->CallStaticObjectMethodA(prim_class, method, &jval); \ 881 check_jni_abort_catcher.Check("unexpected " #c_type " value: " #bad_value); \ 882 } 883 #define DoGoodCall(boxed_type, shorty, c_type, bad_value) \ 884 { \ 885 jclass prim_class = env_->FindClass("java/lang/" #boxed_type); \ 886 jmethodID method = env_->GetStaticMethodID(prim_class, "valueOf", \ 887 "(" #shorty ")Ljava/lang/" #boxed_type ";"); \ 888 EXPECT_NE(nullptr, method); \ 889 EXPECT_FALSE(env_->ExceptionCheck()); \ 890 jvalue jval; \ 891 jval.i = bad_value; \ 892 env_->CallStaticObjectMethodA(prim_class, method, &jval); \ 893 } 894 895 DoFailCall(Boolean, Z, jboolean, 2); 896 DoGoodCall(Byte, B, jbyte, 128); 897 DoGoodCall(Byte, B, jbyte, -129); 898 DoGoodCall(Short, S, jshort, 32768); 899 DoGoodCall(Short, S, jshort, -32769); 900 DoGoodCall(Character, C, jchar, 65536); 901 DoGoodCall(Character, C, jchar, -1); 902 #undef DoCall 903 } 904 905 TEST_F(JniInternalTest, GetStaticMethodID) { 906 jclass jlobject = env_->FindClass("java/lang/Object"); 907 jclass jlnsme = env_->FindClass("java/lang/NoSuchMethodError"); 908 909 // Sanity check that no exceptions are pending 910 ASSERT_FALSE(env_->ExceptionCheck()); 911 912 // Check that java.lang.Object.foo() doesn't exist and NoSuchMethodError is 913 // a pending exception 914 jmethodID method = env_->GetStaticMethodID(jlobject, "foo", "()V"); 915 EXPECT_EQ(nullptr, method); 916 ExpectException(jlnsme); 917 918 // Check that GetStaticMethodID for java.lang.Object.equals(Object) fails as 919 // the method is not static 920 method = env_->GetStaticMethodID(jlobject, "equals", "(Ljava/lang/Object;)Z"); 921 EXPECT_EQ(nullptr, method); 922 ExpectException(jlnsme); 923 924 // Check that java.lang.String.valueOf(int) does exist 925 jclass jlstring = env_->FindClass("java/lang/String"); 926 method = env_->GetStaticMethodID(jlstring, "valueOf", "(I)Ljava/lang/String;"); 927 EXPECT_NE(nullptr, method); 928 EXPECT_FALSE(env_->ExceptionCheck()); 929 930 // Bad arguments. 931 GetStaticMethodIdBadArgumentTest(false); 932 GetStaticMethodIdBadArgumentTest(true); 933 } 934 935 static size_t GetLocalsCapacity(JNIEnv* env) { 936 ScopedObjectAccess soa(Thread::Current()); 937 return reinterpret_cast<JNIEnvExt*>(env)->GetLocalsCapacity(); 938 } 939 940 TEST_F(JniInternalTest, FromReflectedField_ToReflectedField) { 941 jclass jlrField = env_->FindClass("java/lang/reflect/Field"); 942 jclass c = env_->FindClass("java/lang/String"); 943 ASSERT_NE(c, nullptr); 944 jfieldID fid = env_->GetFieldID(c, "count", "I"); 945 ASSERT_NE(fid, nullptr); 946 // Turn the fid into a java.lang.reflect.Field... 947 jobject field = env_->ToReflectedField(c, fid, JNI_FALSE); 948 size_t capacity_before = GetLocalsCapacity(env_); 949 for (size_t i = 0; i <= 10; ++i) { 950 // Regression test for b/18396311, ToReflectedField leaking local refs causing a local 951 // reference table overflows with 512 references to ArtField 952 env_->DeleteLocalRef(env_->ToReflectedField(c, fid, JNI_FALSE)); 953 } 954 size_t capacity_after = GetLocalsCapacity(env_); 955 ASSERT_EQ(capacity_before, capacity_after); 956 957 ASSERT_NE(c, nullptr); 958 ASSERT_TRUE(env_->IsInstanceOf(field, jlrField)); 959 // ...and back again. 960 jfieldID fid2 = env_->FromReflectedField(field); 961 ASSERT_NE(fid2, nullptr); 962 // Make sure we can actually use it. 963 jstring s = env_->NewStringUTF("poop"); 964 if (mirror::kUseStringCompression) { 965 ASSERT_EQ(mirror::String::GetFlaggedCount(4, /* compressible */ true), 966 env_->GetIntField(s, fid2)); 967 // Create incompressible string 968 jstring s_16 = env_->NewStringUTF("\u0444\u0444"); 969 ASSERT_EQ(mirror::String::GetFlaggedCount(2, /* compressible */ false), 970 env_->GetIntField(s_16, fid2)); 971 } else { 972 ASSERT_EQ(4, env_->GetIntField(s, fid2)); 973 } 974 // Bad arguments. 975 GetFromReflectedField_ToReflectedFieldBadArgumentTest(false); 976 GetFromReflectedField_ToReflectedFieldBadArgumentTest(true); 977 } 978 979 TEST_F(JniInternalTest, FromReflectedMethod_ToReflectedMethod) { 980 jclass jlrMethod = env_->FindClass("java/lang/reflect/Method"); 981 ASSERT_NE(jlrMethod, nullptr); 982 jclass jlrConstructor = env_->FindClass("java/lang/reflect/Constructor"); 983 ASSERT_NE(jlrConstructor, nullptr); 984 jclass c = env_->FindClass("java/lang/String"); 985 ASSERT_NE(c, nullptr); 986 987 jmethodID mid = env_->GetMethodID(c, "<init>", "()V"); 988 ASSERT_NE(mid, nullptr); 989 // Turn the mid into a java.lang.reflect.Constructor... 990 jobject method = env_->ToReflectedMethod(c, mid, JNI_FALSE); 991 size_t capacity_before = GetLocalsCapacity(env_); 992 for (size_t i = 0; i <= 10; ++i) { 993 // Regression test for b/18396311, ToReflectedMethod leaking local refs causing a local 994 // reference table overflows with 512 references to ArtMethod 995 env_->DeleteLocalRef(env_->ToReflectedMethod(c, mid, JNI_FALSE)); 996 } 997 size_t capacity_after = GetLocalsCapacity(env_); 998 ASSERT_EQ(capacity_before, capacity_after); 999 ASSERT_NE(method, nullptr); 1000 ASSERT_TRUE(env_->IsInstanceOf(method, jlrConstructor)); 1001 // ...and back again. 1002 jmethodID mid2 = env_->FromReflectedMethod(method); 1003 ASSERT_NE(mid2, nullptr); 1004 // Make sure we can actually use it. 1005 jstring s = reinterpret_cast<jstring>(env_->AllocObject(c)); 1006 ASSERT_NE(s, nullptr); 1007 env_->CallVoidMethod(s, mid2); 1008 ASSERT_EQ(JNI_FALSE, env_->ExceptionCheck()); 1009 env_->ExceptionClear(); 1010 1011 mid = env_->GetMethodID(c, "length", "()I"); 1012 ASSERT_NE(mid, nullptr); 1013 // Turn the mid into a java.lang.reflect.Method... 1014 method = env_->ToReflectedMethod(c, mid, JNI_FALSE); 1015 ASSERT_NE(method, nullptr); 1016 ASSERT_TRUE(env_->IsInstanceOf(method, jlrMethod)); 1017 // ...and back again. 1018 mid2 = env_->FromReflectedMethod(method); 1019 ASSERT_NE(mid2, nullptr); 1020 // Make sure we can actually use it. 1021 s = env_->NewStringUTF("poop"); 1022 ASSERT_NE(s, nullptr); 1023 ASSERT_EQ(4, env_->CallIntMethod(s, mid2)); 1024 1025 // Bad arguments. 1026 GetFromReflectedMethod_ToReflectedMethodBadArgumentTest(false); 1027 GetFromReflectedMethod_ToReflectedMethodBadArgumentTest(true); 1028 } 1029 1030 static void BogusMethod() { 1031 // You can't pass null function pointers to RegisterNatives. 1032 } 1033 1034 TEST_F(JniInternalTest, RegisterAndUnregisterNatives) { 1035 jclass jlobject = env_->FindClass("java/lang/Object"); 1036 jclass jlnsme = env_->FindClass("java/lang/NoSuchMethodError"); 1037 void* native_function = reinterpret_cast<void*>(BogusMethod); 1038 1039 // Sanity check that no exceptions are pending. 1040 ASSERT_FALSE(env_->ExceptionCheck()); 1041 1042 // The following can print errors to the log we'd like to ignore. 1043 { 1044 ScopedLogSeverity sls(LogSeverity::FATAL); 1045 // Check that registering method without name causes a NoSuchMethodError. 1046 { 1047 JNINativeMethod methods[] = { { nullptr, "()V", native_function } }; 1048 EXPECT_EQ(env_->RegisterNatives(jlobject, methods, 1), JNI_ERR); 1049 } 1050 ExpectException(jlnsme); 1051 1052 // Check that registering method without signature causes a NoSuchMethodError. 1053 { 1054 JNINativeMethod methods[] = { { "notify", nullptr, native_function } }; 1055 EXPECT_EQ(env_->RegisterNatives(jlobject, methods, 1), JNI_ERR); 1056 } 1057 ExpectException(jlnsme); 1058 1059 // Check that registering method without function causes a NoSuchMethodError. 1060 { 1061 JNINativeMethod methods[] = { { "notify", "()V", nullptr } }; 1062 EXPECT_EQ(env_->RegisterNatives(jlobject, methods, 1), JNI_ERR); 1063 } 1064 ExpectException(jlnsme); 1065 1066 // Check that registering to a non-existent java.lang.Object.foo() causes a NoSuchMethodError. 1067 { 1068 JNINativeMethod methods[] = { { "foo", "()V", native_function } }; 1069 EXPECT_EQ(env_->RegisterNatives(jlobject, methods, 1), JNI_ERR); 1070 } 1071 ExpectException(jlnsme); 1072 1073 // Check that registering non-native methods causes a NoSuchMethodError. 1074 { 1075 JNINativeMethod methods[] = { { "equals", "(Ljava/lang/Object;)Z", native_function } }; 1076 EXPECT_EQ(env_->RegisterNatives(jlobject, methods, 1), JNI_ERR); 1077 } 1078 ExpectException(jlnsme); 1079 } 1080 1081 // Check that registering native methods is successful. 1082 { 1083 JNINativeMethod methods[] = { { "notify", "()V", native_function } }; 1084 EXPECT_EQ(env_->RegisterNatives(jlobject, methods, 1), JNI_OK); 1085 } 1086 EXPECT_FALSE(env_->ExceptionCheck()); 1087 EXPECT_EQ(env_->UnregisterNatives(jlobject), JNI_OK); 1088 1089 // Check that registering no methods isn't a failure. 1090 { 1091 JNINativeMethod methods[] = { }; 1092 EXPECT_EQ(env_->RegisterNatives(jlobject, methods, 0), JNI_OK); 1093 } 1094 EXPECT_FALSE(env_->ExceptionCheck()); 1095 EXPECT_EQ(env_->UnregisterNatives(jlobject), JNI_OK); 1096 1097 // Check that registering a -ve number of methods is a failure. 1098 CheckJniAbortCatcher check_jni_abort_catcher; 1099 for (int i = -10; i < 0; ++i) { 1100 JNINativeMethod methods[] = { }; 1101 EXPECT_EQ(env_->RegisterNatives(jlobject, methods, i), JNI_ERR); 1102 check_jni_abort_catcher.Check("negative method count: "); 1103 } 1104 EXPECT_FALSE(env_->ExceptionCheck()); 1105 1106 // Unregistering a class with no natives is a warning. 1107 EXPECT_EQ(env_->UnregisterNatives(jlnsme), JNI_OK); 1108 1109 RegisterAndUnregisterNativesBadArguments(false, &check_jni_abort_catcher); 1110 RegisterAndUnregisterNativesBadArguments(true, &check_jni_abort_catcher); 1111 } 1112 1113 #define EXPECT_PRIMITIVE_ARRAY(new_fn, \ 1114 get_region_fn, \ 1115 set_region_fn, \ 1116 get_elements_fn, \ 1117 release_elements_fn, \ 1118 scalar_type, \ 1119 expected_class_descriptor) \ 1120 jsize size = 4; \ 1121 \ 1122 { \ 1123 CheckJniAbortCatcher jni_abort_catcher; \ 1124 down_cast<JNIEnvExt*>(env_)->SetCheckJniEnabled(false); \ 1125 /* Allocate an negative sized array and check it has the right failure type. */ \ 1126 EXPECT_EQ(env_->new_fn(-1), nullptr); \ 1127 jni_abort_catcher.Check("negative array length: -1"); \ 1128 EXPECT_EQ(env_->new_fn(std::numeric_limits<jint>::min()), nullptr); \ 1129 jni_abort_catcher.Check("negative array length: -2147483648"); \ 1130 /* Pass the array as null. */ \ 1131 EXPECT_EQ(0, env_->GetArrayLength(nullptr)); \ 1132 jni_abort_catcher.Check("java_array == null"); \ 1133 env_->get_region_fn(nullptr, 0, 0, nullptr); \ 1134 jni_abort_catcher.Check("java_array == null"); \ 1135 env_->set_region_fn(nullptr, 0, 0, nullptr); \ 1136 jni_abort_catcher.Check("java_array == null"); \ 1137 env_->get_elements_fn(nullptr, nullptr); \ 1138 jni_abort_catcher.Check("java_array == null"); \ 1139 env_->release_elements_fn(nullptr, nullptr, 0); \ 1140 jni_abort_catcher.Check("java_array == null"); \ 1141 /* Pass the elements for region as null. */ \ 1142 scalar_type ## Array a = env_->new_fn(size); \ 1143 env_->get_region_fn(a, 0, size, nullptr); \ 1144 jni_abort_catcher.Check("buf == null"); \ 1145 env_->set_region_fn(a, 0, size, nullptr); \ 1146 jni_abort_catcher.Check("buf == null"); \ 1147 down_cast<JNIEnvExt*>(env_)->SetCheckJniEnabled(true); \ 1148 } \ 1149 /* Allocate an array and check it has the right type and length. */ \ 1150 scalar_type ## Array a = env_->new_fn(size); \ 1151 EXPECT_NE(a, nullptr); \ 1152 EXPECT_TRUE(env_->IsInstanceOf(a, env_->FindClass(expected_class_descriptor))); \ 1153 EXPECT_EQ(size, env_->GetArrayLength(a)); \ 1154 \ 1155 /* GetPrimitiveArrayRegion/SetPrimitiveArrayRegion */ \ 1156 /* AIOOBE for negative start offset. */ \ 1157 env_->get_region_fn(a, -1, 1, nullptr); \ 1158 ExpectException(aioobe_); \ 1159 env_->set_region_fn(a, -1, 1, nullptr); \ 1160 ExpectException(aioobe_); \ 1161 \ 1162 /* AIOOBE for negative length. */ \ 1163 env_->get_region_fn(a, 0, -1, nullptr); \ 1164 ExpectException(aioobe_); \ 1165 env_->set_region_fn(a, 0, -1, nullptr); \ 1166 ExpectException(aioobe_); \ 1167 \ 1168 /* AIOOBE for buffer overrun. */ \ 1169 env_->get_region_fn(a, size - 1, size, nullptr); \ 1170 ExpectException(aioobe_); \ 1171 env_->set_region_fn(a, size - 1, size, nullptr); \ 1172 ExpectException(aioobe_); \ 1173 \ 1174 /* Regression test against integer overflow in range check. */ \ 1175 env_->get_region_fn(a, 0x7fffffff, 0x7fffffff, nullptr); \ 1176 ExpectException(aioobe_); \ 1177 env_->set_region_fn(a, 0x7fffffff, 0x7fffffff, nullptr); \ 1178 ExpectException(aioobe_); \ 1179 \ 1180 /* It's okay for the buffer to be null as long as the length is 0. */ \ 1181 env_->get_region_fn(a, 2, 0, nullptr); \ 1182 /* Even if the offset is invalid... */ \ 1183 env_->get_region_fn(a, 123, 0, nullptr); \ 1184 ExpectException(aioobe_); \ 1185 \ 1186 /* It's okay for the buffer to be null as long as the length is 0. */ \ 1187 env_->set_region_fn(a, 2, 0, nullptr); \ 1188 /* Even if the offset is invalid... */ \ 1189 env_->set_region_fn(a, 123, 0, nullptr); \ 1190 ExpectException(aioobe_); \ 1191 \ 1192 /* Prepare a couple of buffers. */ \ 1193 /* NOLINT, no parentheses around scalar_type. */ \ 1194 std::unique_ptr<scalar_type[]> src_buf(new scalar_type[size]); /* NOLINT */ \ 1195 std::unique_ptr<scalar_type[]> dst_buf(new scalar_type[size]); /* NOLINT */ \ 1196 for (jsize i = 0; i < size; ++i) { src_buf[i] = scalar_type(i); } \ 1197 for (jsize i = 0; i < size; ++i) { dst_buf[i] = scalar_type(-1); } \ 1198 \ 1199 /* Copy all of src_buf onto the heap. */ \ 1200 env_->set_region_fn(a, 0, size, &src_buf[0]); \ 1201 /* Copy back only part. */ \ 1202 env_->get_region_fn(a, 1, size - 2, &dst_buf[1]); \ 1203 EXPECT_NE(memcmp(&src_buf[0], &dst_buf[0], size * sizeof(scalar_type)), 0) \ 1204 << "short copy equal"; \ 1205 /* Copy the missing pieces. */ \ 1206 env_->get_region_fn(a, 0, 1, &dst_buf[0]); \ 1207 env_->get_region_fn(a, size - 1, 1, &dst_buf[size - 1]); \ 1208 EXPECT_EQ(memcmp(&src_buf[0], &dst_buf[0], size * sizeof(scalar_type)), 0) \ 1209 << "fixed copy not equal"; \ 1210 /* Copy back the whole array. */ \ 1211 env_->get_region_fn(a, 0, size, &dst_buf[0]); \ 1212 EXPECT_EQ(memcmp(&src_buf[0], &dst_buf[0], size * sizeof(scalar_type)), 0) \ 1213 << "full copy not equal"; \ 1214 /* GetPrimitiveArrayCritical */ \ 1215 void* v = env_->GetPrimitiveArrayCritical(a, nullptr); \ 1216 EXPECT_EQ(memcmp(&src_buf[0], v, size * sizeof(scalar_type)), 0) \ 1217 << "GetPrimitiveArrayCritical not equal"; \ 1218 env_->ReleasePrimitiveArrayCritical(a, v, 0); \ 1219 /* GetXArrayElements */ \ 1220 scalar_type* xs = env_->get_elements_fn(a, nullptr); /* NOLINT, scalar_type */ \ 1221 EXPECT_EQ(memcmp(&src_buf[0], xs, size * sizeof(scalar_type)), 0) \ 1222 << # get_elements_fn " not equal"; \ 1223 env_->release_elements_fn(a, xs, 0); \ 1224 1225 TEST_F(JniInternalTest, BooleanArrays) { 1226 EXPECT_PRIMITIVE_ARRAY(NewBooleanArray, GetBooleanArrayRegion, SetBooleanArrayRegion, 1227 GetBooleanArrayElements, ReleaseBooleanArrayElements, jboolean, "[Z"); 1228 } 1229 TEST_F(JniInternalTest, ByteArrays) { 1230 EXPECT_PRIMITIVE_ARRAY(NewByteArray, GetByteArrayRegion, SetByteArrayRegion, 1231 GetByteArrayElements, ReleaseByteArrayElements, jbyte, "[B"); 1232 } 1233 TEST_F(JniInternalTest, CharArrays) { 1234 EXPECT_PRIMITIVE_ARRAY(NewCharArray, GetCharArrayRegion, SetCharArrayRegion, 1235 GetCharArrayElements, ReleaseCharArrayElements, jchar, "[C"); 1236 } 1237 TEST_F(JniInternalTest, DoubleArrays) { 1238 EXPECT_PRIMITIVE_ARRAY(NewDoubleArray, GetDoubleArrayRegion, SetDoubleArrayRegion, 1239 GetDoubleArrayElements, ReleaseDoubleArrayElements, jdouble, "[D"); 1240 } 1241 TEST_F(JniInternalTest, FloatArrays) { 1242 EXPECT_PRIMITIVE_ARRAY(NewFloatArray, GetFloatArrayRegion, SetFloatArrayRegion, 1243 GetFloatArrayElements, ReleaseFloatArrayElements, jfloat, "[F"); 1244 } 1245 TEST_F(JniInternalTest, IntArrays) { 1246 EXPECT_PRIMITIVE_ARRAY(NewIntArray, GetIntArrayRegion, SetIntArrayRegion, 1247 GetIntArrayElements, ReleaseIntArrayElements, jint, "[I"); 1248 } 1249 TEST_F(JniInternalTest, LongArrays) { 1250 EXPECT_PRIMITIVE_ARRAY(NewLongArray, GetLongArrayRegion, SetLongArrayRegion, 1251 GetLongArrayElements, ReleaseLongArrayElements, jlong, "[J"); 1252 } 1253 TEST_F(JniInternalTest, ShortArrays) { 1254 EXPECT_PRIMITIVE_ARRAY(NewShortArray, GetShortArrayRegion, SetShortArrayRegion, 1255 GetShortArrayElements, ReleaseShortArrayElements, jshort, "[S"); 1256 } 1257 1258 TEST_F(JniInternalTest, GetPrimitiveArrayElementsOfWrongType) { 1259 GetPrimitiveArrayElementsOfWrongType(false); 1260 GetPrimitiveArrayElementsOfWrongType(true); 1261 } 1262 1263 TEST_F(JniInternalTest, ReleasePrimitiveArrayElementsOfWrongType) { 1264 ReleasePrimitiveArrayElementsOfWrongType(false); 1265 ReleasePrimitiveArrayElementsOfWrongType(true); 1266 } 1267 1268 TEST_F(JniInternalTest, GetReleasePrimitiveArrayCriticalOfWrongType) { 1269 GetReleasePrimitiveArrayCriticalOfWrongType(false); 1270 GetReleasePrimitiveArrayCriticalOfWrongType(true); 1271 } 1272 1273 TEST_F(JniInternalTest, GetPrimitiveArrayRegionElementsOfWrongType) { 1274 GetPrimitiveArrayRegionElementsOfWrongType(false); 1275 GetPrimitiveArrayRegionElementsOfWrongType(true); 1276 } 1277 1278 TEST_F(JniInternalTest, SetPrimitiveArrayRegionElementsOfWrongType) { 1279 SetPrimitiveArrayRegionElementsOfWrongType(false); 1280 SetPrimitiveArrayRegionElementsOfWrongType(true); 1281 } 1282 1283 TEST_F(JniInternalTest, NewObjectArray) { 1284 jclass element_class = env_->FindClass("java/lang/String"); 1285 ASSERT_NE(element_class, nullptr); 1286 jclass array_class = env_->FindClass("[Ljava/lang/String;"); 1287 ASSERT_NE(array_class, nullptr); 1288 1289 jobjectArray a = env_->NewObjectArray(0, element_class, nullptr); 1290 EXPECT_NE(a, nullptr); 1291 EXPECT_TRUE(env_->IsInstanceOf(a, array_class)); 1292 EXPECT_EQ(0, env_->GetArrayLength(a)); 1293 1294 a = env_->NewObjectArray(1, element_class, nullptr); 1295 EXPECT_NE(a, nullptr); 1296 EXPECT_TRUE(env_->IsInstanceOf(a, array_class)); 1297 EXPECT_EQ(1, env_->GetArrayLength(a)); 1298 EXPECT_TRUE(env_->IsSameObject(env_->GetObjectArrayElement(a, 0), nullptr)); 1299 1300 // Negative array length checks. 1301 NewObjectArrayBadArguments(false); 1302 NewObjectArrayBadArguments(true); 1303 } 1304 1305 TEST_F(JniInternalTest, NewObjectArrayWithPrimitiveClasses) { 1306 const char* primitive_descriptors = "VZBSCIJFD"; 1307 const char* primitive_names[] = { 1308 "void", "boolean", "byte", "short", "char", "int", "long", "float", "double" 1309 }; 1310 ASSERT_EQ(strlen(primitive_descriptors), arraysize(primitive_names)); 1311 1312 bool old_check_jni = vm_->SetCheckJniEnabled(false); 1313 CheckJniAbortCatcher jni_abort_catcher; 1314 for (size_t i = 0; i < strlen(primitive_descriptors); ++i) { 1315 env_->NewObjectArray(0, nullptr, nullptr); 1316 jni_abort_catcher.Check("element_jclass == null"); 1317 jclass primitive_class = GetPrimitiveClass(primitive_descriptors[i]); 1318 env_->NewObjectArray(1, primitive_class, nullptr); 1319 std::string error_msg(StringPrintf("not an object type: %s", primitive_names[i])); 1320 jni_abort_catcher.Check(error_msg.c_str()); 1321 } 1322 EXPECT_FALSE(vm_->SetCheckJniEnabled(true)); 1323 for (size_t i = 0; i < strlen(primitive_descriptors); ++i) { 1324 env_->NewObjectArray(0, nullptr, nullptr); 1325 jni_abort_catcher.Check("NewObjectArray received NULL jclass"); 1326 jclass primitive_class = GetPrimitiveClass(primitive_descriptors[i]); 1327 env_->NewObjectArray(1, primitive_class, nullptr); 1328 std::string error_msg(StringPrintf("not an object type: %s", primitive_names[i])); 1329 jni_abort_catcher.Check(error_msg.c_str()); 1330 } 1331 EXPECT_TRUE(vm_->SetCheckJniEnabled(old_check_jni)); 1332 } 1333 1334 TEST_F(JniInternalTest, NewObjectArrayWithInitialValue) { 1335 jclass element_class = env_->FindClass("java/lang/String"); 1336 ASSERT_NE(element_class, nullptr); 1337 jclass array_class = env_->FindClass("[Ljava/lang/String;"); 1338 ASSERT_NE(array_class, nullptr); 1339 1340 jstring s = env_->NewStringUTF("poop"); 1341 jobjectArray a = env_->NewObjectArray(2, element_class, s); 1342 EXPECT_NE(a, nullptr); 1343 EXPECT_TRUE(env_->IsInstanceOf(a, array_class)); 1344 EXPECT_EQ(2, env_->GetArrayLength(a)); 1345 EXPECT_TRUE(env_->IsSameObject(env_->GetObjectArrayElement(a, 0), s)); 1346 EXPECT_TRUE(env_->IsSameObject(env_->GetObjectArrayElement(a, 1), s)); 1347 1348 // Attempt to incorrect create an array of strings with initial value of string arrays. 1349 CheckJniAbortCatcher jni_abort_catcher; 1350 env_->NewObjectArray(2, element_class, a); 1351 jni_abort_catcher.Check("cannot assign object of type 'java.lang.String[]' to array with element " 1352 "type of 'java.lang.String'"); 1353 } 1354 1355 TEST_F(JniInternalTest, GetArrayLength) { 1356 // Already tested in NewObjectArray/NewPrimitiveArray except for null. 1357 CheckJniAbortCatcher jni_abort_catcher; 1358 bool old_check_jni = vm_->SetCheckJniEnabled(false); 1359 EXPECT_EQ(0, env_->GetArrayLength(nullptr)); 1360 jni_abort_catcher.Check("java_array == null"); 1361 EXPECT_FALSE(vm_->SetCheckJniEnabled(true)); 1362 EXPECT_EQ(JNI_ERR, env_->GetArrayLength(nullptr)); 1363 jni_abort_catcher.Check("jarray was NULL"); 1364 EXPECT_TRUE(vm_->SetCheckJniEnabled(old_check_jni)); 1365 } 1366 1367 TEST_F(JniInternalTest, GetObjectClass) { 1368 jclass string_class = env_->FindClass("java/lang/String"); 1369 ASSERT_NE(string_class, nullptr); 1370 jclass class_class = env_->FindClass("java/lang/Class"); 1371 ASSERT_NE(class_class, nullptr); 1372 1373 jstring s = env_->NewStringUTF("poop"); 1374 jclass c = env_->GetObjectClass(s); 1375 ASSERT_TRUE(env_->IsSameObject(string_class, c)); 1376 1377 jclass c2 = env_->GetObjectClass(c); 1378 ASSERT_TRUE(env_->IsSameObject(class_class, env_->GetObjectClass(c2))); 1379 1380 // Null as object should fail. 1381 CheckJniAbortCatcher jni_abort_catcher; 1382 EXPECT_EQ(env_->GetObjectClass(nullptr), nullptr); 1383 jni_abort_catcher.Check("java_object == null"); 1384 } 1385 1386 TEST_F(JniInternalTest, GetSuperclass) { 1387 jclass object_class = env_->FindClass("java/lang/Object"); 1388 ASSERT_NE(object_class, nullptr); 1389 jclass string_class = env_->FindClass("java/lang/String"); 1390 ASSERT_NE(string_class, nullptr); 1391 jclass runnable_interface = env_->FindClass("java/lang/Runnable"); 1392 ASSERT_NE(runnable_interface, nullptr); 1393 ASSERT_TRUE(env_->IsSameObject(object_class, env_->GetSuperclass(string_class))); 1394 ASSERT_EQ(env_->GetSuperclass(object_class), nullptr); 1395 ASSERT_EQ(env_->GetSuperclass(runnable_interface), nullptr); 1396 1397 // Null as class should fail. 1398 CheckJniAbortCatcher jni_abort_catcher; 1399 bool old_check_jni = vm_->SetCheckJniEnabled(false); 1400 EXPECT_EQ(env_->GetSuperclass(nullptr), nullptr); 1401 jni_abort_catcher.Check("java_class == null"); 1402 EXPECT_FALSE(vm_->SetCheckJniEnabled(true)); 1403 EXPECT_EQ(env_->GetSuperclass(nullptr), nullptr); 1404 jni_abort_catcher.Check("GetSuperclass received NULL jclass"); 1405 EXPECT_TRUE(vm_->SetCheckJniEnabled(old_check_jni)); 1406 } 1407 1408 TEST_F(JniInternalTest, IsAssignableFrom) { 1409 jclass object_class = env_->FindClass("java/lang/Object"); 1410 ASSERT_NE(object_class, nullptr); 1411 jclass string_class = env_->FindClass("java/lang/String"); 1412 ASSERT_NE(string_class, nullptr); 1413 1414 // A superclass is assignable from an instance of its 1415 // subclass but not vice versa. 1416 ASSERT_TRUE(env_->IsAssignableFrom(string_class, object_class)); 1417 ASSERT_FALSE(env_->IsAssignableFrom(object_class, string_class)); 1418 1419 jclass charsequence_interface = env_->FindClass("java/lang/CharSequence"); 1420 ASSERT_NE(charsequence_interface, nullptr); 1421 1422 // An interface is assignable from an instance of an implementing 1423 // class but not vice versa. 1424 ASSERT_TRUE(env_->IsAssignableFrom(string_class, charsequence_interface)); 1425 ASSERT_FALSE(env_->IsAssignableFrom(charsequence_interface, string_class)); 1426 1427 // Check that arrays are covariant. 1428 jclass string_array_class = env_->FindClass("[Ljava/lang/String;"); 1429 ASSERT_NE(string_array_class, nullptr); 1430 jclass object_array_class = env_->FindClass("[Ljava/lang/Object;"); 1431 ASSERT_NE(object_array_class, nullptr); 1432 ASSERT_TRUE(env_->IsAssignableFrom(string_array_class, object_array_class)); 1433 ASSERT_FALSE(env_->IsAssignableFrom(object_array_class, string_array_class)); 1434 1435 // Primitive types are tested in 004-JniTest. 1436 1437 // Null as either class should fail. 1438 CheckJniAbortCatcher jni_abort_catcher; 1439 bool old_check_jni = vm_->SetCheckJniEnabled(false); 1440 EXPECT_EQ(env_->IsAssignableFrom(nullptr, string_class), JNI_FALSE); 1441 jni_abort_catcher.Check("java_class1 == null"); 1442 EXPECT_EQ(env_->IsAssignableFrom(object_class, nullptr), JNI_FALSE); 1443 jni_abort_catcher.Check("java_class2 == null"); 1444 EXPECT_FALSE(vm_->SetCheckJniEnabled(true)); 1445 EXPECT_EQ(env_->IsAssignableFrom(nullptr, string_class), JNI_FALSE); 1446 jni_abort_catcher.Check("IsAssignableFrom received NULL jclass"); 1447 EXPECT_EQ(env_->IsAssignableFrom(object_class, nullptr), JNI_FALSE); 1448 jni_abort_catcher.Check("IsAssignableFrom received NULL jclass"); 1449 EXPECT_TRUE(vm_->SetCheckJniEnabled(old_check_jni)); 1450 } 1451 1452 TEST_F(JniInternalTest, GetObjectRefType) { 1453 jclass local = env_->FindClass("java/lang/Object"); 1454 ASSERT_TRUE(local != nullptr); 1455 EXPECT_EQ(JNILocalRefType, env_->GetObjectRefType(local)); 1456 1457 jobject global = env_->NewGlobalRef(local); 1458 EXPECT_EQ(JNIGlobalRefType, env_->GetObjectRefType(global)); 1459 1460 jweak weak_global = env_->NewWeakGlobalRef(local); 1461 EXPECT_EQ(JNIWeakGlobalRefType, env_->GetObjectRefType(weak_global)); 1462 1463 { 1464 CheckJniAbortCatcher jni_abort_catcher; 1465 jobject invalid = reinterpret_cast<jobject>(this); 1466 EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(invalid)); 1467 jni_abort_catcher.Check("use of invalid jobject"); 1468 } 1469 1470 // TODO: invoke a native method and test that its arguments are considered local references. 1471 1472 // Null as pointer should not fail and return invalid-ref. b/18820997 1473 EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(nullptr)); 1474 1475 // TODO: Null as reference should return the original type. 1476 // This requires running a GC so a non-null object gets freed. 1477 } 1478 1479 TEST_F(JniInternalTest, StaleWeakGlobal) { 1480 jclass java_lang_Class = env_->FindClass("java/lang/Class"); 1481 ASSERT_NE(java_lang_Class, nullptr); 1482 jobjectArray local_ref = env_->NewObjectArray(1, java_lang_Class, nullptr); 1483 ASSERT_NE(local_ref, nullptr); 1484 jweak weak_global = env_->NewWeakGlobalRef(local_ref); 1485 ASSERT_NE(weak_global, nullptr); 1486 env_->DeleteLocalRef(local_ref); 1487 // GC should clear the weak global. 1488 Runtime::Current()->GetHeap()->CollectGarbage(/* clear_soft_references */ false); 1489 jobject new_global_ref = env_->NewGlobalRef(weak_global); 1490 EXPECT_EQ(new_global_ref, nullptr); 1491 jobject new_local_ref = env_->NewLocalRef(weak_global); 1492 EXPECT_EQ(new_local_ref, nullptr); 1493 } 1494 1495 TEST_F(JniInternalTest, NewStringUTF) { 1496 EXPECT_EQ(env_->NewStringUTF(nullptr), nullptr); 1497 jstring s; 1498 1499 s = env_->NewStringUTF(""); 1500 EXPECT_NE(s, nullptr); 1501 EXPECT_EQ(0, env_->GetStringLength(s)); 1502 EXPECT_EQ(0, env_->GetStringUTFLength(s)); 1503 s = env_->NewStringUTF("hello"); 1504 EXPECT_NE(s, nullptr); 1505 EXPECT_EQ(5, env_->GetStringLength(s)); 1506 EXPECT_EQ(5, env_->GetStringUTFLength(s)); 1507 1508 // Encoded surrogate pair. 1509 s = env_->NewStringUTF("\xed\xa0\x81\xed\xb0\x80"); 1510 EXPECT_NE(s, nullptr); 1511 EXPECT_EQ(2, env_->GetStringLength(s)); 1512 1513 // The surrogate pair gets encoded into a 4 byte UTF sequence.. 1514 EXPECT_EQ(4, env_->GetStringUTFLength(s)); 1515 const char* chars = env_->GetStringUTFChars(s, nullptr); 1516 EXPECT_STREQ("\xf0\x90\x90\x80", chars); 1517 env_->ReleaseStringUTFChars(s, chars); 1518 1519 // .. but is stored as is in the utf-16 representation. 1520 const jchar* jchars = env_->GetStringChars(s, nullptr); 1521 EXPECT_EQ(0xd801, jchars[0]); 1522 EXPECT_EQ(0xdc00, jchars[1]); 1523 env_->ReleaseStringChars(s, jchars); 1524 1525 // 4 byte UTF sequence appended to an encoded surrogate pair. 1526 s = env_->NewStringUTF("\xed\xa0\x81\xed\xb0\x80 \xf0\x9f\x8f\xa0"); 1527 EXPECT_NE(s, nullptr); 1528 1529 // The 4 byte sequence {0xf0, 0x9f, 0x8f, 0xa0} is converted into a surrogate 1530 // pair {0xd83c, 0xdfe0}. 1531 EXPECT_EQ(5, env_->GetStringLength(s)); 1532 jchars = env_->GetStringChars(s, nullptr); 1533 // The first surrogate pair, encoded as such in the input. 1534 EXPECT_EQ(0xd801, jchars[0]); 1535 EXPECT_EQ(0xdc00, jchars[1]); 1536 // The second surrogate pair, from the 4 byte UTF sequence in the input. 1537 EXPECT_EQ(0xd83c, jchars[3]); 1538 EXPECT_EQ(0xdfe0, jchars[4]); 1539 env_->ReleaseStringChars(s, jchars); 1540 1541 EXPECT_EQ(9, env_->GetStringUTFLength(s)); 1542 chars = env_->GetStringUTFChars(s, nullptr); 1543 EXPECT_STREQ("\xf0\x90\x90\x80 \xf0\x9f\x8f\xa0", chars); 1544 env_->ReleaseStringUTFChars(s, chars); 1545 1546 // A string with 1, 2, 3 and 4 byte UTF sequences with spaces 1547 // between them 1548 s = env_->NewStringUTF("\x24 \xc2\xa2 \xe2\x82\xac \xf0\x9f\x8f\xa0"); 1549 EXPECT_NE(s, nullptr); 1550 EXPECT_EQ(8, env_->GetStringLength(s)); 1551 EXPECT_EQ(13, env_->GetStringUTFLength(s)); 1552 } 1553 1554 TEST_F(JniInternalTest, NewString) { 1555 jchar chars[] = { 'h', 'i' }; 1556 jstring s; 1557 s = env_->NewString(chars, 0); 1558 EXPECT_NE(s, nullptr); 1559 EXPECT_EQ(0, env_->GetStringLength(s)); 1560 EXPECT_EQ(0, env_->GetStringUTFLength(s)); 1561 s = env_->NewString(chars, 2); 1562 EXPECT_NE(s, nullptr); 1563 EXPECT_EQ(2, env_->GetStringLength(s)); 1564 EXPECT_EQ(2, env_->GetStringUTFLength(s)); 1565 1566 // TODO: check some non-ASCII strings. 1567 } 1568 1569 TEST_F(JniInternalTest, NewStringNullCharsZeroLength) { 1570 jstring s = env_->NewString(nullptr, 0); 1571 EXPECT_NE(s, nullptr); 1572 EXPECT_EQ(0, env_->GetStringLength(s)); 1573 } 1574 1575 TEST_F(JniInternalTest, NewStringNullCharsNonzeroLength) { 1576 CheckJniAbortCatcher jni_abort_catcher; 1577 env_->NewString(nullptr, 1); 1578 jni_abort_catcher.Check("chars == null && char_count > 0"); 1579 } 1580 1581 TEST_F(JniInternalTest, NewStringNegativeLength) { 1582 CheckJniAbortCatcher jni_abort_catcher; 1583 bool old_check_jni = vm_->SetCheckJniEnabled(false); 1584 env_->NewString(nullptr, -1); 1585 jni_abort_catcher.Check("char_count < 0: -1"); 1586 env_->NewString(nullptr, std::numeric_limits<jint>::min()); 1587 jni_abort_catcher.Check("char_count < 0: -2147483648"); 1588 EXPECT_FALSE(vm_->SetCheckJniEnabled(true)); 1589 env_->NewString(nullptr, -1); 1590 jni_abort_catcher.Check("negative jsize: -1"); 1591 env_->NewString(nullptr, std::numeric_limits<jint>::min()); 1592 jni_abort_catcher.Check("negative jsize: -2147483648"); 1593 EXPECT_TRUE(vm_->SetCheckJniEnabled(old_check_jni)); 1594 } 1595 1596 TEST_F(JniInternalTest, GetStringLength_GetStringUTFLength) { 1597 // Already tested in the NewString/NewStringUTF tests. 1598 } 1599 1600 TEST_F(JniInternalTest, GetStringRegion_GetStringUTFRegion) { 1601 jstring s = env_->NewStringUTF("hello"); 1602 ASSERT_TRUE(s != nullptr); 1603 1604 env_->GetStringRegion(s, -1, 0, nullptr); 1605 ExpectException(sioobe_); 1606 env_->GetStringRegion(s, 0, -1, nullptr); 1607 ExpectException(sioobe_); 1608 env_->GetStringRegion(s, 0, 10, nullptr); 1609 ExpectException(sioobe_); 1610 env_->GetStringRegion(s, 10, 1, nullptr); 1611 ExpectException(sioobe_); 1612 // Regression test against integer overflow in range check. 1613 env_->GetStringRegion(s, 0x7fffffff, 0x7fffffff, nullptr); 1614 ExpectException(sioobe_); 1615 1616 jchar chars[4] = { 'x', 'x', 'x', 'x' }; 1617 env_->GetStringRegion(s, 1, 2, &chars[1]); 1618 EXPECT_EQ('x', chars[0]); 1619 EXPECT_EQ('e', chars[1]); 1620 EXPECT_EQ('l', chars[2]); 1621 EXPECT_EQ('x', chars[3]); 1622 1623 // It's okay for the buffer to be null as long as the length is 0. 1624 env_->GetStringRegion(s, 2, 0, nullptr); 1625 // Even if the offset is invalid... 1626 env_->GetStringRegion(s, 123, 0, nullptr); 1627 ExpectException(sioobe_); 1628 1629 env_->GetStringUTFRegion(s, -1, 0, nullptr); 1630 ExpectException(sioobe_); 1631 env_->GetStringUTFRegion(s, 0, -1, nullptr); 1632 ExpectException(sioobe_); 1633 env_->GetStringUTFRegion(s, 0, 10, nullptr); 1634 ExpectException(sioobe_); 1635 env_->GetStringUTFRegion(s, 10, 1, nullptr); 1636 ExpectException(sioobe_); 1637 // Regression test against integer overflow in range check. 1638 env_->GetStringUTFRegion(s, 0x7fffffff, 0x7fffffff, nullptr); 1639 ExpectException(sioobe_); 1640 1641 char bytes[4] = { 'x', 'x', 'x', 'x' }; 1642 env_->GetStringUTFRegion(s, 1, 2, &bytes[1]); 1643 EXPECT_EQ('x', bytes[0]); 1644 EXPECT_EQ('e', bytes[1]); 1645 EXPECT_EQ('l', bytes[2]); 1646 EXPECT_EQ('x', bytes[3]); 1647 1648 // It's okay for the buffer to be null as long as the length is 0. 1649 env_->GetStringUTFRegion(s, 2, 0, nullptr); 1650 // Even if the offset is invalid... 1651 env_->GetStringUTFRegion(s, 123, 0, nullptr); 1652 ExpectException(sioobe_); 1653 } 1654 1655 TEST_F(JniInternalTest, GetStringUTFChars_ReleaseStringUTFChars) { 1656 // Passing in a null jstring is ignored normally, but caught by -Xcheck:jni. 1657 bool old_check_jni = vm_->SetCheckJniEnabled(false); 1658 { 1659 CheckJniAbortCatcher check_jni_abort_catcher; 1660 EXPECT_EQ(env_->GetStringUTFChars(nullptr, nullptr), nullptr); 1661 } 1662 { 1663 CheckJniAbortCatcher check_jni_abort_catcher; 1664 EXPECT_FALSE(vm_->SetCheckJniEnabled(true)); 1665 EXPECT_EQ(env_->GetStringUTFChars(nullptr, nullptr), nullptr); 1666 check_jni_abort_catcher.Check("GetStringUTFChars received NULL jstring"); 1667 EXPECT_TRUE(vm_->SetCheckJniEnabled(old_check_jni)); 1668 } 1669 1670 jstring s = env_->NewStringUTF("hello"); 1671 ASSERT_TRUE(s != nullptr); 1672 1673 const char* utf = env_->GetStringUTFChars(s, nullptr); 1674 EXPECT_STREQ("hello", utf); 1675 env_->ReleaseStringUTFChars(s, utf); 1676 1677 jboolean is_copy = JNI_FALSE; 1678 utf = env_->GetStringUTFChars(s, &is_copy); 1679 EXPECT_EQ(JNI_TRUE, is_copy); 1680 EXPECT_STREQ("hello", utf); 1681 env_->ReleaseStringUTFChars(s, utf); 1682 } 1683 1684 TEST_F(JniInternalTest, GetStringChars_ReleaseStringChars) { 1685 jstring s = env_->NewStringUTF("hello"); 1686 ScopedObjectAccess soa(env_); 1687 ObjPtr<mirror::String> s_m = soa.Decode<mirror::String>(s); 1688 ASSERT_TRUE(s != nullptr); 1689 1690 jchar expected[] = { 'h', 'e', 'l', 'l', 'o' }; 1691 const jchar* chars = env_->GetStringChars(s, nullptr); 1692 EXPECT_EQ(expected[0], chars[0]); 1693 EXPECT_EQ(expected[1], chars[1]); 1694 EXPECT_EQ(expected[2], chars[2]); 1695 EXPECT_EQ(expected[3], chars[3]); 1696 EXPECT_EQ(expected[4], chars[4]); 1697 env_->ReleaseStringChars(s, chars); 1698 1699 jboolean is_copy = JNI_FALSE; 1700 chars = env_->GetStringChars(s, &is_copy); 1701 if (Runtime::Current()->GetHeap()->IsMovableObject(s_m)) { 1702 EXPECT_EQ(JNI_TRUE, is_copy); 1703 } else { 1704 EXPECT_EQ(JNI_FALSE, is_copy); 1705 } 1706 EXPECT_EQ(expected[0], chars[0]); 1707 EXPECT_EQ(expected[1], chars[1]); 1708 EXPECT_EQ(expected[2], chars[2]); 1709 EXPECT_EQ(expected[3], chars[3]); 1710 EXPECT_EQ(expected[4], chars[4]); 1711 env_->ReleaseStringChars(s, chars); 1712 } 1713 1714 TEST_F(JniInternalTest, GetStringCritical_ReleaseStringCritical) { 1715 jstring s = env_->NewStringUTF("hello"); 1716 ASSERT_TRUE(s != nullptr); 1717 1718 jchar expected[] = { 'h', 'e', 'l', 'l', 'o' }; 1719 const jchar* chars = env_->GetStringCritical(s, nullptr); 1720 EXPECT_EQ(expected[0], chars[0]); 1721 EXPECT_EQ(expected[1], chars[1]); 1722 EXPECT_EQ(expected[2], chars[2]); 1723 EXPECT_EQ(expected[3], chars[3]); 1724 EXPECT_EQ(expected[4], chars[4]); 1725 env_->ReleaseStringCritical(s, chars); 1726 1727 jboolean is_copy = JNI_TRUE; 1728 chars = env_->GetStringCritical(s, &is_copy); 1729 if (mirror::kUseStringCompression) { 1730 // is_copy has to be JNI_TRUE because "hello" is all-ASCII 1731 EXPECT_EQ(JNI_TRUE, is_copy); 1732 } else { 1733 EXPECT_EQ(JNI_FALSE, is_copy); 1734 } 1735 EXPECT_EQ(expected[0], chars[0]); 1736 EXPECT_EQ(expected[1], chars[1]); 1737 EXPECT_EQ(expected[2], chars[2]); 1738 EXPECT_EQ(expected[3], chars[3]); 1739 EXPECT_EQ(expected[4], chars[4]); 1740 env_->ReleaseStringCritical(s, chars); 1741 1742 if (mirror::kUseStringCompression) { 1743 // is_copy has to be JNI_FALSE because "\xed\xa0\x81\xed\xb0\x80" is incompressible 1744 jboolean is_copy_16 = JNI_TRUE; 1745 jstring s_16 = env_->NewStringUTF("\xed\xa0\x81\xed\xb0\x80"); 1746 chars = env_->GetStringCritical(s_16, &is_copy_16); 1747 EXPECT_EQ(2, env_->GetStringLength(s_16)); 1748 EXPECT_EQ(4, env_->GetStringUTFLength(s_16)); 1749 env_->ReleaseStringCritical(s_16, chars); 1750 } 1751 } 1752 1753 TEST_F(JniInternalTest, GetObjectArrayElement_SetObjectArrayElement) { 1754 jclass java_lang_Class = env_->FindClass("java/lang/Class"); 1755 ASSERT_TRUE(java_lang_Class != nullptr); 1756 1757 jobjectArray array = env_->NewObjectArray(1, java_lang_Class, nullptr); 1758 EXPECT_NE(array, nullptr); 1759 EXPECT_EQ(env_->GetObjectArrayElement(array, 0), nullptr); 1760 env_->SetObjectArrayElement(array, 0, java_lang_Class); 1761 EXPECT_TRUE(env_->IsSameObject(env_->GetObjectArrayElement(array, 0), java_lang_Class)); 1762 1763 // ArrayIndexOutOfBounds for negative index. 1764 env_->SetObjectArrayElement(array, -1, java_lang_Class); 1765 ExpectException(aioobe_); 1766 1767 // ArrayIndexOutOfBounds for too-large index. 1768 env_->SetObjectArrayElement(array, 1, java_lang_Class); 1769 ExpectException(aioobe_); 1770 1771 // ArrayStoreException thrown for bad types. 1772 env_->SetObjectArrayElement(array, 0, env_->NewStringUTF("not a jclass!")); 1773 ExpectException(ase_); 1774 1775 // Null as array should fail. 1776 CheckJniAbortCatcher jni_abort_catcher; 1777 bool old_check_jni = vm_->SetCheckJniEnabled(false); 1778 EXPECT_EQ(nullptr, env_->GetObjectArrayElement(nullptr, 0)); 1779 jni_abort_catcher.Check("java_array == null"); 1780 env_->SetObjectArrayElement(nullptr, 0, nullptr); 1781 jni_abort_catcher.Check("java_array == null"); 1782 EXPECT_FALSE(vm_->SetCheckJniEnabled(true)); 1783 EXPECT_EQ(nullptr, env_->GetObjectArrayElement(nullptr, 0)); 1784 jni_abort_catcher.Check("jarray was NULL"); 1785 env_->SetObjectArrayElement(nullptr, 0, nullptr); 1786 jni_abort_catcher.Check("jarray was NULL"); 1787 EXPECT_TRUE(vm_->SetCheckJniEnabled(old_check_jni)); 1788 } 1789 1790 #define EXPECT_STATIC_PRIMITIVE_FIELD(expect_eq, type, field_name, sig, value1, value2) \ 1791 do { \ 1792 jfieldID fid = env_->GetStaticFieldID(c, field_name, sig); \ 1793 EXPECT_NE(fid, nullptr); \ 1794 env_->SetStatic ## type ## Field(c, fid, value1); \ 1795 expect_eq(value1, env_->GetStatic ## type ## Field(c, fid)); \ 1796 env_->SetStatic ## type ## Field(c, fid, value2); \ 1797 expect_eq(value2, env_->GetStatic ## type ## Field(c, fid)); \ 1798 \ 1799 bool old_check_jni = vm_->SetCheckJniEnabled(false); \ 1800 { \ 1801 CheckJniAbortCatcher jni_abort_catcher; \ 1802 env_->GetStatic ## type ## Field(nullptr, fid); \ 1803 env_->SetStatic ## type ## Field(nullptr, fid, value1); \ 1804 } \ 1805 CheckJniAbortCatcher jni_abort_catcher; \ 1806 env_->GetStatic ## type ## Field(c, nullptr); \ 1807 jni_abort_catcher.Check("fid == null"); \ 1808 env_->SetStatic ## type ## Field(c, nullptr, value1); \ 1809 jni_abort_catcher.Check("fid == null"); \ 1810 \ 1811 EXPECT_FALSE(vm_->SetCheckJniEnabled(true)); \ 1812 env_->GetStatic ## type ## Field(nullptr, fid); \ 1813 jni_abort_catcher.Check("received NULL jclass"); \ 1814 env_->SetStatic ## type ## Field(nullptr, fid, value1); \ 1815 jni_abort_catcher.Check("received NULL jclass"); \ 1816 env_->GetStatic ## type ## Field(c, nullptr); \ 1817 jni_abort_catcher.Check("jfieldID was NULL"); \ 1818 env_->SetStatic ## type ## Field(c, nullptr, value1); \ 1819 jni_abort_catcher.Check("jfieldID was NULL"); \ 1820 EXPECT_TRUE(vm_->SetCheckJniEnabled(old_check_jni)); \ 1821 } while (false) 1822 1823 #define EXPECT_PRIMITIVE_FIELD(expect_eq, instance, type, field_name, sig, value1, value2) \ 1824 do { \ 1825 jfieldID fid = env_->GetFieldID(c, field_name, sig); \ 1826 EXPECT_NE(fid, nullptr); \ 1827 env_->Set ## type ## Field(instance, fid, value1); \ 1828 expect_eq(value1, env_->Get ## type ## Field(instance, fid)); \ 1829 env_->Set ## type ## Field(instance, fid, value2); \ 1830 expect_eq(value2, env_->Get ## type ## Field(instance, fid)); \ 1831 \ 1832 bool old_check_jni = vm_->SetCheckJniEnabled(false); \ 1833 CheckJniAbortCatcher jni_abort_catcher; \ 1834 env_->Get ## type ## Field(nullptr, fid); \ 1835 jni_abort_catcher.Check("obj == null"); \ 1836 env_->Set ## type ## Field(nullptr, fid, value1); \ 1837 jni_abort_catcher.Check("obj == null"); \ 1838 env_->Get ## type ## Field(instance, nullptr); \ 1839 jni_abort_catcher.Check("fid == null"); \ 1840 env_->Set ## type ## Field(instance, nullptr, value1); \ 1841 jni_abort_catcher.Check("fid == null"); \ 1842 EXPECT_FALSE(vm_->SetCheckJniEnabled(true)); \ 1843 env_->Get ## type ## Field(nullptr, fid); \ 1844 jni_abort_catcher.Check("field operation on NULL object:"); \ 1845 env_->Set ## type ## Field(nullptr, fid, value1); \ 1846 jni_abort_catcher.Check("field operation on NULL object:"); \ 1847 env_->Get ## type ## Field(instance, nullptr); \ 1848 jni_abort_catcher.Check("jfieldID was NULL"); \ 1849 env_->Set ## type ## Field(instance, nullptr, value1); \ 1850 jni_abort_catcher.Check("jfieldID was NULL"); \ 1851 EXPECT_TRUE(vm_->SetCheckJniEnabled(old_check_jni)); \ 1852 } while (false) 1853 1854 #define TEST_PRIMITIVE_FIELD_FOR_CLASS(cname) \ 1855 do { \ 1856 Thread::Current()->TransitionFromSuspendedToRunnable(); \ 1857 LoadDex("AllFields"); \ 1858 bool started = runtime_->Start(); \ 1859 ASSERT_TRUE(started); \ 1860 jclass c = env_->FindClass(cname); \ 1861 ASSERT_NE(c, nullptr); \ 1862 jobject o = env_->AllocObject(c); \ 1863 ASSERT_NE(o, nullptr); \ 1864 \ 1865 EXPECT_STATIC_PRIMITIVE_FIELD(EXPECT_EQ, Boolean, "sZ", "Z", JNI_TRUE, JNI_FALSE); \ 1866 EXPECT_STATIC_PRIMITIVE_FIELD(EXPECT_EQ, Byte, "sB", "B", 1, 2); \ 1867 EXPECT_STATIC_PRIMITIVE_FIELD(EXPECT_EQ, Char, "sC", "C", 'a', 'b'); \ 1868 EXPECT_STATIC_PRIMITIVE_FIELD(EXPECT_DOUBLE_EQ, Double, "sD", "D", 1.0, 2.0); \ 1869 EXPECT_STATIC_PRIMITIVE_FIELD(EXPECT_FLOAT_EQ, Float, "sF", "F", 1.0, 2.0); \ 1870 EXPECT_STATIC_PRIMITIVE_FIELD(EXPECT_EQ, Int, "sI", "I", 1, 2); \ 1871 EXPECT_STATIC_PRIMITIVE_FIELD(EXPECT_EQ, Long, "sJ", "J", 1, 2); \ 1872 EXPECT_STATIC_PRIMITIVE_FIELD(EXPECT_EQ, Short, "sS", "S", 1, 2); \ 1873 \ 1874 EXPECT_PRIMITIVE_FIELD(EXPECT_EQ, o, Boolean, "iZ", "Z", JNI_TRUE, JNI_FALSE); \ 1875 EXPECT_PRIMITIVE_FIELD(EXPECT_EQ, o, Byte, "iB", "B", 1, 2); \ 1876 EXPECT_PRIMITIVE_FIELD(EXPECT_EQ, o, Char, "iC", "C", 'a', 'b'); \ 1877 EXPECT_PRIMITIVE_FIELD(EXPECT_DOUBLE_EQ, o, Double, "iD", "D", 1.0, 2.0); \ 1878 EXPECT_PRIMITIVE_FIELD(EXPECT_FLOAT_EQ, o, Float, "iF", "F", 1.0, 2.0); \ 1879 EXPECT_PRIMITIVE_FIELD(EXPECT_EQ, o, Int, "iI", "I", 1, 2); \ 1880 EXPECT_PRIMITIVE_FIELD(EXPECT_EQ, o, Long, "iJ", "J", 1, 2); \ 1881 EXPECT_PRIMITIVE_FIELD(EXPECT_EQ, o, Short, "iS", "S", 1, 2); \ 1882 } while (false) 1883 1884 TEST_F(JniInternalTest, GetPrimitiveField_SetPrimitiveField) { 1885 TEST_PRIMITIVE_FIELD_FOR_CLASS("AllFields"); 1886 } 1887 1888 TEST_F(JniInternalTest, GetPrimitiveField_SetPrimitiveField_Subclass) { 1889 TEST_PRIMITIVE_FIELD_FOR_CLASS("AllFieldsSub"); 1890 } 1891 1892 #define EXPECT_UNRELATED_FIELD_FAILURE(type, field_name, sig, value1) \ 1893 do { \ 1894 jfieldID fid = env_->GetStaticFieldID(c, field_name, sig); \ 1895 EXPECT_NE(fid, nullptr); \ 1896 CheckJniAbortCatcher jni_abort_catcher; \ 1897 env_->Get ## type ## Field(uc, fid); \ 1898 jni_abort_catcher.Check("not valid for an object of class"); \ 1899 env_->Set ## type ## Field(uc, fid, value1); \ 1900 jni_abort_catcher.Check("not valid for an object of class"); \ 1901 } while (false) 1902 1903 TEST_F(JniInternalTest, GetField_SetField_unrelated) { 1904 Thread::Current()->TransitionFromSuspendedToRunnable(); 1905 LoadDex("AllFields"); 1906 bool started = runtime_->Start(); 1907 ASSERT_TRUE(started); 1908 jclass c = env_->FindClass("AllFields"); 1909 ASSERT_NE(c, nullptr); 1910 jclass uc = env_->FindClass("AllFieldsUnrelated"); 1911 ASSERT_NE(uc, nullptr); 1912 bool old_check_jni = vm_->SetCheckJniEnabled(true); 1913 EXPECT_UNRELATED_FIELD_FAILURE(Boolean, "sZ", "Z", JNI_TRUE); 1914 EXPECT_UNRELATED_FIELD_FAILURE(Byte, "sB", "B", 1); 1915 EXPECT_UNRELATED_FIELD_FAILURE(Char, "sC", "C", 'a'); 1916 EXPECT_UNRELATED_FIELD_FAILURE(Double, "sD", "D", 1.0); 1917 EXPECT_UNRELATED_FIELD_FAILURE(Float, "sF", "F", 1.0); 1918 EXPECT_UNRELATED_FIELD_FAILURE(Int, "sI", "I", 1); 1919 EXPECT_UNRELATED_FIELD_FAILURE(Long, "sJ", "J", 1); 1920 EXPECT_UNRELATED_FIELD_FAILURE(Short, "sS", "S", 1); 1921 EXPECT_UNRELATED_FIELD_FAILURE(Object, "sObject", "Ljava/lang/Object;", c); 1922 EXPECT_TRUE(vm_->SetCheckJniEnabled(old_check_jni)); 1923 } 1924 1925 #define TEST_OBJECT_FIELD_FOR_CLASS(cname) \ 1926 do { \ 1927 Thread::Current()->TransitionFromSuspendedToRunnable(); \ 1928 LoadDex("AllFields"); \ 1929 runtime_->Start(); \ 1930 \ 1931 jclass c = env_->FindClass(cname); \ 1932 ASSERT_NE(c, nullptr); \ 1933 jobject o = env_->AllocObject(c); \ 1934 ASSERT_NE(o, nullptr); \ 1935 \ 1936 jstring s1 = env_->NewStringUTF("hello"); \ 1937 ASSERT_NE(s1, nullptr); \ 1938 jstring s2 = env_->NewStringUTF("world"); \ 1939 ASSERT_NE(s2, nullptr); \ 1940 \ 1941 jfieldID s_fid = env_->GetStaticFieldID(c, "sObject", "Ljava/lang/Object;"); \ 1942 ASSERT_NE(s_fid, nullptr); \ 1943 jfieldID i_fid = env_->GetFieldID(c, "iObject", "Ljava/lang/Object;"); \ 1944 ASSERT_NE(i_fid, nullptr); \ 1945 \ 1946 env_->SetStaticObjectField(c, s_fid, s1); \ 1947 ASSERT_TRUE(env_->IsSameObject(s1, env_->GetStaticObjectField(c, s_fid))); \ 1948 env_->SetStaticObjectField(c, s_fid, s2); \ 1949 ASSERT_TRUE(env_->IsSameObject(s2, env_->GetStaticObjectField(c, s_fid))); \ 1950 \ 1951 env_->SetObjectField(o, i_fid, s1); \ 1952 ASSERT_TRUE(env_->IsSameObject(s1, env_->GetObjectField(o, i_fid))); \ 1953 env_->SetObjectField(o, i_fid, s2); \ 1954 ASSERT_TRUE(env_->IsSameObject(s2, env_->GetObjectField(o, i_fid))); \ 1955 } while (false) 1956 1957 TEST_F(JniInternalTest, GetObjectField_SetObjectField) { 1958 TEST_OBJECT_FIELD_FOR_CLASS("AllFields"); 1959 } 1960 1961 TEST_F(JniInternalTest, GetObjectField_SetObjectField_subclass) { 1962 TEST_OBJECT_FIELD_FOR_CLASS("AllFieldsSub"); 1963 } 1964 1965 TEST_F(JniInternalTest, NewLocalRef_nullptr) { 1966 EXPECT_EQ(env_->NewLocalRef(nullptr), nullptr); 1967 } 1968 1969 TEST_F(JniInternalTest, NewLocalRef) { 1970 jstring s = env_->NewStringUTF(""); 1971 ASSERT_NE(s, nullptr); 1972 jobject o = env_->NewLocalRef(s); 1973 EXPECT_NE(o, nullptr); 1974 EXPECT_NE(o, s); 1975 1976 EXPECT_EQ(JNILocalRefType, env_->GetObjectRefType(o)); 1977 } 1978 1979 TEST_F(JniInternalTest, DeleteLocalRef_nullptr) { 1980 env_->DeleteLocalRef(nullptr); 1981 } 1982 1983 TEST_F(JniInternalTest, DeleteLocalRef) { 1984 // This tests leads to warnings and errors in the log. 1985 ScopedLogSeverity sls(LogSeverity::FATAL); 1986 1987 jstring s = env_->NewStringUTF(""); 1988 ASSERT_NE(s, nullptr); 1989 env_->DeleteLocalRef(s); 1990 1991 // Currently, deleting an already-deleted reference is just a CheckJNI warning. 1992 { 1993 bool old_check_jni = vm_->SetCheckJniEnabled(false); 1994 { 1995 CheckJniAbortCatcher check_jni_abort_catcher; 1996 env_->DeleteLocalRef(s); 1997 } 1998 CheckJniAbortCatcher check_jni_abort_catcher; 1999 EXPECT_FALSE(vm_->SetCheckJniEnabled(true)); 2000 env_->DeleteLocalRef(s); 2001 std::string expected(StringPrintf("use of deleted local reference %p", s)); 2002 check_jni_abort_catcher.Check(expected.c_str()); 2003 EXPECT_TRUE(vm_->SetCheckJniEnabled(old_check_jni)); 2004 } 2005 2006 s = env_->NewStringUTF(""); 2007 ASSERT_NE(s, nullptr); 2008 jobject o = env_->NewLocalRef(s); 2009 ASSERT_NE(o, nullptr); 2010 2011 env_->DeleteLocalRef(s); 2012 env_->DeleteLocalRef(o); 2013 } 2014 2015 TEST_F(JniInternalTest, PushLocalFrame_10395422) { 2016 // The JNI specification is ambiguous about whether the given capacity is to be interpreted as a 2017 // maximum or as a minimum, but it seems like it's supposed to be a minimum, and that's how 2018 // Android historically treated it, and it's how the RI treats it. It's also the more useful 2019 // interpretation! 2020 ASSERT_EQ(JNI_OK, env_->PushLocalFrame(0)); 2021 env_->PopLocalFrame(nullptr); 2022 2023 // The following two tests will print errors to the log. 2024 ScopedLogSeverity sls(LogSeverity::FATAL); 2025 2026 // Negative capacities are not allowed. 2027 ASSERT_EQ(JNI_ERR, env_->PushLocalFrame(-1)); 2028 } 2029 2030 TEST_F(JniInternalTest, PushLocalFrame_PopLocalFrame) { 2031 // This tests leads to errors in the log. 2032 ScopedLogSeverity sls(LogSeverity::FATAL); 2033 2034 jobject original = env_->NewStringUTF(""); 2035 ASSERT_NE(original, nullptr); 2036 2037 jobject outer; 2038 jobject inner1, inner2; 2039 ScopedObjectAccess soa(env_); 2040 { 2041 ASSERT_EQ(JNI_OK, env_->PushLocalFrame(4)); 2042 outer = env_->NewLocalRef(original); 2043 2044 { 2045 ASSERT_EQ(JNI_OK, env_->PushLocalFrame(4)); 2046 inner1 = env_->NewLocalRef(outer); 2047 inner2 = env_->NewStringUTF("survivor"); 2048 EXPECT_NE(env_->PopLocalFrame(inner2), nullptr); 2049 } 2050 2051 EXPECT_EQ(JNILocalRefType, env_->GetObjectRefType(original)); 2052 EXPECT_EQ(JNILocalRefType, env_->GetObjectRefType(outer)); 2053 { 2054 CheckJniAbortCatcher check_jni_abort_catcher; 2055 EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(inner1)); 2056 check_jni_abort_catcher.Check("use of deleted local reference"); 2057 } 2058 2059 // Our local reference for the survivor is invalid because the survivor 2060 // gets a new local reference... 2061 { 2062 CheckJniAbortCatcher check_jni_abort_catcher; 2063 EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(inner2)); 2064 check_jni_abort_catcher.Check("use of deleted local reference"); 2065 } 2066 2067 EXPECT_EQ(env_->PopLocalFrame(nullptr), nullptr); 2068 } 2069 EXPECT_EQ(JNILocalRefType, env_->GetObjectRefType(original)); 2070 CheckJniAbortCatcher check_jni_abort_catcher; 2071 EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(outer)); 2072 check_jni_abort_catcher.Check("use of deleted local reference"); 2073 EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(inner1)); 2074 check_jni_abort_catcher.Check("use of deleted local reference"); 2075 EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(inner2)); 2076 check_jni_abort_catcher.Check("use of deleted local reference"); 2077 } 2078 2079 TEST_F(JniInternalTest, PushLocalFrame_LimitAndOverflow) { 2080 // Try a very large value that should fail. 2081 ASSERT_NE(JNI_OK, env_->PushLocalFrame(std::numeric_limits<jint>::max())); 2082 ASSERT_TRUE(env_->ExceptionCheck()); 2083 env_->ExceptionClear(); 2084 2085 // On 32-bit, also check for some overflow conditions. 2086 #ifndef __LP64__ 2087 ASSERT_EQ(JNI_OK, env_->PushLocalFrame(10)); 2088 ASSERT_NE(JNI_OK, env_->PushLocalFrame(std::numeric_limits<jint>::max() - 10)); 2089 ASSERT_TRUE(env_->ExceptionCheck()); 2090 env_->ExceptionClear(); 2091 EXPECT_EQ(env_->PopLocalFrame(nullptr), nullptr); 2092 #endif 2093 } 2094 2095 TEST_F(JniInternalTest, PushLocalFrame_b62223672) { 2096 // The 512 entry limit has been lifted, try a larger value. 2097 ASSERT_EQ(JNI_OK, env_->PushLocalFrame(1024)); 2098 EXPECT_EQ(env_->PopLocalFrame(nullptr), nullptr); 2099 } 2100 2101 TEST_F(JniInternalTest, NewGlobalRef_nullptr) { 2102 EXPECT_EQ(env_->NewGlobalRef(nullptr), nullptr); 2103 } 2104 2105 TEST_F(JniInternalTest, NewGlobalRef) { 2106 jstring s = env_->NewStringUTF(""); 2107 ASSERT_NE(s, nullptr); 2108 jobject o = env_->NewGlobalRef(s); 2109 EXPECT_NE(o, nullptr); 2110 EXPECT_NE(o, s); 2111 2112 EXPECT_EQ(env_->GetObjectRefType(o), JNIGlobalRefType); 2113 } 2114 2115 TEST_F(JniInternalTest, DeleteGlobalRef_nullptr) { 2116 env_->DeleteGlobalRef(nullptr); 2117 } 2118 2119 TEST_F(JniInternalTest, DeleteGlobalRef) { 2120 // This tests leads to warnings and errors in the log. 2121 ScopedLogSeverity sls(LogSeverity::FATAL); 2122 2123 jstring s = env_->NewStringUTF(""); 2124 ASSERT_NE(s, nullptr); 2125 2126 jobject o = env_->NewGlobalRef(s); 2127 ASSERT_NE(o, nullptr); 2128 env_->DeleteGlobalRef(o); 2129 2130 // Currently, deleting an already-deleted reference is just a CheckJNI warning. 2131 { 2132 bool old_check_jni = vm_->SetCheckJniEnabled(false); 2133 { 2134 CheckJniAbortCatcher check_jni_abort_catcher; 2135 env_->DeleteGlobalRef(o); 2136 } 2137 CheckJniAbortCatcher check_jni_abort_catcher; 2138 EXPECT_FALSE(vm_->SetCheckJniEnabled(true)); 2139 env_->DeleteGlobalRef(o); 2140 std::string expected(StringPrintf("use of deleted global reference %p", o)); 2141 check_jni_abort_catcher.Check(expected.c_str()); 2142 EXPECT_TRUE(vm_->SetCheckJniEnabled(old_check_jni)); 2143 } 2144 2145 jobject o1 = env_->NewGlobalRef(s); 2146 ASSERT_NE(o1, nullptr); 2147 jobject o2 = env_->NewGlobalRef(s); 2148 ASSERT_NE(o2, nullptr); 2149 2150 env_->DeleteGlobalRef(o1); 2151 env_->DeleteGlobalRef(o2); 2152 } 2153 2154 TEST_F(JniInternalTest, NewWeakGlobalRef_nullptr) { 2155 EXPECT_EQ(env_->NewWeakGlobalRef(nullptr), nullptr); 2156 } 2157 2158 TEST_F(JniInternalTest, NewWeakGlobalRef) { 2159 jstring s = env_->NewStringUTF(""); 2160 ASSERT_NE(s, nullptr); 2161 jobject o = env_->NewWeakGlobalRef(s); 2162 EXPECT_NE(o, nullptr); 2163 EXPECT_NE(o, s); 2164 2165 EXPECT_EQ(env_->GetObjectRefType(o), JNIWeakGlobalRefType); 2166 } 2167 2168 TEST_F(JniInternalTest, DeleteWeakGlobalRef_nullptr) { 2169 env_->DeleteWeakGlobalRef(nullptr); 2170 } 2171 2172 TEST_F(JniInternalTest, DeleteWeakGlobalRef) { 2173 // This tests leads to warnings and errors in the log. 2174 ScopedLogSeverity sls(LogSeverity::FATAL); 2175 2176 jstring s = env_->NewStringUTF(""); 2177 ASSERT_NE(s, nullptr); 2178 2179 jobject o = env_->NewWeakGlobalRef(s); 2180 ASSERT_NE(o, nullptr); 2181 env_->DeleteWeakGlobalRef(o); 2182 2183 // Currently, deleting an already-deleted reference is just a CheckJNI warning. 2184 { 2185 bool old_check_jni = vm_->SetCheckJniEnabled(false); 2186 { 2187 CheckJniAbortCatcher check_jni_abort_catcher; 2188 env_->DeleteWeakGlobalRef(o); 2189 } 2190 CheckJniAbortCatcher check_jni_abort_catcher; 2191 EXPECT_FALSE(vm_->SetCheckJniEnabled(true)); 2192 env_->DeleteWeakGlobalRef(o); 2193 std::string expected(StringPrintf("use of deleted weak global reference %p", o)); 2194 check_jni_abort_catcher.Check(expected.c_str()); 2195 EXPECT_TRUE(vm_->SetCheckJniEnabled(old_check_jni)); 2196 } 2197 2198 jobject o1 = env_->NewWeakGlobalRef(s); 2199 ASSERT_NE(o1, nullptr); 2200 jobject o2 = env_->NewWeakGlobalRef(s); 2201 ASSERT_NE(o2, nullptr); 2202 2203 env_->DeleteWeakGlobalRef(o1); 2204 env_->DeleteWeakGlobalRef(o2); 2205 } 2206 2207 TEST_F(JniInternalTest, ExceptionDescribe) { 2208 // This checks how ExceptionDescribe handles call without exception. 2209 env_->ExceptionClear(); 2210 env_->ExceptionDescribe(); 2211 } 2212 2213 TEST_F(JniInternalTest, Throw) { 2214 jclass exception_class = env_->FindClass("java/lang/RuntimeException"); 2215 ASSERT_TRUE(exception_class != nullptr); 2216 jthrowable exception = reinterpret_cast<jthrowable>(env_->AllocObject(exception_class)); 2217 ASSERT_TRUE(exception != nullptr); 2218 2219 EXPECT_EQ(JNI_OK, env_->Throw(exception)); 2220 EXPECT_TRUE(env_->ExceptionCheck()); 2221 jthrowable thrown_exception = env_->ExceptionOccurred(); 2222 env_->ExceptionClear(); 2223 EXPECT_TRUE(env_->IsSameObject(exception, thrown_exception)); 2224 2225 // Bad argument. 2226 bool old_check_jni = vm_->SetCheckJniEnabled(false); 2227 EXPECT_EQ(JNI_ERR, env_->Throw(nullptr)); 2228 EXPECT_FALSE(vm_->SetCheckJniEnabled(true)); 2229 CheckJniAbortCatcher check_jni_abort_catcher; 2230 EXPECT_EQ(JNI_ERR, env_->Throw(nullptr)); 2231 check_jni_abort_catcher.Check("Throw received NULL jthrowable"); 2232 EXPECT_TRUE(vm_->SetCheckJniEnabled(old_check_jni)); 2233 } 2234 2235 TEST_F(JniInternalTest, ThrowNew) { 2236 jclass exception_class = env_->FindClass("java/lang/RuntimeException"); 2237 ASSERT_TRUE(exception_class != nullptr); 2238 2239 jthrowable thrown_exception; 2240 2241 EXPECT_EQ(JNI_OK, env_->ThrowNew(exception_class, "hello world")); 2242 EXPECT_TRUE(env_->ExceptionCheck()); 2243 thrown_exception = env_->ExceptionOccurred(); 2244 env_->ExceptionClear(); 2245 EXPECT_TRUE(env_->IsInstanceOf(thrown_exception, exception_class)); 2246 2247 EXPECT_EQ(JNI_OK, env_->ThrowNew(exception_class, nullptr)); 2248 EXPECT_TRUE(env_->ExceptionCheck()); 2249 thrown_exception = env_->ExceptionOccurred(); 2250 env_->ExceptionClear(); 2251 EXPECT_TRUE(env_->IsInstanceOf(thrown_exception, exception_class)); 2252 2253 // Bad argument. 2254 bool old_check_jni = vm_->SetCheckJniEnabled(false); 2255 CheckJniAbortCatcher check_jni_abort_catcher; 2256 EXPECT_EQ(JNI_ERR, env_->ThrowNew(nullptr, nullptr)); 2257 check_jni_abort_catcher.Check("c == null"); 2258 EXPECT_FALSE(vm_->SetCheckJniEnabled(true)); 2259 EXPECT_EQ(JNI_ERR, env_->ThrowNew(nullptr, nullptr)); 2260 check_jni_abort_catcher.Check("ThrowNew received NULL jclass"); 2261 EXPECT_TRUE(vm_->SetCheckJniEnabled(old_check_jni)); 2262 } 2263 2264 TEST_F(JniInternalTest, NewDirectBuffer_GetDirectBufferAddress_GetDirectBufferCapacity) { 2265 // Start runtime. 2266 Thread* self = Thread::Current(); 2267 self->TransitionFromSuspendedToRunnable(); 2268 MakeExecutable(nullptr, "java.lang.Class"); 2269 MakeExecutable(nullptr, "java.lang.Object"); 2270 MakeExecutable(nullptr, "java.nio.DirectByteBuffer"); 2271 MakeExecutable(nullptr, "java.nio.Bits"); 2272 MakeExecutable(nullptr, "java.nio.MappedByteBuffer"); 2273 MakeExecutable(nullptr, "java.nio.ByteBuffer"); 2274 MakeExecutable(nullptr, "java.nio.Buffer"); 2275 // TODO: we only load a dex file here as starting the runtime relies upon it. 2276 const char* class_name = "StaticLeafMethods"; 2277 LoadDex(class_name); 2278 bool started = runtime_->Start(); 2279 ASSERT_TRUE(started); 2280 2281 jclass buffer_class = env_->FindClass("java/nio/Buffer"); 2282 ASSERT_NE(buffer_class, nullptr); 2283 2284 char bytes[1024]; 2285 jobject buffer = env_->NewDirectByteBuffer(bytes, sizeof(bytes)); 2286 ASSERT_NE(buffer, nullptr); 2287 ASSERT_TRUE(env_->IsInstanceOf(buffer, buffer_class)); 2288 ASSERT_EQ(env_->GetDirectBufferAddress(buffer), bytes); 2289 ASSERT_EQ(env_->GetDirectBufferCapacity(buffer), static_cast<jlong>(sizeof(bytes))); 2290 2291 { 2292 CheckJniAbortCatcher check_jni_abort_catcher; 2293 env_->NewDirectByteBuffer(bytes, static_cast<jlong>(INT_MAX) + 1); 2294 check_jni_abort_catcher.Check("in call to NewDirectByteBuffer"); 2295 } 2296 } 2297 2298 TEST_F(JniInternalTest, MonitorEnterExit) { 2299 // This will print some error messages. Suppress. 2300 ScopedLogSeverity sls(LogSeverity::FATAL); 2301 2302 // Create an object to torture. 2303 jclass object_class = env_->FindClass("java/lang/Object"); 2304 ASSERT_NE(object_class, nullptr); 2305 jobject object = env_->AllocObject(object_class); 2306 ASSERT_NE(object, nullptr); 2307 2308 // Expected class of exceptions 2309 jclass imse_class = env_->FindClass("java/lang/IllegalMonitorStateException"); 2310 ASSERT_NE(imse_class, nullptr); 2311 2312 jthrowable thrown_exception; 2313 2314 // Unlock of unowned monitor 2315 env_->MonitorExit(object); 2316 EXPECT_TRUE(env_->ExceptionCheck()); 2317 thrown_exception = env_->ExceptionOccurred(); 2318 env_->ExceptionClear(); 2319 EXPECT_TRUE(env_->IsInstanceOf(thrown_exception, imse_class)); 2320 2321 // Lock of unowned monitor 2322 env_->MonitorEnter(object); 2323 EXPECT_FALSE(env_->ExceptionCheck()); 2324 // Regular unlock 2325 env_->MonitorExit(object); 2326 EXPECT_FALSE(env_->ExceptionCheck()); 2327 2328 // Recursively lock a lot 2329 size_t max_recursive_lock = 1024; 2330 for (size_t i = 0; i < max_recursive_lock; i++) { 2331 env_->MonitorEnter(object); 2332 EXPECT_FALSE(env_->ExceptionCheck()); 2333 } 2334 // Recursively unlock a lot 2335 for (size_t i = 0; i < max_recursive_lock; i++) { 2336 env_->MonitorExit(object); 2337 EXPECT_FALSE(env_->ExceptionCheck()); 2338 } 2339 2340 // Unlock of unowned monitor 2341 env_->MonitorExit(object); 2342 EXPECT_TRUE(env_->ExceptionCheck()); 2343 thrown_exception = env_->ExceptionOccurred(); 2344 env_->ExceptionClear(); 2345 EXPECT_TRUE(env_->IsInstanceOf(thrown_exception, imse_class)); 2346 2347 // It's an error to call MonitorEnter or MonitorExit on null. 2348 { 2349 CheckJniAbortCatcher check_jni_abort_catcher; 2350 env_->MonitorEnter(nullptr); 2351 check_jni_abort_catcher.Check("in call to MonitorEnter"); 2352 env_->MonitorExit(nullptr); 2353 check_jni_abort_catcher.Check("in call to MonitorExit"); 2354 } 2355 } 2356 2357 void Java_MyClassNatives_foo_exit(JNIEnv* env, jobject thisObj) { 2358 // Release the monitor on self. This should trigger an abort. 2359 env->MonitorExit(thisObj); 2360 } 2361 2362 TEST_F(JniInternalTest, MonitorExitLockedInDifferentCall) { 2363 SetUpForTest(false, "foo", "()V", reinterpret_cast<void*>(&Java_MyClassNatives_foo_exit)); 2364 ASSERT_NE(jobj_, nullptr); 2365 2366 env_->MonitorEnter(jobj_); 2367 EXPECT_FALSE(env_->ExceptionCheck()); 2368 2369 CheckJniAbortCatcher check_jni_abort_catcher; 2370 env_->CallNonvirtualVoidMethod(jobj_, jklass_, jmethod_); 2371 check_jni_abort_catcher.Check("Unlocking monitor that wasn't locked here"); 2372 } 2373 2374 void Java_MyClassNatives_foo_enter_no_exit(JNIEnv* env, jobject thisObj) { 2375 // Acquire but don't release the monitor on self. This should trigger an abort on return. 2376 env->MonitorEnter(thisObj); 2377 } 2378 2379 TEST_F(JniInternalTest, MonitorExitNotAllUnlocked) { 2380 SetUpForTest(false, 2381 "foo", 2382 "()V", 2383 reinterpret_cast<void*>(&Java_MyClassNatives_foo_enter_no_exit)); 2384 ASSERT_NE(jobj_, nullptr); 2385 2386 CheckJniAbortCatcher check_jni_abort_catcher; 2387 env_->CallNonvirtualVoidMethod(jobj_, jklass_, jmethod_); 2388 check_jni_abort_catcher.Check("Still holding a locked object on JNI end"); 2389 } 2390 2391 static bool IsLocked(JNIEnv* env, jobject jobj) { 2392 ScopedObjectAccess soa(env); 2393 LockWord lock_word = soa.Decode<mirror::Object>(jobj)->GetLockWord(true); 2394 switch (lock_word.GetState()) { 2395 case LockWord::kHashCode: 2396 case LockWord::kUnlocked: 2397 return false; 2398 case LockWord::kThinLocked: 2399 return true; 2400 case LockWord::kFatLocked: 2401 return lock_word.FatLockMonitor()->IsLocked(); 2402 default: { 2403 LOG(FATAL) << "Invalid monitor state " << lock_word.GetState(); 2404 UNREACHABLE(); 2405 } 2406 } 2407 } 2408 2409 TEST_F(JniInternalTest, DetachThreadUnlockJNIMonitors) { 2410 // We need to lock an object, detach, reattach, and check the locks. 2411 // 2412 // As re-attaching will create a different thread, we need to use a global 2413 // ref to keep the object around. 2414 2415 // Create an object to torture. 2416 jobject global_ref; 2417 { 2418 jclass object_class = env_->FindClass("java/lang/Object"); 2419 ASSERT_NE(object_class, nullptr); 2420 jobject object = env_->AllocObject(object_class); 2421 ASSERT_NE(object, nullptr); 2422 global_ref = env_->NewGlobalRef(object); 2423 } 2424 2425 // Lock it. 2426 env_->MonitorEnter(global_ref); 2427 ASSERT_TRUE(IsLocked(env_, global_ref)); 2428 2429 // Detach and re-attach. 2430 jint detach_result = vm_->DetachCurrentThread(); 2431 ASSERT_EQ(detach_result, JNI_OK); 2432 jint attach_result = vm_->AttachCurrentThread(&env_, nullptr); 2433 ASSERT_EQ(attach_result, JNI_OK); 2434 2435 // Look at the global ref, check whether it's still locked. 2436 ASSERT_FALSE(IsLocked(env_, global_ref)); 2437 2438 // Delete the global ref. 2439 env_->DeleteGlobalRef(global_ref); 2440 } 2441 2442 // Test the offset computation of IndirectReferenceTable offsets. b/26071368. 2443 TEST_F(JniInternalTest, IndirectReferenceTableOffsets) { 2444 // The segment_state_ field is private, and we want to avoid friend declaration. So we'll check 2445 // by modifying memory. 2446 // The parameters don't really matter here. 2447 std::string error_msg; 2448 IndirectReferenceTable irt(5, 2449 IndirectRefKind::kGlobal, 2450 IndirectReferenceTable::ResizableCapacity::kNo, 2451 &error_msg); 2452 ASSERT_TRUE(irt.IsValid()) << error_msg; 2453 IRTSegmentState old_state = irt.GetSegmentState(); 2454 2455 // Write some new state directly. We invert parts of old_state to ensure a new value. 2456 IRTSegmentState new_state; 2457 new_state.top_index = old_state.top_index ^ 0x07705005; 2458 ASSERT_NE(old_state.top_index, new_state.top_index); 2459 2460 uint8_t* base = reinterpret_cast<uint8_t*>(&irt); 2461 int32_t segment_state_offset = 2462 IndirectReferenceTable::SegmentStateOffset(sizeof(void*)).Int32Value(); 2463 *reinterpret_cast<IRTSegmentState*>(base + segment_state_offset) = new_state; 2464 2465 // Read and compare. 2466 EXPECT_EQ(new_state.top_index, irt.GetSegmentState().top_index); 2467 } 2468 2469 // Test the offset computation of JNIEnvExt offsets. b/26071368. 2470 TEST_F(JniInternalTest, JNIEnvExtOffsets) { 2471 EXPECT_EQ(OFFSETOF_MEMBER(JNIEnvExt, local_ref_cookie_), 2472 JNIEnvExt::LocalRefCookieOffset(sizeof(void*)).Uint32Value()); 2473 2474 EXPECT_EQ(OFFSETOF_MEMBER(JNIEnvExt, self_), JNIEnvExt::SelfOffset(sizeof(void*)).Uint32Value()); 2475 2476 // segment_state_ is private in the IndirectReferenceTable. So this test isn't as good as we'd 2477 // hope it to be. 2478 uint32_t segment_state_now = 2479 OFFSETOF_MEMBER(JNIEnvExt, locals_) + 2480 IndirectReferenceTable::SegmentStateOffset(sizeof(void*)).Uint32Value(); 2481 uint32_t segment_state_computed = JNIEnvExt::SegmentStateOffset(sizeof(void*)).Uint32Value(); 2482 EXPECT_EQ(segment_state_now, segment_state_computed); 2483 } 2484 2485 static size_t gGlobalRefCount = 0; 2486 static const JNINativeInterface* gOriginalEnv = nullptr; 2487 2488 static jobject CountNewGlobalRef(JNIEnv* env, jobject o) { 2489 ++gGlobalRefCount; 2490 return gOriginalEnv->NewGlobalRef(env, o); 2491 } 2492 2493 // Test the table override. 2494 TEST_F(JniInternalTest, JNIEnvExtTableOverride) { 2495 JNINativeInterface env_override; 2496 memcpy(&env_override, env_->functions, sizeof(JNINativeInterface)); 2497 2498 gOriginalEnv = env_->functions; 2499 env_override.NewGlobalRef = CountNewGlobalRef; 2500 gGlobalRefCount = 0; 2501 2502 jclass local = env_->FindClass("java/lang/Object"); 2503 ASSERT_TRUE(local != nullptr); 2504 2505 // Set the table, add a global ref, see whether the counter increases. 2506 JNIEnvExt::SetTableOverride(&env_override); 2507 2508 jobject global = env_->NewGlobalRef(local); 2509 EXPECT_EQ(1u, gGlobalRefCount); 2510 env_->DeleteGlobalRef(global); 2511 2512 // Reset 2513 JNIEnvExt::SetTableOverride(nullptr); 2514 2515 jobject global2 = env_->NewGlobalRef(local); 2516 EXPECT_EQ(1u, gGlobalRefCount); 2517 env_->DeleteGlobalRef(global2); 2518 } 2519 2520 TEST_F(JniInternalTest, NonAttachedThread) { 2521 // This tests leads to warnings and errors in the log. 2522 ScopedLogSeverity sls(LogSeverity::FATAL); 2523 CheckJniAbortCatcher check_jni_abort_catcher; 2524 2525 auto callee = [](void* env_ptr) -> void* { 2526 JNIEnv* env = reinterpret_cast<JNIEnv*>(env_ptr); 2527 env->NewStringUTF("test"); 2528 return nullptr; 2529 }; 2530 2531 bool old_check_jni = vm_->SetCheckJniEnabled(false); 2532 vm_->SetCheckJniEnabled(true); 2533 { 2534 pthread_t pthread; 2535 int pthread_create_result = pthread_create(&pthread, 2536 /* pthread_attr */ nullptr, 2537 callee, 2538 reinterpret_cast<void*>(env_)); 2539 CHECK_EQ(pthread_create_result, 0); 2540 int pthread_join_result = pthread_join(pthread, /* thread_return */ nullptr); 2541 CHECK_EQ(pthread_join_result, 0); 2542 } 2543 vm_->SetCheckJniEnabled(old_check_jni); 2544 2545 check_jni_abort_catcher.Check("is making JNI calls without being attached"); 2546 } 2547 2548 } // namespace art 2549