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