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