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