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 "common_compiler_test.h" 20 #include "mirror/art_method-inl.h" 21 #include "mirror/string-inl.h" 22 #include "scoped_thread_state_change.h" 23 #include "ScopedLocalRef.h" 24 25 namespace art { 26 27 // TODO: Convert to CommonRuntimeTest. Currently MakeExecutable is used. 28 class JniInternalTest : public CommonCompilerTest { 29 protected: 30 virtual void SetUp() { 31 CommonCompilerTest::SetUp(); 32 33 vm_ = Runtime::Current()->GetJavaVM(); 34 35 // Turn on -verbose:jni for the JNI tests. 36 // gLogVerbosity.jni = true; 37 38 vm_->AttachCurrentThread(&env_, nullptr); 39 40 ScopedLocalRef<jclass> aioobe(env_, 41 env_->FindClass("java/lang/ArrayIndexOutOfBoundsException")); 42 CHECK(aioobe.get() != nullptr); 43 aioobe_ = reinterpret_cast<jclass>(env_->NewGlobalRef(aioobe.get())); 44 45 ScopedLocalRef<jclass> ase(env_, env_->FindClass("java/lang/ArrayStoreException")); 46 CHECK(ase.get() != nullptr); 47 ase_ = reinterpret_cast<jclass>(env_->NewGlobalRef(ase.get())); 48 49 ScopedLocalRef<jclass> sioobe(env_, 50 env_->FindClass("java/lang/StringIndexOutOfBoundsException")); 51 CHECK(sioobe.get() != nullptr); 52 sioobe_ = reinterpret_cast<jclass>(env_->NewGlobalRef(sioobe.get())); 53 } 54 55 void ExpectException(jclass exception_class) { 56 EXPECT_TRUE(env_->ExceptionCheck()); 57 jthrowable exception = env_->ExceptionOccurred(); 58 EXPECT_NE(nullptr, exception); 59 env_->ExceptionClear(); 60 EXPECT_TRUE(env_->IsInstanceOf(exception, exception_class)); 61 } 62 63 void ExpectClassFound(const char* name) { 64 EXPECT_NE(env_->FindClass(name), nullptr) << name; 65 EXPECT_FALSE(env_->ExceptionCheck()) << name; 66 } 67 68 void ExpectClassNotFound(const char* name) { 69 EXPECT_EQ(env_->FindClass(name), nullptr) << name; 70 EXPECT_TRUE(env_->ExceptionCheck()) << name; 71 env_->ExceptionClear(); 72 } 73 74 void CleanUpJniEnv() { 75 if (aioobe_ != nullptr) { 76 env_->DeleteGlobalRef(aioobe_); 77 aioobe_ = nullptr; 78 } 79 if (ase_ != nullptr) { 80 env_->DeleteGlobalRef(ase_); 81 ase_ = nullptr; 82 } 83 if (sioobe_ != nullptr) { 84 env_->DeleteGlobalRef(sioobe_); 85 sioobe_ = nullptr; 86 } 87 } 88 89 virtual void TearDown() OVERRIDE { 90 CleanUpJniEnv(); 91 CommonCompilerTest::TearDown(); 92 } 93 94 jclass GetPrimitiveClass(char descriptor) { 95 ScopedObjectAccess soa(env_); 96 mirror::Class* c = class_linker_->FindPrimitiveClass(descriptor); 97 CHECK(c != nullptr); 98 return soa.AddLocalReference<jclass>(c); 99 } 100 101 JavaVMExt* vm_; 102 JNIEnv* env_; 103 jclass aioobe_; 104 jclass ase_; 105 jclass sioobe_; 106 }; 107 108 TEST_F(JniInternalTest, AllocObject) { 109 jclass c = env_->FindClass("java/lang/String"); 110 ASSERT_NE(c, nullptr); 111 jobject o = env_->AllocObject(c); 112 ASSERT_NE(o, nullptr); 113 114 // We have an instance of the class we asked for... 115 ASSERT_TRUE(env_->IsInstanceOf(o, c)); 116 // ...whose fields haven't been initialized because 117 // we didn't call a constructor. 118 ASSERT_EQ(0, env_->GetIntField(o, env_->GetFieldID(c, "count", "I"))); 119 ASSERT_EQ(0, env_->GetIntField(o, env_->GetFieldID(c, "offset", "I"))); 120 ASSERT_TRUE(env_->GetObjectField(o, env_->GetFieldID(c, "value", "[C")) == nullptr); 121 } 122 123 TEST_F(JniInternalTest, GetVersion) { 124 ASSERT_EQ(JNI_VERSION_1_6, env_->GetVersion()); 125 } 126 127 TEST_F(JniInternalTest, FindClass) { 128 // Reference types... 129 ExpectClassFound("java/lang/String"); 130 // ...for arrays too, where you must include "L;". 131 ExpectClassFound("[Ljava/lang/String;"); 132 // Primitive arrays are okay too, if the primitive type is valid. 133 ExpectClassFound("[C"); 134 135 { 136 CheckJniAbortCatcher check_jni_abort_catcher; 137 env_->FindClass(nullptr); 138 check_jni_abort_catcher.Check("name == null"); 139 140 // We support . as well as / for compatibility, if -Xcheck:jni is off. 141 ExpectClassFound("java.lang.String"); 142 check_jni_abort_catcher.Check("illegal class name 'java.lang.String'"); 143 ExpectClassNotFound("Ljava.lang.String;"); 144 check_jni_abort_catcher.Check("illegal class name 'Ljava.lang.String;'"); 145 ExpectClassFound("[Ljava.lang.String;"); 146 check_jni_abort_catcher.Check("illegal class name '[Ljava.lang.String;'"); 147 ExpectClassNotFound("[java.lang.String"); 148 check_jni_abort_catcher.Check("illegal class name '[java.lang.String'"); 149 150 // You can't include the "L;" in a JNI class descriptor. 151 ExpectClassNotFound("Ljava/lang/String;"); 152 check_jni_abort_catcher.Check("illegal class name 'Ljava/lang/String;'"); 153 154 // But you must include it for an array of any reference type. 155 ExpectClassNotFound("[java/lang/String"); 156 check_jni_abort_catcher.Check("illegal class name '[java/lang/String'"); 157 158 ExpectClassNotFound("[K"); 159 check_jni_abort_catcher.Check("illegal class name '[K'"); 160 161 // Void arrays aren't allowed. 162 ExpectClassNotFound("[V"); 163 check_jni_abort_catcher.Check("illegal class name '[V'"); 164 } 165 166 // But primitive types aren't allowed... 167 ExpectClassNotFound("C"); 168 ExpectClassNotFound("V"); 169 ExpectClassNotFound("K"); 170 } 171 172 TEST_F(JniInternalTest, GetFieldID) { 173 jclass jlnsfe = env_->FindClass("java/lang/NoSuchFieldError"); 174 ASSERT_NE(jlnsfe, nullptr); 175 jclass c = env_->FindClass("java/lang/String"); 176 ASSERT_NE(c, nullptr); 177 178 // Wrong type. 179 jfieldID fid = env_->GetFieldID(c, "count", "J"); 180 EXPECT_EQ(nullptr, fid); 181 ExpectException(jlnsfe); 182 183 // Wrong type where type doesn't exist. 184 fid = env_->GetFieldID(c, "count", "Lrod/jane/freddy;"); 185 EXPECT_EQ(nullptr, fid); 186 ExpectException(jlnsfe); 187 188 // Wrong name. 189 fid = env_->GetFieldID(c, "Count", "I"); 190 EXPECT_EQ(nullptr, fid); 191 ExpectException(jlnsfe); 192 193 // Good declared field lookup. 194 fid = env_->GetFieldID(c, "count", "I"); 195 EXPECT_NE(nullptr, fid); 196 EXPECT_FALSE(env_->ExceptionCheck()); 197 198 // Good superclass field lookup. 199 c = env_->FindClass("java/lang/StringBuilder"); 200 fid = env_->GetFieldID(c, "count", "I"); 201 EXPECT_NE(nullptr, fid); 202 EXPECT_NE(fid, nullptr); 203 EXPECT_FALSE(env_->ExceptionCheck()); 204 205 // Not instance. 206 fid = env_->GetFieldID(c, "CASE_INSENSITIVE_ORDER", "Ljava/util/Comparator;"); 207 EXPECT_EQ(nullptr, fid); 208 ExpectException(jlnsfe); 209 210 // Bad arguments. 211 CheckJniAbortCatcher check_jni_abort_catcher; 212 fid = env_->GetFieldID(nullptr, "count", "I"); 213 EXPECT_EQ(nullptr, fid); 214 check_jni_abort_catcher.Check("java_class == null"); 215 fid = env_->GetFieldID(c, nullptr, "I"); 216 EXPECT_EQ(nullptr, fid); 217 check_jni_abort_catcher.Check("name == null"); 218 fid = env_->GetFieldID(c, "count", nullptr); 219 EXPECT_EQ(nullptr, fid); 220 check_jni_abort_catcher.Check("sig == null"); 221 } 222 223 TEST_F(JniInternalTest, GetStaticFieldID) { 224 jclass jlnsfe = env_->FindClass("java/lang/NoSuchFieldError"); 225 ASSERT_NE(jlnsfe, nullptr); 226 jclass c = env_->FindClass("java/lang/String"); 227 ASSERT_NE(c, nullptr); 228 229 // Wrong type. 230 jfieldID fid = env_->GetStaticFieldID(c, "CASE_INSENSITIVE_ORDER", "J"); 231 EXPECT_EQ(nullptr, fid); 232 ExpectException(jlnsfe); 233 234 // Wrong type where type doesn't exist. 235 fid = env_->GetStaticFieldID(c, "CASE_INSENSITIVE_ORDER", "Lrod/jane/freddy;"); 236 EXPECT_EQ(nullptr, fid); 237 ExpectException(jlnsfe); 238 239 // Wrong name. 240 fid = env_->GetStaticFieldID(c, "cASE_INSENSITIVE_ORDER", "Ljava/util/Comparator;"); 241 EXPECT_EQ(nullptr, fid); 242 ExpectException(jlnsfe); 243 244 // Good declared field lookup. 245 fid = env_->GetStaticFieldID(c, "CASE_INSENSITIVE_ORDER", "Ljava/util/Comparator;"); 246 EXPECT_NE(nullptr, fid); 247 EXPECT_NE(fid, nullptr); 248 EXPECT_FALSE(env_->ExceptionCheck()); 249 250 // Not static. 251 fid = env_->GetStaticFieldID(c, "count", "I"); 252 EXPECT_EQ(nullptr, fid); 253 ExpectException(jlnsfe); 254 255 // Bad arguments. 256 CheckJniAbortCatcher check_jni_abort_catcher; 257 fid = env_->GetStaticFieldID(nullptr, "CASE_INSENSITIVE_ORDER", "Ljava/util/Comparator;"); 258 EXPECT_EQ(nullptr, fid); 259 check_jni_abort_catcher.Check("java_class == null"); 260 fid = env_->GetStaticFieldID(c, nullptr, "Ljava/util/Comparator;"); 261 EXPECT_EQ(nullptr, fid); 262 check_jni_abort_catcher.Check("name == null"); 263 fid = env_->GetStaticFieldID(c, "CASE_INSENSITIVE_ORDER", nullptr); 264 EXPECT_EQ(nullptr, fid); 265 check_jni_abort_catcher.Check("sig == null"); 266 } 267 268 TEST_F(JniInternalTest, GetMethodID) { 269 jclass jlobject = env_->FindClass("java/lang/Object"); 270 jclass jlstring = env_->FindClass("java/lang/String"); 271 jclass jlnsme = env_->FindClass("java/lang/NoSuchMethodError"); 272 jclass jncrbc = env_->FindClass("java/nio/channels/ReadableByteChannel"); 273 274 // Sanity check that no exceptions are pending. 275 ASSERT_FALSE(env_->ExceptionCheck()); 276 277 // Check that java.lang.Object.foo() doesn't exist and NoSuchMethodError is 278 // a pending exception. 279 jmethodID method = env_->GetMethodID(jlobject, "foo", "()V"); 280 EXPECT_EQ(nullptr, method); 281 ExpectException(jlnsme); 282 283 // Check that java.lang.Object.equals() does exist. 284 method = env_->GetMethodID(jlobject, "equals", "(Ljava/lang/Object;)Z"); 285 EXPECT_NE(nullptr, method); 286 EXPECT_FALSE(env_->ExceptionCheck()); 287 288 // Check that GetMethodID for java.lang.String.valueOf(int) fails as the 289 // method is static. 290 method = env_->GetMethodID(jlstring, "valueOf", "(I)Ljava/lang/String;"); 291 EXPECT_EQ(nullptr, method); 292 ExpectException(jlnsme); 293 294 // Check that GetMethodID for java.lang.NoSuchMethodError.<init>(String) finds the constructor. 295 method = env_->GetMethodID(jlnsme, "<init>", "(Ljava/lang/String;)V"); 296 EXPECT_NE(nullptr, method); 297 EXPECT_FALSE(env_->ExceptionCheck()); 298 299 // Check that GetMethodID can find a interface method inherited from another interface. 300 method = env_->GetMethodID(jncrbc, "close", "()V"); 301 EXPECT_NE(nullptr, method); 302 EXPECT_FALSE(env_->ExceptionCheck()); 303 304 // Bad arguments. 305 CheckJniAbortCatcher check_jni_abort_catcher; 306 method = env_->GetMethodID(nullptr, "<init>", "(Ljava/lang/String;)V"); 307 EXPECT_EQ(nullptr, method); 308 check_jni_abort_catcher.Check("java_class == null"); 309 method = env_->GetMethodID(jlnsme, nullptr, "(Ljava/lang/String;)V"); 310 EXPECT_EQ(nullptr, method); 311 check_jni_abort_catcher.Check("name == null"); 312 method = env_->GetMethodID(jlnsme, "<init>", nullptr); 313 EXPECT_EQ(nullptr, method); 314 check_jni_abort_catcher.Check("sig == null"); 315 } 316 317 TEST_F(JniInternalTest, CallVoidMethodNullReceiver) { 318 jclass jlobject = env_->FindClass("java/lang/Object"); 319 jmethodID method; 320 321 // Check that GetMethodID for java.lang.NoSuchMethodError.<init>(String) finds the constructor. 322 method = env_->GetMethodID(jlobject, "<init>", "()V"); 323 EXPECT_NE(nullptr, method); 324 EXPECT_FALSE(env_->ExceptionCheck()); 325 326 // Null object to CallVoidMethod. 327 CheckJniAbortCatcher check_jni_abort_catcher; 328 method = env_->GetMethodID(nullptr, "<init>", "(Ljava/lang/String;)V"); 329 env_->CallVoidMethod(nullptr, method); 330 check_jni_abort_catcher.Check("null"); 331 } 332 333 TEST_F(JniInternalTest, GetStaticMethodID) { 334 jclass jlobject = env_->FindClass("java/lang/Object"); 335 jclass jlnsme = env_->FindClass("java/lang/NoSuchMethodError"); 336 337 // Sanity check that no exceptions are pending 338 ASSERT_FALSE(env_->ExceptionCheck()); 339 340 // Check that java.lang.Object.foo() doesn't exist and NoSuchMethodError is 341 // a pending exception 342 jmethodID method = env_->GetStaticMethodID(jlobject, "foo", "()V"); 343 EXPECT_EQ(nullptr, method); 344 ExpectException(jlnsme); 345 346 // Check that GetStaticMethodID for java.lang.Object.equals(Object) fails as 347 // the method is not static 348 method = env_->GetStaticMethodID(jlobject, "equals", "(Ljava/lang/Object;)Z"); 349 EXPECT_EQ(nullptr, method); 350 ExpectException(jlnsme); 351 352 // Check that java.lang.String.valueOf(int) does exist 353 jclass jlstring = env_->FindClass("java/lang/String"); 354 method = env_->GetStaticMethodID(jlstring, "valueOf", "(I)Ljava/lang/String;"); 355 EXPECT_NE(nullptr, method); 356 EXPECT_FALSE(env_->ExceptionCheck()); 357 358 // Bad arguments. 359 CheckJniAbortCatcher check_jni_abort_catcher; 360 method = env_->GetStaticMethodID(nullptr, "valueOf", "(I)Ljava/lang/String;"); 361 EXPECT_EQ(nullptr, method); 362 check_jni_abort_catcher.Check("java_class == null"); 363 method = env_->GetStaticMethodID(jlstring, nullptr, "(I)Ljava/lang/String;"); 364 EXPECT_EQ(nullptr, method); 365 check_jni_abort_catcher.Check("name == null"); 366 method = env_->GetStaticMethodID(jlstring, "valueOf", nullptr); 367 EXPECT_EQ(nullptr, method); 368 check_jni_abort_catcher.Check("sig == null"); 369 } 370 371 TEST_F(JniInternalTest, FromReflectedField_ToReflectedField) { 372 jclass jlrField = env_->FindClass("java/lang/reflect/Field"); 373 jclass c = env_->FindClass("java/lang/String"); 374 ASSERT_NE(c, nullptr); 375 jfieldID fid = env_->GetFieldID(c, "count", "I"); 376 ASSERT_NE(fid, nullptr); 377 // Turn the fid into a java.lang.reflect.Field... 378 jobject field = env_->ToReflectedField(c, fid, JNI_FALSE); 379 for (size_t i = 0; i <= 512; ++i) { 380 // Regression test for b/18396311, ToReflectedField leaking local refs causing a local 381 // reference table overflows with 512 references to ArtField 382 env_->DeleteLocalRef(env_->ToReflectedField(c, fid, JNI_FALSE)); 383 } 384 ASSERT_NE(c, nullptr); 385 ASSERT_TRUE(env_->IsInstanceOf(field, jlrField)); 386 // ...and back again. 387 jfieldID fid2 = env_->FromReflectedField(field); 388 ASSERT_NE(fid2, nullptr); 389 // Make sure we can actually use it. 390 jstring s = env_->NewStringUTF("poop"); 391 ASSERT_EQ(4, env_->GetIntField(s, fid2)); 392 393 // Bad arguments. 394 CheckJniAbortCatcher check_jni_abort_catcher; 395 field = env_->ToReflectedField(c, nullptr, JNI_FALSE); 396 EXPECT_EQ(field, nullptr); 397 check_jni_abort_catcher.Check("fid == null"); 398 fid2 = env_->FromReflectedField(nullptr); 399 ASSERT_EQ(fid2, nullptr); 400 check_jni_abort_catcher.Check("jlr_field == null"); 401 } 402 403 TEST_F(JniInternalTest, FromReflectedMethod_ToReflectedMethod) { 404 jclass jlrMethod = env_->FindClass("java/lang/reflect/Method"); 405 ASSERT_NE(jlrMethod, nullptr); 406 jclass jlrConstructor = env_->FindClass("java/lang/reflect/Constructor"); 407 ASSERT_NE(jlrConstructor, nullptr); 408 jclass c = env_->FindClass("java/lang/String"); 409 ASSERT_NE(c, nullptr); 410 411 jmethodID mid = env_->GetMethodID(c, "<init>", "()V"); 412 ASSERT_NE(mid, nullptr); 413 // Turn the mid into a java.lang.reflect.Constructor... 414 jobject method = env_->ToReflectedMethod(c, mid, JNI_FALSE); 415 for (size_t i = 0; i <= 512; ++i) { 416 // Regression test for b/18396311, ToReflectedMethod leaking local refs causing a local 417 // reference table overflows with 512 references to ArtMethod 418 env_->DeleteLocalRef(env_->ToReflectedMethod(c, mid, JNI_FALSE)); 419 } 420 ASSERT_NE(method, nullptr); 421 ASSERT_TRUE(env_->IsInstanceOf(method, jlrConstructor)); 422 // ...and back again. 423 jmethodID mid2 = env_->FromReflectedMethod(method); 424 ASSERT_NE(mid2, nullptr); 425 // Make sure we can actually use it. 426 jstring s = reinterpret_cast<jstring>(env_->AllocObject(c)); 427 ASSERT_NE(s, nullptr); 428 env_->CallVoidMethod(s, mid2); 429 ASSERT_EQ(JNI_FALSE, env_->ExceptionCheck()); 430 431 mid = env_->GetMethodID(c, "length", "()I"); 432 ASSERT_NE(mid, nullptr); 433 // Turn the mid into a java.lang.reflect.Method... 434 method = env_->ToReflectedMethod(c, mid, JNI_FALSE); 435 ASSERT_NE(method, nullptr); 436 ASSERT_TRUE(env_->IsInstanceOf(method, jlrMethod)); 437 // ...and back again. 438 mid2 = env_->FromReflectedMethod(method); 439 ASSERT_NE(mid2, nullptr); 440 // Make sure we can actually use it. 441 s = env_->NewStringUTF("poop"); 442 ASSERT_NE(s, nullptr); 443 ASSERT_EQ(4, env_->CallIntMethod(s, mid2)); 444 445 // Bad arguments. 446 CheckJniAbortCatcher check_jni_abort_catcher; 447 method = env_->ToReflectedMethod(c, nullptr, JNI_FALSE); 448 EXPECT_EQ(method, nullptr); 449 check_jni_abort_catcher.Check("mid == null"); 450 mid2 = env_->FromReflectedMethod(method); 451 ASSERT_EQ(mid2, nullptr); 452 check_jni_abort_catcher.Check("jlr_method == null"); 453 } 454 455 static void BogusMethod() { 456 // You can't pass nullptr function pointers to RegisterNatives. 457 } 458 459 TEST_F(JniInternalTest, RegisterAndUnregisterNatives) { 460 jclass jlobject = env_->FindClass("java/lang/Object"); 461 jclass jlnsme = env_->FindClass("java/lang/NoSuchMethodError"); 462 void* native_function = reinterpret_cast<void*>(BogusMethod); 463 464 // Sanity check that no exceptions are pending. 465 ASSERT_FALSE(env_->ExceptionCheck()); 466 467 // Check that registering method without name causes a NoSuchMethodError. 468 { 469 JNINativeMethod methods[] = { { nullptr, "()V", native_function } }; 470 EXPECT_EQ(env_->RegisterNatives(jlobject, methods, 1), JNI_ERR); 471 } 472 ExpectException(jlnsme); 473 474 // Check that registering method without signature causes a NoSuchMethodError. 475 { 476 JNINativeMethod methods[] = { { "notify", nullptr, native_function } }; 477 EXPECT_EQ(env_->RegisterNatives(jlobject, methods, 1), JNI_ERR); 478 } 479 ExpectException(jlnsme); 480 481 // Check that registering method without function causes a NoSuchMethodError. 482 { 483 JNINativeMethod methods[] = { { "notify", "()V", nullptr } }; 484 EXPECT_EQ(env_->RegisterNatives(jlobject, methods, 1), JNI_ERR); 485 } 486 ExpectException(jlnsme); 487 488 // Check that registering to a non-existent java.lang.Object.foo() causes a NoSuchMethodError. 489 { 490 JNINativeMethod methods[] = { { "foo", "()V", native_function } }; 491 EXPECT_EQ(env_->RegisterNatives(jlobject, methods, 1), JNI_ERR); 492 } 493 ExpectException(jlnsme); 494 495 // Check that registering non-native methods causes a NoSuchMethodError. 496 { 497 JNINativeMethod methods[] = { { "equals", "(Ljava/lang/Object;)Z", native_function } }; 498 EXPECT_EQ(env_->RegisterNatives(jlobject, methods, 1), JNI_ERR); 499 } 500 ExpectException(jlnsme); 501 502 // Check that registering native methods is successful. 503 { 504 JNINativeMethod methods[] = { { "notify", "()V", native_function } }; 505 EXPECT_EQ(env_->RegisterNatives(jlobject, methods, 1), JNI_OK); 506 } 507 EXPECT_FALSE(env_->ExceptionCheck()); 508 EXPECT_EQ(env_->UnregisterNatives(jlobject), JNI_OK); 509 510 // Check that registering no methods isn't a failure. 511 { 512 JNINativeMethod methods[] = { }; 513 EXPECT_EQ(env_->RegisterNatives(jlobject, methods, 0), JNI_OK); 514 } 515 EXPECT_FALSE(env_->ExceptionCheck()); 516 EXPECT_EQ(env_->UnregisterNatives(jlobject), JNI_OK); 517 518 // Check that registering a -ve number of methods is a failure. 519 CheckJniAbortCatcher check_jni_abort_catcher; 520 for (int i = -10; i < 0; ++i) { 521 JNINativeMethod methods[] = { }; 522 EXPECT_EQ(env_->RegisterNatives(jlobject, methods, i), JNI_ERR); 523 check_jni_abort_catcher.Check("negative method count: "); 524 } 525 EXPECT_FALSE(env_->ExceptionCheck()); 526 527 // Passing a class of null is a failure. 528 { 529 JNINativeMethod methods[] = { }; 530 EXPECT_EQ(env_->RegisterNatives(nullptr, methods, 0), JNI_ERR); 531 check_jni_abort_catcher.Check("java_class == null"); 532 } 533 534 // Passing methods as null is a failure. 535 EXPECT_EQ(env_->RegisterNatives(jlobject, nullptr, 1), JNI_ERR); 536 check_jni_abort_catcher.Check("methods == null"); 537 538 // Unregisters null is a failure. 539 EXPECT_EQ(env_->UnregisterNatives(nullptr), JNI_ERR); 540 check_jni_abort_catcher.Check("java_class == null"); 541 542 // Unregistering a class with no natives is a warning. 543 EXPECT_EQ(env_->UnregisterNatives(jlnsme), JNI_OK); 544 } 545 546 #define EXPECT_PRIMITIVE_ARRAY(new_fn, \ 547 get_region_fn, \ 548 set_region_fn, \ 549 get_elements_fn, \ 550 release_elements_fn, \ 551 scalar_type, \ 552 expected_class_descriptor) \ 553 jsize size = 4; \ 554 \ 555 { \ 556 CheckJniAbortCatcher jni_abort_catcher; \ 557 /* Allocate an negative sized array and check it has the right failure type. */ \ 558 EXPECT_EQ(env_->new_fn(-1), nullptr); \ 559 jni_abort_catcher.Check("negative array length: -1"); \ 560 EXPECT_EQ(env_->new_fn(std::numeric_limits<jint>::min()), nullptr); \ 561 jni_abort_catcher.Check("negative array length: -2147483648"); \ 562 /* Pass the array as null. */ \ 563 EXPECT_EQ(0, env_->GetArrayLength(nullptr)); \ 564 jni_abort_catcher.Check("java_array == null"); \ 565 env_->get_region_fn(nullptr, 0, 0, nullptr); \ 566 jni_abort_catcher.Check("java_array == null"); \ 567 env_->set_region_fn(nullptr, 0, 0, nullptr); \ 568 jni_abort_catcher.Check("java_array == null"); \ 569 env_->get_elements_fn(nullptr, nullptr); \ 570 jni_abort_catcher.Check("java_array == null"); \ 571 env_->release_elements_fn(nullptr, nullptr, 0); \ 572 jni_abort_catcher.Check("java_array == null"); \ 573 /* Pass the elements for region as null. */ \ 574 scalar_type ## Array a = env_->new_fn(size); \ 575 env_->get_region_fn(a, 0, size, nullptr); \ 576 jni_abort_catcher.Check("buf == null"); \ 577 env_->set_region_fn(a, 0, size, nullptr); \ 578 jni_abort_catcher.Check("buf == null"); \ 579 } \ 580 /* Allocate an array and check it has the right type and length. */ \ 581 scalar_type ## Array a = env_->new_fn(size); \ 582 EXPECT_NE(a, nullptr); \ 583 EXPECT_TRUE(env_->IsInstanceOf(a, env_->FindClass(expected_class_descriptor))); \ 584 EXPECT_EQ(size, env_->GetArrayLength(a)); \ 585 \ 586 /* GetPrimitiveArrayRegion/SetPrimitiveArrayRegion */ \ 587 /* AIOOBE for negative start offset. */ \ 588 env_->get_region_fn(a, -1, 1, nullptr); \ 589 ExpectException(aioobe_); \ 590 env_->set_region_fn(a, -1, 1, nullptr); \ 591 ExpectException(aioobe_); \ 592 \ 593 /* AIOOBE for negative length. */ \ 594 env_->get_region_fn(a, 0, -1, nullptr); \ 595 ExpectException(aioobe_); \ 596 env_->set_region_fn(a, 0, -1, nullptr); \ 597 ExpectException(aioobe_); \ 598 \ 599 /* AIOOBE for buffer overrun. */ \ 600 env_->get_region_fn(a, size - 1, size, nullptr); \ 601 ExpectException(aioobe_); \ 602 env_->set_region_fn(a, size - 1, size, nullptr); \ 603 ExpectException(aioobe_); \ 604 \ 605 /* It's okay for the buffer to be nullptr as long as the length is 0. */ \ 606 env_->get_region_fn(a, 2, 0, nullptr); \ 607 /* Even if the offset is invalid... */ \ 608 env_->get_region_fn(a, 123, 0, nullptr); \ 609 ExpectException(aioobe_); \ 610 \ 611 /* It's okay for the buffer to be nullptr as long as the length is 0. */ \ 612 env_->set_region_fn(a, 2, 0, nullptr); \ 613 /* Even if the offset is invalid... */ \ 614 env_->set_region_fn(a, 123, 0, nullptr); \ 615 ExpectException(aioobe_); \ 616 \ 617 /* Prepare a couple of buffers. */ \ 618 std::unique_ptr<scalar_type[]> src_buf(new scalar_type[size]); \ 619 std::unique_ptr<scalar_type[]> dst_buf(new scalar_type[size]); \ 620 for (jsize i = 0; i < size; ++i) { src_buf[i] = scalar_type(i); } \ 621 for (jsize i = 0; i < size; ++i) { dst_buf[i] = scalar_type(-1); } \ 622 \ 623 /* Copy all of src_buf onto the heap. */ \ 624 env_->set_region_fn(a, 0, size, &src_buf[0]); \ 625 /* Copy back only part. */ \ 626 env_->get_region_fn(a, 1, size - 2, &dst_buf[1]); \ 627 EXPECT_NE(memcmp(&src_buf[0], &dst_buf[0], size * sizeof(scalar_type)), 0) \ 628 << "short copy equal"; \ 629 /* Copy the missing pieces. */ \ 630 env_->get_region_fn(a, 0, 1, &dst_buf[0]); \ 631 env_->get_region_fn(a, size - 1, 1, &dst_buf[size - 1]); \ 632 EXPECT_EQ(memcmp(&src_buf[0], &dst_buf[0], size * sizeof(scalar_type)), 0) \ 633 << "fixed copy not equal"; \ 634 /* Copy back the whole array. */ \ 635 env_->get_region_fn(a, 0, size, &dst_buf[0]); \ 636 EXPECT_EQ(memcmp(&src_buf[0], &dst_buf[0], size * sizeof(scalar_type)), 0) \ 637 << "full copy not equal"; \ 638 /* GetPrimitiveArrayCritical */ \ 639 void* v = env_->GetPrimitiveArrayCritical(a, nullptr); \ 640 EXPECT_EQ(memcmp(&src_buf[0], v, size * sizeof(scalar_type)), 0) \ 641 << "GetPrimitiveArrayCritical not equal"; \ 642 env_->ReleasePrimitiveArrayCritical(a, v, 0); \ 643 /* GetXArrayElements */ \ 644 scalar_type* xs = env_->get_elements_fn(a, nullptr); \ 645 EXPECT_EQ(memcmp(&src_buf[0], xs, size * sizeof(scalar_type)), 0) \ 646 << # get_elements_fn " not equal"; \ 647 env_->release_elements_fn(a, xs, 0); \ 648 649 TEST_F(JniInternalTest, BooleanArrays) { 650 EXPECT_PRIMITIVE_ARRAY(NewBooleanArray, GetBooleanArrayRegion, SetBooleanArrayRegion, 651 GetBooleanArrayElements, ReleaseBooleanArrayElements, jboolean, "[Z"); 652 } 653 TEST_F(JniInternalTest, ByteArrays) { 654 EXPECT_PRIMITIVE_ARRAY(NewByteArray, GetByteArrayRegion, SetByteArrayRegion, 655 GetByteArrayElements, ReleaseByteArrayElements, jbyte, "[B"); 656 } 657 TEST_F(JniInternalTest, CharArrays) { 658 EXPECT_PRIMITIVE_ARRAY(NewCharArray, GetCharArrayRegion, SetCharArrayRegion, 659 GetCharArrayElements, ReleaseCharArrayElements, jchar, "[C"); 660 } 661 TEST_F(JniInternalTest, DoubleArrays) { 662 EXPECT_PRIMITIVE_ARRAY(NewDoubleArray, GetDoubleArrayRegion, SetDoubleArrayRegion, 663 GetDoubleArrayElements, ReleaseDoubleArrayElements, jdouble, "[D"); 664 } 665 TEST_F(JniInternalTest, FloatArrays) { 666 EXPECT_PRIMITIVE_ARRAY(NewFloatArray, GetFloatArrayRegion, SetFloatArrayRegion, 667 GetFloatArrayElements, ReleaseFloatArrayElements, jfloat, "[F"); 668 } 669 TEST_F(JniInternalTest, IntArrays) { 670 EXPECT_PRIMITIVE_ARRAY(NewIntArray, GetIntArrayRegion, SetIntArrayRegion, 671 GetIntArrayElements, ReleaseIntArrayElements, jint, "[I"); 672 } 673 TEST_F(JniInternalTest, LongArrays) { 674 EXPECT_PRIMITIVE_ARRAY(NewLongArray, GetLongArrayRegion, SetLongArrayRegion, 675 GetLongArrayElements, ReleaseLongArrayElements, jlong, "[J"); 676 } 677 TEST_F(JniInternalTest, ShortArrays) { 678 EXPECT_PRIMITIVE_ARRAY(NewShortArray, GetShortArrayRegion, SetShortArrayRegion, 679 GetShortArrayElements, ReleaseShortArrayElements, jshort, "[S"); 680 } 681 682 TEST_F(JniInternalTest, GetPrimitiveArrayElementsOfWrongType) { 683 CheckJniAbortCatcher jni_abort_catcher; 684 jbooleanArray array = env_->NewBooleanArray(10); 685 jboolean is_copy; 686 EXPECT_EQ(env_->GetByteArrayElements(reinterpret_cast<jbyteArray>(array), &is_copy), nullptr); 687 jni_abort_catcher.Check( 688 "attempt to get byte primitive array elements with an object of type boolean[]"); 689 EXPECT_EQ(env_->GetShortArrayElements(reinterpret_cast<jshortArray>(array), &is_copy), nullptr); 690 jni_abort_catcher.Check( 691 "attempt to get short primitive array elements with an object of type boolean[]"); 692 EXPECT_EQ(env_->GetCharArrayElements(reinterpret_cast<jcharArray>(array), &is_copy), nullptr); 693 jni_abort_catcher.Check( 694 "attempt to get char primitive array elements with an object of type boolean[]"); 695 EXPECT_EQ(env_->GetIntArrayElements(reinterpret_cast<jintArray>(array), &is_copy), nullptr); 696 jni_abort_catcher.Check( 697 "attempt to get int primitive array elements with an object of type boolean[]"); 698 EXPECT_EQ(env_->GetLongArrayElements(reinterpret_cast<jlongArray>(array), &is_copy), nullptr); 699 jni_abort_catcher.Check( 700 "attempt to get long primitive array elements with an object of type boolean[]"); 701 EXPECT_EQ(env_->GetFloatArrayElements(reinterpret_cast<jfloatArray>(array), &is_copy), nullptr); 702 jni_abort_catcher.Check( 703 "attempt to get float primitive array elements with an object of type boolean[]"); 704 EXPECT_EQ(env_->GetDoubleArrayElements(reinterpret_cast<jdoubleArray>(array), &is_copy), nullptr); 705 jni_abort_catcher.Check( 706 "attempt to get double primitive array elements with an object of type boolean[]"); 707 jbyteArray array2 = env_->NewByteArray(10); 708 EXPECT_EQ(env_->GetBooleanArrayElements(reinterpret_cast<jbooleanArray>(array2), &is_copy), 709 nullptr); 710 jni_abort_catcher.Check( 711 "attempt to get boolean primitive array elements with an object of type byte[]"); 712 jobject object = env_->NewStringUTF("Test String"); 713 EXPECT_EQ(env_->GetBooleanArrayElements(reinterpret_cast<jbooleanArray>(object), &is_copy), 714 nullptr); 715 jni_abort_catcher.Check( 716 "attempt to get boolean primitive array elements with an object of type java.lang.String"); 717 } 718 719 TEST_F(JniInternalTest, ReleasePrimitiveArrayElementsOfWrongType) { 720 CheckJniAbortCatcher jni_abort_catcher; 721 jbooleanArray array = env_->NewBooleanArray(10); 722 ASSERT_TRUE(array != nullptr); 723 jboolean is_copy; 724 jboolean* elements = env_->GetBooleanArrayElements(array, &is_copy); 725 ASSERT_TRUE(elements != nullptr); 726 env_->ReleaseByteArrayElements(reinterpret_cast<jbyteArray>(array), 727 reinterpret_cast<jbyte*>(elements), 0); 728 jni_abort_catcher.Check( 729 "attempt to release byte primitive array elements with an object of type boolean[]"); 730 env_->ReleaseShortArrayElements(reinterpret_cast<jshortArray>(array), 731 reinterpret_cast<jshort*>(elements), 0); 732 jni_abort_catcher.Check( 733 "attempt to release short primitive array elements with an object of type boolean[]"); 734 env_->ReleaseCharArrayElements(reinterpret_cast<jcharArray>(array), 735 reinterpret_cast<jchar*>(elements), 0); 736 jni_abort_catcher.Check( 737 "attempt to release char primitive array elements with an object of type boolean[]"); 738 env_->ReleaseIntArrayElements(reinterpret_cast<jintArray>(array), 739 reinterpret_cast<jint*>(elements), 0); 740 jni_abort_catcher.Check( 741 "attempt to release int primitive array elements with an object of type boolean[]"); 742 env_->ReleaseLongArrayElements(reinterpret_cast<jlongArray>(array), 743 reinterpret_cast<jlong*>(elements), 0); 744 jni_abort_catcher.Check( 745 "attempt to release long primitive array elements with an object of type boolean[]"); 746 env_->ReleaseFloatArrayElements(reinterpret_cast<jfloatArray>(array), 747 reinterpret_cast<jfloat*>(elements), 0); 748 jni_abort_catcher.Check( 749 "attempt to release float primitive array elements with an object of type boolean[]"); 750 env_->ReleaseDoubleArrayElements(reinterpret_cast<jdoubleArray>(array), 751 reinterpret_cast<jdouble*>(elements), 0); 752 jni_abort_catcher.Check( 753 "attempt to release double primitive array elements with an object of type boolean[]"); 754 jbyteArray array2 = env_->NewByteArray(10); 755 env_->ReleaseBooleanArrayElements(reinterpret_cast<jbooleanArray>(array2), elements, 0); 756 jni_abort_catcher.Check( 757 "attempt to release boolean primitive array elements with an object of type byte[]"); 758 jobject object = env_->NewStringUTF("Test String"); 759 env_->ReleaseBooleanArrayElements(reinterpret_cast<jbooleanArray>(object), elements, 0); 760 jni_abort_catcher.Check( 761 "attempt to release boolean primitive array elements with an object of type " 762 "java.lang.String"); 763 } 764 TEST_F(JniInternalTest, GetReleasePrimitiveArrayCriticalOfWrongType) { 765 CheckJniAbortCatcher jni_abort_catcher; 766 jobject object = env_->NewStringUTF("Test String"); 767 jboolean is_copy; 768 void* elements = env_->GetPrimitiveArrayCritical(reinterpret_cast<jarray>(object), &is_copy); 769 jni_abort_catcher.Check("expected primitive array, given java.lang.String"); 770 env_->ReleasePrimitiveArrayCritical(reinterpret_cast<jarray>(object), elements, 0); 771 jni_abort_catcher.Check("expected primitive array, given java.lang.String"); 772 } 773 774 TEST_F(JniInternalTest, GetPrimitiveArrayRegionElementsOfWrongType) { 775 CheckJniAbortCatcher jni_abort_catcher; 776 constexpr size_t kLength = 10; 777 jbooleanArray array = env_->NewBooleanArray(kLength); 778 ASSERT_TRUE(array != nullptr); 779 jboolean elements[kLength]; 780 env_->GetByteArrayRegion(reinterpret_cast<jbyteArray>(array), 0, kLength, 781 reinterpret_cast<jbyte*>(elements)); 782 jni_abort_catcher.Check( 783 "attempt to get region of byte primitive array elements with an object of type boolean[]"); 784 env_->GetShortArrayRegion(reinterpret_cast<jshortArray>(array), 0, kLength, 785 reinterpret_cast<jshort*>(elements)); 786 jni_abort_catcher.Check( 787 "attempt to get region of short primitive array elements with an object of type boolean[]"); 788 env_->GetCharArrayRegion(reinterpret_cast<jcharArray>(array), 0, kLength, 789 reinterpret_cast<jchar*>(elements)); 790 jni_abort_catcher.Check( 791 "attempt to get region of char primitive array elements with an object of type boolean[]"); 792 env_->GetIntArrayRegion(reinterpret_cast<jintArray>(array), 0, kLength, 793 reinterpret_cast<jint*>(elements)); 794 jni_abort_catcher.Check( 795 "attempt to get region of int primitive array elements with an object of type boolean[]"); 796 env_->GetLongArrayRegion(reinterpret_cast<jlongArray>(array), 0, kLength, 797 reinterpret_cast<jlong*>(elements)); 798 jni_abort_catcher.Check( 799 "attempt to get region of long primitive array elements with an object of type boolean[]"); 800 env_->GetFloatArrayRegion(reinterpret_cast<jfloatArray>(array), 0, kLength, 801 reinterpret_cast<jfloat*>(elements)); 802 jni_abort_catcher.Check( 803 "attempt to get region of float primitive array elements with an object of type boolean[]"); 804 env_->GetDoubleArrayRegion(reinterpret_cast<jdoubleArray>(array), 0, kLength, 805 reinterpret_cast<jdouble*>(elements)); 806 jni_abort_catcher.Check( 807 "attempt to get region of double primitive array elements with an object of type boolean[]"); 808 jbyteArray array2 = env_->NewByteArray(10); 809 env_->GetBooleanArrayRegion(reinterpret_cast<jbooleanArray>(array2), 0, kLength, 810 reinterpret_cast<jboolean*>(elements)); 811 jni_abort_catcher.Check( 812 "attempt to get region of boolean primitive array elements with an object of type byte[]"); 813 jobject object = env_->NewStringUTF("Test String"); 814 env_->GetBooleanArrayRegion(reinterpret_cast<jbooleanArray>(object), 0, kLength, 815 reinterpret_cast<jboolean*>(elements)); 816 jni_abort_catcher.Check( 817 "attempt to get region of boolean primitive array elements with an object of type " 818 "java.lang.String"); 819 } 820 821 TEST_F(JniInternalTest, SetPrimitiveArrayRegionElementsOfWrongType) { 822 CheckJniAbortCatcher jni_abort_catcher; 823 constexpr size_t kLength = 10; 824 jbooleanArray array = env_->NewBooleanArray(kLength); 825 ASSERT_TRUE(array != nullptr); 826 jboolean elements[kLength]; 827 env_->SetByteArrayRegion(reinterpret_cast<jbyteArray>(array), 0, kLength, 828 reinterpret_cast<jbyte*>(elements)); 829 jni_abort_catcher.Check( 830 "attempt to set region of byte primitive array elements with an object of type boolean[]"); 831 env_->SetShortArrayRegion(reinterpret_cast<jshortArray>(array), 0, kLength, 832 reinterpret_cast<jshort*>(elements)); 833 jni_abort_catcher.Check( 834 "attempt to set region of short primitive array elements with an object of type boolean[]"); 835 env_->SetCharArrayRegion(reinterpret_cast<jcharArray>(array), 0, kLength, 836 reinterpret_cast<jchar*>(elements)); 837 jni_abort_catcher.Check( 838 "attempt to set region of char primitive array elements with an object of type boolean[]"); 839 env_->SetIntArrayRegion(reinterpret_cast<jintArray>(array), 0, kLength, 840 reinterpret_cast<jint*>(elements)); 841 jni_abort_catcher.Check( 842 "attempt to set region of int primitive array elements with an object of type boolean[]"); 843 env_->SetLongArrayRegion(reinterpret_cast<jlongArray>(array), 0, kLength, 844 reinterpret_cast<jlong*>(elements)); 845 jni_abort_catcher.Check( 846 "attempt to set region of long primitive array elements with an object of type boolean[]"); 847 env_->SetFloatArrayRegion(reinterpret_cast<jfloatArray>(array), 0, kLength, 848 reinterpret_cast<jfloat*>(elements)); 849 jni_abort_catcher.Check( 850 "attempt to set region of float primitive array elements with an object of type boolean[]"); 851 env_->SetDoubleArrayRegion(reinterpret_cast<jdoubleArray>(array), 0, kLength, 852 reinterpret_cast<jdouble*>(elements)); 853 jni_abort_catcher.Check( 854 "attempt to set region of double primitive array elements with an object of type boolean[]"); 855 jbyteArray array2 = env_->NewByteArray(10); 856 env_->SetBooleanArrayRegion(reinterpret_cast<jbooleanArray>(array2), 0, kLength, 857 reinterpret_cast<jboolean*>(elements)); 858 jni_abort_catcher.Check( 859 "attempt to set region of boolean primitive array elements with an object of type byte[]"); 860 jobject object = env_->NewStringUTF("Test String"); 861 env_->SetBooleanArrayRegion(reinterpret_cast<jbooleanArray>(object), 0, kLength, 862 reinterpret_cast<jboolean*>(elements)); 863 jni_abort_catcher.Check( 864 "attempt to set region of boolean primitive array elements with an object of type " 865 "java.lang.String"); 866 } 867 868 TEST_F(JniInternalTest, NewObjectArray) { 869 jclass element_class = env_->FindClass("java/lang/String"); 870 ASSERT_NE(element_class, nullptr); 871 jclass array_class = env_->FindClass("[Ljava/lang/String;"); 872 ASSERT_NE(array_class, nullptr); 873 874 jobjectArray a = env_->NewObjectArray(0, element_class, nullptr); 875 EXPECT_NE(a, nullptr); 876 EXPECT_TRUE(env_->IsInstanceOf(a, array_class)); 877 EXPECT_EQ(0, env_->GetArrayLength(a)); 878 879 a = env_->NewObjectArray(1, element_class, nullptr); 880 EXPECT_NE(a, nullptr); 881 EXPECT_TRUE(env_->IsInstanceOf(a, array_class)); 882 EXPECT_EQ(1, env_->GetArrayLength(a)); 883 EXPECT_TRUE(env_->IsSameObject(env_->GetObjectArrayElement(a, 0), nullptr)); 884 885 // Negative array length checks. 886 CheckJniAbortCatcher jni_abort_catcher; 887 env_->NewObjectArray(-1, element_class, nullptr); 888 jni_abort_catcher.Check("negative array length: -1"); 889 890 env_->NewObjectArray(std::numeric_limits<jint>::min(), element_class, nullptr); 891 jni_abort_catcher.Check("negative array length: -2147483648"); 892 } 893 894 TEST_F(JniInternalTest, NewObjectArrayWithPrimitiveClasses) { 895 const char* primitive_descriptors = "VZBSCIJFD"; 896 const char* primitive_names[] = { 897 "void", "boolean", "byte", "short", "char", "int", "long", "float", "double" 898 }; 899 ASSERT_EQ(strlen(primitive_descriptors), arraysize(primitive_names)); 900 901 CheckJniAbortCatcher jni_abort_catcher; 902 for (size_t i = 0; i < strlen(primitive_descriptors); ++i) { 903 env_->NewObjectArray(0, nullptr, nullptr); 904 jni_abort_catcher.Check("element_jclass == null"); 905 jclass primitive_class = GetPrimitiveClass(primitive_descriptors[i]); 906 env_->NewObjectArray(1, primitive_class, nullptr); 907 std::string error_msg(StringPrintf("not an object type: %s", primitive_names[i])); 908 jni_abort_catcher.Check(error_msg.c_str()); 909 } 910 } 911 912 TEST_F(JniInternalTest, NewObjectArrayWithInitialValue) { 913 jclass element_class = env_->FindClass("java/lang/String"); 914 ASSERT_NE(element_class, nullptr); 915 jclass array_class = env_->FindClass("[Ljava/lang/String;"); 916 ASSERT_NE(array_class, nullptr); 917 918 jstring s = env_->NewStringUTF("poop"); 919 jobjectArray a = env_->NewObjectArray(2, element_class, s); 920 EXPECT_NE(a, nullptr); 921 EXPECT_TRUE(env_->IsInstanceOf(a, array_class)); 922 EXPECT_EQ(2, env_->GetArrayLength(a)); 923 EXPECT_TRUE(env_->IsSameObject(env_->GetObjectArrayElement(a, 0), s)); 924 EXPECT_TRUE(env_->IsSameObject(env_->GetObjectArrayElement(a, 1), s)); 925 926 // Attempt to incorrect create an array of strings with initial value of string arrays. 927 CheckJniAbortCatcher jni_abort_catcher; 928 env_->NewObjectArray(2, element_class, a); 929 jni_abort_catcher.Check("cannot assign object of type 'java.lang.String[]' to array with element " 930 "type of 'java.lang.String'"); 931 } 932 933 TEST_F(JniInternalTest, GetArrayLength) { 934 // Already tested in NewObjectArray/NewPrimitiveArray. 935 } 936 937 TEST_F(JniInternalTest, GetObjectClass) { 938 jclass string_class = env_->FindClass("java/lang/String"); 939 ASSERT_NE(string_class, nullptr); 940 jclass class_class = env_->FindClass("java/lang/Class"); 941 ASSERT_NE(class_class, nullptr); 942 943 jstring s = env_->NewStringUTF("poop"); 944 jclass c = env_->GetObjectClass(s); 945 ASSERT_TRUE(env_->IsSameObject(string_class, c)); 946 947 jclass c2 = env_->GetObjectClass(c); 948 ASSERT_TRUE(env_->IsSameObject(class_class, env_->GetObjectClass(c2))); 949 950 // Null as object should fail. 951 CheckJniAbortCatcher jni_abort_catcher; 952 EXPECT_EQ(env_->GetObjectClass(nullptr), nullptr); 953 jni_abort_catcher.Check("java_object == null"); 954 } 955 956 TEST_F(JniInternalTest, GetSuperclass) { 957 jclass object_class = env_->FindClass("java/lang/Object"); 958 ASSERT_NE(object_class, nullptr); 959 jclass string_class = env_->FindClass("java/lang/String"); 960 ASSERT_NE(string_class, nullptr); 961 jclass runnable_interface = env_->FindClass("java/lang/Runnable"); 962 ASSERT_NE(runnable_interface, nullptr); 963 ASSERT_TRUE(env_->IsSameObject(object_class, env_->GetSuperclass(string_class))); 964 ASSERT_EQ(env_->GetSuperclass(object_class), nullptr); 965 ASSERT_TRUE(env_->IsSameObject(object_class, env_->GetSuperclass(runnable_interface))); 966 967 // Null as class should fail. 968 CheckJniAbortCatcher jni_abort_catcher; 969 EXPECT_EQ(env_->GetSuperclass(nullptr), nullptr); 970 jni_abort_catcher.Check("java_class == null"); 971 } 972 973 TEST_F(JniInternalTest, IsAssignableFrom) { 974 jclass object_class = env_->FindClass("java/lang/Object"); 975 ASSERT_NE(object_class, nullptr); 976 jclass string_class = env_->FindClass("java/lang/String"); 977 ASSERT_NE(string_class, nullptr); 978 979 // A superclass is assignable from an instance of its 980 // subclass but not vice versa. 981 ASSERT_TRUE(env_->IsAssignableFrom(string_class, object_class)); 982 ASSERT_FALSE(env_->IsAssignableFrom(object_class, string_class)); 983 984 jclass charsequence_interface = env_->FindClass("java/lang/CharSequence"); 985 ASSERT_NE(charsequence_interface, nullptr); 986 987 // An interface is assignable from an instance of an implementing 988 // class but not vice versa. 989 ASSERT_TRUE(env_->IsAssignableFrom(string_class, charsequence_interface)); 990 ASSERT_FALSE(env_->IsAssignableFrom(charsequence_interface, string_class)); 991 992 // Check that arrays are covariant. 993 jclass string_array_class = env_->FindClass("[Ljava/lang/String;"); 994 ASSERT_NE(string_array_class, nullptr); 995 jclass object_array_class = env_->FindClass("[Ljava/lang/Object;"); 996 ASSERT_NE(object_array_class, nullptr); 997 ASSERT_TRUE(env_->IsAssignableFrom(string_array_class, object_array_class)); 998 ASSERT_FALSE(env_->IsAssignableFrom(object_array_class, string_array_class)); 999 1000 // Primitive types are tested in 004-JniTest. 1001 1002 // Null as either class should fail. 1003 CheckJniAbortCatcher jni_abort_catcher; 1004 EXPECT_EQ(env_->IsAssignableFrom(nullptr, string_class), JNI_FALSE); 1005 jni_abort_catcher.Check("java_class1 == null"); 1006 EXPECT_EQ(env_->IsAssignableFrom(object_class, nullptr), JNI_FALSE); 1007 jni_abort_catcher.Check("java_class2 == null"); 1008 } 1009 1010 TEST_F(JniInternalTest, GetObjectRefType) { 1011 jclass local = env_->FindClass("java/lang/Object"); 1012 ASSERT_TRUE(local != nullptr); 1013 EXPECT_EQ(JNILocalRefType, env_->GetObjectRefType(local)); 1014 1015 jobject global = env_->NewGlobalRef(local); 1016 EXPECT_EQ(JNIGlobalRefType, env_->GetObjectRefType(global)); 1017 1018 jweak weak_global = env_->NewWeakGlobalRef(local); 1019 EXPECT_EQ(JNIWeakGlobalRefType, env_->GetObjectRefType(weak_global)); 1020 1021 jobject invalid = reinterpret_cast<jobject>(this); 1022 EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(invalid)); 1023 1024 // TODO: invoke a native method and test that its arguments are considered local references. 1025 1026 // Null as pointer should not fail and return invalid-ref. b/18820997 1027 EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(nullptr)); 1028 1029 // TODO: Null as reference should return the original type. 1030 // This requires running a GC so a non-null object gets freed. 1031 } 1032 1033 TEST_F(JniInternalTest, StaleWeakGlobal) { 1034 jclass java_lang_Class = env_->FindClass("java/lang/Class"); 1035 ASSERT_NE(java_lang_Class, nullptr); 1036 jobjectArray local_ref = env_->NewObjectArray(1, java_lang_Class, nullptr); 1037 ASSERT_NE(local_ref, nullptr); 1038 jweak weak_global = env_->NewWeakGlobalRef(local_ref); 1039 ASSERT_NE(weak_global, nullptr); 1040 env_->DeleteLocalRef(local_ref); 1041 Runtime::Current()->GetHeap()->CollectGarbage(false); // GC should clear the weak global. 1042 jobject new_global_ref = env_->NewGlobalRef(weak_global); 1043 EXPECT_EQ(new_global_ref, nullptr); 1044 jobject new_local_ref = env_->NewLocalRef(weak_global); 1045 EXPECT_EQ(new_local_ref, nullptr); 1046 } 1047 1048 TEST_F(JniInternalTest, NewStringUTF) { 1049 EXPECT_EQ(env_->NewStringUTF(nullptr), nullptr); 1050 jstring s; 1051 1052 s = env_->NewStringUTF(""); 1053 EXPECT_NE(s, nullptr); 1054 EXPECT_EQ(0, env_->GetStringLength(s)); 1055 EXPECT_EQ(0, env_->GetStringUTFLength(s)); 1056 s = env_->NewStringUTF("hello"); 1057 EXPECT_NE(s, nullptr); 1058 EXPECT_EQ(5, env_->GetStringLength(s)); 1059 EXPECT_EQ(5, env_->GetStringUTFLength(s)); 1060 1061 // TODO: check some non-ASCII strings. 1062 } 1063 1064 TEST_F(JniInternalTest, NewString) { 1065 jchar chars[] = { 'h', 'i' }; 1066 jstring s; 1067 s = env_->NewString(chars, 0); 1068 EXPECT_NE(s, nullptr); 1069 EXPECT_EQ(0, env_->GetStringLength(s)); 1070 EXPECT_EQ(0, env_->GetStringUTFLength(s)); 1071 s = env_->NewString(chars, 2); 1072 EXPECT_NE(s, nullptr); 1073 EXPECT_EQ(2, env_->GetStringLength(s)); 1074 EXPECT_EQ(2, env_->GetStringUTFLength(s)); 1075 1076 // TODO: check some non-ASCII strings. 1077 } 1078 1079 TEST_F(JniInternalTest, NewStringNullCharsZeroLength) { 1080 jstring s = env_->NewString(nullptr, 0); 1081 EXPECT_NE(s, nullptr); 1082 EXPECT_EQ(0, env_->GetStringLength(s)); 1083 } 1084 1085 TEST_F(JniInternalTest, NewStringNullCharsNonzeroLength) { 1086 CheckJniAbortCatcher jni_abort_catcher; 1087 env_->NewString(nullptr, 1); 1088 jni_abort_catcher.Check("chars == null && char_count > 0"); 1089 } 1090 1091 TEST_F(JniInternalTest, NewStringNegativeLength) { 1092 CheckJniAbortCatcher jni_abort_catcher; 1093 env_->NewString(nullptr, -1); 1094 jni_abort_catcher.Check("char_count < 0: -1"); 1095 env_->NewString(nullptr, std::numeric_limits<jint>::min()); 1096 jni_abort_catcher.Check("char_count < 0: -2147483648"); 1097 } 1098 1099 TEST_F(JniInternalTest, GetStringLength_GetStringUTFLength) { 1100 // Already tested in the NewString/NewStringUTF tests. 1101 } 1102 1103 TEST_F(JniInternalTest, GetStringRegion_GetStringUTFRegion) { 1104 jstring s = env_->NewStringUTF("hello"); 1105 ASSERT_TRUE(s != nullptr); 1106 1107 env_->GetStringRegion(s, -1, 0, nullptr); 1108 ExpectException(sioobe_); 1109 env_->GetStringRegion(s, 0, -1, nullptr); 1110 ExpectException(sioobe_); 1111 env_->GetStringRegion(s, 0, 10, nullptr); 1112 ExpectException(sioobe_); 1113 env_->GetStringRegion(s, 10, 1, nullptr); 1114 ExpectException(sioobe_); 1115 1116 jchar chars[4] = { 'x', 'x', 'x', 'x' }; 1117 env_->GetStringRegion(s, 1, 2, &chars[1]); 1118 EXPECT_EQ('x', chars[0]); 1119 EXPECT_EQ('e', chars[1]); 1120 EXPECT_EQ('l', chars[2]); 1121 EXPECT_EQ('x', chars[3]); 1122 1123 // It's okay for the buffer to be nullptr as long as the length is 0. 1124 env_->GetStringRegion(s, 2, 0, nullptr); 1125 // Even if the offset is invalid... 1126 env_->GetStringRegion(s, 123, 0, nullptr); 1127 ExpectException(sioobe_); 1128 1129 env_->GetStringUTFRegion(s, -1, 0, nullptr); 1130 ExpectException(sioobe_); 1131 env_->GetStringUTFRegion(s, 0, -1, nullptr); 1132 ExpectException(sioobe_); 1133 env_->GetStringUTFRegion(s, 0, 10, nullptr); 1134 ExpectException(sioobe_); 1135 env_->GetStringUTFRegion(s, 10, 1, nullptr); 1136 ExpectException(sioobe_); 1137 1138 char bytes[4] = { 'x', 'x', 'x', 'x' }; 1139 env_->GetStringUTFRegion(s, 1, 2, &bytes[1]); 1140 EXPECT_EQ('x', bytes[0]); 1141 EXPECT_EQ('e', bytes[1]); 1142 EXPECT_EQ('l', bytes[2]); 1143 EXPECT_EQ('x', bytes[3]); 1144 1145 // It's okay for the buffer to be nullptr as long as the length is 0. 1146 env_->GetStringUTFRegion(s, 2, 0, nullptr); 1147 // Even if the offset is invalid... 1148 env_->GetStringUTFRegion(s, 123, 0, nullptr); 1149 ExpectException(sioobe_); 1150 } 1151 1152 TEST_F(JniInternalTest, GetStringUTFChars_ReleaseStringUTFChars) { 1153 // Passing in a nullptr jstring is ignored normally, but caught by -Xcheck:jni. 1154 { 1155 CheckJniAbortCatcher check_jni_abort_catcher; 1156 EXPECT_EQ(env_->GetStringUTFChars(nullptr, nullptr), nullptr); 1157 check_jni_abort_catcher.Check("GetStringUTFChars received null jstring"); 1158 } 1159 1160 jstring s = env_->NewStringUTF("hello"); 1161 ASSERT_TRUE(s != nullptr); 1162 1163 const char* utf = env_->GetStringUTFChars(s, nullptr); 1164 EXPECT_STREQ("hello", utf); 1165 env_->ReleaseStringUTFChars(s, utf); 1166 1167 jboolean is_copy = JNI_FALSE; 1168 utf = env_->GetStringUTFChars(s, &is_copy); 1169 EXPECT_EQ(JNI_TRUE, is_copy); 1170 EXPECT_STREQ("hello", utf); 1171 env_->ReleaseStringUTFChars(s, utf); 1172 } 1173 1174 TEST_F(JniInternalTest, GetStringChars_ReleaseStringChars) { 1175 jstring s = env_->NewStringUTF("hello"); 1176 ScopedObjectAccess soa(env_); 1177 mirror::String* s_m = soa.Decode<mirror::String*>(s); 1178 ASSERT_TRUE(s != nullptr); 1179 1180 jchar expected[] = { 'h', 'e', 'l', 'l', 'o' }; 1181 const jchar* chars = env_->GetStringChars(s, nullptr); 1182 EXPECT_EQ(expected[0], chars[0]); 1183 EXPECT_EQ(expected[1], chars[1]); 1184 EXPECT_EQ(expected[2], chars[2]); 1185 EXPECT_EQ(expected[3], chars[3]); 1186 EXPECT_EQ(expected[4], chars[4]); 1187 env_->ReleaseStringChars(s, chars); 1188 1189 jboolean is_copy = JNI_FALSE; 1190 chars = env_->GetStringChars(s, &is_copy); 1191 if (Runtime::Current()->GetHeap()->IsMovableObject(s_m->GetCharArray())) { 1192 EXPECT_EQ(JNI_TRUE, is_copy); 1193 } else { 1194 EXPECT_EQ(JNI_FALSE, is_copy); 1195 } 1196 EXPECT_EQ(expected[0], chars[0]); 1197 EXPECT_EQ(expected[1], chars[1]); 1198 EXPECT_EQ(expected[2], chars[2]); 1199 EXPECT_EQ(expected[3], chars[3]); 1200 EXPECT_EQ(expected[4], chars[4]); 1201 env_->ReleaseStringChars(s, chars); 1202 } 1203 1204 TEST_F(JniInternalTest, GetStringCritical_ReleaseStringCritical) { 1205 jstring s = env_->NewStringUTF("hello"); 1206 ASSERT_TRUE(s != nullptr); 1207 1208 jchar expected[] = { 'h', 'e', 'l', 'l', 'o' }; 1209 const jchar* chars = env_->GetStringCritical(s, nullptr); 1210 EXPECT_EQ(expected[0], chars[0]); 1211 EXPECT_EQ(expected[1], chars[1]); 1212 EXPECT_EQ(expected[2], chars[2]); 1213 EXPECT_EQ(expected[3], chars[3]); 1214 EXPECT_EQ(expected[4], chars[4]); 1215 env_->ReleaseStringCritical(s, chars); 1216 1217 jboolean is_copy = JNI_TRUE; 1218 chars = env_->GetStringCritical(s, &is_copy); 1219 EXPECT_EQ(JNI_FALSE, is_copy); 1220 EXPECT_EQ(expected[0], chars[0]); 1221 EXPECT_EQ(expected[1], chars[1]); 1222 EXPECT_EQ(expected[2], chars[2]); 1223 EXPECT_EQ(expected[3], chars[3]); 1224 EXPECT_EQ(expected[4], chars[4]); 1225 env_->ReleaseStringCritical(s, chars); 1226 } 1227 1228 TEST_F(JniInternalTest, GetObjectArrayElement_SetObjectArrayElement) { 1229 jclass java_lang_Class = env_->FindClass("java/lang/Class"); 1230 ASSERT_TRUE(java_lang_Class != nullptr); 1231 1232 jobjectArray array = env_->NewObjectArray(1, java_lang_Class, nullptr); 1233 EXPECT_NE(array, nullptr); 1234 EXPECT_EQ(env_->GetObjectArrayElement(array, 0), nullptr); 1235 env_->SetObjectArrayElement(array, 0, java_lang_Class); 1236 EXPECT_TRUE(env_->IsSameObject(env_->GetObjectArrayElement(array, 0), java_lang_Class)); 1237 1238 // ArrayIndexOutOfBounds for negative index. 1239 env_->SetObjectArrayElement(array, -1, java_lang_Class); 1240 ExpectException(aioobe_); 1241 1242 // ArrayIndexOutOfBounds for too-large index. 1243 env_->SetObjectArrayElement(array, 1, java_lang_Class); 1244 ExpectException(aioobe_); 1245 1246 // ArrayStoreException thrown for bad types. 1247 env_->SetObjectArrayElement(array, 0, env_->NewStringUTF("not a jclass!")); 1248 ExpectException(ase_); 1249 1250 // Null as array should fail. 1251 CheckJniAbortCatcher jni_abort_catcher; 1252 EXPECT_EQ(nullptr, env_->GetObjectArrayElement(nullptr, 0)); 1253 jni_abort_catcher.Check("java_array == null"); 1254 env_->SetObjectArrayElement(nullptr, 0, nullptr); 1255 jni_abort_catcher.Check("java_array == null"); 1256 } 1257 1258 #define EXPECT_STATIC_PRIMITIVE_FIELD(type, field_name, sig, value1, value2) \ 1259 do { \ 1260 jfieldID fid = env_->GetStaticFieldID(c, field_name, sig); \ 1261 EXPECT_NE(fid, nullptr); \ 1262 env_->SetStatic ## type ## Field(c, fid, value1); \ 1263 EXPECT_EQ(value1, env_->GetStatic ## type ## Field(c, fid)); \ 1264 env_->SetStatic ## type ## Field(c, fid, value2); \ 1265 EXPECT_EQ(value2, env_->GetStatic ## type ## Field(c, fid)); \ 1266 \ 1267 CheckJniAbortCatcher jni_abort_catcher; \ 1268 env_->GetStatic ## type ## Field(nullptr, fid); \ 1269 jni_abort_catcher.Check("received null jclass"); \ 1270 env_->SetStatic ## type ## Field(nullptr, fid, value1); \ 1271 jni_abort_catcher.Check("received null jclass"); \ 1272 env_->GetStatic ## type ## Field(c, nullptr); \ 1273 jni_abort_catcher.Check("fid == null"); \ 1274 env_->SetStatic ## type ## Field(c, nullptr, value1); \ 1275 jni_abort_catcher.Check("fid == null"); \ 1276 } while (false) 1277 1278 #define EXPECT_PRIMITIVE_FIELD(instance, type, field_name, sig, value1, value2) \ 1279 do { \ 1280 jfieldID fid = env_->GetFieldID(c, field_name, sig); \ 1281 EXPECT_NE(fid, nullptr); \ 1282 env_->Set ## type ## Field(instance, fid, value1); \ 1283 EXPECT_EQ(value1, env_->Get ## type ## Field(instance, fid)); \ 1284 env_->Set ## type ## Field(instance, fid, value2); \ 1285 EXPECT_EQ(value2, env_->Get ## type ## Field(instance, fid)); \ 1286 \ 1287 CheckJniAbortCatcher jni_abort_catcher; \ 1288 env_->Get ## type ## Field(nullptr, fid); \ 1289 jni_abort_catcher.Check("obj == null"); \ 1290 env_->Set ## type ## Field(nullptr, fid, value1); \ 1291 jni_abort_catcher.Check("obj == null"); \ 1292 env_->Get ## type ## Field(instance, nullptr); \ 1293 jni_abort_catcher.Check("fid == null"); \ 1294 env_->Set ## type ## Field(instance, nullptr, value1); \ 1295 jni_abort_catcher.Check("fid == null"); \ 1296 } while (false) 1297 1298 1299 TEST_F(JniInternalTest, GetPrimitiveField_SetPrimitiveField) { 1300 TEST_DISABLED_FOR_PORTABLE(); 1301 Thread::Current()->TransitionFromSuspendedToRunnable(); 1302 LoadDex("AllFields"); 1303 bool started = runtime_->Start(); 1304 ASSERT_TRUE(started); 1305 1306 jclass c = env_->FindClass("AllFields"); 1307 ASSERT_NE(c, nullptr); 1308 jobject o = env_->AllocObject(c); 1309 ASSERT_NE(o, nullptr); 1310 1311 EXPECT_STATIC_PRIMITIVE_FIELD(Boolean, "sZ", "Z", JNI_TRUE, JNI_FALSE); 1312 EXPECT_STATIC_PRIMITIVE_FIELD(Byte, "sB", "B", 1, 2); 1313 EXPECT_STATIC_PRIMITIVE_FIELD(Char, "sC", "C", 'a', 'b'); 1314 EXPECT_STATIC_PRIMITIVE_FIELD(Double, "sD", "D", 1.0, 2.0); 1315 EXPECT_STATIC_PRIMITIVE_FIELD(Float, "sF", "F", 1.0, 2.0); 1316 EXPECT_STATIC_PRIMITIVE_FIELD(Int, "sI", "I", 1, 2); 1317 EXPECT_STATIC_PRIMITIVE_FIELD(Long, "sJ", "J", 1, 2); 1318 EXPECT_STATIC_PRIMITIVE_FIELD(Short, "sS", "S", 1, 2); 1319 1320 EXPECT_PRIMITIVE_FIELD(o, Boolean, "iZ", "Z", JNI_TRUE, JNI_FALSE); 1321 EXPECT_PRIMITIVE_FIELD(o, Byte, "iB", "B", 1, 2); 1322 EXPECT_PRIMITIVE_FIELD(o, Char, "iC", "C", 'a', 'b'); 1323 EXPECT_PRIMITIVE_FIELD(o, Double, "iD", "D", 1.0, 2.0); 1324 EXPECT_PRIMITIVE_FIELD(o, Float, "iF", "F", 1.0, 2.0); 1325 EXPECT_PRIMITIVE_FIELD(o, Int, "iI", "I", 1, 2); 1326 EXPECT_PRIMITIVE_FIELD(o, Long, "iJ", "J", 1, 2); 1327 EXPECT_PRIMITIVE_FIELD(o, Short, "iS", "S", 1, 2); 1328 } 1329 1330 TEST_F(JniInternalTest, GetObjectField_SetObjectField) { 1331 TEST_DISABLED_FOR_PORTABLE(); 1332 Thread::Current()->TransitionFromSuspendedToRunnable(); 1333 LoadDex("AllFields"); 1334 runtime_->Start(); 1335 1336 jclass c = env_->FindClass("AllFields"); 1337 ASSERT_NE(c, nullptr); 1338 jobject o = env_->AllocObject(c); 1339 ASSERT_NE(o, nullptr); 1340 1341 jstring s1 = env_->NewStringUTF("hello"); 1342 ASSERT_NE(s1, nullptr); 1343 jstring s2 = env_->NewStringUTF("world"); 1344 ASSERT_NE(s2, nullptr); 1345 1346 jfieldID s_fid = env_->GetStaticFieldID(c, "sObject", "Ljava/lang/Object;"); 1347 ASSERT_NE(s_fid, nullptr); 1348 jfieldID i_fid = env_->GetFieldID(c, "iObject", "Ljava/lang/Object;"); 1349 ASSERT_NE(i_fid, nullptr); 1350 1351 env_->SetStaticObjectField(c, s_fid, s1); 1352 ASSERT_TRUE(env_->IsSameObject(s1, env_->GetStaticObjectField(c, s_fid))); 1353 env_->SetStaticObjectField(c, s_fid, s2); 1354 ASSERT_TRUE(env_->IsSameObject(s2, env_->GetStaticObjectField(c, s_fid))); 1355 1356 env_->SetObjectField(o, i_fid, s1); 1357 ASSERT_TRUE(env_->IsSameObject(s1, env_->GetObjectField(o, i_fid))); 1358 env_->SetObjectField(o, i_fid, s2); 1359 ASSERT_TRUE(env_->IsSameObject(s2, env_->GetObjectField(o, i_fid))); 1360 } 1361 1362 TEST_F(JniInternalTest, NewLocalRef_nullptr) { 1363 EXPECT_EQ(env_->NewLocalRef(nullptr), nullptr); 1364 } 1365 1366 TEST_F(JniInternalTest, NewLocalRef) { 1367 jstring s = env_->NewStringUTF(""); 1368 ASSERT_NE(s, nullptr); 1369 jobject o = env_->NewLocalRef(s); 1370 EXPECT_NE(o, nullptr); 1371 EXPECT_NE(o, s); 1372 1373 EXPECT_EQ(JNILocalRefType, env_->GetObjectRefType(o)); 1374 } 1375 1376 TEST_F(JniInternalTest, DeleteLocalRef_nullptr) { 1377 env_->DeleteLocalRef(nullptr); 1378 } 1379 1380 TEST_F(JniInternalTest, DeleteLocalRef) { 1381 jstring s = env_->NewStringUTF(""); 1382 ASSERT_NE(s, nullptr); 1383 env_->DeleteLocalRef(s); 1384 1385 // Currently, deleting an already-deleted reference is just a CheckJNI warning. 1386 { 1387 CheckJniAbortCatcher check_jni_abort_catcher; 1388 env_->DeleteLocalRef(s); 1389 1390 std::string expected(StringPrintf("native code passing in reference to " 1391 "invalid local reference: %p", s)); 1392 check_jni_abort_catcher.Check(expected.c_str()); 1393 } 1394 1395 s = env_->NewStringUTF(""); 1396 ASSERT_NE(s, nullptr); 1397 jobject o = env_->NewLocalRef(s); 1398 ASSERT_NE(o, nullptr); 1399 1400 env_->DeleteLocalRef(s); 1401 env_->DeleteLocalRef(o); 1402 } 1403 1404 TEST_F(JniInternalTest, PushLocalFrame_10395422) { 1405 // The JNI specification is ambiguous about whether the given capacity is to be interpreted as a 1406 // maximum or as a minimum, but it seems like it's supposed to be a minimum, and that's how 1407 // Android historically treated it, and it's how the RI treats it. It's also the more useful 1408 // interpretation! 1409 ASSERT_EQ(JNI_OK, env_->PushLocalFrame(0)); 1410 env_->PopLocalFrame(nullptr); 1411 1412 // Negative capacities are not allowed. 1413 ASSERT_EQ(JNI_ERR, env_->PushLocalFrame(-1)); 1414 1415 // And it's okay to have an upper limit. Ours is currently 512. 1416 ASSERT_EQ(JNI_ERR, env_->PushLocalFrame(8192)); 1417 } 1418 1419 TEST_F(JniInternalTest, PushLocalFrame_PopLocalFrame) { 1420 jobject original = env_->NewStringUTF(""); 1421 ASSERT_NE(original, nullptr); 1422 1423 jobject outer; 1424 jobject inner1, inner2; 1425 ScopedObjectAccess soa(env_); 1426 mirror::Object* inner2_direct_pointer; 1427 { 1428 ASSERT_EQ(JNI_OK, env_->PushLocalFrame(4)); 1429 outer = env_->NewLocalRef(original); 1430 1431 { 1432 ASSERT_EQ(JNI_OK, env_->PushLocalFrame(4)); 1433 inner1 = env_->NewLocalRef(outer); 1434 inner2 = env_->NewStringUTF("survivor"); 1435 inner2_direct_pointer = soa.Decode<mirror::Object*>(inner2); 1436 env_->PopLocalFrame(inner2); 1437 } 1438 1439 EXPECT_EQ(JNILocalRefType, env_->GetObjectRefType(original)); 1440 EXPECT_EQ(JNILocalRefType, env_->GetObjectRefType(outer)); 1441 EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(inner1)); 1442 1443 // Our local reference for the survivor is invalid because the survivor 1444 // gets a new local reference... 1445 EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(inner2)); 1446 1447 env_->PopLocalFrame(nullptr); 1448 } 1449 EXPECT_EQ(JNILocalRefType, env_->GetObjectRefType(original)); 1450 EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(outer)); 1451 EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(inner1)); 1452 EXPECT_EQ(JNIInvalidRefType, env_->GetObjectRefType(inner2)); 1453 } 1454 1455 TEST_F(JniInternalTest, NewGlobalRef_nullptr) { 1456 EXPECT_EQ(env_->NewGlobalRef(nullptr), nullptr); 1457 } 1458 1459 TEST_F(JniInternalTest, NewGlobalRef) { 1460 jstring s = env_->NewStringUTF(""); 1461 ASSERT_NE(s, nullptr); 1462 jobject o = env_->NewGlobalRef(s); 1463 EXPECT_NE(o, nullptr); 1464 EXPECT_NE(o, s); 1465 1466 EXPECT_EQ(env_->GetObjectRefType(o), JNIGlobalRefType); 1467 } 1468 1469 TEST_F(JniInternalTest, DeleteGlobalRef_nullptr) { 1470 env_->DeleteGlobalRef(nullptr); 1471 } 1472 1473 TEST_F(JniInternalTest, DeleteGlobalRef) { 1474 jstring s = env_->NewStringUTF(""); 1475 ASSERT_NE(s, nullptr); 1476 1477 jobject o = env_->NewGlobalRef(s); 1478 ASSERT_NE(o, nullptr); 1479 env_->DeleteGlobalRef(o); 1480 1481 // Currently, deleting an already-deleted reference is just a CheckJNI warning. 1482 { 1483 CheckJniAbortCatcher check_jni_abort_catcher; 1484 env_->DeleteGlobalRef(o); 1485 1486 std::string expected(StringPrintf("native code passing in reference to " 1487 "invalid global reference: %p", o)); 1488 check_jni_abort_catcher.Check(expected.c_str()); 1489 } 1490 1491 jobject o1 = env_->NewGlobalRef(s); 1492 ASSERT_NE(o1, nullptr); 1493 jobject o2 = env_->NewGlobalRef(s); 1494 ASSERT_NE(o2, nullptr); 1495 1496 env_->DeleteGlobalRef(o1); 1497 env_->DeleteGlobalRef(o2); 1498 } 1499 1500 TEST_F(JniInternalTest, NewWeakGlobalRef_nullptr) { 1501 EXPECT_EQ(env_->NewWeakGlobalRef(nullptr), nullptr); 1502 } 1503 1504 TEST_F(JniInternalTest, NewWeakGlobalRef) { 1505 jstring s = env_->NewStringUTF(""); 1506 ASSERT_NE(s, nullptr); 1507 jobject o = env_->NewWeakGlobalRef(s); 1508 EXPECT_NE(o, nullptr); 1509 EXPECT_NE(o, s); 1510 1511 EXPECT_EQ(env_->GetObjectRefType(o), JNIWeakGlobalRefType); 1512 } 1513 1514 TEST_F(JniInternalTest, DeleteWeakGlobalRef_nullptr) { 1515 env_->DeleteWeakGlobalRef(nullptr); 1516 } 1517 1518 TEST_F(JniInternalTest, DeleteWeakGlobalRef) { 1519 jstring s = env_->NewStringUTF(""); 1520 ASSERT_NE(s, nullptr); 1521 1522 jobject o = env_->NewWeakGlobalRef(s); 1523 ASSERT_NE(o, nullptr); 1524 env_->DeleteWeakGlobalRef(o); 1525 1526 // Currently, deleting an already-deleted reference is just a CheckJNI warning. 1527 { 1528 CheckJniAbortCatcher check_jni_abort_catcher; 1529 env_->DeleteWeakGlobalRef(o); 1530 1531 std::string expected(StringPrintf("native code passing in reference to " 1532 "invalid weak global reference: %p", o)); 1533 check_jni_abort_catcher.Check(expected.c_str()); 1534 } 1535 1536 jobject o1 = env_->NewWeakGlobalRef(s); 1537 ASSERT_NE(o1, nullptr); 1538 jobject o2 = env_->NewWeakGlobalRef(s); 1539 ASSERT_NE(o2, nullptr); 1540 1541 env_->DeleteWeakGlobalRef(o1); 1542 env_->DeleteWeakGlobalRef(o2); 1543 } 1544 1545 TEST_F(JniInternalTest, ExceptionDescribe) { 1546 // This checks how ExceptionDescribe handles call without exception. 1547 env_->ExceptionClear(); 1548 env_->ExceptionDescribe(); 1549 } 1550 1551 TEST_F(JniInternalTest, Throw) { 1552 EXPECT_EQ(JNI_ERR, env_->Throw(nullptr)); 1553 1554 jclass exception_class = env_->FindClass("java/lang/RuntimeException"); 1555 ASSERT_TRUE(exception_class != nullptr); 1556 jthrowable exception = reinterpret_cast<jthrowable>(env_->AllocObject(exception_class)); 1557 ASSERT_TRUE(exception != nullptr); 1558 1559 EXPECT_EQ(JNI_OK, env_->Throw(exception)); 1560 EXPECT_TRUE(env_->ExceptionCheck()); 1561 jthrowable thrown_exception = env_->ExceptionOccurred(); 1562 env_->ExceptionClear(); 1563 EXPECT_TRUE(env_->IsSameObject(exception, thrown_exception)); 1564 } 1565 1566 TEST_F(JniInternalTest, ThrowNew) { 1567 EXPECT_EQ(JNI_ERR, env_->Throw(nullptr)); 1568 1569 jclass exception_class = env_->FindClass("java/lang/RuntimeException"); 1570 ASSERT_TRUE(exception_class != nullptr); 1571 1572 jthrowable thrown_exception; 1573 1574 EXPECT_EQ(JNI_OK, env_->ThrowNew(exception_class, "hello world")); 1575 EXPECT_TRUE(env_->ExceptionCheck()); 1576 thrown_exception = env_->ExceptionOccurred(); 1577 env_->ExceptionClear(); 1578 EXPECT_TRUE(env_->IsInstanceOf(thrown_exception, exception_class)); 1579 1580 EXPECT_EQ(JNI_OK, env_->ThrowNew(exception_class, nullptr)); 1581 EXPECT_TRUE(env_->ExceptionCheck()); 1582 thrown_exception = env_->ExceptionOccurred(); 1583 env_->ExceptionClear(); 1584 EXPECT_TRUE(env_->IsInstanceOf(thrown_exception, exception_class)); 1585 } 1586 1587 TEST_F(JniInternalTest, NewDirectBuffer_GetDirectBufferAddress_GetDirectBufferCapacity) { 1588 // Start runtime. 1589 Thread* self = Thread::Current(); 1590 self->TransitionFromSuspendedToRunnable(); 1591 MakeExecutable(nullptr, "java.lang.Class"); 1592 MakeExecutable(nullptr, "java.lang.Object"); 1593 MakeExecutable(nullptr, "java.nio.DirectByteBuffer"); 1594 MakeExecutable(nullptr, "java.nio.MemoryBlock"); 1595 MakeExecutable(nullptr, "java.nio.MemoryBlock$UnmanagedBlock"); 1596 MakeExecutable(nullptr, "java.nio.MappedByteBuffer"); 1597 MakeExecutable(nullptr, "java.nio.ByteBuffer"); 1598 MakeExecutable(nullptr, "java.nio.Buffer"); 1599 // TODO: we only load a dex file here as starting the runtime relies upon it. 1600 const char* class_name = "StaticLeafMethods"; 1601 LoadDex(class_name); 1602 bool started = runtime_->Start(); 1603 ASSERT_TRUE(started); 1604 1605 jclass buffer_class = env_->FindClass("java/nio/Buffer"); 1606 ASSERT_NE(buffer_class, nullptr); 1607 1608 char bytes[1024]; 1609 jobject buffer = env_->NewDirectByteBuffer(bytes, sizeof(bytes)); 1610 ASSERT_NE(buffer, nullptr); 1611 ASSERT_TRUE(env_->IsInstanceOf(buffer, buffer_class)); 1612 ASSERT_EQ(env_->GetDirectBufferAddress(buffer), bytes); 1613 ASSERT_EQ(env_->GetDirectBufferCapacity(buffer), static_cast<jlong>(sizeof(bytes))); 1614 1615 { 1616 CheckJniAbortCatcher check_jni_abort_catcher; 1617 env_->NewDirectByteBuffer(bytes, static_cast<jlong>(INT_MAX) + 1); 1618 check_jni_abort_catcher.Check("in call to NewDirectByteBuffer"); 1619 } 1620 } 1621 1622 TEST_F(JniInternalTest, MonitorEnterExit) { 1623 // Create an object to torture. 1624 jclass object_class = env_->FindClass("java/lang/Object"); 1625 ASSERT_NE(object_class, nullptr); 1626 jobject object = env_->AllocObject(object_class); 1627 ASSERT_NE(object, nullptr); 1628 1629 // Expected class of exceptions 1630 jclass imse_class = env_->FindClass("java/lang/IllegalMonitorStateException"); 1631 ASSERT_NE(imse_class, nullptr); 1632 1633 jthrowable thrown_exception; 1634 1635 // Unlock of unowned monitor 1636 env_->MonitorExit(object); 1637 EXPECT_TRUE(env_->ExceptionCheck()); 1638 thrown_exception = env_->ExceptionOccurred(); 1639 env_->ExceptionClear(); 1640 EXPECT_TRUE(env_->IsInstanceOf(thrown_exception, imse_class)); 1641 1642 // Lock of unowned monitor 1643 env_->MonitorEnter(object); 1644 EXPECT_FALSE(env_->ExceptionCheck()); 1645 // Regular unlock 1646 env_->MonitorExit(object); 1647 EXPECT_FALSE(env_->ExceptionCheck()); 1648 1649 // Recursively lock a lot 1650 size_t max_recursive_lock = 1024; 1651 for (size_t i = 0; i < max_recursive_lock; i++) { 1652 env_->MonitorEnter(object); 1653 EXPECT_FALSE(env_->ExceptionCheck()); 1654 } 1655 // Recursively unlock a lot 1656 for (size_t i = 0; i < max_recursive_lock; i++) { 1657 env_->MonitorExit(object); 1658 EXPECT_FALSE(env_->ExceptionCheck()); 1659 } 1660 1661 // Unlock of unowned monitor 1662 env_->MonitorExit(object); 1663 EXPECT_TRUE(env_->ExceptionCheck()); 1664 thrown_exception = env_->ExceptionOccurred(); 1665 env_->ExceptionClear(); 1666 EXPECT_TRUE(env_->IsInstanceOf(thrown_exception, imse_class)); 1667 1668 // It's an error to call MonitorEnter or MonitorExit on nullptr. 1669 { 1670 CheckJniAbortCatcher check_jni_abort_catcher; 1671 env_->MonitorEnter(nullptr); 1672 check_jni_abort_catcher.Check("in call to MonitorEnter"); 1673 env_->MonitorExit(nullptr); 1674 check_jni_abort_catcher.Check("in call to MonitorExit"); 1675 } 1676 } 1677 1678 TEST_F(JniInternalTest, DetachCurrentThread) { 1679 CleanUpJniEnv(); // cleanup now so TearDown won't have junk from wrong JNIEnv 1680 jint ok = vm_->DetachCurrentThread(); 1681 EXPECT_EQ(JNI_OK, ok); 1682 1683 jint err = vm_->DetachCurrentThread(); 1684 EXPECT_EQ(JNI_ERR, err); 1685 vm_->AttachCurrentThread(&env_, nullptr); // need attached thread for CommonRuntimeTest::TearDown 1686 } 1687 1688 } // namespace art 1689