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