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