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