diff options
Diffstat (limited to 'runtime/class_linker.cc')
| -rw-r--r-- | runtime/class_linker.cc | 23 | 
1 files changed, 18 insertions, 5 deletions
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc index e9b8643223..8fcb6b25fa 100644 --- a/runtime/class_linker.cc +++ b/runtime/class_linker.cc @@ -1063,9 +1063,8 @@ bool ClassLinker::InitFromBootImage(std::string* error_msg) {    return true;  } -static bool IsBootClassLoader(ScopedObjectAccessAlreadyRunnable& soa, -                              mirror::ClassLoader* class_loader) -    SHARED_REQUIRES(Locks::mutator_lock_) { +bool ClassLinker::IsBootClassLoader(ScopedObjectAccessAlreadyRunnable& soa, +                                    mirror::ClassLoader* class_loader) {    return class_loader == nullptr ||        class_loader->GetClass() ==            soa.Decode<mirror::Class*>(WellKnownClasses::java_lang_BootClassLoader); @@ -1106,7 +1105,7 @@ static bool FlattenPathClassLoader(mirror::ClassLoader* class_loader,        soa.DecodeField(WellKnownClasses::dalvik_system_DexPathList_dexElements);    CHECK(dex_path_list_field != nullptr);    CHECK(dex_elements_field != nullptr); -  while (!IsBootClassLoader(soa, class_loader)) { +  while (!ClassLinker::IsBootClassLoader(soa, class_loader)) {      if (class_loader->GetClass() !=          soa.Decode<mirror::Class*>(WellKnownClasses::dalvik_system_PathClassLoader)) {        *error_msg = StringPrintf("Unknown class loader type %s", PrettyTypeOf(class_loader).c_str()); @@ -5317,6 +5316,19 @@ bool ClassLinker::LoadSuperAndInterfaces(Handle<mirror::Class> klass, const DexF    const DexFile::ClassDef& class_def = dex_file.GetClassDef(klass->GetDexClassDefIndex());    uint16_t super_class_idx = class_def.superclass_idx_;    if (super_class_idx != DexFile::kDexNoIndex16) { +    // Check that a class does not inherit from itself directly. +    // +    // TODO: This is a cheap check to detect the straightforward case +    // of a class extending itself (b/28685551), but we should do a +    // proper cycle detection on loaded classes, to detect all cases +    // of class circularity errors (b/28830038). +    if (super_class_idx == class_def.class_idx_) { +      ThrowClassCircularityError(klass.Get(), +                                 "Class %s extends itself", +                                 PrettyDescriptor(klass.Get()).c_str()); +      return false; +    } +      mirror::Class* super_class = ResolveType(dex_file, super_class_idx, klass.Get());      if (super_class == nullptr) {        DCHECK(Thread::Current()->IsExceptionPending()); @@ -7815,7 +7827,8 @@ const char* ClassLinker::GetClassRootDescriptor(ClassRoot class_root) {    return descriptor;  } -jobject ClassLinker::CreatePathClassLoader(Thread* self, std::vector<const DexFile*>& dex_files) { +jobject ClassLinker::CreatePathClassLoader(Thread* self, +                                           const std::vector<const DexFile*>& dex_files) {    // SOAAlreadyRunnable is protected, and we need something to add a global reference.    // We could move the jobject to the callers, but all call-sites do this...    ScopedObjectAccessUnchecked soa(self);  |