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