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