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/ScopedLocalRef.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, GetStaticMethodID) { 839 jclass jlobject = env_->FindClass("java/lang/Object"); 840 jclass jlnsme = env_->FindClass("java/lang/NoSuchMethodError"); 841 842 // Sanity check that no exceptions are pending 843 ASSERT_FALSE(env_->ExceptionCheck()); 844 845 // Check that java.lang.Object.foo() doesn't exist and NoSuchMethodError is 846 // a pending exception 847 jmethodID method = env_->GetStaticMethodID(jlobject, "foo", "()V"); 848 EXPECT_EQ(nullptr, method); 849 ExpectException(jlnsme); 850 851 // Check that GetStaticMethodID for java.lang.Object.equals(Object) fails as 852 // the method is not static 853 method = env_->GetStaticMethodID(jlobject, "equals", "(Ljava/lang/Object;)Z"); 854 EXPECT_EQ(nullptr, method); 855 ExpectException(jlnsme); 856 857 // Check that java.lang.String.valueOf(int) does exist 858 jclass jlstring = env_->FindClass("java/lang/String"); 859 method = env_->GetStaticMethodID(jlstring, "valueOf", "(I)Ljava/lang/String;"); 860 EXPECT_NE(nullptr, method); 861 EXPECT_FALSE(env_->ExceptionCheck()); 862 863 // Bad arguments. 864 GetStaticMethodIdBadArgumentTest(false); 865 GetStaticMethodIdBadArgumentTest(true); 866 } 867 868 static size_t GetLocalsCapacity(JNIEnv* env) { 869 ScopedObjectAccess soa(Thread::Current()); 870 return reinterpret_cast<JNIEnvExt*>(env)->locals.Capacity(); 871 } 872 873 TEST_F(JniInternalTest, FromReflectedField_ToReflectedField) { 874 jclass jlrField = env_->FindClass("java/lang/reflect/Field"); 875 jclass c = env_->FindClass("java/lang/String"); 876 ASSERT_NE(c, nullptr); 877 jfieldID fid = env_->GetFieldID(c, "count", "I"); 878 ASSERT_NE(fid, nullptr); 879 // Turn the fid into a java.lang.reflect.Field... 880 jobject field = env_->ToReflectedField(c, fid, JNI_FALSE); 881 size_t capacity_before = GetLocalsCapacity(env_); 882 for (size_t i = 0; i <= 10; ++i) { 883 // Regression test for b/18396311, ToReflectedField leaking local refs causing a local 884 // reference table overflows with 512 references to ArtField 885 env_->DeleteLocalRef(env_->ToReflectedField(c, fid, JNI_FALSE)); 886 } 887 size_t capacity_after = GetLocalsCapacity(env_); 888 ASSERT_EQ(capacity_before, capacity_after); 889 890 ASSERT_NE(c, nullptr); 891 ASSERT_TRUE(env_->IsInstanceOf(field, jlrField)); 892 // ...and back again. 893 jfieldID fid2 = env_->FromReflectedField(field); 894 ASSERT_NE(fid2, nullptr); 895 // Make sure we can actually use it. 896 jstring s = env_->NewStringUTF("poop"); 897 if (mirror::kUseStringCompression) { 898 ASSERT_EQ(mirror::String::GetFlaggedCount(4, /* compressible */ true), 899 env_->GetIntField(s, fid2)); 900 // Create incompressible string 901 jstring s_16 = env_->NewStringUTF("\u0444\u0444"); 902 ASSERT_EQ(mirror::String::GetFlaggedCount(2, /* compressible */ false), 903 env_->GetIntField(s_16, fid2)); 904 } else { 905 ASSERT_EQ(4, env_->GetIntField(s, fid2)); 906 } 907 // Bad arguments. 908 GetFromReflectedField_ToReflectedFieldBadArgumentTest(false); 909 GetFromReflectedField_ToReflectedFieldBadArgumentTest(true); 910 } 911 912 TEST_F(JniInternalTest, FromReflectedMethod_ToReflectedMethod) { 913 jclass jlrMethod = env_->FindClass("java/lang/reflect/Method"); 914 ASSERT_NE(jlrMethod, nullptr); 915 jclass jlrConstructor = env_->FindClass("java/lang/reflect/Constructor"); 916 ASSERT_NE(jlrConstructor, nullptr); 917 jclass c = env_->FindClass("java/lang/String"); 918 ASSERT_NE(c, nullptr); 919 920 jmethodID mid = env_->GetMethodID(c, "<init>", "()V"); 921 ASSERT_NE(mid, nullptr); 922 // Turn the mid into a java.lang.reflect.Constructor... 923 jobject method = env_->ToReflectedMethod(c, mid, JNI_FALSE); 924 size_t capacity_before = GetLocalsCapacity(env_); 925 for (size_t i = 0; i <= 10; ++i) { 926 // Regression test for b/18396311, ToReflectedMethod leaking local refs causing a local 927 // reference table overflows with 512 references to ArtMethod 928 env_->DeleteLocalRef(env_->ToReflectedMethod(c, mid, JNI_FALSE)); 929 } 930 size_t capacity_after = GetLocalsCapacity(env_); 931 ASSERT_EQ(capacity_before, capacity_after); 932 ASSERT_NE(method, nullptr); 933 ASSERT_TRUE(env_->IsInstanceOf(method, jlrConstructor)); 934 // ...and back again. 935 jmethodID mid2 = env_->FromReflectedMethod(method); 936 ASSERT_NE(mid2, nullptr); 937 // Make sure we can actually use it. 938 jstring s = reinterpret_cast<jstring>(env_->AllocObject(c)); 939 ASSERT_NE(s, nullptr); 940 env_->CallVoidMethod(s, mid2); 941 ASSERT_EQ(JNI_FALSE, env_->ExceptionCheck()); 942 env_->ExceptionClear(); 943 944 mid = env_->GetMethodID(c, "length", "()I"); 945 ASSERT_NE(mid, nullptr); 946 // Turn the mid into a java.lang.reflect.Method... 947 method = env_->ToReflectedMethod(c, mid, JNI_FALSE); 948 ASSERT_NE(method, nullptr); 949 ASSERT_TRUE(env_->IsInstanceOf(method, jlrMethod)); 950 // ...and back again. 951 mid2 = env_->FromReflectedMethod(method); 952 ASSERT_NE(mid2, nullptr); 953 // Make sure we can actually use it. 954 s = env_->NewStringUTF("poop"); 955 ASSERT_NE(s, nullptr); 956 ASSERT_EQ(4, env_->CallIntMethod(s, mid2)); 957 958 // Bad arguments. 959 GetFromReflectedMethod_ToReflectedMethodBadArgumentTest(false); 960 GetFromReflectedMethod_ToReflectedMethodBadArgumentTest(true); 961 } 962 963 static void BogusMethod() { 964 // You can't pass null function pointers to RegisterNatives. 965 } 966 967 TEST_F(JniInternalTest, RegisterAndUnregisterNatives) { 968 jclass jlobject = env_->FindClass("java/lang/Object"); 969 jclass jlnsme = env_->FindClass("java/lang/NoSuchMethodError"); 970 void* native_function = reinterpret_cast<void*>(BogusMethod); 971 972 // Sanity check that no exceptions are pending. 973 ASSERT_FALSE(env_->ExceptionCheck()); 974 975 // The following can print errors to the log we'd like to ignore. 976 { 977 ScopedLogSeverity sls(LogSeverity::FATAL); 978 // Check that registering method without name causes a NoSuchMethodError. 979 { 980 JNINativeMethod methods[] = { { nullptr, "()V", native_function } }; 981 EXPECT_EQ(env_->RegisterNatives(jlobject, methods, 1), JNI_ERR); 982 } 983 ExpectException(jlnsme); 984 985 // Check that registering method without signature causes a NoSuchMethodError. 986 { 987 JNINativeMethod methods[] = { { "notify", nullptr, native_function } }; 988 EXPECT_EQ(env_->RegisterNatives(jlobject, methods, 1), JNI_ERR); 989 } 990 ExpectException(jlnsme); 991 992 // Check that registering method without function causes a NoSuchMethodError. 993 { 994 JNINativeMethod methods[] = { { "notify", "()V", nullptr } }; 995 EXPECT_EQ(env_->RegisterNatives(jlobject, methods, 1), JNI_ERR); 996 } 997 ExpectException(jlnsme); 998 999 // Check that registering to a non-existent java.lang.Object.foo() causes a NoSuchMethodError. 1000 { 1001 JNINativeMethod methods[] = { { "foo", "()V", native_function } }; 1002 EXPECT_EQ(env_->RegisterNatives(jlobject, methods, 1), JNI_ERR); 1003 } 1004 ExpectException(jlnsme); 1005 1006 // Check that registering non-native methods causes a NoSuchMethodError. 1007 { 1008 JNINativeMethod methods[] = { { "equals", "(Ljava/lang/Object;)Z", native_function } }; 1009 EXPECT_EQ(env_->RegisterNatives(jlobject, methods, 1), JNI_ERR); 1010 } 1011 ExpectException(jlnsme); 1012 } 1013 1014 // Check that registering native methods is successful. 1015 { 1016 JNINativeMethod methods[] = { { "notify", "()V", native_function } }; 1017 EXPECT_EQ(env_->RegisterNatives(jlobject, methods, 1), JNI_OK); 1018 } 1019 EXPECT_FALSE(env_->ExceptionCheck()); 1020 EXPECT_EQ(env_->UnregisterNatives(jlobject), JNI_OK); 1021 1022 // Check that registering no methods isn't a failure. 1023 { 1024 JNINativeMethod methods[] = { }; 1025 EXPECT_EQ(env_->RegisterNatives(jlobject, methods, 0), JNI_OK); 1026 } 1027 EXPECT_FALSE(env_->ExceptionCheck()); 1028 EXPECT_EQ(env_->UnregisterNatives(jlobject), JNI_OK); 1029 1030 // Check that registering a -ve number of methods is a failure. 1031 CheckJniAbortCatcher check_jni_abort_catcher; 1032 for (int i = -10; i < 0; ++i) { 1033 JNINativeMethod methods[] = { }; 1034 EXPECT_EQ(env_->RegisterNatives(jlobject, methods, i), JNI_ERR); 1035 check_jni_abort_catcher.Check("negative method count: "); 1036 } 1037 EXPECT_FALSE(env_->ExceptionCheck()); 1038 1039 // Unregistering a class with no natives is a warning. 1040 EXPECT_EQ(env_->UnregisterNatives(jlnsme), JNI_OK); 1041 1042 RegisterAndUnregisterNativesBadArguments(false, &check_jni_abort_catcher); 1043 RegisterAndUnregisterNativesBadArguments(true, &check_jni_abort_catcher); 1044 } 1045 1046 #define EXPECT_PRIMITIVE_ARRAY(new_fn, \ 1047 get_region_fn, \ 1048 set_region_fn, \ 1049 get_elements_fn, \ 1050 release_elements_fn, \ 1051 scalar_type, \ 1052 expected_class_descriptor) \ 1053 jsize size = 4; \ 1054 \ 1055 { \ 1056 CheckJniAbortCatcher jni_abort_catcher; \ 1057 down_cast<JNIEnvExt*>(env_)->SetCheckJniEnabled(false); \ 1058 /* Allocate an negative sized array and check it has the right failure type. */ \ 1059 EXPECT_EQ(env_->new_fn(-1), nullptr); \ 1060 jni_abort_catcher.Check("negative array length: -1"); \ 1061 EXPECT_EQ(env_->new_fn(std::numeric_limits<jint>::min()), nullptr); \ 1062 jni_abort_catcher.Check("negative array length: -2147483648"); \ 1063 /* Pass the array as null. */ \ 1064 EXPECT_EQ(0, env_->GetArrayLength(nullptr)); \ 1065 jni_abort_catcher.Check("java_array == null"); \ 1066 env_->get_region_fn(nullptr, 0, 0, nullptr); \ 1067 jni_abort_catcher.Check("java_array == null"); \ 1068 env_->set_region_fn(nullptr, 0, 0, nullptr); \ 1069 jni_abort_catcher.Check("java_array == null"); \ 1070 env_->get_elements_fn(nullptr, nullptr); \ 1071 jni_abort_catcher.Check("java_array == null"); \ 1072 env_->release_elements_fn(nullptr, nullptr, 0); \ 1073 jni_abort_catcher.Check("java_array == null"); \ 1074 /* Pass the elements for region as null. */ \ 1075 scalar_type ## Array a = env_->new_fn(size); \ 1076 env_->get_region_fn(a, 0, size, nullptr); \ 1077 jni_abort_catcher.Check("buf == null"); \ 1078 env_->set_region_fn(a, 0, size, nullptr); \ 1079 jni_abort_catcher.Check("buf == null"); \ 1080 down_cast<JNIEnvExt*>(env_)->SetCheckJniEnabled(true); \ 1081 } \ 1082 /* Allocate an array and check it has the right type and length. */ \ 1083 scalar_type ## Array a = env_->new_fn(size); \ 1084 EXPECT_NE(a, nullptr); \ 1085 EXPECT_TRUE(env_->IsInstanceOf(a, env_->FindClass(expected_class_descriptor))); \ 1086 EXPECT_EQ(size, env_->GetArrayLength(a)); \ 1087 \ 1088 /* GetPrimitiveArrayRegion/SetPrimitiveArrayRegion */ \ 1089 /* AIOOBE for negative start offset. */ \ 1090 env_->get_region_fn(a, -1, 1, nullptr); \ 1091 ExpectException(aioobe_); \ 1092 env_->set_region_fn(a, -1, 1, nullptr); \ 1093 ExpectException(aioobe_); \ 1094 \ 1095 /* AIOOBE for negative length. */ \ 1096 env_->get_region_fn(a, 0, -1, nullptr); \ 1097 ExpectException(aioobe_); \ 1098 env_->set_region_fn(a, 0, -1, nullptr); \ 1099 ExpectException(aioobe_); \ 1100 \ 1101 /* AIOOBE for buffer overrun. */ \ 1102 env_->get_region_fn(a, size - 1, size, nullptr); \ 1103 ExpectException(aioobe_); \ 1104 env_->set_region_fn(a, size - 1, size, nullptr); \ 1105 ExpectException(aioobe_); \ 1106 \ 1107 /* Regression test against integer overflow in range check. */ \ 1108 env_->get_region_fn(a, 0x7fffffff, 0x7fffffff, nullptr); \ 1109 ExpectException(aioobe_); \ 1110 env_->set_region_fn(a, 0x7fffffff, 0x7fffffff, nullptr); \ 1111 ExpectException(aioobe_); \ 1112 \ 1113 /* It's okay for the buffer to be null as long as the length is 0. */ \ 1114 env_->get_region_fn(a, 2, 0, nullptr); \ 1115 /* Even if the offset is invalid... */ \ 1116 env_->get_region_fn(a, 123, 0, nullptr); \ 1117 ExpectException(aioobe_); \ 1118 \ 1119 /* It's okay for the buffer to be null as long as the length is 0. */ \ 1120 env_->set_region_fn(a, 2, 0, nullptr); \ 1121 /* Even if the offset is invalid... */ \ 1122 env_->set_region_fn(a, 123, 0, nullptr); \ 1123 ExpectException(aioobe_); \ 1124 \ 1125 /* Prepare a couple of buffers. */ \ 1126 /* NOLINT, no parentheses around scalar_type. */ \ 1127 std::unique_ptr<scalar_type[]> src_buf(new scalar_type[size]); /* NOLINT */ \ 1128 std::unique_ptr<scalar_type[]> dst_buf(new scalar_type[size]); /* NOLINT */ \ 1129 for (jsize i = 0; i < size; ++i) { src_buf[i] = scalar_type(i); } \ 1130 for (jsize i = 0; i < size; ++i) { dst_buf[i] = scalar_type(-1); } \ 1131 \ 1132 /* Copy all of src_buf onto the heap. */ \ 1133 env_->set_region_fn(a, 0, size, &src_buf[0]); \ 1134 /* Copy back only part. */ \ 1135 env_->get_region_fn(a, 1, size - 2, &dst_buf[1]); \ 1136 EXPECT_NE(memcmp(&src_buf[0], &dst_buf[0], size * sizeof(scalar_type)), 0) \ 1137 << "short copy equal"; \ 1138 /* Copy the missing pieces. */ \ 1139 env_->get_region_fn(a, 0, 1, &dst_buf[0]); \ 1140 env_->get_region_fn(a, size - 1, 1, &dst_buf[size - 1]); \ 1141 EXPECT_EQ(memcmp(&src_buf[0], &dst_buf[0], size * sizeof(scalar_type)), 0) \ 1142 << "fixed copy not equal"; \ 1143 /* Copy back the whole array. */ \ 1144 env_->get_region_fn(a, 0, size, &dst_buf[0]); \ 1145 EXPECT_EQ(memcmp(&src_buf[0], &dst_buf[0], size * sizeof(scalar_type)), 0) \ 1146 << "full copy not equal"; \ 1147 /* GetPrimitiveArrayCritical */ \ 1148 void* v = env_->GetPrimitiveArrayCritical(a, nullptr); \ 1149 EXPECT_EQ(memcmp(&src_buf[0], v, size * sizeof(scalar_type)), 0) \ 1150 << "GetPrimitiveArrayCritical not equal"; \ 1151 env_->ReleasePrimitiveArrayCritical(a, v, 0); \ 1152 /* GetXArrayElements */ \ 1153 scalar_type* xs = env_->get_elements_fn(a, nullptr); /* NOLINT, scalar_type */ \ 1154 EXPECT_EQ(memcmp(&src_buf[0], xs, size * sizeof(scalar_type)), 0) \ 1155 << # get_elements_fn " not equal"; \ 1156 env_->release_elements_fn(a, xs, 0); \ 1157 1158 TEST_F(JniInternalTest, BooleanArrays) { 1159 EXPECT_PRIMITIVE_ARRAY(NewBooleanArray, GetBooleanArrayRegion, SetBooleanArrayRegion, 1160 GetBooleanArrayElements, ReleaseBooleanArrayElements, jboolean, "[Z"); 1161 } 1162 TEST_F(JniInternalTest, ByteArrays) { 1163 EXPECT_PRIMITIVE_ARRAY(NewByteArray, GetByteArrayRegion, SetByteArrayRegion, 1164 GetByteArrayElements, ReleaseByteArrayElements, jbyte, "[B"); 1165 } 1166 TEST_F(JniInternalTest, CharArrays) { 1167 EXPECT_PRIMITIVE_ARRAY(NewCharArray, GetCharArrayRegion, SetCharArrayRegion, 1168 GetCharArrayElements, ReleaseCharArrayElements, jchar, "[C"); 1169 } 1170 TEST_F(JniInternalTest, DoubleArrays) { 1171 EXPECT_PRIMITIVE_ARRAY(NewDoubleArray, GetDoubleArrayRegion, SetDoubleArrayRegion, 1172 GetDoubleArrayElements, ReleaseDoubleArrayElements, jdouble, "[D"); 1173 } 1174 TEST_F(JniInternalTest, FloatArrays) { 1175 EXPECT_PRIMITIVE_ARRAY(NewFloatArray, GetFloatArrayRegion, SetFloatArrayRegion, 1176 GetFloatArrayElements, ReleaseFloatArrayElements, jfloat, "[F"); 1177 } 1178 TEST_F(JniInternalTest, IntArrays) { 1179 EXPECT_PRIMITIVE_ARRAY(NewIntArray, GetIntArrayRegion, SetIntArrayRegion, 1180 GetIntArrayElements, ReleaseIntArrayElements, jint, "[I"); 1181 } 1182 TEST_F(JniInternalTest, LongArrays) { 1183 EXPECT_PRIMITIVE_ARRAY(NewLongArray, GetLongArrayRegion, SetLongArrayRegion, 1184 GetLongArrayElements, ReleaseLongArrayElements, jlong, "[J"); 1185 } 1186 TEST_F(JniInternalTest, ShortArrays) { 1187 EXPECT_PRIMITIVE_ARRAY(NewShortArray, GetShortArrayRegion, SetShortArrayRegion, 1188 GetShortArrayElements, ReleaseShortArrayElements, jshort, "[S"); 1189 } 1190 1191 TEST_F(JniInternalTest, GetPrimitiveArrayElementsOfWrongType) { 1192 GetPrimitiveArrayElementsOfWrongType(false); 1193 GetPrimitiveArrayElementsOfWrongType(true); 1194 } 1195 1196 TEST_F(JniInternalTest, ReleasePrimitiveArrayElementsOfWrongType) { 1197 ReleasePrimitiveArrayElementsOfWrongType(false); 1198 ReleasePrimitiveArrayElementsOfWrongType(true); 1199 } 1200 1201 TEST_F(JniInternalTest, GetReleasePrimitiveArrayCriticalOfWrongType) { 1202 GetReleasePrimitiveArrayCriticalOfWrongType(false); 1203 GetReleasePrimitiveArrayCriticalOfWrongType(true); 1204 } 1205 1206 TEST_F(JniInternalTest, GetPrimitiveArrayRegionElementsOfWrongType) { 1207 GetPrimitiveArrayRegionElementsOfWrongType(false); 1208 GetPrimitiveArrayRegionElementsOfWrongType(true); 1209 } 1210 1211 TEST_F(JniInternalTest, SetPrimitiveArrayRegionElementsOfWrongType) { 1212 SetPrimitiveArrayRegionElementsOfWrongType(false); 1213 SetPrimitiveArrayRegionElementsOfWrongType(true); 1214 } 1215 1216 TEST_F(JniInternalTest, NewObjectArray) { 1217 jclass element_class = env_->FindClass("java/lang/String"); 1218 ASSERT_NE(element_class, nullptr); 1219 jclass array_class = env_->FindClass("[Ljava/lang/String;"); 1220 ASSERT_NE(array_class, nullptr); 1221 1222 jobjectArray a = env_->NewObjectArray(0, element_class, nullptr); 1223 EXPECT_NE(a, nullptr); 1224 EXPECT_TRUE(env_->IsInstanceOf(a, array_class)); 1225 EXPECT_EQ(0, env_->GetArrayLength(a)); 1226 1227 a = env_->NewObjectArray(1, element_class, nullptr); 1228 EXPECT_NE(a, nullptr); 1229 EXPECT_TRUE(env_->IsInstanceOf(a, array_class)); 1230 EXPECT_EQ(1, env_->GetArrayLength(a)); 1231 EXPECT_TRUE(env_->IsSameObject(env_->GetObjectArrayElement(a, 0), nullptr)); 1232 1233 // Negative array length checks. 1234 NewObjectArrayBadArguments(false); 1235 NewObjectArrayBadArguments(true); 1236 } 1237 1238 TEST_F(JniInternalTest, NewObjectArrayWithPrimitiveClasses) { 1239 const char* primitive_descriptors = "VZBSCIJFD"; 1240 const char* primitive_names[] = { 1241 "void", "boolean", "byte", "short", "char", "int", "long", "float", "double" 1242 }; 1243 ASSERT_EQ(strlen(primitive_descriptors), arraysize(primitive_names)); 1244 1245 bool old_check_jni = vm_->SetCheckJniEnabled(false); 1246 CheckJniAbortCatcher jni_abort_catcher; 1247 for (size_t i = 0; i < strlen(primitive_descriptors); ++i) { 1248 env_->NewObjectArray(0, nullptr, nullptr); 1249 jni_abort_catcher.Check("element_jclass == null"); 1250 jclass primitive_class = GetPrimitiveClass(primitive_descriptors[i]); 1251 env_->NewObjectArray(1, primitive_class, nullptr); 1252 std::string error_msg(StringPrintf("not an object type: %s", primitive_names[i])); 1253 jni_abort_catcher.Check(error_msg.c_str()); 1254 } 1255 EXPECT_FALSE(vm_->SetCheckJniEnabled(true)); 1256 for (size_t i = 0; i < strlen(primitive_descriptors); ++i) { 1257 env_->NewObjectArray(0, nullptr, nullptr); 1258 jni_abort_catcher.Check("NewObjectArray received NULL jclass"); 1259 jclass primitive_class = GetPrimitiveClass(primitive_descriptors[i]); 1260 env_->NewObjectArray(1, primitive_class, nullptr); 1261 std::string error_msg(StringPrintf("not an object type: %s", primitive_names[i])); 1262 jni_abort_catcher.Check(error_msg.c_str()); 1263 } 1264 EXPECT_TRUE(vm_->SetCheckJniEnabled(old_check_jni)); 1265 } 1266 1267 TEST_F(JniInternalTest, NewObjectArrayWithInitialValue) { 1268 jclass element_class = env_->FindClass("java/lang/String"); 1269 ASSERT_NE(element_class, nullptr); 1270 jclass array_class = env_->FindClass("[Ljava/lang/String;"); 1271 ASSERT_NE(array_class, nullptr); 1272 1273 jstring s = env_->NewStringUTF("poop"); 1274 jobjectArray a = env_->NewObjectArray(2, element_class, s); 1275 EXPECT_NE(a, nullptr); 1276 EXPECT_TRUE(env_->IsInstanceOf(a, array_class)); 1277 EXPECT_EQ(2, env_->GetArrayLength(a)); 1278 EXPECT_TRUE(env_->IsSameObject(env_->GetObjectArrayElement(a, 0), s)); 1279 EXPECT_TRUE(env_->IsSameObject(env_->GetObjectArrayElement(a, 1), s)); 1280 1281 // Attempt to incorrect create an array of strings with initial value of string arrays. 1282 CheckJniAbortCatcher jni_abort_catcher; 1283 env_->NewObjectArray(2, element_class, a); 1284 jni_abort_catcher.Check("cannot assign object of type 'java.lang.String[]' to array with element " 1285 "type of 'java.lang.String'"); 1286 } 1287 1288 TEST_F(JniInternalTest, GetArrayLength) { 1289 // Already tested in NewObjectArray/NewPrimitiveArray except for null. 1290 CheckJniAbortCatcher jni_abort_catcher; 1291 bool old_check_jni = vm_->SetCheckJniEnabled(false); 1292 EXPECT_EQ(0, env_->GetArrayLength(nullptr)); 1293 jni_abort_catcher.Check("java_array == null"); 1294 EXPECT_FALSE(vm_->SetCheckJniEnabled(true)); 1295 EXPECT_EQ(JNI_ERR, env_->GetArrayLength(nullptr)); 1296 jni_abort_catcher.Check("jarray was NULL"); 1297 EXPECT_TRUE(vm_->SetCheckJniEnabled(old_check_jni)); 1298 } 1299 1300 TEST_F(JniInternalTest, GetObjectClass) { 1301 jclass string_class = env_->FindClass("java/lang/String"); 1302 ASSERT_NE(string_class, nullptr); 1303 jclass class_class = env_->FindClass("java/lang/Class"); 1304 ASSERT_NE(class_class, nullptr); 1305 1306 jstring s = env_->NewStringUTF("poop"); 1307 jclass c = env_->GetObjectClass(s); 1308 ASSERT_TRUE(env_->IsSameObject(string_class, c)); 1309 1310 jclass c2 = env_->GetObjectClass(c); 1311 ASSERT_TRUE(env_->IsSameObject(class_class, env_->GetObjectClass(c2))); 1312 1313 // Null as object should fail. 1314 CheckJniAbortCatcher jni_abort_catcher; 1315 EXPECT_EQ(env_->GetObjectClass(nullptr), nullptr); 1316 jni_abort_catcher.Check("java_object == null"); 1317 } 1318 1319 TEST_F(JniInternalTest, GetSuperclass) { 1320 jclass object_class = env_->FindClass("java/lang/Object"); 1321 ASSERT_NE(object_class, nullptr); 1322 jclass string_class = env_->FindClass("java/lang/String"); 1323 ASSERT_NE(string_class, nullptr); 1324 jclass runnable_interface = env_->FindClass("java/lang/Runnable"); 1325 ASSERT_NE(runnable_interface, nullptr); 1326 ASSERT_TRUE(env_->IsSameObject(object_class, env_->GetSuperclass(string_class))); 1327 ASSERT_EQ(env_->GetSuperclass(object_class), nullptr); 1328 ASSERT_EQ(env_->GetSuperclass(runnable_interface), nullptr); 1329 1330 // Null as class should fail. 1331 CheckJniAbortCatcher jni_abort_catcher; 1332 bool old_check_jni = vm_->SetCheckJniEnabled(false); 1333 EXPECT_EQ(env_->GetSuperclass(nullptr), nullptr); 1334 jni_abort_catcher.Check("java_class == null"); 1335 EXPECT_FALSE(vm_->SetCheckJniEnabled(true)); 1336 EXPECT_EQ(env_->GetSuperclass(nullptr), nullptr); 1337 jni_abort_catcher.Check("GetSuperclass received NULL jclass"); 1338 EXPECT_TRUE(vm_->SetCheckJniEnabled(old_check_jni)); 1339 } 1340 1341 TEST_F(JniInternalTest, IsAssignableFrom) { 1342 jclass object_class = env_->FindClass("java/lang/Object"); 1343 ASSERT_NE(object_class, nullptr); 1344 jclass string_class = env_->FindClass("java/lang/String"); 1345 ASSERT_NE(string_class, nullptr); 1346 1347 // A superclass is assignable from an instance of its 1348 // subclass but not vice versa. 1349 ASSERT_TRUE(env_->IsAssignableFrom(string_class, object_class)); 1350 ASSERT_FALSE(env_->IsAssignableFrom(object_class, string_class)); 1351 1352 jclass charsequence_interface = env_->FindClass("java/lang/CharSequence"); 1353 ASSERT_NE(charsequence_interface, nullptr); 1354 1355 // An interface is assignable from an instance of an implementing 1356 // class but not vice versa. 1357 ASSERT_TRUE(env_->IsAssignableFrom(string_class, charsequence_interface)); 1358 ASSERT_FALSE(env_->IsAssignableFrom(charsequence_interface, string_class)); 1359 1360 // Check that arrays are covariant. 1361 jclass string_array_class = env_->FindClass("[Ljava/lang/String;"); 1362 ASSERT_NE(string_array_class, nullptr); 1363 jclass object_array_class = env_->FindClass("[Ljava/lang/Object;"); 1364 ASSERT_NE(object_array_class, nullptr); 1365 ASSERT_TRUE(env_->IsAssignableFrom(string_array_class, object_array_class)); 1366 ASSERT_FALSE(env_->IsAssignableFrom(object_array_class, string_array_class)); 1367 1368 // Primitive types are tested in 004-JniTest. 1369 1370 // Null as either class should fail. 1371 CheckJniAbortCatcher jni_abort_catcher; 1372 bool old_check_jni = vm_->SetCheckJniEnabled(false); 1373 EXPECT_EQ(env_->IsAssignableFrom(nullptr, string_class), JNI_FALSE); 1374 jni_abort_catcher.Check("java_class1 == null"); 1375 EXPECT_EQ(env_->IsAssignableFrom(object_class, nullptr), JNI_FALSE); 1376 jni_abort_catcher.Check("java_class2 == null"); 1377 EXPECT_FALSE(vm_->SetCheckJniEnabled(true)); 1378 EXPECT_EQ(env_->IsAssignableFrom(nullptr, string_class), JNI_FALSE); 1379 jni_abort_catcher.Check("IsAssignableFrom received NULL jclass"); 1380 EXPECT_EQ(env_->IsAssignableFrom(object_class, nullptr), JNI_FALSE); 1381 jni_abort_catcher.Check("IsAssignableFrom received NULL jclass"); 1382 EXPECT_TRUE(vm_->SetCheckJniEnabled(old_check_jni)); 1383 } 1384 1385 TEST_F(JniInternalTest, GetObjectRefType) { 1386 jclass local = env_->FindClass("java/lang/Object"); 1387 ASSERT_TRUE(local != nullptr); 1388 EXPECT_EQ(JNILocalRefType, env_->GetObjectRefType(local)); 1389 1390 jobject global = env_->NewGlobalRef(local); 1391 EXPECT_EQ(JNIGlobalRefType, env_->GetObjectRefType(global)); 1392 1393 jweak weak_global = env_->NewWeakGlobalRef(local); 1394 EXPECT_EQ(JNIWeakGlobalRefType, env_->GetObjectRefType(weak_global)); 1395 1396 { 1397 CheckJniAbortCatcher jni_abort_catcher; 1398 jobject invalid = reinterpret_cast<jobject>(this); 1399 EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(invalid)); 1400 jni_abort_catcher.Check("use of invalid jobject"); 1401 } 1402 1403 // TODO: invoke a native method and test that its arguments are considered local references. 1404 1405 // Null as pointer should not fail and return invalid-ref. b/18820997 1406 EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(nullptr)); 1407 1408 // TODO: Null as reference should return the original type. 1409 // This requires running a GC so a non-null object gets freed. 1410 } 1411 1412 TEST_F(JniInternalTest, StaleWeakGlobal) { 1413 jclass java_lang_Class = env_->FindClass("java/lang/Class"); 1414 ASSERT_NE(java_lang_Class, nullptr); 1415 jobjectArray local_ref = env_->NewObjectArray(1, java_lang_Class, nullptr); 1416 ASSERT_NE(local_ref, nullptr); 1417 jweak weak_global = env_->NewWeakGlobalRef(local_ref); 1418 ASSERT_NE(weak_global, nullptr); 1419 env_->DeleteLocalRef(local_ref); 1420 Runtime::Current()->GetHeap()->CollectGarbage(false); // GC should clear the weak global. 1421 jobject new_global_ref = env_->NewGlobalRef(weak_global); 1422 EXPECT_EQ(new_global_ref, nullptr); 1423 jobject new_local_ref = env_->NewLocalRef(weak_global); 1424 EXPECT_EQ(new_local_ref, nullptr); 1425 } 1426 1427 TEST_F(JniInternalTest, NewStringUTF) { 1428 EXPECT_EQ(env_->NewStringUTF(nullptr), nullptr); 1429 jstring s; 1430 1431 s = env_->NewStringUTF(""); 1432 EXPECT_NE(s, nullptr); 1433 EXPECT_EQ(0, env_->GetStringLength(s)); 1434 EXPECT_EQ(0, env_->GetStringUTFLength(s)); 1435 s = env_->NewStringUTF("hello"); 1436 EXPECT_NE(s, nullptr); 1437 EXPECT_EQ(5, env_->GetStringLength(s)); 1438 EXPECT_EQ(5, env_->GetStringUTFLength(s)); 1439 1440 // Encoded surrogate pair. 1441 s = env_->NewStringUTF("\xed\xa0\x81\xed\xb0\x80"); 1442 EXPECT_NE(s, nullptr); 1443 EXPECT_EQ(2, env_->GetStringLength(s)); 1444 1445 // The surrogate pair gets encoded into a 4 byte UTF sequence.. 1446 EXPECT_EQ(4, env_->GetStringUTFLength(s)); 1447 const char* chars = env_->GetStringUTFChars(s, nullptr); 1448 EXPECT_STREQ("\xf0\x90\x90\x80", chars); 1449 env_->ReleaseStringUTFChars(s, chars); 1450 1451 // .. but is stored as is in the utf-16 representation. 1452 const jchar* jchars = env_->GetStringChars(s, nullptr); 1453 EXPECT_EQ(0xd801, jchars[0]); 1454 EXPECT_EQ(0xdc00, jchars[1]); 1455 env_->ReleaseStringChars(s, jchars); 1456 1457 // 4 byte UTF sequence appended to an encoded surrogate pair. 1458 s = env_->NewStringUTF("\xed\xa0\x81\xed\xb0\x80 \xf0\x9f\x8f\xa0"); 1459 EXPECT_NE(s, nullptr); 1460 1461 // The 4 byte sequence {0xf0, 0x9f, 0x8f, 0xa0} is converted into a surrogate 1462 // pair {0xd83c, 0xdfe0}. 1463 EXPECT_EQ(5, env_->GetStringLength(s)); 1464 jchars = env_->GetStringChars(s, nullptr); 1465 // The first surrogate pair, encoded as such in the input. 1466 EXPECT_EQ(0xd801, jchars[0]); 1467 EXPECT_EQ(0xdc00, jchars[1]); 1468 // The second surrogate pair, from the 4 byte UTF sequence in the input. 1469 EXPECT_EQ(0xd83c, jchars[3]); 1470 EXPECT_EQ(0xdfe0, jchars[4]); 1471 env_->ReleaseStringChars(s, jchars); 1472 1473 EXPECT_EQ(9, env_->GetStringUTFLength(s)); 1474 chars = env_->GetStringUTFChars(s, nullptr); 1475 EXPECT_STREQ("\xf0\x90\x90\x80 \xf0\x9f\x8f\xa0", chars); 1476 env_->ReleaseStringUTFChars(s, chars); 1477 1478 // A string with 1, 2, 3 and 4 byte UTF sequences with spaces 1479 // between them 1480 s = env_->NewStringUTF("\x24 \xc2\xa2 \xe2\x82\xac \xf0\x9f\x8f\xa0"); 1481 EXPECT_NE(s, nullptr); 1482 EXPECT_EQ(8, env_->GetStringLength(s)); 1483 EXPECT_EQ(13, env_->GetStringUTFLength(s)); 1484 } 1485 1486 TEST_F(JniInternalTest, NewString) { 1487 jchar chars[] = { 'h', 'i' }; 1488 jstring s; 1489 s = env_->NewString(chars, 0); 1490 EXPECT_NE(s, nullptr); 1491 EXPECT_EQ(0, env_->GetStringLength(s)); 1492 EXPECT_EQ(0, env_->GetStringUTFLength(s)); 1493 s = env_->NewString(chars, 2); 1494 EXPECT_NE(s, nullptr); 1495 EXPECT_EQ(2, env_->GetStringLength(s)); 1496 EXPECT_EQ(2, env_->GetStringUTFLength(s)); 1497 1498 // TODO: check some non-ASCII strings. 1499 } 1500 1501 TEST_F(JniInternalTest, NewStringNullCharsZeroLength) { 1502 jstring s = env_->NewString(nullptr, 0); 1503 EXPECT_NE(s, nullptr); 1504 EXPECT_EQ(0, env_->GetStringLength(s)); 1505 } 1506 1507 TEST_F(JniInternalTest, NewStringNullCharsNonzeroLength) { 1508 CheckJniAbortCatcher jni_abort_catcher; 1509 env_->NewString(nullptr, 1); 1510 jni_abort_catcher.Check("chars == null && char_count > 0"); 1511 } 1512 1513 TEST_F(JniInternalTest, NewStringNegativeLength) { 1514 CheckJniAbortCatcher jni_abort_catcher; 1515 bool old_check_jni = vm_->SetCheckJniEnabled(false); 1516 env_->NewString(nullptr, -1); 1517 jni_abort_catcher.Check("char_count < 0: -1"); 1518 env_->NewString(nullptr, std::numeric_limits<jint>::min()); 1519 jni_abort_catcher.Check("char_count < 0: -2147483648"); 1520 EXPECT_FALSE(vm_->SetCheckJniEnabled(true)); 1521 env_->NewString(nullptr, -1); 1522 jni_abort_catcher.Check("negative jsize: -1"); 1523 env_->NewString(nullptr, std::numeric_limits<jint>::min()); 1524 jni_abort_catcher.Check("negative jsize: -2147483648"); 1525 EXPECT_TRUE(vm_->SetCheckJniEnabled(old_check_jni)); 1526 } 1527 1528 TEST_F(JniInternalTest, GetStringLength_GetStringUTFLength) { 1529 // Already tested in the NewString/NewStringUTF tests. 1530 } 1531 1532 TEST_F(JniInternalTest, GetStringRegion_GetStringUTFRegion) { 1533 jstring s = env_->NewStringUTF("hello"); 1534 ASSERT_TRUE(s != nullptr); 1535 1536 env_->GetStringRegion(s, -1, 0, nullptr); 1537 ExpectException(sioobe_); 1538 env_->GetStringRegion(s, 0, -1, nullptr); 1539 ExpectException(sioobe_); 1540 env_->GetStringRegion(s, 0, 10, nullptr); 1541 ExpectException(sioobe_); 1542 env_->GetStringRegion(s, 10, 1, nullptr); 1543 ExpectException(sioobe_); 1544 // Regression test against integer overflow in range check. 1545 env_->GetStringRegion(s, 0x7fffffff, 0x7fffffff, nullptr); 1546 ExpectException(sioobe_); 1547 1548 jchar chars[4] = { 'x', 'x', 'x', 'x' }; 1549 env_->GetStringRegion(s, 1, 2, &chars[1]); 1550 EXPECT_EQ('x', chars[0]); 1551 EXPECT_EQ('e', chars[1]); 1552 EXPECT_EQ('l', chars[2]); 1553 EXPECT_EQ('x', chars[3]); 1554 1555 // It's okay for the buffer to be null as long as the length is 0. 1556 env_->GetStringRegion(s, 2, 0, nullptr); 1557 // Even if the offset is invalid... 1558 env_->GetStringRegion(s, 123, 0, nullptr); 1559 ExpectException(sioobe_); 1560 1561 env_->GetStringUTFRegion(s, -1, 0, nullptr); 1562 ExpectException(sioobe_); 1563 env_->GetStringUTFRegion(s, 0, -1, nullptr); 1564 ExpectException(sioobe_); 1565 env_->GetStringUTFRegion(s, 0, 10, nullptr); 1566 ExpectException(sioobe_); 1567 env_->GetStringUTFRegion(s, 10, 1, nullptr); 1568 ExpectException(sioobe_); 1569 // Regression test against integer overflow in range check. 1570 env_->GetStringUTFRegion(s, 0x7fffffff, 0x7fffffff, nullptr); 1571 ExpectException(sioobe_); 1572 1573 char bytes[4] = { 'x', 'x', 'x', 'x' }; 1574 env_->GetStringUTFRegion(s, 1, 2, &bytes[1]); 1575 EXPECT_EQ('x', bytes[0]); 1576 EXPECT_EQ('e', bytes[1]); 1577 EXPECT_EQ('l', bytes[2]); 1578 EXPECT_EQ('x', bytes[3]); 1579 1580 // It's okay for the buffer to be null as long as the length is 0. 1581 env_->GetStringUTFRegion(s, 2, 0, nullptr); 1582 // Even if the offset is invalid... 1583 env_->GetStringUTFRegion(s, 123, 0, nullptr); 1584 ExpectException(sioobe_); 1585 } 1586 1587 TEST_F(JniInternalTest, GetStringUTFChars_ReleaseStringUTFChars) { 1588 // Passing in a null jstring is ignored normally, but caught by -Xcheck:jni. 1589 bool old_check_jni = vm_->SetCheckJniEnabled(false); 1590 { 1591 CheckJniAbortCatcher check_jni_abort_catcher; 1592 EXPECT_EQ(env_->GetStringUTFChars(nullptr, nullptr), nullptr); 1593 } 1594 { 1595 CheckJniAbortCatcher check_jni_abort_catcher; 1596 EXPECT_FALSE(vm_->SetCheckJniEnabled(true)); 1597 EXPECT_EQ(env_->GetStringUTFChars(nullptr, nullptr), nullptr); 1598 check_jni_abort_catcher.Check("GetStringUTFChars received NULL jstring"); 1599 EXPECT_TRUE(vm_->SetCheckJniEnabled(old_check_jni)); 1600 } 1601 1602 jstring s = env_->NewStringUTF("hello"); 1603 ASSERT_TRUE(s != nullptr); 1604 1605 const char* utf = env_->GetStringUTFChars(s, nullptr); 1606 EXPECT_STREQ("hello", utf); 1607 env_->ReleaseStringUTFChars(s, utf); 1608 1609 jboolean is_copy = JNI_FALSE; 1610 utf = env_->GetStringUTFChars(s, &is_copy); 1611 EXPECT_EQ(JNI_TRUE, is_copy); 1612 EXPECT_STREQ("hello", utf); 1613 env_->ReleaseStringUTFChars(s, utf); 1614 } 1615 1616 TEST_F(JniInternalTest, GetStringChars_ReleaseStringChars) { 1617 jstring s = env_->NewStringUTF("hello"); 1618 ScopedObjectAccess soa(env_); 1619 ObjPtr<mirror::String> s_m = soa.Decode<mirror::String>(s); 1620 ASSERT_TRUE(s != nullptr); 1621 1622 jchar expected[] = { 'h', 'e', 'l', 'l', 'o' }; 1623 const jchar* chars = env_->GetStringChars(s, nullptr); 1624 EXPECT_EQ(expected[0], chars[0]); 1625 EXPECT_EQ(expected[1], chars[1]); 1626 EXPECT_EQ(expected[2], chars[2]); 1627 EXPECT_EQ(expected[3], chars[3]); 1628 EXPECT_EQ(expected[4], chars[4]); 1629 env_->ReleaseStringChars(s, chars); 1630 1631 jboolean is_copy = JNI_FALSE; 1632 chars = env_->GetStringChars(s, &is_copy); 1633 if (Runtime::Current()->GetHeap()->IsMovableObject(s_m)) { 1634 EXPECT_EQ(JNI_TRUE, is_copy); 1635 } else { 1636 EXPECT_EQ(JNI_FALSE, is_copy); 1637 } 1638 EXPECT_EQ(expected[0], chars[0]); 1639 EXPECT_EQ(expected[1], chars[1]); 1640 EXPECT_EQ(expected[2], chars[2]); 1641 EXPECT_EQ(expected[3], chars[3]); 1642 EXPECT_EQ(expected[4], chars[4]); 1643 env_->ReleaseStringChars(s, chars); 1644 } 1645 1646 TEST_F(JniInternalTest, GetStringCritical_ReleaseStringCritical) { 1647 jstring s = env_->NewStringUTF("hello"); 1648 ASSERT_TRUE(s != nullptr); 1649 1650 jchar expected[] = { 'h', 'e', 'l', 'l', 'o' }; 1651 const jchar* chars = env_->GetStringCritical(s, nullptr); 1652 EXPECT_EQ(expected[0], chars[0]); 1653 EXPECT_EQ(expected[1], chars[1]); 1654 EXPECT_EQ(expected[2], chars[2]); 1655 EXPECT_EQ(expected[3], chars[3]); 1656 EXPECT_EQ(expected[4], chars[4]); 1657 env_->ReleaseStringCritical(s, chars); 1658 1659 jboolean is_copy = JNI_TRUE; 1660 chars = env_->GetStringCritical(s, &is_copy); 1661 if (mirror::kUseStringCompression) { 1662 // is_copy has to be JNI_TRUE because "hello" is all-ASCII 1663 EXPECT_EQ(JNI_TRUE, is_copy); 1664 } else { 1665 EXPECT_EQ(JNI_FALSE, is_copy); 1666 } 1667 EXPECT_EQ(expected[0], chars[0]); 1668 EXPECT_EQ(expected[1], chars[1]); 1669 EXPECT_EQ(expected[2], chars[2]); 1670 EXPECT_EQ(expected[3], chars[3]); 1671 EXPECT_EQ(expected[4], chars[4]); 1672 env_->ReleaseStringCritical(s, chars); 1673 1674 if (mirror::kUseStringCompression) { 1675 // is_copy has to be JNI_FALSE because "\xed\xa0\x81\xed\xb0\x80" is incompressible 1676 jboolean is_copy_16 = JNI_TRUE; 1677 jstring s_16 = env_->NewStringUTF("\xed\xa0\x81\xed\xb0\x80"); 1678 chars = env_->GetStringCritical(s_16, &is_copy_16); 1679 EXPECT_EQ(2, env_->GetStringLength(s_16)); 1680 EXPECT_EQ(4, env_->GetStringUTFLength(s_16)); 1681 env_->ReleaseStringCritical(s_16, chars); 1682 } 1683 } 1684 1685 TEST_F(JniInternalTest, GetObjectArrayElement_SetObjectArrayElement) { 1686 jclass java_lang_Class = env_->FindClass("java/lang/Class"); 1687 ASSERT_TRUE(java_lang_Class != nullptr); 1688 1689 jobjectArray array = env_->NewObjectArray(1, java_lang_Class, nullptr); 1690 EXPECT_NE(array, nullptr); 1691 EXPECT_EQ(env_->GetObjectArrayElement(array, 0), nullptr); 1692 env_->SetObjectArrayElement(array, 0, java_lang_Class); 1693 EXPECT_TRUE(env_->IsSameObject(env_->GetObjectArrayElement(array, 0), java_lang_Class)); 1694 1695 // ArrayIndexOutOfBounds for negative index. 1696 env_->SetObjectArrayElement(array, -1, java_lang_Class); 1697 ExpectException(aioobe_); 1698 1699 // ArrayIndexOutOfBounds for too-large index. 1700 env_->SetObjectArrayElement(array, 1, java_lang_Class); 1701 ExpectException(aioobe_); 1702 1703 // ArrayStoreException thrown for bad types. 1704 env_->SetObjectArrayElement(array, 0, env_->NewStringUTF("not a jclass!")); 1705 ExpectException(ase_); 1706 1707 // Null as array should fail. 1708 CheckJniAbortCatcher jni_abort_catcher; 1709 bool old_check_jni = vm_->SetCheckJniEnabled(false); 1710 EXPECT_EQ(nullptr, env_->GetObjectArrayElement(nullptr, 0)); 1711 jni_abort_catcher.Check("java_array == null"); 1712 env_->SetObjectArrayElement(nullptr, 0, nullptr); 1713 jni_abort_catcher.Check("java_array == null"); 1714 EXPECT_FALSE(vm_->SetCheckJniEnabled(true)); 1715 EXPECT_EQ(nullptr, env_->GetObjectArrayElement(nullptr, 0)); 1716 jni_abort_catcher.Check("jarray was NULL"); 1717 env_->SetObjectArrayElement(nullptr, 0, nullptr); 1718 jni_abort_catcher.Check("jarray was NULL"); 1719 EXPECT_TRUE(vm_->SetCheckJniEnabled(old_check_jni)); 1720 } 1721 1722 #define EXPECT_STATIC_PRIMITIVE_FIELD(expect_eq, type, field_name, sig, value1, value2) \ 1723 do { \ 1724 jfieldID fid = env_->GetStaticFieldID(c, field_name, sig); \ 1725 EXPECT_NE(fid, nullptr); \ 1726 env_->SetStatic ## type ## Field(c, fid, value1); \ 1727 expect_eq(value1, env_->GetStatic ## type ## Field(c, fid)); \ 1728 env_->SetStatic ## type ## Field(c, fid, value2); \ 1729 expect_eq(value2, env_->GetStatic ## type ## Field(c, fid)); \ 1730 \ 1731 bool old_check_jni = vm_->SetCheckJniEnabled(false); \ 1732 { \ 1733 CheckJniAbortCatcher jni_abort_catcher; \ 1734 env_->GetStatic ## type ## Field(nullptr, fid); \ 1735 env_->SetStatic ## type ## Field(nullptr, fid, value1); \ 1736 } \ 1737 CheckJniAbortCatcher jni_abort_catcher; \ 1738 env_->GetStatic ## type ## Field(c, nullptr); \ 1739 jni_abort_catcher.Check("fid == null"); \ 1740 env_->SetStatic ## type ## Field(c, nullptr, value1); \ 1741 jni_abort_catcher.Check("fid == null"); \ 1742 \ 1743 EXPECT_FALSE(vm_->SetCheckJniEnabled(true)); \ 1744 env_->GetStatic ## type ## Field(nullptr, fid); \ 1745 jni_abort_catcher.Check("received NULL jclass"); \ 1746 env_->SetStatic ## type ## Field(nullptr, fid, value1); \ 1747 jni_abort_catcher.Check("received NULL jclass"); \ 1748 env_->GetStatic ## type ## Field(c, nullptr); \ 1749 jni_abort_catcher.Check("jfieldID was NULL"); \ 1750 env_->SetStatic ## type ## Field(c, nullptr, value1); \ 1751 jni_abort_catcher.Check("jfieldID was NULL"); \ 1752 EXPECT_TRUE(vm_->SetCheckJniEnabled(old_check_jni)); \ 1753 } while (false) 1754 1755 #define EXPECT_PRIMITIVE_FIELD(expect_eq, instance, type, field_name, sig, value1, value2) \ 1756 do { \ 1757 jfieldID fid = env_->GetFieldID(c, field_name, sig); \ 1758 EXPECT_NE(fid, nullptr); \ 1759 env_->Set ## type ## Field(instance, fid, value1); \ 1760 expect_eq(value1, env_->Get ## type ## Field(instance, fid)); \ 1761 env_->Set ## type ## Field(instance, fid, value2); \ 1762 expect_eq(value2, env_->Get ## type ## Field(instance, fid)); \ 1763 \ 1764 bool old_check_jni = vm_->SetCheckJniEnabled(false); \ 1765 CheckJniAbortCatcher jni_abort_catcher; \ 1766 env_->Get ## type ## Field(nullptr, fid); \ 1767 jni_abort_catcher.Check("obj == null"); \ 1768 env_->Set ## type ## Field(nullptr, fid, value1); \ 1769 jni_abort_catcher.Check("obj == null"); \ 1770 env_->Get ## type ## Field(instance, nullptr); \ 1771 jni_abort_catcher.Check("fid == null"); \ 1772 env_->Set ## type ## Field(instance, nullptr, value1); \ 1773 jni_abort_catcher.Check("fid == null"); \ 1774 EXPECT_FALSE(vm_->SetCheckJniEnabled(true)); \ 1775 env_->Get ## type ## Field(nullptr, fid); \ 1776 jni_abort_catcher.Check("field operation on NULL object:"); \ 1777 env_->Set ## type ## Field(nullptr, fid, value1); \ 1778 jni_abort_catcher.Check("field operation on NULL object:"); \ 1779 env_->Get ## type ## Field(instance, nullptr); \ 1780 jni_abort_catcher.Check("jfieldID was NULL"); \ 1781 env_->Set ## type ## Field(instance, nullptr, value1); \ 1782 jni_abort_catcher.Check("jfieldID was NULL"); \ 1783 EXPECT_TRUE(vm_->SetCheckJniEnabled(old_check_jni)); \ 1784 } while (false) 1785 1786 1787 TEST_F(JniInternalTest, GetPrimitiveField_SetPrimitiveField) { 1788 Thread::Current()->TransitionFromSuspendedToRunnable(); 1789 LoadDex("AllFields"); 1790 bool started = runtime_->Start(); 1791 ASSERT_TRUE(started); 1792 1793 jclass c = env_->FindClass("AllFields"); 1794 ASSERT_NE(c, nullptr); 1795 jobject o = env_->AllocObject(c); 1796 ASSERT_NE(o, nullptr); 1797 1798 EXPECT_STATIC_PRIMITIVE_FIELD(EXPECT_EQ, Boolean, "sZ", "Z", JNI_TRUE, JNI_FALSE); 1799 EXPECT_STATIC_PRIMITIVE_FIELD(EXPECT_EQ, Byte, "sB", "B", 1, 2); 1800 EXPECT_STATIC_PRIMITIVE_FIELD(EXPECT_EQ, Char, "sC", "C", 'a', 'b'); 1801 EXPECT_STATIC_PRIMITIVE_FIELD(EXPECT_DOUBLE_EQ, Double, "sD", "D", 1.0, 2.0); 1802 EXPECT_STATIC_PRIMITIVE_FIELD(EXPECT_FLOAT_EQ, Float, "sF", "F", 1.0, 2.0); 1803 EXPECT_STATIC_PRIMITIVE_FIELD(EXPECT_EQ, Int, "sI", "I", 1, 2); 1804 EXPECT_STATIC_PRIMITIVE_FIELD(EXPECT_EQ, Long, "sJ", "J", 1, 2); 1805 EXPECT_STATIC_PRIMITIVE_FIELD(EXPECT_EQ, Short, "sS", "S", 1, 2); 1806 1807 EXPECT_PRIMITIVE_FIELD(EXPECT_EQ, o, Boolean, "iZ", "Z", JNI_TRUE, JNI_FALSE); 1808 EXPECT_PRIMITIVE_FIELD(EXPECT_EQ, o, Byte, "iB", "B", 1, 2); 1809 EXPECT_PRIMITIVE_FIELD(EXPECT_EQ, o, Char, "iC", "C", 'a', 'b'); 1810 EXPECT_PRIMITIVE_FIELD(EXPECT_DOUBLE_EQ, o, Double, "iD", "D", 1.0, 2.0); 1811 EXPECT_PRIMITIVE_FIELD(EXPECT_FLOAT_EQ, o, Float, "iF", "F", 1.0, 2.0); 1812 EXPECT_PRIMITIVE_FIELD(EXPECT_EQ, o, Int, "iI", "I", 1, 2); 1813 EXPECT_PRIMITIVE_FIELD(EXPECT_EQ, o, Long, "iJ", "J", 1, 2); 1814 EXPECT_PRIMITIVE_FIELD(EXPECT_EQ, o, Short, "iS", "S", 1, 2); 1815 } 1816 1817 TEST_F(JniInternalTest, GetObjectField_SetObjectField) { 1818 Thread::Current()->TransitionFromSuspendedToRunnable(); 1819 LoadDex("AllFields"); 1820 runtime_->Start(); 1821 1822 jclass c = env_->FindClass("AllFields"); 1823 ASSERT_NE(c, nullptr); 1824 jobject o = env_->AllocObject(c); 1825 ASSERT_NE(o, nullptr); 1826 1827 jstring s1 = env_->NewStringUTF("hello"); 1828 ASSERT_NE(s1, nullptr); 1829 jstring s2 = env_->NewStringUTF("world"); 1830 ASSERT_NE(s2, nullptr); 1831 1832 jfieldID s_fid = env_->GetStaticFieldID(c, "sObject", "Ljava/lang/Object;"); 1833 ASSERT_NE(s_fid, nullptr); 1834 jfieldID i_fid = env_->GetFieldID(c, "iObject", "Ljava/lang/Object;"); 1835 ASSERT_NE(i_fid, nullptr); 1836 1837 env_->SetStaticObjectField(c, s_fid, s1); 1838 ASSERT_TRUE(env_->IsSameObject(s1, env_->GetStaticObjectField(c, s_fid))); 1839 env_->SetStaticObjectField(c, s_fid, s2); 1840 ASSERT_TRUE(env_->IsSameObject(s2, env_->GetStaticObjectField(c, s_fid))); 1841 1842 env_->SetObjectField(o, i_fid, s1); 1843 ASSERT_TRUE(env_->IsSameObject(s1, env_->GetObjectField(o, i_fid))); 1844 env_->SetObjectField(o, i_fid, s2); 1845 ASSERT_TRUE(env_->IsSameObject(s2, env_->GetObjectField(o, i_fid))); 1846 } 1847 1848 TEST_F(JniInternalTest, NewLocalRef_nullptr) { 1849 EXPECT_EQ(env_->NewLocalRef(nullptr), nullptr); 1850 } 1851 1852 TEST_F(JniInternalTest, NewLocalRef) { 1853 jstring s = env_->NewStringUTF(""); 1854 ASSERT_NE(s, nullptr); 1855 jobject o = env_->NewLocalRef(s); 1856 EXPECT_NE(o, nullptr); 1857 EXPECT_NE(o, s); 1858 1859 EXPECT_EQ(JNILocalRefType, env_->GetObjectRefType(o)); 1860 } 1861 1862 TEST_F(JniInternalTest, DeleteLocalRef_nullptr) { 1863 env_->DeleteLocalRef(nullptr); 1864 } 1865 1866 TEST_F(JniInternalTest, DeleteLocalRef) { 1867 // This tests leads to warnings and errors in the log. 1868 ScopedLogSeverity sls(LogSeverity::FATAL); 1869 1870 jstring s = env_->NewStringUTF(""); 1871 ASSERT_NE(s, nullptr); 1872 env_->DeleteLocalRef(s); 1873 1874 // Currently, deleting an already-deleted reference is just a CheckJNI warning. 1875 { 1876 bool old_check_jni = vm_->SetCheckJniEnabled(false); 1877 { 1878 CheckJniAbortCatcher check_jni_abort_catcher; 1879 env_->DeleteLocalRef(s); 1880 } 1881 CheckJniAbortCatcher check_jni_abort_catcher; 1882 EXPECT_FALSE(vm_->SetCheckJniEnabled(true)); 1883 env_->DeleteLocalRef(s); 1884 std::string expected(StringPrintf("use of deleted local reference %p", s)); 1885 check_jni_abort_catcher.Check(expected.c_str()); 1886 EXPECT_TRUE(vm_->SetCheckJniEnabled(old_check_jni)); 1887 } 1888 1889 s = env_->NewStringUTF(""); 1890 ASSERT_NE(s, nullptr); 1891 jobject o = env_->NewLocalRef(s); 1892 ASSERT_NE(o, nullptr); 1893 1894 env_->DeleteLocalRef(s); 1895 env_->DeleteLocalRef(o); 1896 } 1897 1898 TEST_F(JniInternalTest, PushLocalFrame_10395422) { 1899 // The JNI specification is ambiguous about whether the given capacity is to be interpreted as a 1900 // maximum or as a minimum, but it seems like it's supposed to be a minimum, and that's how 1901 // Android historically treated it, and it's how the RI treats it. It's also the more useful 1902 // interpretation! 1903 ASSERT_EQ(JNI_OK, env_->PushLocalFrame(0)); 1904 env_->PopLocalFrame(nullptr); 1905 1906 // The following two tests will print errors to the log. 1907 ScopedLogSeverity sls(LogSeverity::FATAL); 1908 1909 // Negative capacities are not allowed. 1910 ASSERT_EQ(JNI_ERR, env_->PushLocalFrame(-1)); 1911 } 1912 1913 TEST_F(JniInternalTest, PushLocalFrame_PopLocalFrame) { 1914 // This tests leads to errors in the log. 1915 ScopedLogSeverity sls(LogSeverity::FATAL); 1916 1917 jobject original = env_->NewStringUTF(""); 1918 ASSERT_NE(original, nullptr); 1919 1920 jobject outer; 1921 jobject inner1, inner2; 1922 ScopedObjectAccess soa(env_); 1923 { 1924 ASSERT_EQ(JNI_OK, env_->PushLocalFrame(4)); 1925 outer = env_->NewLocalRef(original); 1926 1927 { 1928 ASSERT_EQ(JNI_OK, env_->PushLocalFrame(4)); 1929 inner1 = env_->NewLocalRef(outer); 1930 inner2 = env_->NewStringUTF("survivor"); 1931 EXPECT_NE(env_->PopLocalFrame(inner2), nullptr); 1932 } 1933 1934 EXPECT_EQ(JNILocalRefType, env_->GetObjectRefType(original)); 1935 EXPECT_EQ(JNILocalRefType, env_->GetObjectRefType(outer)); 1936 { 1937 CheckJniAbortCatcher check_jni_abort_catcher; 1938 EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(inner1)); 1939 check_jni_abort_catcher.Check("use of deleted local reference"); 1940 } 1941 1942 // Our local reference for the survivor is invalid because the survivor 1943 // gets a new local reference... 1944 { 1945 CheckJniAbortCatcher check_jni_abort_catcher; 1946 EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(inner2)); 1947 check_jni_abort_catcher.Check("use of deleted local reference"); 1948 } 1949 1950 EXPECT_EQ(env_->PopLocalFrame(nullptr), nullptr); 1951 } 1952 EXPECT_EQ(JNILocalRefType, env_->GetObjectRefType(original)); 1953 CheckJniAbortCatcher check_jni_abort_catcher; 1954 EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(outer)); 1955 check_jni_abort_catcher.Check("use of deleted local reference"); 1956 EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(inner1)); 1957 check_jni_abort_catcher.Check("use of deleted local reference"); 1958 EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(inner2)); 1959 check_jni_abort_catcher.Check("use of deleted local reference"); 1960 } 1961 1962 TEST_F(JniInternalTest, PushLocalFrame_LimitAndOverflow) { 1963 // Try a very large value that should fail. 1964 ASSERT_NE(JNI_OK, env_->PushLocalFrame(std::numeric_limits<jint>::max())); 1965 ASSERT_TRUE(env_->ExceptionCheck()); 1966 env_->ExceptionClear(); 1967 1968 // On 32-bit, also check for some overflow conditions. 1969 #ifndef __LP64__ 1970 ASSERT_EQ(JNI_OK, env_->PushLocalFrame(10)); 1971 ASSERT_NE(JNI_OK, env_->PushLocalFrame(std::numeric_limits<jint>::max() - 10)); 1972 ASSERT_TRUE(env_->ExceptionCheck()); 1973 env_->ExceptionClear(); 1974 EXPECT_EQ(env_->PopLocalFrame(nullptr), nullptr); 1975 #endif 1976 } 1977 1978 TEST_F(JniInternalTest, PushLocalFrame_b62223672) { 1979 // The 512 entry limit has been lifted, try a larger value. 1980 ASSERT_EQ(JNI_OK, env_->PushLocalFrame(1024)); 1981 EXPECT_EQ(env_->PopLocalFrame(nullptr), nullptr); 1982 } 1983 1984 TEST_F(JniInternalTest, NewGlobalRef_nullptr) { 1985 EXPECT_EQ(env_->NewGlobalRef(nullptr), nullptr); 1986 } 1987 1988 TEST_F(JniInternalTest, NewGlobalRef) { 1989 jstring s = env_->NewStringUTF(""); 1990 ASSERT_NE(s, nullptr); 1991 jobject o = env_->NewGlobalRef(s); 1992 EXPECT_NE(o, nullptr); 1993 EXPECT_NE(o, s); 1994 1995 EXPECT_EQ(env_->GetObjectRefType(o), JNIGlobalRefType); 1996 } 1997 1998 TEST_F(JniInternalTest, DeleteGlobalRef_nullptr) { 1999 env_->DeleteGlobalRef(nullptr); 2000 } 2001 2002 TEST_F(JniInternalTest, DeleteGlobalRef) { 2003 // This tests leads to warnings and errors in the log. 2004 ScopedLogSeverity sls(LogSeverity::FATAL); 2005 2006 jstring s = env_->NewStringUTF(""); 2007 ASSERT_NE(s, nullptr); 2008 2009 jobject o = env_->NewGlobalRef(s); 2010 ASSERT_NE(o, nullptr); 2011 env_->DeleteGlobalRef(o); 2012 2013 // Currently, deleting an already-deleted reference is just a CheckJNI warning. 2014 { 2015 bool old_check_jni = vm_->SetCheckJniEnabled(false); 2016 { 2017 CheckJniAbortCatcher check_jni_abort_catcher; 2018 env_->DeleteGlobalRef(o); 2019 } 2020 CheckJniAbortCatcher check_jni_abort_catcher; 2021 EXPECT_FALSE(vm_->SetCheckJniEnabled(true)); 2022 env_->DeleteGlobalRef(o); 2023 std::string expected(StringPrintf("use of deleted global reference %p", o)); 2024 check_jni_abort_catcher.Check(expected.c_str()); 2025 EXPECT_TRUE(vm_->SetCheckJniEnabled(old_check_jni)); 2026 } 2027 2028 jobject o1 = env_->NewGlobalRef(s); 2029 ASSERT_NE(o1, nullptr); 2030 jobject o2 = env_->NewGlobalRef(s); 2031 ASSERT_NE(o2, nullptr); 2032 2033 env_->DeleteGlobalRef(o1); 2034 env_->DeleteGlobalRef(o2); 2035 } 2036 2037 TEST_F(JniInternalTest, NewWeakGlobalRef_nullptr) { 2038 EXPECT_EQ(env_->NewWeakGlobalRef(nullptr), nullptr); 2039 } 2040 2041 TEST_F(JniInternalTest, NewWeakGlobalRef) { 2042 jstring s = env_->NewStringUTF(""); 2043 ASSERT_NE(s, nullptr); 2044 jobject o = env_->NewWeakGlobalRef(s); 2045 EXPECT_NE(o, nullptr); 2046 EXPECT_NE(o, s); 2047 2048 EXPECT_EQ(env_->GetObjectRefType(o), JNIWeakGlobalRefType); 2049 } 2050 2051 TEST_F(JniInternalTest, DeleteWeakGlobalRef_nullptr) { 2052 env_->DeleteWeakGlobalRef(nullptr); 2053 } 2054 2055 TEST_F(JniInternalTest, DeleteWeakGlobalRef) { 2056 // This tests leads to warnings and errors in the log. 2057 ScopedLogSeverity sls(LogSeverity::FATAL); 2058 2059 jstring s = env_->NewStringUTF(""); 2060 ASSERT_NE(s, nullptr); 2061 2062 jobject o = env_->NewWeakGlobalRef(s); 2063 ASSERT_NE(o, nullptr); 2064 env_->DeleteWeakGlobalRef(o); 2065 2066 // Currently, deleting an already-deleted reference is just a CheckJNI warning. 2067 { 2068 bool old_check_jni = vm_->SetCheckJniEnabled(false); 2069 { 2070 CheckJniAbortCatcher check_jni_abort_catcher; 2071 env_->DeleteWeakGlobalRef(o); 2072 } 2073 CheckJniAbortCatcher check_jni_abort_catcher; 2074 EXPECT_FALSE(vm_->SetCheckJniEnabled(true)); 2075 env_->DeleteWeakGlobalRef(o); 2076 std::string expected(StringPrintf("use of deleted weak global reference %p", o)); 2077 check_jni_abort_catcher.Check(expected.c_str()); 2078 EXPECT_TRUE(vm_->SetCheckJniEnabled(old_check_jni)); 2079 } 2080 2081 jobject o1 = env_->NewWeakGlobalRef(s); 2082 ASSERT_NE(o1, nullptr); 2083 jobject o2 = env_->NewWeakGlobalRef(s); 2084 ASSERT_NE(o2, nullptr); 2085 2086 env_->DeleteWeakGlobalRef(o1); 2087 env_->DeleteWeakGlobalRef(o2); 2088 } 2089 2090 TEST_F(JniInternalTest, ExceptionDescribe) { 2091 // This checks how ExceptionDescribe handles call without exception. 2092 env_->ExceptionClear(); 2093 env_->ExceptionDescribe(); 2094 } 2095 2096 TEST_F(JniInternalTest, Throw) { 2097 jclass exception_class = env_->FindClass("java/lang/RuntimeException"); 2098 ASSERT_TRUE(exception_class != nullptr); 2099 jthrowable exception = reinterpret_cast<jthrowable>(env_->AllocObject(exception_class)); 2100 ASSERT_TRUE(exception != nullptr); 2101 2102 EXPECT_EQ(JNI_OK, env_->Throw(exception)); 2103 EXPECT_TRUE(env_->ExceptionCheck()); 2104 jthrowable thrown_exception = env_->ExceptionOccurred(); 2105 env_->ExceptionClear(); 2106 EXPECT_TRUE(env_->IsSameObject(exception, thrown_exception)); 2107 2108 // Bad argument. 2109 bool old_check_jni = vm_->SetCheckJniEnabled(false); 2110 EXPECT_EQ(JNI_ERR, env_->Throw(nullptr)); 2111 EXPECT_FALSE(vm_->SetCheckJniEnabled(true)); 2112 CheckJniAbortCatcher check_jni_abort_catcher; 2113 EXPECT_EQ(JNI_ERR, env_->Throw(nullptr)); 2114 check_jni_abort_catcher.Check("Throw received NULL jthrowable"); 2115 EXPECT_TRUE(vm_->SetCheckJniEnabled(old_check_jni)); 2116 } 2117 2118 TEST_F(JniInternalTest, ThrowNew) { 2119 jclass exception_class = env_->FindClass("java/lang/RuntimeException"); 2120 ASSERT_TRUE(exception_class != nullptr); 2121 2122 jthrowable thrown_exception; 2123 2124 EXPECT_EQ(JNI_OK, env_->ThrowNew(exception_class, "hello world")); 2125 EXPECT_TRUE(env_->ExceptionCheck()); 2126 thrown_exception = env_->ExceptionOccurred(); 2127 env_->ExceptionClear(); 2128 EXPECT_TRUE(env_->IsInstanceOf(thrown_exception, exception_class)); 2129 2130 EXPECT_EQ(JNI_OK, env_->ThrowNew(exception_class, nullptr)); 2131 EXPECT_TRUE(env_->ExceptionCheck()); 2132 thrown_exception = env_->ExceptionOccurred(); 2133 env_->ExceptionClear(); 2134 EXPECT_TRUE(env_->IsInstanceOf(thrown_exception, exception_class)); 2135 2136 // Bad argument. 2137 bool old_check_jni = vm_->SetCheckJniEnabled(false); 2138 CheckJniAbortCatcher check_jni_abort_catcher; 2139 EXPECT_EQ(JNI_ERR, env_->ThrowNew(nullptr, nullptr)); 2140 check_jni_abort_catcher.Check("c == null"); 2141 EXPECT_FALSE(vm_->SetCheckJniEnabled(true)); 2142 EXPECT_EQ(JNI_ERR, env_->ThrowNew(nullptr, nullptr)); 2143 check_jni_abort_catcher.Check("ThrowNew received NULL jclass"); 2144 EXPECT_TRUE(vm_->SetCheckJniEnabled(old_check_jni)); 2145 } 2146 2147 TEST_F(JniInternalTest, NewDirectBuffer_GetDirectBufferAddress_GetDirectBufferCapacity) { 2148 // Start runtime. 2149 Thread* self = Thread::Current(); 2150 self->TransitionFromSuspendedToRunnable(); 2151 MakeExecutable(nullptr, "java.lang.Class"); 2152 MakeExecutable(nullptr, "java.lang.Object"); 2153 MakeExecutable(nullptr, "java.nio.DirectByteBuffer"); 2154 MakeExecutable(nullptr, "java.nio.Bits"); 2155 MakeExecutable(nullptr, "java.nio.MappedByteBuffer"); 2156 MakeExecutable(nullptr, "java.nio.ByteBuffer"); 2157 MakeExecutable(nullptr, "java.nio.Buffer"); 2158 // TODO: we only load a dex file here as starting the runtime relies upon it. 2159 const char* class_name = "StaticLeafMethods"; 2160 LoadDex(class_name); 2161 bool started = runtime_->Start(); 2162 ASSERT_TRUE(started); 2163 2164 jclass buffer_class = env_->FindClass("java/nio/Buffer"); 2165 ASSERT_NE(buffer_class, nullptr); 2166 2167 char bytes[1024]; 2168 jobject buffer = env_->NewDirectByteBuffer(bytes, sizeof(bytes)); 2169 ASSERT_NE(buffer, nullptr); 2170 ASSERT_TRUE(env_->IsInstanceOf(buffer, buffer_class)); 2171 ASSERT_EQ(env_->GetDirectBufferAddress(buffer), bytes); 2172 ASSERT_EQ(env_->GetDirectBufferCapacity(buffer), static_cast<jlong>(sizeof(bytes))); 2173 2174 { 2175 CheckJniAbortCatcher check_jni_abort_catcher; 2176 env_->NewDirectByteBuffer(bytes, static_cast<jlong>(INT_MAX) + 1); 2177 check_jni_abort_catcher.Check("in call to NewDirectByteBuffer"); 2178 } 2179 } 2180 2181 TEST_F(JniInternalTest, MonitorEnterExit) { 2182 // This will print some error messages. Suppress. 2183 ScopedLogSeverity sls(LogSeverity::FATAL); 2184 2185 // Create an object to torture. 2186 jclass object_class = env_->FindClass("java/lang/Object"); 2187 ASSERT_NE(object_class, nullptr); 2188 jobject object = env_->AllocObject(object_class); 2189 ASSERT_NE(object, nullptr); 2190 2191 // Expected class of exceptions 2192 jclass imse_class = env_->FindClass("java/lang/IllegalMonitorStateException"); 2193 ASSERT_NE(imse_class, nullptr); 2194 2195 jthrowable thrown_exception; 2196 2197 // Unlock of unowned monitor 2198 env_->MonitorExit(object); 2199 EXPECT_TRUE(env_->ExceptionCheck()); 2200 thrown_exception = env_->ExceptionOccurred(); 2201 env_->ExceptionClear(); 2202 EXPECT_TRUE(env_->IsInstanceOf(thrown_exception, imse_class)); 2203 2204 // Lock of unowned monitor 2205 env_->MonitorEnter(object); 2206 EXPECT_FALSE(env_->ExceptionCheck()); 2207 // Regular unlock 2208 env_->MonitorExit(object); 2209 EXPECT_FALSE(env_->ExceptionCheck()); 2210 2211 // Recursively lock a lot 2212 size_t max_recursive_lock = 1024; 2213 for (size_t i = 0; i < max_recursive_lock; i++) { 2214 env_->MonitorEnter(object); 2215 EXPECT_FALSE(env_->ExceptionCheck()); 2216 } 2217 // Recursively unlock a lot 2218 for (size_t i = 0; i < max_recursive_lock; i++) { 2219 env_->MonitorExit(object); 2220 EXPECT_FALSE(env_->ExceptionCheck()); 2221 } 2222 2223 // Unlock of unowned monitor 2224 env_->MonitorExit(object); 2225 EXPECT_TRUE(env_->ExceptionCheck()); 2226 thrown_exception = env_->ExceptionOccurred(); 2227 env_->ExceptionClear(); 2228 EXPECT_TRUE(env_->IsInstanceOf(thrown_exception, imse_class)); 2229 2230 // It's an error to call MonitorEnter or MonitorExit on null. 2231 { 2232 CheckJniAbortCatcher check_jni_abort_catcher; 2233 env_->MonitorEnter(nullptr); 2234 check_jni_abort_catcher.Check("in call to MonitorEnter"); 2235 env_->MonitorExit(nullptr); 2236 check_jni_abort_catcher.Check("in call to MonitorExit"); 2237 } 2238 } 2239 2240 void Java_MyClassNatives_foo_exit(JNIEnv* env, jobject thisObj) { 2241 // Release the monitor on self. This should trigger an abort. 2242 env->MonitorExit(thisObj); 2243 } 2244 2245 TEST_F(JniInternalTest, MonitorExitLockedInDifferentCall) { 2246 SetUpForTest(false, "foo", "()V", reinterpret_cast<void*>(&Java_MyClassNatives_foo_exit)); 2247 ASSERT_NE(jobj_, nullptr); 2248 2249 env_->MonitorEnter(jobj_); 2250 EXPECT_FALSE(env_->ExceptionCheck()); 2251 2252 CheckJniAbortCatcher check_jni_abort_catcher; 2253 env_->CallNonvirtualVoidMethod(jobj_, jklass_, jmethod_); 2254 check_jni_abort_catcher.Check("Unlocking monitor that wasn't locked here"); 2255 } 2256 2257 void Java_MyClassNatives_foo_enter_no_exit(JNIEnv* env, jobject thisObj) { 2258 // Acquire but don't release the monitor on self. This should trigger an abort on return. 2259 env->MonitorEnter(thisObj); 2260 } 2261 2262 TEST_F(JniInternalTest, MonitorExitNotAllUnlocked) { 2263 SetUpForTest(false, 2264 "foo", 2265 "()V", 2266 reinterpret_cast<void*>(&Java_MyClassNatives_foo_enter_no_exit)); 2267 ASSERT_NE(jobj_, nullptr); 2268 2269 CheckJniAbortCatcher check_jni_abort_catcher; 2270 env_->CallNonvirtualVoidMethod(jobj_, jklass_, jmethod_); 2271 check_jni_abort_catcher.Check("Still holding a locked object on JNI end"); 2272 } 2273 2274 static bool IsLocked(JNIEnv* env, jobject jobj) { 2275 ScopedObjectAccess soa(env); 2276 LockWord lock_word = soa.Decode<mirror::Object>(jobj)->GetLockWord(true); 2277 switch (lock_word.GetState()) { 2278 case LockWord::kHashCode: 2279 case LockWord::kUnlocked: 2280 return false; 2281 case LockWord::kThinLocked: 2282 return true; 2283 case LockWord::kFatLocked: 2284 return lock_word.FatLockMonitor()->IsLocked(); 2285 default: { 2286 LOG(FATAL) << "Invalid monitor state " << lock_word.GetState(); 2287 UNREACHABLE(); 2288 } 2289 } 2290 } 2291 2292 TEST_F(JniInternalTest, DetachThreadUnlockJNIMonitors) { 2293 // We need to lock an object, detach, reattach, and check the locks. 2294 // 2295 // As re-attaching will create a different thread, we need to use a global 2296 // ref to keep the object around. 2297 2298 // Create an object to torture. 2299 jobject global_ref; 2300 { 2301 jclass object_class = env_->FindClass("java/lang/Object"); 2302 ASSERT_NE(object_class, nullptr); 2303 jobject object = env_->AllocObject(object_class); 2304 ASSERT_NE(object, nullptr); 2305 global_ref = env_->NewGlobalRef(object); 2306 } 2307 2308 // Lock it. 2309 env_->MonitorEnter(global_ref); 2310 ASSERT_TRUE(IsLocked(env_, global_ref)); 2311 2312 // Detach and re-attach. 2313 jint detach_result = vm_->DetachCurrentThread(); 2314 ASSERT_EQ(detach_result, JNI_OK); 2315 jint attach_result = vm_->AttachCurrentThread(&env_, nullptr); 2316 ASSERT_EQ(attach_result, JNI_OK); 2317 2318 // Look at the global ref, check whether it's still locked. 2319 ASSERT_FALSE(IsLocked(env_, global_ref)); 2320 2321 // Delete the global ref. 2322 env_->DeleteGlobalRef(global_ref); 2323 } 2324 2325 // Test the offset computation of IndirectReferenceTable offsets. b/26071368. 2326 TEST_F(JniInternalTest, IndirectReferenceTableOffsets) { 2327 // The segment_state_ field is private, and we want to avoid friend declaration. So we'll check 2328 // by modifying memory. 2329 // The parameters don't really matter here. 2330 std::string error_msg; 2331 IndirectReferenceTable irt(5, 2332 IndirectRefKind::kGlobal, 2333 IndirectReferenceTable::ResizableCapacity::kNo, 2334 &error_msg); 2335 ASSERT_TRUE(irt.IsValid()) << error_msg; 2336 IRTSegmentState old_state = irt.GetSegmentState(); 2337 2338 // Write some new state directly. We invert parts of old_state to ensure a new value. 2339 IRTSegmentState new_state; 2340 new_state.top_index = old_state.top_index ^ 0x07705005; 2341 ASSERT_NE(old_state.top_index, new_state.top_index); 2342 2343 uint8_t* base = reinterpret_cast<uint8_t*>(&irt); 2344 int32_t segment_state_offset = 2345 IndirectReferenceTable::SegmentStateOffset(sizeof(void*)).Int32Value(); 2346 *reinterpret_cast<IRTSegmentState*>(base + segment_state_offset) = new_state; 2347 2348 // Read and compare. 2349 EXPECT_EQ(new_state.top_index, irt.GetSegmentState().top_index); 2350 } 2351 2352 // Test the offset computation of JNIEnvExt offsets. b/26071368. 2353 TEST_F(JniInternalTest, JNIEnvExtOffsets) { 2354 EXPECT_EQ(OFFSETOF_MEMBER(JNIEnvExt, local_ref_cookie), 2355 JNIEnvExt::LocalRefCookieOffset(sizeof(void*)).Uint32Value()); 2356 2357 EXPECT_EQ(OFFSETOF_MEMBER(JNIEnvExt, self), JNIEnvExt::SelfOffset(sizeof(void*)).Uint32Value()); 2358 2359 // segment_state_ is private in the IndirectReferenceTable. So this test isn't as good as we'd 2360 // hope it to be. 2361 uint32_t segment_state_now = 2362 OFFSETOF_MEMBER(JNIEnvExt, locals) + 2363 IndirectReferenceTable::SegmentStateOffset(sizeof(void*)).Uint32Value(); 2364 uint32_t segment_state_computed = JNIEnvExt::SegmentStateOffset(sizeof(void*)).Uint32Value(); 2365 EXPECT_EQ(segment_state_now, segment_state_computed); 2366 } 2367 2368 static size_t gGlobalRefCount = 0; 2369 static const JNINativeInterface* gOriginalEnv = nullptr; 2370 2371 static jobject CountNewGlobalRef(JNIEnv* env, jobject o) { 2372 ++gGlobalRefCount; 2373 return gOriginalEnv->NewGlobalRef(env, o); 2374 } 2375 2376 // Test the table override. 2377 TEST_F(JniInternalTest, JNIEnvExtTableOverride) { 2378 JNINativeInterface env_override; 2379 memcpy(&env_override, env_->functions, sizeof(JNINativeInterface)); 2380 2381 gOriginalEnv = env_->functions; 2382 env_override.NewGlobalRef = CountNewGlobalRef; 2383 gGlobalRefCount = 0; 2384 2385 jclass local = env_->FindClass("java/lang/Object"); 2386 ASSERT_TRUE(local != nullptr); 2387 2388 // Set the table, add a global ref, see whether the counter increases. 2389 JNIEnvExt::SetTableOverride(&env_override); 2390 2391 jobject global = env_->NewGlobalRef(local); 2392 EXPECT_EQ(1u, gGlobalRefCount); 2393 env_->DeleteGlobalRef(global); 2394 2395 // Reset 2396 JNIEnvExt::SetTableOverride(nullptr); 2397 2398 jobject global2 = env_->NewGlobalRef(local); 2399 EXPECT_EQ(1u, gGlobalRefCount); 2400 env_->DeleteGlobalRef(global2); 2401 } 2402 2403 } // namespace art 2404