1 /*
2 * Copyright (C) 2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "java_lang_Class.h"
18
19 #include <iostream>
20
21 #include "art_field-inl.h"
22 #include "art_method-inl.h"
23 #include "base/enums.h"
24 #include "class_linker-inl.h"
25 #include "class_root-inl.h"
26 #include "common_throws.h"
27 #include "compat_framework.h"
28 #include "dex/descriptors_names.h"
29 #include "dex/dex_file-inl.h"
30 #include "dex/dex_file_annotations.h"
31 #include "dex/utf.h"
32 #include "hidden_api.h"
33 #include "jni/jni_internal.h"
34 #include "mirror/class-alloc-inl.h"
35 #include "mirror/class-inl.h"
36 #include "mirror/class_loader.h"
37 #include "mirror/field.h"
38 #include "mirror/method.h"
39 #include "mirror/method_handles_lookup.h"
40 #include "mirror/object-inl.h"
41 #include "mirror/object_array-alloc-inl.h"
42 #include "mirror/object_array-inl.h"
43 #include "mirror/proxy.h"
44 #include "mirror/string-alloc-inl.h"
45 #include "mirror/string-inl.h"
46 #include "native_util.h"
47 #include "nativehelper/jni_macros.h"
48 #include "nativehelper/scoped_local_ref.h"
49 #include "nativehelper/scoped_utf_chars.h"
50 #include "nth_caller_visitor.h"
51 #include "obj_ptr-inl.h"
52 #include "reflection.h"
53 #include "reflective_handle_scope-inl.h"
54 #include "scoped_fast_native_object_access-inl.h"
55 #include "scoped_thread_state_change-inl.h"
56 #include "well_known_classes.h"
57
58 namespace art {
59
GetHiddenapiAccessContextFunction(Thread * self)60 static std::function<hiddenapi::AccessContext()> GetHiddenapiAccessContextFunction(Thread* self) {
61 return [=]() REQUIRES_SHARED(Locks::mutator_lock_) {
62 return hiddenapi::GetReflectionCallerAccessContext(self);
63 };
64 }
65
66 // Returns true if the first non-ClassClass caller up the stack should not be
67 // allowed access to `member`.
68 template<typename T>
ShouldDenyAccessToMember(T * member,Thread * self)69 ALWAYS_INLINE static bool ShouldDenyAccessToMember(T* member, Thread* self)
70 REQUIRES_SHARED(Locks::mutator_lock_) {
71 return hiddenapi::ShouldDenyAccessToMember(member,
72 GetHiddenapiAccessContextFunction(self),
73 hiddenapi::AccessMethod::kReflection);
74 }
75
DecodeClass(const ScopedFastNativeObjectAccess & soa,jobject java_class)76 ALWAYS_INLINE static inline ObjPtr<mirror::Class> DecodeClass(
77 const ScopedFastNativeObjectAccess& soa, jobject java_class)
78 REQUIRES_SHARED(Locks::mutator_lock_) {
79 ObjPtr<mirror::Class> c = soa.Decode<mirror::Class>(java_class);
80 DCHECK(c != nullptr);
81 DCHECK(c->IsClass());
82 // TODO: we could EnsureInitialized here, rather than on every reflective get/set or invoke .
83 // For now, we conservatively preserve the old dalvik behavior. A quick "IsInitialized" check
84 // every time probably doesn't make much difference to reflection performance anyway.
85 return c;
86 }
87
88 // "name" is in "binary name" format, e.g. "dalvik.system.Debug$1".
Class_classForName(JNIEnv * env,jclass,jstring javaName,jboolean initialize,jobject javaLoader)89 static jclass Class_classForName(JNIEnv* env, jclass, jstring javaName, jboolean initialize,
90 jobject javaLoader) {
91 ScopedFastNativeObjectAccess soa(env);
92 ScopedUtfChars name(env, javaName);
93 if (name.c_str() == nullptr) {
94 return nullptr;
95 }
96
97 // We need to validate and convert the name (from x.y.z to x/y/z). This
98 // is especially handy for array types, since we want to avoid
99 // auto-generating bogus array classes.
100 if (!IsValidBinaryClassName(name.c_str())) {
101 soa.Self()->ThrowNewExceptionF("Ljava/lang/ClassNotFoundException;",
102 "Invalid name: %s", name.c_str());
103 return nullptr;
104 }
105
106 std::string descriptor(DotToDescriptor(name.c_str()));
107 StackHandleScope<2> hs(soa.Self());
108 Handle<mirror::ClassLoader> class_loader(
109 hs.NewHandle(soa.Decode<mirror::ClassLoader>(javaLoader)));
110 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
111 Handle<mirror::Class> c(
112 hs.NewHandle(class_linker->FindClass(soa.Self(), descriptor.c_str(), class_loader)));
113 if (c == nullptr) {
114 ScopedLocalRef<jthrowable> cause(env, env->ExceptionOccurred());
115 env->ExceptionClear();
116 jthrowable cnfe = reinterpret_cast<jthrowable>(
117 env->NewObject(WellKnownClasses::java_lang_ClassNotFoundException,
118 WellKnownClasses::java_lang_ClassNotFoundException_init,
119 javaName,
120 cause.get()));
121 if (cnfe != nullptr) {
122 // Make sure allocation didn't fail with an OOME.
123 env->Throw(cnfe);
124 }
125 return nullptr;
126 }
127 if (initialize) {
128 class_linker->EnsureInitialized(soa.Self(), c, true, true);
129 }
130 return soa.AddLocalReference<jclass>(c.Get());
131 }
132
Class_getPrimitiveClass(JNIEnv * env,jclass,jstring name)133 static jclass Class_getPrimitiveClass(JNIEnv* env, jclass, jstring name) {
134 ScopedFastNativeObjectAccess soa(env);
135 ObjPtr<mirror::Class> klass = mirror::Class::GetPrimitiveClass(soa.Decode<mirror::String>(name));
136 return soa.AddLocalReference<jclass>(klass);
137 }
138
Class_getNameNative(JNIEnv * env,jobject javaThis)139 static jstring Class_getNameNative(JNIEnv* env, jobject javaThis) {
140 ScopedFastNativeObjectAccess soa(env);
141 StackHandleScope<1> hs(soa.Self());
142 ObjPtr<mirror::Class> c = DecodeClass(soa, javaThis);
143 return soa.AddLocalReference<jstring>(mirror::Class::ComputeName(hs.NewHandle(c)));
144 }
145
Class_getInterfacesInternal(JNIEnv * env,jobject javaThis)146 static jobjectArray Class_getInterfacesInternal(JNIEnv* env, jobject javaThis) {
147 ScopedFastNativeObjectAccess soa(env);
148 StackHandleScope<1> hs(soa.Self());
149 Handle<mirror::Class> klass = hs.NewHandle(DecodeClass(soa, javaThis));
150 if (klass->IsObsoleteObject()) {
151 ThrowRuntimeException("Obsolete Object!");
152 return nullptr;
153 }
154
155 if (klass->IsProxyClass()) {
156 StackHandleScope<1> hs2(soa.Self());
157 Handle<mirror::ObjectArray<mirror::Class>> interfaces =
158 hs2.NewHandle(klass->GetProxyInterfaces());
159 return soa.AddLocalReference<jobjectArray>(
160 mirror::ObjectArray<mirror::Class>::Clone(interfaces, soa.Self()));
161 }
162
163 const dex::TypeList* iface_list = klass->GetInterfaceTypeList();
164 if (iface_list == nullptr) {
165 return nullptr;
166 }
167
168 ClassLinker* linker = Runtime::Current()->GetClassLinker();
169 const uint32_t num_ifaces = iface_list->Size();
170 ObjPtr<mirror::Class> class_array_class =
171 GetClassRoot<mirror::ObjectArray<mirror::Class>>(linker);
172 ObjPtr<mirror::ObjectArray<mirror::Class>> ifaces =
173 mirror::ObjectArray<mirror::Class>::Alloc(soa.Self(), class_array_class, num_ifaces);
174 if (ifaces.IsNull()) {
175 DCHECK(soa.Self()->IsExceptionPending());
176 return nullptr;
177 }
178
179 // Check that we aren't in an active transaction, we call SetWithoutChecks
180 // with kActiveTransaction == false.
181 DCHECK(!Runtime::Current()->IsActiveTransaction());
182
183 for (uint32_t i = 0; i < num_ifaces; ++i) {
184 const dex::TypeIndex type_idx = iface_list->GetTypeItem(i).type_idx_;
185 ObjPtr<mirror::Class> interface = linker->LookupResolvedType(type_idx, klass.Get());
186 DCHECK(interface != nullptr);
187 ifaces->SetWithoutChecks<false>(i, interface);
188 }
189
190 return soa.AddLocalReference<jobjectArray>(ifaces);
191 }
192
Class_getDeclaredFieldsUnchecked(JNIEnv * env,jobject javaThis,jboolean publicOnly)193 static jobjectArray Class_getDeclaredFieldsUnchecked(JNIEnv* env, jobject javaThis,
194 jboolean publicOnly) {
195 ScopedFastNativeObjectAccess soa(env);
196 ObjPtr<mirror::Class> klass = DecodeClass(soa, javaThis);
197 return soa.AddLocalReference<jobjectArray>(
198 klass->GetDeclaredFields(soa.Self(),
199 publicOnly != JNI_FALSE,
200 /*force_resolve=*/ false));
201 }
202
Class_getDeclaredFields(JNIEnv * env,jobject javaThis)203 static jobjectArray Class_getDeclaredFields(JNIEnv* env, jobject javaThis) {
204 ScopedFastNativeObjectAccess soa(env);
205 ObjPtr<mirror::Class> klass = DecodeClass(soa, javaThis);
206 return soa.AddLocalReference<jobjectArray>(
207 klass->GetDeclaredFields(soa.Self(),
208 /*public_only=*/ false,
209 /*force_resolve=*/ true));
210 }
211
Class_getPublicDeclaredFields(JNIEnv * env,jobject javaThis)212 static jobjectArray Class_getPublicDeclaredFields(JNIEnv* env, jobject javaThis) {
213 ScopedFastNativeObjectAccess soa(env);
214 ObjPtr<mirror::Class> klass = DecodeClass(soa, javaThis);
215 return soa.AddLocalReference<jobjectArray>(
216 klass->GetDeclaredFields(soa.Self(),
217 /*public_only=*/ true,
218 /*force_resolve=*/ true));
219 }
220
221 // Performs a binary search through an array of fields, TODO: Is this fast enough if we don't use
222 // the dex cache for lookups? I think CompareModifiedUtf8ToUtf16AsCodePointValues should be fairly
223 // fast.
FindFieldByName(ObjPtr<mirror::String> name,LengthPrefixedArray<ArtField> * fields)224 ALWAYS_INLINE static inline ArtField* FindFieldByName(ObjPtr<mirror::String> name,
225 LengthPrefixedArray<ArtField>* fields)
226 REQUIRES_SHARED(Locks::mutator_lock_) {
227 if (fields == nullptr) {
228 return nullptr;
229 }
230 size_t low = 0;
231 size_t high = fields->size();
232 const bool is_name_compressed = name->IsCompressed();
233 const uint16_t* const data = (is_name_compressed) ? nullptr : name->GetValue();
234 const uint8_t* const data_compressed = (is_name_compressed) ? name->GetValueCompressed()
235 : nullptr;
236 const size_t length = name->GetLength();
237 while (low < high) {
238 auto mid = (low + high) / 2;
239 ArtField& field = fields->At(mid);
240 int result = 0;
241 if (is_name_compressed) {
242 size_t field_length = strlen(field.GetName());
243 size_t min_size = (length < field_length) ? length : field_length;
244 result = memcmp(field.GetName(), data_compressed, min_size);
245 if (result == 0) {
246 result = field_length - length;
247 }
248 } else {
249 result = CompareModifiedUtf8ToUtf16AsCodePointValues(field.GetName(), data, length);
250 }
251 // Alternate approach, only a few % faster at the cost of more allocations.
252 // int result = field->GetStringName(self, true)->CompareTo(name);
253 if (result < 0) {
254 low = mid + 1;
255 } else if (result > 0) {
256 high = mid;
257 } else {
258 return &field;
259 }
260 }
261 if (kIsDebugBuild) {
262 for (ArtField& field : MakeIterationRangeFromLengthPrefixedArray(fields)) {
263 CHECK_NE(field.GetName(), name->ToModifiedUtf8());
264 }
265 }
266 return nullptr;
267 }
268
GetDeclaredField(Thread * self,ObjPtr<mirror::Class> c,ObjPtr<mirror::String> name)269 ALWAYS_INLINE static inline ObjPtr<mirror::Field> GetDeclaredField(Thread* self,
270 ObjPtr<mirror::Class> c,
271 ObjPtr<mirror::String> name)
272 REQUIRES_SHARED(Locks::mutator_lock_) {
273 if (UNLIKELY(c->IsObsoleteObject())) {
274 ThrowRuntimeException("Obsolete Object!");
275 return nullptr;
276 }
277 ArtField* art_field = FindFieldByName(name, c->GetIFieldsPtr());
278 if (art_field != nullptr) {
279 return mirror::Field::CreateFromArtField(self, art_field, true);
280 }
281 art_field = FindFieldByName(name, c->GetSFieldsPtr());
282 if (art_field != nullptr) {
283 return mirror::Field::CreateFromArtField(self, art_field, true);
284 }
285 return nullptr;
286 }
287
GetPublicFieldRecursive(Thread * self,ObjPtr<mirror::Class> clazz,ObjPtr<mirror::String> name)288 static ObjPtr<mirror::Field> GetPublicFieldRecursive(
289 Thread* self, ObjPtr<mirror::Class> clazz, ObjPtr<mirror::String> name)
290 REQUIRES_SHARED(Locks::mutator_lock_) {
291 DCHECK(clazz != nullptr);
292 DCHECK(name != nullptr);
293 DCHECK(self != nullptr);
294
295 if (UNLIKELY(clazz->IsObsoleteObject())) {
296 ThrowRuntimeException("Obsolete Object!");
297 return nullptr;
298 }
299 StackHandleScope<2> hs(self);
300 MutableHandle<mirror::Class> h_clazz(hs.NewHandle(clazz));
301 Handle<mirror::String> h_name(hs.NewHandle(name));
302
303 // We search the current class, its direct interfaces then its superclass.
304 while (h_clazz != nullptr) {
305 ObjPtr<mirror::Field> result = GetDeclaredField(self, h_clazz.Get(), h_name.Get());
306 if ((result != nullptr) && (result->GetAccessFlags() & kAccPublic)) {
307 return result;
308 } else if (UNLIKELY(self->IsExceptionPending())) {
309 // Something went wrong. Bail out.
310 return nullptr;
311 }
312
313 uint32_t num_direct_interfaces = h_clazz->NumDirectInterfaces();
314 for (uint32_t i = 0; i < num_direct_interfaces; i++) {
315 ObjPtr<mirror::Class> iface = mirror::Class::ResolveDirectInterface(self, h_clazz, i);
316 if (UNLIKELY(iface == nullptr)) {
317 self->AssertPendingException();
318 return nullptr;
319 }
320 result = GetPublicFieldRecursive(self, iface, h_name.Get());
321 if (result != nullptr) {
322 DCHECK(result->GetAccessFlags() & kAccPublic);
323 return result;
324 } else if (UNLIKELY(self->IsExceptionPending())) {
325 // Something went wrong. Bail out.
326 return nullptr;
327 }
328 }
329
330 // We don't try the superclass if we are an interface.
331 if (h_clazz->IsInterface()) {
332 break;
333 }
334
335 // Get the next class.
336 h_clazz.Assign(h_clazz->GetSuperClass());
337 }
338 return nullptr;
339 }
340
Class_getPublicFieldRecursive(JNIEnv * env,jobject javaThis,jstring name)341 static jobject Class_getPublicFieldRecursive(JNIEnv* env, jobject javaThis, jstring name) {
342 ScopedFastNativeObjectAccess soa(env);
343 auto name_string = soa.Decode<mirror::String>(name);
344 if (UNLIKELY(name_string == nullptr)) {
345 ThrowNullPointerException("name == null");
346 return nullptr;
347 }
348
349 StackHandleScope<1> hs(soa.Self());
350 Handle<mirror::Field> field = hs.NewHandle(GetPublicFieldRecursive(
351 soa.Self(), DecodeClass(soa, javaThis), name_string));
352 if (field.Get() == nullptr || ShouldDenyAccessToMember(field->GetArtField(), soa.Self())) {
353 return nullptr;
354 }
355 return soa.AddLocalReference<jobject>(field.Get());
356 }
357
Class_getDeclaredField(JNIEnv * env,jobject javaThis,jstring name)358 static jobject Class_getDeclaredField(JNIEnv* env, jobject javaThis, jstring name) {
359 ScopedFastNativeObjectAccess soa(env);
360 StackHandleScope<3> hs(soa.Self());
361 Handle<mirror::String> h_string = hs.NewHandle(soa.Decode<mirror::String>(name));
362 if (h_string == nullptr) {
363 ThrowNullPointerException("name == null");
364 return nullptr;
365 }
366 Handle<mirror::Class> h_klass = hs.NewHandle(DecodeClass(soa, javaThis));
367 Handle<mirror::Field> result =
368 hs.NewHandle(GetDeclaredField(soa.Self(), h_klass.Get(), h_string.Get()));
369 if (result == nullptr || ShouldDenyAccessToMember(result->GetArtField(), soa.Self())) {
370 std::string name_str = h_string->ToModifiedUtf8();
371 if (name_str == "value" && h_klass->IsStringClass()) {
372 // We log the error for this specific case, as the user might just swallow the exception.
373 // This helps diagnose crashes when applications rely on the String#value field being
374 // there.
375 // Also print on the error stream to test it through run-test.
376 std::string message("The String#value field is not present on Android versions >= 6.0");
377 LOG(ERROR) << message;
378 std::cerr << message << std::endl;
379 }
380 // We may have a pending exception if we failed to resolve.
381 if (!soa.Self()->IsExceptionPending()) {
382 ThrowNoSuchFieldException(h_klass.Get(), name_str.c_str());
383 }
384 return nullptr;
385 }
386 return soa.AddLocalReference<jobject>(result.Get());
387 }
388
Class_getDeclaredConstructorInternal(JNIEnv * env,jobject javaThis,jobjectArray args)389 static jobject Class_getDeclaredConstructorInternal(
390 JNIEnv* env, jobject javaThis, jobjectArray args) {
391 ScopedFastNativeObjectAccess soa(env);
392 DCHECK_EQ(Runtime::Current()->GetClassLinker()->GetImagePointerSize(), kRuntimePointerSize);
393 DCHECK(!Runtime::Current()->IsActiveTransaction());
394
395 StackHandleScope<1> hs(soa.Self());
396 ObjPtr<mirror::Class> klass = DecodeClass(soa, javaThis);
397 if (UNLIKELY(klass->IsObsoleteObject())) {
398 ThrowRuntimeException("Obsolete Object!");
399 return nullptr;
400 }
401 Handle<mirror::Constructor> result = hs.NewHandle(
402 mirror::Class::GetDeclaredConstructorInternal<kRuntimePointerSize>(
403 soa.Self(),
404 klass,
405 soa.Decode<mirror::ObjectArray<mirror::Class>>(args)));
406 if (result == nullptr || ShouldDenyAccessToMember(result->GetArtMethod(), soa.Self())) {
407 return nullptr;
408 }
409 return soa.AddLocalReference<jobject>(result.Get());
410 }
411
MethodMatchesConstructor(ArtMethod * m,bool public_only,const hiddenapi::AccessContext & hiddenapi_context)412 static ALWAYS_INLINE inline bool MethodMatchesConstructor(
413 ArtMethod* m,
414 bool public_only,
415 const hiddenapi::AccessContext& hiddenapi_context) REQUIRES_SHARED(Locks::mutator_lock_) {
416 DCHECK(m != nullptr);
417 return m->IsConstructor() &&
418 !m->IsStatic() &&
419 mirror::Class::IsDiscoverable(public_only, hiddenapi_context, m);
420 }
421
Class_getDeclaredConstructorsInternal(JNIEnv * env,jobject javaThis,jboolean publicOnly)422 static jobjectArray Class_getDeclaredConstructorsInternal(
423 JNIEnv* env, jobject javaThis, jboolean publicOnly) {
424 ScopedFastNativeObjectAccess soa(env);
425 StackHandleScope<2> hs(soa.Self());
426 bool public_only = (publicOnly != JNI_FALSE);
427 auto hiddenapi_context = hiddenapi::GetReflectionCallerAccessContext(soa.Self());
428 Handle<mirror::Class> h_klass = hs.NewHandle(DecodeClass(soa, javaThis));
429 if (UNLIKELY(h_klass->IsObsoleteObject())) {
430 ThrowRuntimeException("Obsolete Object!");
431 return nullptr;
432 }
433 size_t constructor_count = 0;
434 // Two pass approach for speed.
435 for (auto& m : h_klass->GetDirectMethods(kRuntimePointerSize)) {
436 constructor_count += MethodMatchesConstructor(&m, public_only, hiddenapi_context) ? 1u : 0u;
437 }
438 auto h_constructors = hs.NewHandle(mirror::ObjectArray<mirror::Constructor>::Alloc(
439 soa.Self(), GetClassRoot<mirror::ObjectArray<mirror::Constructor>>(), constructor_count));
440 if (UNLIKELY(h_constructors == nullptr)) {
441 soa.Self()->AssertPendingException();
442 return nullptr;
443 }
444 constructor_count = 0;
445 for (auto& m : h_klass->GetDirectMethods(kRuntimePointerSize)) {
446 if (MethodMatchesConstructor(&m, public_only, hiddenapi_context)) {
447 DCHECK_EQ(Runtime::Current()->GetClassLinker()->GetImagePointerSize(), kRuntimePointerSize);
448 DCHECK(!Runtime::Current()->IsActiveTransaction());
449 ObjPtr<mirror::Constructor> constructor =
450 mirror::Constructor::CreateFromArtMethod<kRuntimePointerSize>(soa.Self(), &m);
451 if (UNLIKELY(constructor == nullptr)) {
452 soa.Self()->AssertPendingOOMException();
453 return nullptr;
454 }
455 h_constructors->SetWithoutChecks<false>(constructor_count++, constructor);
456 }
457 }
458 return soa.AddLocalReference<jobjectArray>(h_constructors.Get());
459 }
460
Class_getDeclaredMethodInternal(JNIEnv * env,jobject javaThis,jstring name,jobjectArray args)461 static jobject Class_getDeclaredMethodInternal(JNIEnv* env, jobject javaThis,
462 jstring name, jobjectArray args) {
463 ScopedFastNativeObjectAccess soa(env);
464 StackHandleScope<1> hs(soa.Self());
465 DCHECK_EQ(Runtime::Current()->GetClassLinker()->GetImagePointerSize(), kRuntimePointerSize);
466 DCHECK(!Runtime::Current()->IsActiveTransaction());
467 ObjPtr<mirror::Class> klass = DecodeClass(soa, javaThis);
468 if (UNLIKELY(klass->IsObsoleteObject())) {
469 ThrowRuntimeException("Obsolete Object!");
470 return nullptr;
471 }
472 Handle<mirror::Method> result = hs.NewHandle(
473 mirror::Class::GetDeclaredMethodInternal<kRuntimePointerSize>(
474 soa.Self(),
475 klass,
476 soa.Decode<mirror::String>(name),
477 soa.Decode<mirror::ObjectArray<mirror::Class>>(args),
478 GetHiddenapiAccessContextFunction(soa.Self())));
479 if (result == nullptr || ShouldDenyAccessToMember(result->GetArtMethod(), soa.Self())) {
480 return nullptr;
481 }
482 return soa.AddLocalReference<jobject>(result.Get());
483 }
484
Class_getDeclaredMethodsUnchecked(JNIEnv * env,jobject javaThis,jboolean publicOnly)485 static jobjectArray Class_getDeclaredMethodsUnchecked(JNIEnv* env, jobject javaThis,
486 jboolean publicOnly) {
487 ScopedFastNativeObjectAccess soa(env);
488 StackHandleScope<2> hs(soa.Self());
489
490 auto hiddenapi_context = hiddenapi::GetReflectionCallerAccessContext(soa.Self());
491 bool public_only = (publicOnly != JNI_FALSE);
492
493 Handle<mirror::Class> klass = hs.NewHandle(DecodeClass(soa, javaThis));
494 if (klass->IsObsoleteObject()) {
495 ThrowRuntimeException("Obsolete Object!");
496 return nullptr;
497 }
498 size_t num_methods = 0;
499 for (ArtMethod& m : klass->GetDeclaredMethods(kRuntimePointerSize)) {
500 uint32_t modifiers = m.GetAccessFlags();
501 // Add non-constructor declared methods.
502 if ((modifiers & kAccConstructor) == 0 &&
503 mirror::Class::IsDiscoverable(public_only, hiddenapi_context, &m)) {
504 ++num_methods;
505 }
506 }
507 auto ret = hs.NewHandle(mirror::ObjectArray<mirror::Method>::Alloc(
508 soa.Self(), GetClassRoot<mirror::ObjectArray<mirror::Method>>(), num_methods));
509 if (ret == nullptr) {
510 soa.Self()->AssertPendingOOMException();
511 return nullptr;
512 }
513 num_methods = 0;
514 for (ArtMethod& m : klass->GetDeclaredMethods(kRuntimePointerSize)) {
515 uint32_t modifiers = m.GetAccessFlags();
516 if ((modifiers & kAccConstructor) == 0 &&
517 mirror::Class::IsDiscoverable(public_only, hiddenapi_context, &m)) {
518 DCHECK_EQ(Runtime::Current()->GetClassLinker()->GetImagePointerSize(), kRuntimePointerSize);
519 DCHECK(!Runtime::Current()->IsActiveTransaction());
520 ObjPtr<mirror::Method> method =
521 mirror::Method::CreateFromArtMethod<kRuntimePointerSize>(soa.Self(), &m);
522 if (method == nullptr) {
523 soa.Self()->AssertPendingException();
524 return nullptr;
525 }
526 ret->SetWithoutChecks<false>(num_methods++, method);
527 }
528 }
529 return soa.AddLocalReference<jobjectArray>(ret.Get());
530 }
531
Class_getDeclaredAnnotation(JNIEnv * env,jobject javaThis,jclass annotationClass)532 static jobject Class_getDeclaredAnnotation(JNIEnv* env, jobject javaThis, jclass annotationClass) {
533 ScopedFastNativeObjectAccess soa(env);
534 StackHandleScope<2> hs(soa.Self());
535 Handle<mirror::Class> klass(hs.NewHandle(DecodeClass(soa, javaThis)));
536 if (klass->IsObsoleteObject()) {
537 ThrowRuntimeException("Obsolete Object!");
538 return nullptr;
539 }
540
541 // Handle public contract to throw NPE if the "annotationClass" argument was null.
542 if (UNLIKELY(annotationClass == nullptr)) {
543 ThrowNullPointerException("annotationClass");
544 return nullptr;
545 }
546
547 if (klass->IsProxyClass() || klass->GetDexCache() == nullptr) {
548 return nullptr;
549 }
550 Handle<mirror::Class> annotation_class(hs.NewHandle(soa.Decode<mirror::Class>(annotationClass)));
551 return soa.AddLocalReference<jobject>(
552 annotations::GetAnnotationForClass(klass, annotation_class));
553 }
554
Class_getDeclaredAnnotations(JNIEnv * env,jobject javaThis)555 static jobjectArray Class_getDeclaredAnnotations(JNIEnv* env, jobject javaThis) {
556 ScopedFastNativeObjectAccess soa(env);
557 StackHandleScope<1> hs(soa.Self());
558 Handle<mirror::Class> klass(hs.NewHandle(DecodeClass(soa, javaThis)));
559 if (klass->IsObsoleteObject()) {
560 ThrowRuntimeException("Obsolete Object!");
561 return nullptr;
562 }
563 if (klass->IsProxyClass() || klass->GetDexCache() == nullptr) {
564 // Return an empty array instead of a null pointer.
565 ObjPtr<mirror::Class> annotation_array_class =
566 soa.Decode<mirror::Class>(WellKnownClasses::java_lang_annotation_Annotation__array);
567 ObjPtr<mirror::ObjectArray<mirror::Object>> empty_array =
568 mirror::ObjectArray<mirror::Object>::Alloc(soa.Self(),
569 annotation_array_class,
570 /* length= */ 0);
571 return soa.AddLocalReference<jobjectArray>(empty_array);
572 }
573 return soa.AddLocalReference<jobjectArray>(annotations::GetAnnotationsForClass(klass));
574 }
575
Class_getDeclaredClasses(JNIEnv * env,jobject javaThis)576 static jobjectArray Class_getDeclaredClasses(JNIEnv* env, jobject javaThis) {
577 ScopedFastNativeObjectAccess soa(env);
578 StackHandleScope<1> hs(soa.Self());
579 Handle<mirror::Class> klass(hs.NewHandle(DecodeClass(soa, javaThis)));
580 if (klass->IsObsoleteObject()) {
581 ThrowRuntimeException("Obsolete Object!");
582 return nullptr;
583 }
584 ObjPtr<mirror::ObjectArray<mirror::Class>> classes = nullptr;
585 if (!klass->IsProxyClass() && klass->GetDexCache() != nullptr) {
586 classes = annotations::GetDeclaredClasses(klass);
587 }
588 if (classes == nullptr) {
589 // Return an empty array instead of a null pointer.
590 if (soa.Self()->IsExceptionPending()) {
591 // Pending exception from GetDeclaredClasses.
592 return nullptr;
593 }
594 ObjPtr<mirror::Class> class_array_class = GetClassRoot<mirror::ObjectArray<mirror::Class>>();
595 DCHECK(class_array_class != nullptr);
596 ObjPtr<mirror::ObjectArray<mirror::Class>> empty_array =
597 mirror::ObjectArray<mirror::Class>::Alloc(soa.Self(), class_array_class, 0);
598 return soa.AddLocalReference<jobjectArray>(empty_array);
599 }
600 return soa.AddLocalReference<jobjectArray>(classes);
601 }
602
Class_getEnclosingClass(JNIEnv * env,jobject javaThis)603 static jclass Class_getEnclosingClass(JNIEnv* env, jobject javaThis) {
604 ScopedFastNativeObjectAccess soa(env);
605 StackHandleScope<1> hs(soa.Self());
606 Handle<mirror::Class> klass(hs.NewHandle(DecodeClass(soa, javaThis)));
607 if (klass->IsObsoleteObject()) {
608 ThrowRuntimeException("Obsolete Object!");
609 return nullptr;
610 }
611 if (klass->IsProxyClass() || klass->GetDexCache() == nullptr) {
612 return nullptr;
613 }
614 return soa.AddLocalReference<jclass>(annotations::GetEnclosingClass(klass));
615 }
616
Class_getEnclosingConstructorNative(JNIEnv * env,jobject javaThis)617 static jobject Class_getEnclosingConstructorNative(JNIEnv* env, jobject javaThis) {
618 ScopedFastNativeObjectAccess soa(env);
619 StackHandleScope<1> hs(soa.Self());
620 Handle<mirror::Class> klass(hs.NewHandle(DecodeClass(soa, javaThis)));
621 if (klass->IsObsoleteObject()) {
622 ThrowRuntimeException("Obsolete Object!");
623 return nullptr;
624 }
625 if (klass->IsProxyClass() || klass->GetDexCache() == nullptr) {
626 return nullptr;
627 }
628 ObjPtr<mirror::Object> method = annotations::GetEnclosingMethod(klass);
629 if (method != nullptr) {
630 if (GetClassRoot<mirror::Constructor>() == method->GetClass()) {
631 return soa.AddLocalReference<jobject>(method);
632 }
633 }
634 return nullptr;
635 }
636
Class_getEnclosingMethodNative(JNIEnv * env,jobject javaThis)637 static jobject Class_getEnclosingMethodNative(JNIEnv* env, jobject javaThis) {
638 ScopedFastNativeObjectAccess soa(env);
639 StackHandleScope<1> hs(soa.Self());
640 Handle<mirror::Class> klass(hs.NewHandle(DecodeClass(soa, javaThis)));
641 if (klass->IsObsoleteObject()) {
642 ThrowRuntimeException("Obsolete Object!");
643 return nullptr;
644 }
645 if (klass->IsProxyClass() || klass->GetDexCache() == nullptr) {
646 return nullptr;
647 }
648 ObjPtr<mirror::Object> method = annotations::GetEnclosingMethod(klass);
649 if (method != nullptr) {
650 if (GetClassRoot<mirror::Method>() == method->GetClass()) {
651 return soa.AddLocalReference<jobject>(method);
652 }
653 }
654 return nullptr;
655 }
656
Class_getInnerClassFlags(JNIEnv * env,jobject javaThis,jint defaultValue)657 static jint Class_getInnerClassFlags(JNIEnv* env, jobject javaThis, jint defaultValue) {
658 ScopedFastNativeObjectAccess soa(env);
659 StackHandleScope<1> hs(soa.Self());
660 Handle<mirror::Class> klass(hs.NewHandle(DecodeClass(soa, javaThis)));
661 if (klass->IsObsoleteObject()) {
662 ThrowRuntimeException("Obsolete Object!");
663 return 0;
664 }
665 return mirror::Class::GetInnerClassFlags(klass, defaultValue);
666 }
667
Class_getInnerClassName(JNIEnv * env,jobject javaThis)668 static jstring Class_getInnerClassName(JNIEnv* env, jobject javaThis) {
669 ScopedFastNativeObjectAccess soa(env);
670 StackHandleScope<1> hs(soa.Self());
671 Handle<mirror::Class> klass(hs.NewHandle(DecodeClass(soa, javaThis)));
672 if (klass->IsObsoleteObject()) {
673 ThrowRuntimeException("Obsolete Object!");
674 return nullptr;
675 }
676 if (klass->IsProxyClass() || klass->GetDexCache() == nullptr) {
677 return nullptr;
678 }
679 ObjPtr<mirror::String> class_name = nullptr;
680 if (!annotations::GetInnerClass(klass, &class_name)) {
681 return nullptr;
682 }
683 return soa.AddLocalReference<jstring>(class_name);
684 }
685
Class_getSignatureAnnotation(JNIEnv * env,jobject javaThis)686 static jobjectArray Class_getSignatureAnnotation(JNIEnv* env, jobject javaThis) {
687 ScopedFastNativeObjectAccess soa(env);
688 StackHandleScope<1> hs(soa.Self());
689 Handle<mirror::Class> klass(hs.NewHandle(DecodeClass(soa, javaThis)));
690 if (klass->IsObsoleteObject()) {
691 ThrowRuntimeException("Obsolete Object!");
692 return nullptr;
693 }
694 if (klass->IsProxyClass() || klass->GetDexCache() == nullptr) {
695 return nullptr;
696 }
697 return soa.AddLocalReference<jobjectArray>(
698 annotations::GetSignatureAnnotationForClass(klass));
699 }
700
Class_isAnonymousClass(JNIEnv * env,jobject javaThis)701 static jboolean Class_isAnonymousClass(JNIEnv* env, jobject javaThis) {
702 ScopedFastNativeObjectAccess soa(env);
703 StackHandleScope<1> hs(soa.Self());
704 Handle<mirror::Class> klass(hs.NewHandle(DecodeClass(soa, javaThis)));
705 if (klass->IsObsoleteObject()) {
706 ThrowRuntimeException("Obsolete Object!");
707 return 0;
708 }
709 if (klass->IsProxyClass() || klass->GetDexCache() == nullptr) {
710 return false;
711 }
712 ObjPtr<mirror::String> class_name = nullptr;
713 if (!annotations::GetInnerClass(klass, &class_name)) {
714 return false;
715 }
716 return class_name == nullptr;
717 }
718
Class_isDeclaredAnnotationPresent(JNIEnv * env,jobject javaThis,jclass annotationType)719 static jboolean Class_isDeclaredAnnotationPresent(JNIEnv* env, jobject javaThis,
720 jclass annotationType) {
721 ScopedFastNativeObjectAccess soa(env);
722 StackHandleScope<2> hs(soa.Self());
723 Handle<mirror::Class> klass(hs.NewHandle(DecodeClass(soa, javaThis)));
724 if (klass->IsObsoleteObject()) {
725 ThrowRuntimeException("Obsolete Object!");
726 return false;
727 }
728 if (klass->IsProxyClass() || klass->GetDexCache() == nullptr) {
729 return false;
730 }
731 Handle<mirror::Class> annotation_class(hs.NewHandle(soa.Decode<mirror::Class>(annotationType)));
732 return annotations::IsClassAnnotationPresent(klass, annotation_class);
733 }
734
Class_getDeclaringClass(JNIEnv * env,jobject javaThis)735 static jclass Class_getDeclaringClass(JNIEnv* env, jobject javaThis) {
736 ScopedFastNativeObjectAccess soa(env);
737 StackHandleScope<1> hs(soa.Self());
738 Handle<mirror::Class> klass(hs.NewHandle(DecodeClass(soa, javaThis)));
739 if (klass->IsObsoleteObject()) {
740 ThrowRuntimeException("Obsolete Object!");
741 return nullptr;
742 }
743 if (klass->IsProxyClass() || klass->GetDexCache() == nullptr) {
744 return nullptr;
745 }
746 // Return null for anonymous classes.
747 if (Class_isAnonymousClass(env, javaThis)) {
748 return nullptr;
749 }
750 return soa.AddLocalReference<jclass>(annotations::GetDeclaringClass(klass));
751 }
752
Class_newInstance(JNIEnv * env,jobject javaThis)753 static jobject Class_newInstance(JNIEnv* env, jobject javaThis) {
754 ScopedFastNativeObjectAccess soa(env);
755 StackHandleScope<4> hs(soa.Self());
756 Handle<mirror::Class> klass = hs.NewHandle(DecodeClass(soa, javaThis));
757 if (klass->IsObsoleteObject()) {
758 ThrowRuntimeException("Obsolete Object!");
759 return nullptr;
760 }
761 if (UNLIKELY(klass->GetPrimitiveType() != 0 || klass->IsInterface() || klass->IsArrayClass() ||
762 klass->IsAbstract())) {
763 soa.Self()->ThrowNewExceptionF("Ljava/lang/InstantiationException;",
764 "%s cannot be instantiated",
765 klass->PrettyClass().c_str());
766 return nullptr;
767 }
768 auto caller = hs.NewHandle<mirror::Class>(nullptr);
769 // Verify that we can access the class.
770 if (!klass->IsPublic()) {
771 caller.Assign(GetCallingClass(soa.Self(), 1));
772 if (caller != nullptr && !caller->CanAccess(klass.Get())) {
773 soa.Self()->ThrowNewExceptionF(
774 "Ljava/lang/IllegalAccessException;", "%s is not accessible from %s",
775 klass->PrettyClass().c_str(), caller->PrettyClass().c_str());
776 return nullptr;
777 }
778 }
779 StackArtMethodHandleScope<1> mhs(soa.Self());
780 ReflectiveHandle<ArtMethod> constructor(mhs.NewMethodHandle(klass->GetDeclaredConstructor(
781 soa.Self(), ScopedNullHandle<mirror::ObjectArray<mirror::Class>>(), kRuntimePointerSize)));
782 if (UNLIKELY(constructor == nullptr) || ShouldDenyAccessToMember(constructor.Get(), soa.Self())) {
783 soa.Self()->ThrowNewExceptionF("Ljava/lang/InstantiationException;",
784 "%s has no zero argument constructor",
785 klass->PrettyClass().c_str());
786 return nullptr;
787 }
788 // Invoke the string allocator to return an empty string for the string class.
789 if (klass->IsStringClass()) {
790 gc::AllocatorType allocator_type = Runtime::Current()->GetHeap()->GetCurrentAllocator();
791 ObjPtr<mirror::Object> obj = mirror::String::AllocEmptyString(soa.Self(), allocator_type);
792 if (UNLIKELY(soa.Self()->IsExceptionPending())) {
793 return nullptr;
794 } else {
795 return soa.AddLocalReference<jobject>(obj);
796 }
797 }
798 auto receiver = hs.NewHandle(klass->AllocObject(soa.Self()));
799 if (UNLIKELY(receiver == nullptr)) {
800 soa.Self()->AssertPendingOOMException();
801 return nullptr;
802 }
803 // Verify that we can access the constructor.
804 ObjPtr<mirror::Class> declaring_class = constructor->GetDeclaringClass();
805 if (!constructor->IsPublic()) {
806 if (caller == nullptr) {
807 caller.Assign(GetCallingClass(soa.Self(), 1));
808 }
809 if (UNLIKELY(caller != nullptr && !VerifyAccess(receiver.Get(),
810 declaring_class,
811 constructor->GetAccessFlags(),
812 caller.Get()))) {
813 soa.Self()->ThrowNewExceptionF(
814 "Ljava/lang/IllegalAccessException;", "%s is not accessible from %s",
815 constructor->PrettyMethod().c_str(), caller->PrettyClass().c_str());
816 return nullptr;
817 }
818 }
819 // Ensure that we are initialized.
820 if (UNLIKELY(!declaring_class->IsVisiblyInitialized())) {
821 Thread* self = soa.Self();
822 Handle<mirror::Class> h_class = hs.NewHandle(declaring_class);
823 if (UNLIKELY(!Runtime::Current()->GetClassLinker()->EnsureInitialized(
824 self, h_class, /*can_init_fields=*/ true, /*can_init_parents=*/ true))) {
825 DCHECK(self->IsExceptionPending());
826 return nullptr;
827 }
828 DCHECK(h_class->IsInitializing());
829 }
830 // Invoke the constructor.
831 JValue result;
832 uint32_t args[1] = { static_cast<uint32_t>(reinterpret_cast<uintptr_t>(receiver.Get())) };
833 constructor->Invoke(soa.Self(), args, sizeof(args), &result, "V");
834 if (UNLIKELY(soa.Self()->IsExceptionPending())) {
835 return nullptr;
836 }
837 // Constructors are ()V methods, so we shouldn't touch the result of InvokeMethod.
838 return soa.AddLocalReference<jobject>(receiver.Get());
839 }
840
841 static JNINativeMethod gMethods[] = {
842 FAST_NATIVE_METHOD(Class, classForName,
843 "(Ljava/lang/String;ZLjava/lang/ClassLoader;)Ljava/lang/Class;"),
844 FAST_NATIVE_METHOD(Class, getDeclaredAnnotation,
845 "(Ljava/lang/Class;)Ljava/lang/annotation/Annotation;"),
846 FAST_NATIVE_METHOD(Class, getDeclaredAnnotations, "()[Ljava/lang/annotation/Annotation;"),
847 FAST_NATIVE_METHOD(Class, getDeclaredClasses, "()[Ljava/lang/Class;"),
848 FAST_NATIVE_METHOD(Class, getDeclaredConstructorInternal,
849 "([Ljava/lang/Class;)Ljava/lang/reflect/Constructor;"),
850 FAST_NATIVE_METHOD(Class, getDeclaredConstructorsInternal, "(Z)[Ljava/lang/reflect/Constructor;"),
851 FAST_NATIVE_METHOD(Class, getDeclaredField, "(Ljava/lang/String;)Ljava/lang/reflect/Field;"),
852 FAST_NATIVE_METHOD(Class, getPublicFieldRecursive, "(Ljava/lang/String;)Ljava/lang/reflect/Field;"),
853 FAST_NATIVE_METHOD(Class, getDeclaredFields, "()[Ljava/lang/reflect/Field;"),
854 FAST_NATIVE_METHOD(Class, getDeclaredFieldsUnchecked, "(Z)[Ljava/lang/reflect/Field;"),
855 FAST_NATIVE_METHOD(Class, getDeclaredMethodInternal,
856 "(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;"),
857 FAST_NATIVE_METHOD(Class, getDeclaredMethodsUnchecked,
858 "(Z)[Ljava/lang/reflect/Method;"),
859 FAST_NATIVE_METHOD(Class, getDeclaringClass, "()Ljava/lang/Class;"),
860 FAST_NATIVE_METHOD(Class, getEnclosingClass, "()Ljava/lang/Class;"),
861 FAST_NATIVE_METHOD(Class, getEnclosingConstructorNative, "()Ljava/lang/reflect/Constructor;"),
862 FAST_NATIVE_METHOD(Class, getEnclosingMethodNative, "()Ljava/lang/reflect/Method;"),
863 FAST_NATIVE_METHOD(Class, getInnerClassFlags, "(I)I"),
864 FAST_NATIVE_METHOD(Class, getInnerClassName, "()Ljava/lang/String;"),
865 FAST_NATIVE_METHOD(Class, getInterfacesInternal, "()[Ljava/lang/Class;"),
866 FAST_NATIVE_METHOD(Class, getPrimitiveClass, "(Ljava/lang/String;)Ljava/lang/Class;"),
867 FAST_NATIVE_METHOD(Class, getNameNative, "()Ljava/lang/String;"),
868 FAST_NATIVE_METHOD(Class, getPublicDeclaredFields, "()[Ljava/lang/reflect/Field;"),
869 FAST_NATIVE_METHOD(Class, getSignatureAnnotation, "()[Ljava/lang/String;"),
870 FAST_NATIVE_METHOD(Class, isAnonymousClass, "()Z"),
871 FAST_NATIVE_METHOD(Class, isDeclaredAnnotationPresent, "(Ljava/lang/Class;)Z"),
872 FAST_NATIVE_METHOD(Class, newInstance, "()Ljava/lang/Object;"),
873 };
874
register_java_lang_Class(JNIEnv * env)875 void register_java_lang_Class(JNIEnv* env) {
876 REGISTER_NATIVE_METHODS("java/lang/Class");
877 }
878
879 } // namespace art
880