Eine aufbereitete Darstellung der Quelle

 
     
 
 
Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 

Benutzer

Quelle  hidden_api_test.cc

  Sprache: C
 

/*
 * Copyright (C) 2018 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */


#include "hidden_api.h"

#include <fstream>
#include <sstream>

#include "android-base/stringprintf.h"
#include "base/file_utils.h"
#include "base/sdk_version.h"
#include "base/stl_util.h"
#include "common_runtime_test.h"
#include "jni/jni_internal.h"
#include "proxy_test.h"
#include "well_known_classes-inl.h"

namespace art HIDDEN {

using android::base::StringPrintf;
using hiddenapi::detail::MemberSignature;
using hiddenapi::detail::ShouldDenyAccessToMemberImpl;

// Should be the same as dalvik.system.VMRuntime.HIDE_MAXTARGETSDK_P_HIDDEN_APIS,
// dalvik.system.VMRuntime.HIDE_MAXTARGETSDK_Q_HIDDEN_APIS, and
// dalvik.system.VMRuntime.EXEMPT_TEST_API_ACCESS_VERIFICATION.
static constexpr uint64_t kHideMaxtargetsdkPHiddenApis = 149997251;
static constexpr uint64_t kHideMaxtargetsdkQHiddenApis = 149994052;
static constexpr uint64_t kAllowTestApiAccess = 166236554;

static bool LoadDexFiles(const std::string& path,
                         const std::string& dex_location,
                         Thread* self,
                         /* out */ std::vector<std::unique_ptr<const DexFile>>* dex_files,
                         /* out */ ObjPtr<mirror::ClassLoader>* class_loader,
                         /* out */ std::string* error_msg) REQUIRES_SHARED(Locks::mutator_lock_) {
  ArtDexFileLoader dex_file_loader(path.c_str(), dex_location);
  if (!dex_file_loader.Open(/* verify= */ true,
                            /* verify_checksum= */ true,
                            error_msg,
                            dex_files)) {
    return false;
  }

  ClassLinker* const linker = Runtime::Current()->GetClassLinker();

  StackHandleScope<2> hs(self);
  Handle<mirror::Class> h_class =
      hs.NewHandle(WellKnownClasses::dalvik_system_PathClassLoader.Get());
  Handle<mirror::ClassLoader> h_loader = hs.NewHandle(linker->CreateWellKnownClassLoader(
      self,
      MakeNonOwningPointerVector(*dex_files),
      h_class,
      /* parent_loader= */ ScopedNullHandle<mirror::ClassLoader>(),
      /* shared_libraries= */ ScopedNullHandle<mirror::ObjectArray<mirror::ClassLoader>>(),
      /* shared_libraries_after= */ ScopedNullHandle<mirror::ObjectArray<mirror::ClassLoader>>()));
  for (const auto& dex_file : *dex_files) {
    linker->RegisterDexFile(*dex_file.get(), h_loader.Get());
  }

  *class_loader = h_loader.Get();
  return true;
}

static bool CheckAllDexFilesInDomain(ObjPtr<mirror::ClassLoader> loader,
                                     const std::vector<std::unique_ptr<const DexFile>>& dex_files,
                                     hiddenapi::Domain expected_domain,
                                     /* out */ std::string* error_msg)
    REQUIRES_SHARED(Locks::mutator_lock_) {
  for (const auto& dex_file : dex_files) {
    hiddenapi::AccessContext context(loader, dex_file.get());
    if (context.GetDomain() != expected_domain) {
      std::stringstream ss;
      ss << dex_file->GetLocation() << ": access context domain does not match "
          << "(expected=" << static_cast<uint32_t>(expected_domain)
          << ", actual=" << static_cast<uint32_t>(context.GetDomain()) << ")";
      *error_msg = ss.str();
      return false;
    }
    if (dex_file->GetHiddenapiDomain() != expected_domain) {
      std::stringstream ss;
      ss << dex_file->GetLocation() << ": dex file domain does not match "
          << "(expected=" << static_cast<uint32_t>(expected_domain)
          << ", actual=" << static_cast<uint32_t>(dex_file->GetHiddenapiDomain()) << ")";
      *error_msg = ss.str();
      return false;
    }
  }

  return true;
}

class HiddenApiTest : public CommonRuntimeTest {
 protected:
  void SetUp() override {
    // Do the normal setup.
    CommonRuntimeTest::SetUp();
    self_ = Thread::Current();
    self_->TransitionFromSuspendedToRunnable();
    jclass_loader_ = LoadDex("HiddenApiSignatures");
    bool started = runtime_->Start();
    CHECK(started);

    class1_field1_ = GetArtField("mypackage/packagea/Class1""field1""I");
    class1_field12_ = GetArtField("mypackage/packagea/Class1""field12""I");
    class1_init_ = GetArtMethod("mypackage/packagea/Class1""<init>""()V");
    class1_method1_ = GetArtMethod("mypackage/packagea/Class1""method1""()V");
    class1_method1_i_ = GetArtMethod("mypackage/packagea/Class1""method1""(I)V");
    class1_method12_ = GetArtMethod("mypackage/packagea/Class1""method12""()V");
    class12_field1_ = GetArtField("mypackage/packagea/Class12""field1""I");
    class12_method1_ = GetArtMethod("mypackage/packagea/Class12""method1""()V");
    class2_field1_ = GetArtField("mypackage/packagea/Class2""field1""I");
    class2_method1_ = GetArtMethod("mypackage/packagea/Class2""method1""()V");
    class2_method1_i_ = GetArtMethod("mypackage/packagea/Class2""method1""(I)V");
    class3_field1_ = GetArtField("mypackage/packageb/Class3""field1""I");
    class3_method1_ = GetArtMethod("mypackage/packageb/Class3""method1""()V");
    class3_method1_i_ = GetArtMethod("mypackage/packageb/Class3""method1""(I)V");
  }

  ArtMethod* GetArtMethod(const char* class_name, const char* name, const char* signature) {
    JNIEnv* env = Thread::Current()->GetJniEnv();
    jclass klass = env->FindClass(class_name);
    jmethodID method_id = env->GetMethodID(klass, name, signature);
    ArtMethod* art_method = jni::DecodeArtMethod(method_id);
    return art_method;
  }

  ArtField* GetArtField(const char* class_name, const char* name, const char* signature) {
    JNIEnv* env = Thread::Current()->GetJniEnv();
    jclass klass = env->FindClass(class_name);
    jfieldID field_id = env->GetFieldID(klass, name, signature);
    ScopedObjectAccess soa(Thread::Current());
    ArtField* art_field = jni::DecodeArtField(field_id);
    return art_field;
  }

  void SetChangeIdState(uint64_t change, bool enabled) {
    CompatFramework& compat_framework = runtime_->GetCompatFramework();
    std::set<uint64_t> disabled_changes = compat_framework.GetDisabledCompatChanges();
    if (enabled) {
      disabled_changes.erase(change);
    } else {
      disabled_changes.insert(change);
    }
    compat_framework.SetDisabledCompatChanges(disabled_changes);
  }

  bool ShouldDenyAccess(hiddenapi::ApiList list) REQUIRES_SHARED(Locks::mutator_lock_) {
    // This is only used for log messages, so its state doesn't matter.
    const hiddenapi::AccessContext placeholder_context(/* is_trusted= */ false);

    // Choose parameters such that there are no side effects (AccessMethod::kCheck)
    // and that the member is not on the exemptions list (here we choose one which
    // is not even in boot class path).
    return ShouldDenyAccessToMemberImpl(/* member= */ class1_field1_,
                                        list,
                                        /* runtime_flags= */ 0,
                                        /* caller_context= */ placeholder_context,
                                        /* callee_context= */ placeholder_context,
                                        hiddenapi::AccessMethod::kCheck);
  }

  bool ShouldDenyAccess(hiddenapi::ApiList list1, hiddenapi::ApiList list2)
      REQUIRES_SHARED(Locks::mutator_lock_) {
    return ShouldDenyAccess(hiddenapi::ApiList::Combine(list1, list2));
  }

  void TestLocation(const std::string& location, hiddenapi::Domain expected_domain) {
    std::string error_msg;
    ScopedObjectAccess soa(Thread::Current());
    std::vector<std::unique_ptr<const DexFile>> dex_files;
    ObjPtr<mirror::ClassLoader> class_loader;
    ASSERT_TRUE(LoadDexFiles(
        GetTestDexFileName("Main"), location, soa.Self(), &dex_files, &class_loader, &error_msg))
        << error_msg;
    ASSERT_GE(dex_files.size(), 1u);
    ASSERT_TRUE(CheckAllDexFilesInDomain(class_loader, dex_files, expected_domain, &error_msg))
        << error_msg;
    dex_files.clear();
  }

 protected:
  Thread* self_;
  jobject jclass_loader_;
  ArtField* class1_field1_;
  ArtField* class1_field12_;
  ArtMethod* class1_init_;
  ArtMethod* class1_method1_;
  ArtMethod* class1_method1_i_;
  ArtMethod* class1_method12_;
  ArtField* class12_field1_;
  ArtMethod* class12_method1_;
  ArtField* class2_field1_;
  ArtMethod* class2_method1_;
  ArtMethod* class2_method1_i_;
  ArtField* class3_field1_;
  ArtMethod* class3_method1_;
  ArtMethod* class3_method1_i_;
};

TEST_F(HiddenApiTest, CheckGetActionFromRuntimeFlags) {
  ScopedObjectAccess soa(self_);

  runtime_->SetHiddenApiEnforcementPolicy(hiddenapi::EnforcementPolicy::kJustWarn);
  ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Sdk()), false);
  ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Unsupported()), false);
  ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::MaxTargetS()), false);
  ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::MaxTargetR()), false);
  ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::MaxTargetQ()), false);
  ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::MaxTargetP()), false);
  ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::MaxTargetO()), false);
  ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Blocked()), false);

  runtime_->SetHiddenApiEnforcementPolicy(hiddenapi::EnforcementPolicy::kEnabled);
  runtime_->SetTargetSdkVersion(
      static_cast<uint32_t>(hiddenapi::ApiList::MaxTargetO().GetMaxAllowedSdkVersion()));
  SetChangeIdState(kHideMaxtargetsdkPHiddenApis, false);
  SetChangeIdState(kHideMaxtargetsdkQHiddenApis, false);
  ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Sdk()), false);
  ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Unsupported()), false);
  ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::MaxTargetS()), false);
  ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::MaxTargetR()), false);
  ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::MaxTargetQ()), false);
  ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::MaxTargetP()), false);
  ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::MaxTargetO()), false);
  ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Blocked()), true);

  runtime_->SetHiddenApiEnforcementPolicy(hiddenapi::EnforcementPolicy::kEnabled);
  runtime_->SetTargetSdkVersion(
      static_cast<uint32_t>(hiddenapi::ApiList::MaxTargetO().GetMaxAllowedSdkVersion()) + 1);
  SetChangeIdState(kHideMaxtargetsdkPHiddenApis, false);
  SetChangeIdState(kHideMaxtargetsdkQHiddenApis, false);
  ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Sdk()), false);
  ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Unsupported()), false);
  ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::MaxTargetS()), false);
  ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::MaxTargetR()), false);
  ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::MaxTargetQ()), false);
  ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::MaxTargetP()), false);
  ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::MaxTargetO()), true);
  ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Blocked()), true);
  SetChangeIdState(kHideMaxtargetsdkQHiddenApis, true);
  ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Sdk()), false);
  ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Unsupported()), false);
  ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::MaxTargetS()), false);
  ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::MaxTargetR()), false);
  ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::MaxTargetQ()), true);
  ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::MaxTargetP()), false);
  ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::MaxTargetO()), true);
  ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Blocked()), true);

  runtime_->SetHiddenApiEnforcementPolicy(hiddenapi::EnforcementPolicy::kEnabled);
  runtime_->SetTargetSdkVersion(
      static_cast<uint32_t>(hiddenapi::ApiList::MaxTargetP().GetMaxAllowedSdkVersion()) + 1);
  SetChangeIdState(kHideMaxtargetsdkPHiddenApis, true);
  SetChangeIdState(kHideMaxtargetsdkQHiddenApis, false);
  ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Sdk()), false);
  ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Unsupported()), false);
  ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::MaxTargetS()), false);
  ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::MaxTargetR()), false);
  ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::MaxTargetQ()), false);
  ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::MaxTargetP()), true);
  ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::MaxTargetO()), true);
  ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Blocked()), true);

  runtime_->SetHiddenApiEnforcementPolicy(hiddenapi::EnforcementPolicy::kEnabled);
  runtime_->SetTargetSdkVersion(
      static_cast<uint32_t>(hiddenapi::ApiList::MaxTargetQ().GetMaxAllowedSdkVersion()) + 1);
  SetChangeIdState(kHideMaxtargetsdkPHiddenApis, true);
  SetChangeIdState(kHideMaxtargetsdkQHiddenApis, true);
  ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Sdk()), false);
  ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Unsupported()), false);
  ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::MaxTargetS()), false);
  ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::MaxTargetR()), false);
  ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::MaxTargetQ()), true);
  ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::MaxTargetP()), true);
  ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::MaxTargetO()), true);
  ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Blocked()), true);

  runtime_->SetHiddenApiEnforcementPolicy(hiddenapi::EnforcementPolicy::kEnabled);
  runtime_->SetTargetSdkVersion(
      static_cast<uint32_t>(hiddenapi::ApiList::MaxTargetR().GetMaxAllowedSdkVersion()) + 1);
  SetChangeIdState(kHideMaxtargetsdkPHiddenApis, true);
  SetChangeIdState(kHideMaxtargetsdkQHiddenApis, true);
  ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Sdk()), false);
  ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Unsupported()), false);
  ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::MaxTargetS()), false);
  ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::MaxTargetR()), true);
  ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::MaxTargetQ()), true);
  ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::MaxTargetP()), true);
  ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::MaxTargetO()), true);
  ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Blocked()), true);

  runtime_->SetHiddenApiEnforcementPolicy(hiddenapi::EnforcementPolicy::kEnabled);
  runtime_->SetTargetSdkVersion(
      static_cast<uint32_t>(hiddenapi::ApiList::MaxTargetS().GetMaxAllowedSdkVersion()) + 1);
  ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Sdk()), false);
  ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Unsupported()), false);
  ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::MaxTargetS()), true);
  ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::MaxTargetR()), true);
  ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::MaxTargetQ()), true);
  ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::MaxTargetP()), true);
  ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::MaxTargetO()), true);
  ASSERT_EQ(ShouldDenyAccess(hiddenapi::ApiList::Blocked()), true);
}

TEST_F(HiddenApiTest, CheckTestApiEnforcement) {
  ScopedObjectAccess soa(self_);

  runtime_->SetHiddenApiEnforcementPolicy(hiddenapi::EnforcementPolicy::kEnabled);
  runtime_->SetTargetSdkVersion(
      static_cast<uint32_t>(hiddenapi::ApiList::MaxTargetR().GetMaxAllowedSdkVersion()) + 1);

  // clang-format off

  // Default case where all TestApis are treated like non-TestApi.
  runtime_->SetTestApiEnforcementPolicy(hiddenapi::EnforcementPolicy::kEnabled);
  SetChangeIdState(kAllowTestApiAccess, false);
  ASSERT_EQ(
      ShouldDenyAccess(hiddenapi::ApiList::TestApi(), hiddenapi::ApiList::Sdk()), false);
  ASSERT_EQ(
      ShouldDenyAccess(hiddenapi::ApiList::TestApi(), hiddenapi::ApiList::Unsupported()), false);
  ASSERT_EQ(
      ShouldDenyAccess(hiddenapi::ApiList::TestApi(), hiddenapi::ApiList::MaxTargetR())true);
  ASSERT_EQ(
      ShouldDenyAccess(hiddenapi::ApiList::TestApi(), hiddenapi::ApiList::MaxTargetQ())true);
  ASSERT_EQ(
      ShouldDenyAccess(hiddenapi::ApiList::TestApi(), hiddenapi::ApiList::MaxTargetP())true);
  ASSERT_EQ(
      ShouldDenyAccess(hiddenapi::ApiList::TestApi(), hiddenapi::ApiList::MaxTargetO())true);
  ASSERT_EQ(
      ShouldDenyAccess(hiddenapi::ApiList::TestApi(), hiddenapi::ApiList::Blocked()), true);

  // A case where we want to allow access to TestApis.
  runtime_->SetTestApiEnforcementPolicy(hiddenapi::EnforcementPolicy::kDisabled);
  SetChangeIdState(kAllowTestApiAccess, false);
  ASSERT_EQ(
      ShouldDenyAccess(hiddenapi::ApiList::TestApi(), hiddenapi::ApiList::Sdk()), false);
  ASSERT_EQ(
      ShouldDenyAccess(hiddenapi::ApiList::TestApi(), hiddenapi::ApiList::Unsupported()), false);
  ASSERT_EQ(
      ShouldDenyAccess(hiddenapi::ApiList::TestApi(), hiddenapi::ApiList::MaxTargetR())false);
  ASSERT_EQ(
      ShouldDenyAccess(hiddenapi::ApiList::TestApi(), hiddenapi::ApiList::MaxTargetQ())false);
  ASSERT_EQ(
      ShouldDenyAccess(hiddenapi::ApiList::TestApi(), hiddenapi::ApiList::MaxTargetP())false);
  ASSERT_EQ(
      ShouldDenyAccess(hiddenapi::ApiList::TestApi(), hiddenapi::ApiList::MaxTargetO())false);
  ASSERT_EQ(
      ShouldDenyAccess(hiddenapi::ApiList::TestApi(), hiddenapi::ApiList::Blocked()), false);

  // A second case where we want to allow access to TestApis.
  runtime_->SetTestApiEnforcementPolicy(hiddenapi::EnforcementPolicy::kEnabled);
  SetChangeIdState(kAllowTestApiAccess, true);
  ASSERT_EQ(
      ShouldDenyAccess(hiddenapi::ApiList::TestApi(), hiddenapi::ApiList::Sdk()), false);
  ASSERT_EQ(
      ShouldDenyAccess(hiddenapi::ApiList::TestApi(), hiddenapi::ApiList::Unsupported()), false);
  ASSERT_EQ(
      ShouldDenyAccess(hiddenapi::ApiList::TestApi(), hiddenapi::ApiList::MaxTargetR())false);
  ASSERT_EQ(
      ShouldDenyAccess(hiddenapi::ApiList::TestApi(), hiddenapi::ApiList::MaxTargetQ())false);
  ASSERT_EQ(
      ShouldDenyAccess(hiddenapi::ApiList::TestApi(), hiddenapi::ApiList::MaxTargetP())false);
  ASSERT_EQ(
      ShouldDenyAccess(hiddenapi::ApiList::TestApi(), hiddenapi::ApiList::MaxTargetO())false);
  ASSERT_EQ(
      ShouldDenyAccess(hiddenapi::ApiList::TestApi(), hiddenapi::ApiList::Blocked()), false);

  // clang-format on
}

TEST_F(HiddenApiTest, CheckMembersRead) {
  ASSERT_NE(nullptr, class1_field1_);
  ASSERT_NE(nullptr, class1_field12_);
  ASSERT_NE(nullptr, class1_init_);
  ASSERT_NE(nullptr, class1_method1_);
  ASSERT_NE(nullptr, class1_method1_i_);
  ASSERT_NE(nullptr, class1_method12_);
  ASSERT_NE(nullptr, class12_field1_);
  ASSERT_NE(nullptr, class12_method1_);
  ASSERT_NE(nullptr, class2_field1_);
  ASSERT_NE(nullptr, class2_method1_);
  ASSERT_NE(nullptr, class2_method1_i_);
  ASSERT_NE(nullptr, class3_field1_);
  ASSERT_NE(nullptr, class3_method1_);
  ASSERT_NE(nullptr, class3_method1_i_);
}

TEST_F(HiddenApiTest, CheckEverythingMatchesL) {
  ScopedObjectAccess soa(self_);
  std::string prefix("L");
  ASSERT_TRUE(MemberSignature(class1_field1_).DoesPrefixMatch(prefix));
  ASSERT_TRUE(MemberSignature(class1_field12_).DoesPrefixMatch(prefix));
  ASSERT_TRUE(MemberSignature(class1_init_).DoesPrefixMatch(prefix));
  ASSERT_TRUE(MemberSignature(class1_method1_).DoesPrefixMatch(prefix));
  ASSERT_TRUE(MemberSignature(class1_method1_i_).DoesPrefixMatch(prefix));
  ASSERT_TRUE(MemberSignature(class12_field1_).DoesPrefixMatch(prefix));
  ASSERT_TRUE(MemberSignature(class12_method1_).DoesPrefixMatch(prefix));
  ASSERT_TRUE(MemberSignature(class1_method12_).DoesPrefixMatch(prefix));
  ASSERT_TRUE(MemberSignature(class2_field1_).DoesPrefixMatch(prefix));
  ASSERT_TRUE(MemberSignature(class2_method1_).DoesPrefixMatch(prefix));
  ASSERT_TRUE(MemberSignature(class2_method1_i_).DoesPrefixMatch(prefix));
  ASSERT_TRUE(MemberSignature(class3_field1_).DoesPrefixMatch(prefix));
  ASSERT_TRUE(MemberSignature(class3_method1_).DoesPrefixMatch(prefix));
  ASSERT_TRUE(MemberSignature(class3_method1_i_).DoesPrefixMatch(prefix));
}

TEST_F(HiddenApiTest, CheckPackageMatch) {
  ScopedObjectAccess soa(self_);
  std::string prefix("Lmypackage/packagea/");
  ASSERT_TRUE(MemberSignature(class1_field1_).DoesPrefixMatch(prefix));
  ASSERT_TRUE(MemberSignature(class1_field12_).DoesPrefixMatch(prefix));
  ASSERT_TRUE(MemberSignature(class1_init_).DoesPrefixMatch(prefix));
  ASSERT_TRUE(MemberSignature(class1_method1_).DoesPrefixMatch(prefix));
  ASSERT_TRUE(MemberSignature(class1_method1_i_).DoesPrefixMatch(prefix));
  ASSERT_TRUE(MemberSignature(class1_method12_).DoesPrefixMatch(prefix));
  ASSERT_TRUE(MemberSignature(class12_field1_).DoesPrefixMatch(prefix));
  ASSERT_TRUE(MemberSignature(class12_method1_).DoesPrefixMatch(prefix));
  ASSERT_TRUE(MemberSignature(class2_field1_).DoesPrefixMatch(prefix));
  ASSERT_TRUE(MemberSignature(class2_method1_).DoesPrefixMatch(prefix));
  ASSERT_TRUE(MemberSignature(class2_method1_i_).DoesPrefixMatch(prefix));
  ASSERT_FALSE(MemberSignature(class3_field1_).DoesPrefixMatch(prefix));
  ASSERT_FALSE(MemberSignature(class3_method1_).DoesPrefixMatch(prefix));
  ASSERT_FALSE(MemberSignature(class3_method1_i_).DoesPrefixMatch(prefix));
}

TEST_F(HiddenApiTest, CheckClassMatch) {
  ScopedObjectAccess soa(self_);
  std::string prefix("Lmypackage/packagea/Class1");
  ASSERT_TRUE(MemberSignature(class1_field1_).DoesPrefixMatch(prefix));
  ASSERT_TRUE(MemberSignature(class1_field12_).DoesPrefixMatch(prefix));
  ASSERT_TRUE(MemberSignature(class1_init_).DoesPrefixMatch(prefix));
  ASSERT_TRUE(MemberSignature(class1_method1_).DoesPrefixMatch(prefix));
  ASSERT_TRUE(MemberSignature(class1_method1_i_).DoesPrefixMatch(prefix));
  ASSERT_TRUE(MemberSignature(class1_method12_).DoesPrefixMatch(prefix));
  ASSERT_TRUE(MemberSignature(class12_field1_).DoesPrefixMatch(prefix));
  ASSERT_TRUE(MemberSignature(class12_method1_).DoesPrefixMatch(prefix));
  ASSERT_FALSE(MemberSignature(class2_field1_).DoesPrefixMatch(prefix));
  ASSERT_FALSE(MemberSignature(class2_method1_).DoesPrefixMatch(prefix));
  ASSERT_FALSE(MemberSignature(class2_method1_i_).DoesPrefixMatch(prefix));
}

TEST_F(HiddenApiTest, CheckClassExactMatch) {
  ScopedObjectAccess soa(self_);
  std::string prefix("Lmypackage/packagea/Class1;");
  ASSERT_TRUE(MemberSignature(class1_field1_).DoesPrefixMatch(prefix));
  ASSERT_TRUE(MemberSignature(class1_field12_).DoesPrefixMatch(prefix));
  ASSERT_TRUE(MemberSignature(class1_init_).DoesPrefixMatch(prefix));
  ASSERT_TRUE(MemberSignature(class1_method1_).DoesPrefixMatch(prefix));
  ASSERT_TRUE(MemberSignature(class1_method1_i_).DoesPrefixMatch(prefix));
  ASSERT_FALSE(MemberSignature(class12_field1_).DoesPrefixMatch(prefix));
  ASSERT_FALSE(MemberSignature(class12_method1_).DoesPrefixMatch(prefix));
  ASSERT_FALSE(MemberSignature(class2_field1_).DoesPrefixMatch(prefix));
  ASSERT_FALSE(MemberSignature(class2_method1_).DoesPrefixMatch(prefix));
  ASSERT_FALSE(MemberSignature(class2_method1_i_).DoesPrefixMatch(prefix));
}

TEST_F(HiddenApiTest, CheckMethodMatch) {
  ScopedObjectAccess soa(self_);
  std::string prefix("Lmypackage/packagea/Class1;->method1");
  ASSERT_FALSE(MemberSignature(class1_field1_).DoesPrefixMatch(prefix));
  ASSERT_FALSE(MemberSignature(class1_field12_).DoesPrefixMatch(prefix));
  ASSERT_FALSE(MemberSignature(class1_init_).DoesPrefixMatch(prefix));
  ASSERT_TRUE(MemberSignature(class1_method1_).DoesPrefixMatch(prefix));
  ASSERT_TRUE(MemberSignature(class1_method1_i_).DoesPrefixMatch(prefix));
  ASSERT_TRUE(MemberSignature(class1_method12_).DoesPrefixMatch(prefix));
  ASSERT_FALSE(MemberSignature(class12_field1_).DoesPrefixMatch(prefix));
  ASSERT_FALSE(MemberSignature(class12_method1_).DoesPrefixMatch(prefix));
}

TEST_F(HiddenApiTest, CheckMethodExactMatch) {
  ScopedObjectAccess soa(self_);
  std::string prefix("Lmypackage/packagea/Class1;->method1(");
  ASSERT_FALSE(MemberSignature(class1_field1_).DoesPrefixMatch(prefix));
  ASSERT_FALSE(MemberSignature(class1_field12_).DoesPrefixMatch(prefix));
  ASSERT_FALSE(MemberSignature(class1_init_).DoesPrefixMatch(prefix));
  ASSERT_TRUE(MemberSignature(class1_method1_).DoesPrefixMatch(prefix));
  ASSERT_TRUE(MemberSignature(class1_method1_i_).DoesPrefixMatch(prefix));
  ASSERT_FALSE(MemberSignature(class1_method12_).DoesPrefixMatch(prefix));
}

TEST_F(HiddenApiTest, CheckMethodSignatureMatch) {
  ScopedObjectAccess soa(self_);
  std::string prefix("Lmypackage/packagea/Class1;->method1(I)");
  ASSERT_FALSE(MemberSignature(class1_field1_).DoesPrefixMatch(prefix));
  ASSERT_FALSE(MemberSignature(class1_field12_).DoesPrefixMatch(prefix));
  ASSERT_FALSE(MemberSignature(class1_method1_).DoesPrefixMatch(prefix));
  ASSERT_TRUE(MemberSignature(class1_method1_i_).DoesPrefixMatch(prefix));
  ASSERT_FALSE(MemberSignature(class1_method12_).DoesPrefixMatch(prefix));
}

TEST_F(HiddenApiTest, CheckMethodSignatureAndReturnMatch) {
  ScopedObjectAccess soa(self_);
  std::string prefix("Lmypackage/packagea/Class1;->method1()V");
  ASSERT_FALSE(MemberSignature(class1_field1_).DoesPrefixMatch(prefix));
  ASSERT_FALSE(MemberSignature(class1_field12_).DoesPrefixMatch(prefix));
  ASSERT_TRUE(MemberSignature(class1_method1_).DoesPrefixMatch(prefix));
  ASSERT_FALSE(MemberSignature(class1_method1_i_).DoesPrefixMatch(prefix));
  ASSERT_FALSE(MemberSignature(class1_method12_).DoesPrefixMatch(prefix));
}

TEST_F(HiddenApiTest, CheckFieldMatch) {
  ScopedObjectAccess soa(self_);
  std::string prefix("Lmypackage/packagea/Class1;->field1");
  ASSERT_TRUE(MemberSignature(class1_field1_).DoesPrefixMatch(prefix));
  ASSERT_TRUE(MemberSignature(class1_field12_).DoesPrefixMatch(prefix));
  ASSERT_FALSE(MemberSignature(class1_method1_).DoesPrefixMatch(prefix));
  ASSERT_FALSE(MemberSignature(class1_method1_i_).DoesPrefixMatch(prefix));
  ASSERT_FALSE(MemberSignature(class1_method12_).DoesPrefixMatch(prefix));
}

TEST_F(HiddenApiTest, CheckFieldExactMatch) {
  ScopedObjectAccess soa(self_);
  std::string prefix("Lmypackage/packagea/Class1;->field1:");
  ASSERT_TRUE(MemberSignature(class1_field1_).DoesPrefixMatch(prefix));
  ASSERT_FALSE(MemberSignature(class1_field12_).DoesPrefixMatch(prefix));
  ASSERT_FALSE(MemberSignature(class1_method1_).DoesPrefixMatch(prefix));
}

TEST_F(HiddenApiTest, CheckFieldTypeMatch) {
  ScopedObjectAccess soa(self_);
  std::string prefix("Lmypackage/packagea/Class1;->field1:I");
  ASSERT_TRUE(MemberSignature(class1_field1_).DoesPrefixMatch(prefix));
  ASSERT_FALSE(MemberSignature(class1_field12_).DoesPrefixMatch(prefix));
  ASSERT_FALSE(MemberSignature(class1_method1_).DoesPrefixMatch(prefix));
}

TEST_F(HiddenApiTest, CheckConstructorMatch) {
  ScopedObjectAccess soa(self_);
  std::string prefix("Lmypackage/packagea/Class1;-><init>");
  ASSERT_TRUE(MemberSignature(class1_init_).DoesPrefixMatch(prefix));
  ASSERT_FALSE(MemberSignature(class1_method1_).DoesPrefixMatch(prefix));
}

TEST_F(HiddenApiTest, CheckConstructorExactMatch) {
  ScopedObjectAccess soa(self_);
  std::string prefix("Lmypackage/packagea/Class1;-><init>()V");
  ASSERT_TRUE(MemberSignature(class1_init_).DoesPrefixMatch(prefix));
  ASSERT_FALSE(MemberSignature(class1_method1_).DoesPrefixMatch(prefix));
}

TEST_F(HiddenApiTest, CheckMethodSignatureTrailingCharsNoMatch) {
  ScopedObjectAccess soa(self_);
  std::string prefix("Lmypackage/packagea/Class1;->method1()Vfoo");
  ASSERT_FALSE(MemberSignature(class1_method1_).DoesPrefixMatch(prefix));
}

TEST_F(HiddenApiTest, CheckConstructorTrailingCharsNoMatch) {
  ScopedObjectAccess soa(self_);
  std::string prefix("Lmypackage/packagea/Class1;-><init>()Vfoo");
  ASSERT_FALSE(MemberSignature(class1_init_).DoesPrefixMatch(prefix));
}

TEST_F(HiddenApiTest, CheckFieldTrailingCharsNoMatch) {
  ScopedObjectAccess soa(self_);
  std::string prefix("Lmypackage/packagea/Class1;->field1:Ifoo");
  ASSERT_FALSE(MemberSignature(class1_field1_).DoesPrefixMatch(prefix));
}

TEST_F(HiddenApiTest, CheckMemberSignatureForProxyClass) {
  ScopedObjectAccess soa(self_);
  StackHandleScope<4> hs(soa.Self());
  Handle<mirror::ClassLoader> class_loader(
      hs.NewHandle(soa.Decode<mirror::ClassLoader>(jclass_loader_)));

  // Find interface we will create a proxy for.
  Handle<mirror::Class> h_iface =
      hs.NewHandle(FindClass("Lmypackage/packagea/Interface;", class_loader));
  ASSERT_TRUE(h_iface != nullptr);

  // Create the proxy class.
  std::vector<Handle<mirror::Class>> interfaces;
  interfaces.push_back(h_iface);
  Handle<mirror::Class> proxyClass = hs.NewHandle(proxy_test::GenerateProxyClass(
      soa, jclass_loader_, runtime_->GetClassLinker(), "$Proxy1234", interfaces));
  ASSERT_TRUE(proxyClass != nullptr);
  ASSERT_TRUE(proxyClass->IsProxyClass());
  ASSERT_TRUE(proxyClass->IsInitialized());

  // Find the "method" virtual method.
  ArtMethod* method = nullptr;
  for (auto& m : proxyClass->GetDeclaredMethods(kRuntimePointerSize)) {
    if (m.IsVirtual() &&
        strcmp("method", m.GetInterfaceMethodIfProxy(kRuntimePointerSize)->GetName()) == 0) {
      method = &m;
      break;
    }
  }
  ASSERT_TRUE(method != nullptr);

  // Find the "interfaces" static field. This is generated for all proxies.
  ArtField* field = nullptr;
  for (size_t i = 0; i < proxyClass->NumFields(); ++i) {
    ArtField* f = proxyClass->GetField(i);
    if (strcmp("interfaces", f->GetName()) == 0) {
      field = f;
      break;
    }
  }
  ASSERT_TRUE(field != nullptr);
  ASSERT_TRUE(field->IsStatic());

  // Test the signature. We expect the signature from the interface class.
  std::ostringstream ss_method;
  MemberSignature(method->GetInterfaceMethodIfProxy(kRuntimePointerSize)).Dump(ss_method);
  ASSERT_EQ("Lmypackage/packagea/Interface;->method()V", ss_method.str());

  // Test the signature. We expect the signature of the proxy class.
  std::ostringstream ss_field;
  MemberSignature(field).Dump(ss_field);
  ASSERT_EQ("L$Proxy1234;->interfaces:[Ljava/lang/Class;", ss_field.str());
}

TEST_F(HiddenApiTest, DexDomain_DataDir) {
  std::string data_location_path = "/data/foo.jar";
  ASSERT_FALSE(LocationIsOnSystemFramework(data_location_path));
  TestLocation(data_location_path, hiddenapi::Domain::kApplication);
}

TEST_F(HiddenApiTest, DexDomain_SystemDir) {
  std::string system_location_path = "/system/foo.jar";
  ASSERT_FALSE(LocationIsOnSystemFramework(system_location_path));
  TestLocation(system_location_path, hiddenapi::Domain::kApplication);
}

TEST_F(HiddenApiTest, DexDomain_SystemExtDir) {
  std::string system_ext_location_path = "/system_ext/foo.jar";
  ASSERT_FALSE(LocationIsOnSystemExtFramework(system_ext_location_path));
  TestLocation(system_ext_location_path, hiddenapi::Domain::kApplication);
}

TEST_F(HiddenApiTest, DexDomain_SystemSystemExtDir) {
  std::string system_ext_location_path = "/system/system_ext/foo.jar";
  ASSERT_FALSE(LocationIsOnSystemExtFramework(system_ext_location_path));
  TestLocation(system_ext_location_path, hiddenapi::Domain::kApplication);
}

TEST_F(HiddenApiTest, DexDomain_SystemFrameworkDir) {
  std::string system_framework_location_path = "/system/framework/foo.jar";
  ASSERT_TRUE(LocationIsOnSystemFramework(system_framework_location_path));
  TestLocation(system_framework_location_path, hiddenapi::Domain::kPlatform);
}

TEST_F(HiddenApiTest, DexDomain_SystemExtFrameworkDir) {
  std::string system_ext_framework_location_path = "/system_ext/framework/foo.jar";
  ASSERT_TRUE(LocationIsOnSystemExtFramework(system_ext_framework_location_path));
  TestLocation(system_ext_framework_location_path, hiddenapi::Domain::kPlatform);
}

TEST_F(HiddenApiTest, DexDomain_SystemSystemExtFrameworkDir) {
  std::string system_ext_framework_location_path = "/system/system_ext/framework/foo.jar";
  ASSERT_TRUE(LocationIsOnSystemExtFramework(system_ext_framework_location_path));
  TestLocation(system_ext_framework_location_path, hiddenapi::Domain::kPlatform);
}

TEST_F(HiddenApiTest, DexDomain_DataDir_MultiDex) {
  std::string data_multi_location_path = "/data/multifoo.jar";
  ASSERT_FALSE(LocationIsOnSystemFramework(data_multi_location_path));
  TestLocation(data_multi_location_path, hiddenapi::Domain::kApplication);
}

TEST_F(HiddenApiTest, DexDomain_SystemDir_MultiDex) {
  std::string system_multi_location_path = "/system/multifoo.jar";
  ASSERT_FALSE(LocationIsOnSystemFramework(system_multi_location_path));
  TestLocation(system_multi_location_path, hiddenapi::Domain::kApplication);
}

TEST_F(HiddenApiTest, DexDomain_SystemExtDir_MultiDex) {
  std::string system_ext_multi_location_path = "/system_ext/multifoo.jar";
  ASSERT_FALSE(LocationIsOnSystemExtFramework(system_ext_multi_location_path));
  TestLocation(system_ext_multi_location_path, hiddenapi::Domain::kApplication);
}

TEST_F(HiddenApiTest, DexDomain_SystemSystemExtDir_MultiDex) {
  std::string system_ext_multi_location_path = "/system/system_ext/multifoo.jar";
  ASSERT_FALSE(LocationIsOnSystemExtFramework(system_ext_multi_location_path));
  TestLocation(system_ext_multi_location_path, hiddenapi::Domain::kApplication);
}

TEST_F(HiddenApiTest, DexDomain_SystemFrameworkDir_MultiDex) {
  std::string system_framework_multi_location_path = "/system/framework/multifoo.jar";
  ASSERT_TRUE(LocationIsOnSystemFramework(system_framework_multi_location_path));
  TestLocation(system_framework_multi_location_path, hiddenapi::Domain::kPlatform);
}

TEST_F(HiddenApiTest, DexDomain_SystemExtFrameworkDir_MultiDex) {
  std::string system_ext_framework_multi_location_path = "/system_ext/framework/multifoo.jar";
  ASSERT_TRUE(LocationIsOnSystemExtFramework(system_ext_framework_multi_location_path));
  TestLocation(system_ext_framework_multi_location_path, hiddenapi::Domain::kPlatform);
}

TEST_F(HiddenApiTest, DexDomain_SystemSystemExtFrameworkDir_MultiDex) {
  std::string system_ext_framework_multi_location_path =
      "/system/system_ext/framework/multifoo.jar";
  ASSERT_TRUE(LocationIsOnSystemExtFramework(system_ext_framework_multi_location_path));
  TestLocation(system_ext_framework_multi_location_path, hiddenapi::Domain::kPlatform);
}

}  // namespace art

Messung V0.5 in Prozent
C=88 H=95 G=91

¤ Dauer der Verarbeitung: 0.2 Sekunden  (vorverarbeitet am  2026-06-29) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Quellcodebibliothek
     Eigene Quellcodes
     Fremde Quellcodes
     Suchen

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik