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