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