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