Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 742fd61d authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "libandroidfw: Remove pre-verification"

parents 8587adc4 498f6053
Loading
Loading
Loading
Loading
+2 −3
Original line number Original line Diff line number Diff line
@@ -299,10 +299,9 @@ ApkAssetsCookie AssetManager2::FindEntry(uint32_t resid, uint16_t density_overri


  const PackageGroup& package_group = package_groups_[idx];
  const PackageGroup& package_group = package_groups_[idx];
  const size_t package_count = package_group.packages_.size();
  const size_t package_count = package_group.packages_.size();
  FindEntryResult current_entry;
  for (size_t i = 0; i < package_count; i++) {
  for (size_t i = 0; i < package_count; i++) {
    const LoadedPackage* loaded_package = package_group.packages_[i];
    const LoadedPackage* loaded_package = package_group.packages_[i];

    FindEntryResult current_entry;
    if (!loaded_package->FindEntry(type_idx, entry_id, *desired_config, &current_entry)) {
    if (!loaded_package->FindEntry(type_idx, entry_id, *desired_config, &current_entry)) {
      continue;
      continue;
    }
    }
@@ -394,7 +393,7 @@ ApkAssetsCookie AssetManager2::GetResource(uint32_t resid, bool may_be_bag,
    return kInvalidCookie;
    return kInvalidCookie;
  }
  }


  if (dtohl(entry.entry->flags) & ResTable_entry::FLAG_COMPLEX) {
  if (dtohs(entry.entry->flags) & ResTable_entry::FLAG_COMPLEX) {
    if (!may_be_bag) {
    if (!may_be_bag) {
      LOG(ERROR) << base::StringPrintf("Resource %08x is a complex map type.", resid);
      LOG(ERROR) << base::StringPrintf("Resource %08x is a complex map type.", resid);
      return kInvalidCookie;
      return kInvalidCookie;
+33 −94
Original line number Original line Diff line number Diff line
@@ -129,9 +129,14 @@ LoadedPackage::~LoadedPackage() = default;
// Precondition: The header passed in has already been verified, so reading any fields and trusting
// Precondition: The header passed in has already been verified, so reading any fields and trusting
// the ResChunk_header is safe.
// the ResChunk_header is safe.
static bool VerifyResTableType(const ResTable_type* header) {
static bool VerifyResTableType(const ResTable_type* header) {
  if (header->id == 0) {
    LOG(ERROR) << "RES_TABLE_TYPE_TYPE has invalid ID 0.";
    return false;
  }

  const size_t entry_count = dtohl(header->entryCount);
  const size_t entry_count = dtohl(header->entryCount);
  if (entry_count > std::numeric_limits<uint16_t>::max()) {
  if (entry_count > std::numeric_limits<uint16_t>::max()) {
    LOG(ERROR) << "Too many entries in RES_TABLE_TYPE_TYPE.";
    LOG(ERROR) << "RES_TABLE_TYPE_TYPE has too many entries (" << entry_count << ").";
    return false;
    return false;
  }
  }


@@ -141,17 +146,17 @@ static bool VerifyResTableType(const ResTable_type* header) {
  const size_t offsets_length = sizeof(uint32_t) * entry_count;
  const size_t offsets_length = sizeof(uint32_t) * entry_count;


  if (offsets_offset > entries_offset || entries_offset - offsets_offset < offsets_length) {
  if (offsets_offset > entries_offset || entries_offset - offsets_offset < offsets_length) {
    LOG(ERROR) << "Entry offsets overlap actual entry data.";
    LOG(ERROR) << "RES_TABLE_TYPE_TYPE entry offsets overlap actual entry data.";
    return false;
    return false;
  }
  }


  if (entries_offset > dtohl(header->header.size)) {
  if (entries_offset > dtohl(header->header.size)) {
    LOG(ERROR) << "Entry offsets extend beyond chunk.";
    LOG(ERROR) << "RES_TABLE_TYPE_TYPE entry offsets extend beyond chunk.";
    return false;
    return false;
  }
  }


  if (entries_offset & 0x03) {
  if (entries_offset & 0x03) {
    LOG(ERROR) << "Entries start at unaligned address.";
    LOG(ERROR) << "RES_TABLE_TYPE_TYPE entries start at unaligned address.";
    return false;
    return false;
  }
  }
  return true;
  return true;
@@ -236,7 +241,6 @@ static bool VerifyResTableEntry(const ResTable_type* type, uint32_t entry_offset
  return true;
  return true;
}
}


template <bool Verified>
bool LoadedPackage::FindEntry(const TypeSpecPtr& type_spec_ptr, uint16_t entry_idx,
bool LoadedPackage::FindEntry(const TypeSpecPtr& type_spec_ptr, uint16_t entry_idx,
                              const ResTable_config& config, FindEntryResult* out_entry) const {
                              const ResTable_config& config, FindEntryResult* out_entry) const {
  const ResTable_config* best_config = nullptr;
  const ResTable_config* best_config = nullptr;
@@ -254,13 +258,6 @@ bool LoadedPackage::FindEntry(const TypeSpecPtr& type_spec_ptr, uint16_t entry_i
      const size_t entry_count = dtohl(type_chunk->entryCount);
      const size_t entry_count = dtohl(type_chunk->entryCount);
      const size_t offsets_offset = dtohs(type_chunk->header.headerSize);
      const size_t offsets_offset = dtohs(type_chunk->header.headerSize);


      // If the package hasn't been verified, do bounds checking.
      if (!Verified) {
        if (!VerifyResTableType(type_chunk)) {
          continue;
        }
      }

      // Check if there is the desired entry in this type.
      // Check if there is the desired entry in this type.


      if (type_chunk->flags & ResTable_type::FLAG_SPARSE) {
      if (type_chunk->flags & ResTable_type::FLAG_SPARSE) {
@@ -282,7 +279,7 @@ bool LoadedPackage::FindEntry(const TypeSpecPtr& type_spec_ptr, uint16_t entry_i


        // Extract the offset from the entry. Each offset must be a multiple of 4 so we store it as
        // Extract the offset from the entry. Each offset must be a multiple of 4 so we store it as
        // the real offset divided by 4.
        // the real offset divided by 4.
        best_offset = dtohs(result->offset) * 4u;
        best_offset = uint32_t{dtohs(result->offset)} * 4u;
      } else {
      } else {
        if (entry_idx >= entry_count) {
        if (entry_idx >= entry_count) {
          // This entry cannot be here.
          // This entry cannot be here.
@@ -309,11 +306,9 @@ bool LoadedPackage::FindEntry(const TypeSpecPtr& type_spec_ptr, uint16_t entry_i
    return false;
    return false;
  }
  }


  if (!Verified) {
  if (UNLIKELY(!VerifyResTableEntry(best_type, best_offset, entry_idx))) {
    if (!VerifyResTableEntry(best_type, best_offset, entry_idx)) {
    return false;
    return false;
  }
  }
  }


  const ResTable_entry* best_entry = reinterpret_cast<const ResTable_entry*>(
  const ResTable_entry* best_entry = reinterpret_cast<const ResTable_entry*>(
      reinterpret_cast<const uint8_t*>(best_type) + best_offset + dtohl(best_type->entriesStart));
      reinterpret_cast<const uint8_t*>(best_type) + best_offset + dtohl(best_type->entriesStart));
@@ -334,7 +329,7 @@ bool LoadedPackage::FindEntry(uint8_t type_idx, uint16_t entry_idx, const ResTab
  // If the type IDs are offset in this package, we need to take that into account when searching
  // If the type IDs are offset in this package, we need to take that into account when searching
  // for a type.
  // for a type.
  const TypeSpecPtr& ptr = type_specs_[type_idx - type_id_offset_];
  const TypeSpecPtr& ptr = type_specs_[type_idx - type_id_offset_];
  if (ptr == nullptr) {
  if (UNLIKELY(ptr == nullptr)) {
    return false;
    return false;
  }
  }


@@ -345,54 +340,7 @@ bool LoadedPackage::FindEntry(uint8_t type_idx, uint16_t entry_idx, const ResTab
      return false;
      return false;
    }
    }
  }
  }

  return FindEntry(ptr, entry_idx, config, out_entry);
  // Don't bother checking if the entry ID is larger than the number of entries.
  if (entry_idx >= dtohl(ptr->type_spec->entryCount)) {
    return false;
  }

  if (verified_) {
    return FindEntry<true>(ptr, entry_idx, config, out_entry);
  }
  return FindEntry<false>(ptr, entry_idx, config, out_entry);
}

static bool VerifyType(const Chunk& chunk) {
  ATRACE_CALL();
  const ResTable_type* header = chunk.header<ResTable_type, kResTableTypeMinSize>();

  if (!VerifyResTableType(header)) {
    return false;
  }

  const size_t entry_count = dtohl(header->entryCount);
  const size_t offsets_offset = chunk.header_size();

  if (header->flags & ResTable_type::FLAG_SPARSE) {
    // This is encoded as a sparse map, so perform a binary search.
    const ResTable_sparseTypeEntry* sparse_indices =
        reinterpret_cast<const ResTable_sparseTypeEntry*>(reinterpret_cast<const uint8_t*>(header) +
                                                          offsets_offset);
    for (size_t i = 0; i < entry_count; i++) {
      const uint32_t offset = uint32_t{dtohs(sparse_indices[i].offset)} * 4u;
      if (!VerifyResTableEntry(header, offset, i)) {
        return false;
      }
    }
  } else {
    // Check each entry offset.
    const uint32_t* offsets = reinterpret_cast<const uint32_t*>(
        reinterpret_cast<const uint8_t*>(header) + offsets_offset);
    for (size_t i = 0; i < entry_count; i++) {
      uint32_t offset = dtohl(offsets[i]);
      if (offset != ResTable_type::NO_ENTRY) {
        if (!VerifyResTableEntry(header, offset, i)) {
          return false;
        }
      }
    }
  }
  return true;
}
}


void LoadedPackage::CollectConfigurations(bool exclude_mipmap,
void LoadedPackage::CollectConfigurations(bool exclude_mipmap,
@@ -507,7 +455,7 @@ std::unique_ptr<const LoadedPackage> LoadedPackage::Load(const Chunk& chunk,
      sizeof(ResTable_package) - sizeof(ResTable_package::typeIdOffset);
      sizeof(ResTable_package) - sizeof(ResTable_package::typeIdOffset);
  const ResTable_package* header = chunk.header<ResTable_package, kMinPackageSize>();
  const ResTable_package* header = chunk.header<ResTable_package, kMinPackageSize>();
  if (header == nullptr) {
  if (header == nullptr) {
    LOG(ERROR) << "Chunk RES_TABLE_PACKAGE_TYPE is too small.";
    LOG(ERROR) << "RES_TABLE_PACKAGE_TYPE too small.";
    return {};
    return {};
  }
  }


@@ -529,7 +477,7 @@ std::unique_ptr<const LoadedPackage> LoadedPackage::Load(const Chunk& chunk,
  if (header->header.headerSize >= sizeof(ResTable_package)) {
  if (header->header.headerSize >= sizeof(ResTable_package)) {
    uint32_t type_id_offset = dtohl(header->typeIdOffset);
    uint32_t type_id_offset = dtohl(header->typeIdOffset);
    if (type_id_offset > std::numeric_limits<uint8_t>::max()) {
    if (type_id_offset > std::numeric_limits<uint8_t>::max()) {
      LOG(ERROR) << "Type ID offset in RES_TABLE_PACKAGE_TYPE is too large.";
      LOG(ERROR) << "RES_TABLE_PACKAGE_TYPE type ID offset too large.";
      return {};
      return {};
    }
    }
    loaded_package->type_id_offset_ = static_cast<int>(type_id_offset);
    loaded_package->type_id_offset_ = static_cast<int>(type_id_offset);
@@ -560,7 +508,7 @@ std::unique_ptr<const LoadedPackage> LoadedPackage::Load(const Chunk& chunk,
          status_t err = loaded_package->type_string_pool_.setTo(
          status_t err = loaded_package->type_string_pool_.setTo(
              child_chunk.header<ResStringPool_header>(), child_chunk.size());
              child_chunk.header<ResStringPool_header>(), child_chunk.size());
          if (err != NO_ERROR) {
          if (err != NO_ERROR) {
            LOG(ERROR) << "Corrupt package type string pool.";
            LOG(ERROR) << "RES_STRING_POOL_TYPE for types corrupt.";
            return {};
            return {};
          }
          }
        } else if (pool_address == header_address + dtohl(header->keyStrings)) {
        } else if (pool_address == header_address + dtohl(header->keyStrings)) {
@@ -568,11 +516,11 @@ std::unique_ptr<const LoadedPackage> LoadedPackage::Load(const Chunk& chunk,
          status_t err = loaded_package->key_string_pool_.setTo(
          status_t err = loaded_package->key_string_pool_.setTo(
              child_chunk.header<ResStringPool_header>(), child_chunk.size());
              child_chunk.header<ResStringPool_header>(), child_chunk.size());
          if (err != NO_ERROR) {
          if (err != NO_ERROR) {
            LOG(ERROR) << "Corrupt package key string pool.";
            LOG(ERROR) << "RES_STRING_POOL_TYPE for keys corrupt.";
            return {};
            return {};
          }
          }
        } else {
        } else {
          LOG(WARNING) << "Too many string pool chunks found in package.";
          LOG(WARNING) << "Too many RES_STRING_POOL_TYPEs found in RES_TABLE_PACKAGE_TYPE.";
        }
        }
      } break;
      } break;


@@ -603,18 +551,18 @@ std::unique_ptr<const LoadedPackage> LoadedPackage::Load(const Chunk& chunk,


        const ResTable_typeSpec* type_spec = child_chunk.header<ResTable_typeSpec>();
        const ResTable_typeSpec* type_spec = child_chunk.header<ResTable_typeSpec>();
        if (type_spec == nullptr) {
        if (type_spec == nullptr) {
          LOG(ERROR) << "Chunk RES_TABLE_TYPE_SPEC_TYPE is too small.";
          LOG(ERROR) << "RES_TABLE_TYPE_SPEC_TYPE too small.";
          return {};
          return {};
        }
        }


        if (type_spec->id == 0) {
        if (type_spec->id == 0) {
          LOG(ERROR) << "Chunk RES_TABLE_TYPE_SPEC_TYPE has invalid ID 0.";
          LOG(ERROR) << "RES_TABLE_TYPE_SPEC_TYPE has invalid ID 0.";
          return {};
          return {};
        }
        }


        if (loaded_package->type_id_offset_ + static_cast<int>(type_spec->id) >
        if (loaded_package->type_id_offset_ + static_cast<int>(type_spec->id) >
            std::numeric_limits<uint8_t>::max()) {
            std::numeric_limits<uint8_t>::max()) {
          LOG(ERROR) << "Chunk RES_TABLE_TYPE_SPEC_TYPE has out of range ID.";
          LOG(ERROR) << "RES_TABLE_TYPE_SPEC_TYPE has out of range ID.";
          return {};
          return {};
        }
        }


@@ -626,12 +574,12 @@ std::unique_ptr<const LoadedPackage> LoadedPackage::Load(const Chunk& chunk,
        // There can only be 2^16 entries in a type, because that is the ID
        // There can only be 2^16 entries in a type, because that is the ID
        // space for entries (EEEE) in the resource ID 0xPPTTEEEE.
        // space for entries (EEEE) in the resource ID 0xPPTTEEEE.
        if (entry_count > std::numeric_limits<uint16_t>::max()) {
        if (entry_count > std::numeric_limits<uint16_t>::max()) {
          LOG(ERROR) << "Too many entries in RES_TABLE_TYPE_SPEC_TYPE: " << entry_count << ".";
          LOG(ERROR) << "RES_TABLE_TYPE_SPEC_TYPE has too many entries (" << entry_count << ").";
          return {};
          return {};
        }
        }


        if (entry_count * sizeof(uint32_t) > chunk.data_size()) {
        if (entry_count * sizeof(uint32_t) > chunk.data_size()) {
          LOG(ERROR) << "Chunk too small to hold entries in RES_TABLE_TYPE_SPEC_TYPE.";
          LOG(ERROR) << "RES_TABLE_TYPE_SPEC_TYPE too small to hold entries.";
          return {};
          return {};
        }
        }


@@ -650,41 +598,32 @@ std::unique_ptr<const LoadedPackage> LoadedPackage::Load(const Chunk& chunk,
      case RES_TABLE_TYPE_TYPE: {
      case RES_TABLE_TYPE_TYPE: {
        const ResTable_type* type = child_chunk.header<ResTable_type, kResTableTypeMinSize>();
        const ResTable_type* type = child_chunk.header<ResTable_type, kResTableTypeMinSize>();
        if (type == nullptr) {
        if (type == nullptr) {
          LOG(ERROR) << "Chunk RES_TABLE_TYPE_TYPE is too small.";
          LOG(ERROR) << "RES_TABLE_TYPE_TYPE too small.";
          return {};
          return {};
        }
        }


        if (type->id == 0) {
        if (!VerifyResTableType(type)) {
          LOG(ERROR) << "Chunk RES_TABLE_TYPE_TYPE has invalid ID 0.";
          return {};
          return {};
        }
        }


        // Type chunks must be preceded by their TypeSpec chunks.
        // Type chunks must be preceded by their TypeSpec chunks.
        if (!types_builder || type->id - 1 != last_type_idx) {
        if (!types_builder || type->id - 1 != last_type_idx) {
          LOG(ERROR) << "Found RES_TABLE_TYPE_TYPE chunk without RES_TABLE_TYPE_SPEC_TYPE.";
          LOG(ERROR) << "RES_TABLE_TYPE_TYPE found without preceding RES_TABLE_TYPE_SPEC_TYPE.";
          return {};
          return {};
        }
        }


        // Only verify the type if we haven't already failed verification.
        if (loaded_package->verified_) {
          if (!VerifyType(child_chunk)) {
            LOG(WARNING) << "Package failed verification, resource retrieval may be slower";
            loaded_package->verified_ = false;
          }
        }

        types_builder->AddType(type);
        types_builder->AddType(type);
      } break;
      } break;


      case RES_TABLE_LIBRARY_TYPE: {
      case RES_TABLE_LIBRARY_TYPE: {
        const ResTable_lib_header* lib = child_chunk.header<ResTable_lib_header>();
        const ResTable_lib_header* lib = child_chunk.header<ResTable_lib_header>();
        if (lib == nullptr) {
        if (lib == nullptr) {
          LOG(ERROR) << "Chunk RES_TABLE_LIBRARY_TYPE is too small.";
          LOG(ERROR) << "RES_TABLE_LIBRARY_TYPE too small.";
          return {};
          return {};
        }
        }


        if (child_chunk.data_size() / sizeof(ResTable_lib_entry) < dtohl(lib->count)) {
        if (child_chunk.data_size() / sizeof(ResTable_lib_entry) < dtohl(lib->count)) {
          LOG(ERROR) << "Chunk too small to hold entries in RES_TABLE_LIBRARY_TYPE.";
          LOG(ERROR) << "RES_TABLE_LIBRARY_TYPE too small to hold entries.";
          return {};
          return {};
        }
        }


@@ -751,7 +690,7 @@ bool LoadedArsc::FindEntry(uint32_t resid, const ResTable_config& config,
  const uint8_t type_id = get_type_id(resid);
  const uint8_t type_id = get_type_id(resid);
  const uint16_t entry_id = get_entry_id(resid);
  const uint16_t entry_id = get_entry_id(resid);


  if (type_id == 0) {
  if (UNLIKELY(type_id == 0)) {
    LOG(ERROR) << base::StringPrintf("Invalid ID 0x%08x.", resid);
    LOG(ERROR) << base::StringPrintf("Invalid ID 0x%08x.", resid);
    return false;
    return false;
  }
  }
@@ -769,7 +708,7 @@ bool LoadedArsc::LoadTable(const Chunk& chunk, const LoadedIdmap* loaded_idmap,
  ATRACE_CALL();
  ATRACE_CALL();
  const ResTable_header* header = chunk.header<ResTable_header>();
  const ResTable_header* header = chunk.header<ResTable_header>();
  if (header == nullptr) {
  if (header == nullptr) {
    LOG(ERROR) << "Chunk RES_TABLE_TYPE is too small.";
    LOG(ERROR) << "RES_TABLE_TYPE too small.";
    return false;
    return false;
  }
  }


@@ -788,11 +727,11 @@ bool LoadedArsc::LoadTable(const Chunk& chunk, const LoadedIdmap* loaded_idmap,
          status_t err = global_string_pool_.setTo(child_chunk.header<ResStringPool_header>(),
          status_t err = global_string_pool_.setTo(child_chunk.header<ResStringPool_header>(),
                                                   child_chunk.size());
                                                   child_chunk.size());
          if (err != NO_ERROR) {
          if (err != NO_ERROR) {
            LOG(ERROR) << "Corrupt string pool.";
            LOG(ERROR) << "RES_STRING_POOL_TYPE corrupt.";
            return false;
            return false;
          }
          }
        } else {
        } else {
          LOG(WARNING) << "Multiple string pool chunks found in resource table.";
          LOG(WARNING) << "Multiple RES_STRING_POOL_TYPEs found in RES_TABLE_TYPE.";
        }
        }
        break;
        break;


+0 −7
Original line number Original line Diff line number Diff line
@@ -119,11 +119,6 @@ class LoadedPackage {
    return overlay_;
    return overlay_;
  }
  }


  // Returns true if this package is verified to be valid.
  inline bool IsVerified() const {
    return verified_;
  }

  // Returns the map of package name to package ID used in this LoadedPackage. At runtime, a
  // Returns the map of package name to package ID used in this LoadedPackage. At runtime, a
  // package could have been assigned a different package ID than what this LoadedPackage was
  // package could have been assigned a different package ID than what this LoadedPackage was
  // compiled with. AssetManager rewrites the package IDs so that they are compatible at runtime.
  // compiled with. AssetManager rewrites the package IDs so that they are compatible at runtime.
@@ -145,7 +140,6 @@ class LoadedPackage {


  LoadedPackage();
  LoadedPackage();


  template <bool Verified>
  bool FindEntry(const util::unique_cptr<TypeSpec>& type_spec_ptr, uint16_t entry_idx,
  bool FindEntry(const util::unique_cptr<TypeSpec>& type_spec_ptr, uint16_t entry_idx,
                 const ResTable_config& config, FindEntryResult* out_entry) const;
                 const ResTable_config& config, FindEntryResult* out_entry) const;


@@ -157,7 +151,6 @@ class LoadedPackage {
  bool dynamic_ = false;
  bool dynamic_ = false;
  bool system_ = false;
  bool system_ = false;
  bool overlay_ = false;
  bool overlay_ = false;
  bool verified_ = true;


  ByteBucketArray<util::unique_cptr<TypeSpec>> type_specs_;
  ByteBucketArray<util::unique_cptr<TypeSpec>> type_specs_;
  std::vector<DynamicPackageEntry> dynamic_package_map_;
  std::vector<DynamicPackageEntry> dynamic_package_map_;
+0 −16
Original line number Original line Diff line number Diff line
@@ -39,7 +39,6 @@ TEST(ApkAssetsTest, LoadApk) {


  const LoadedPackage* loaded_package = loaded_arsc->GetPackageForId(0x7f010000);
  const LoadedPackage* loaded_package = loaded_arsc->GetPackageForId(0x7f010000);
  ASSERT_NE(nullptr, loaded_package);
  ASSERT_NE(nullptr, loaded_package);
  EXPECT_TRUE(loaded_package->IsVerified());


  std::unique_ptr<Asset> asset = loaded_apk->Open("res/layout/main.xml");
  std::unique_ptr<Asset> asset = loaded_apk->Open("res/layout/main.xml");
  ASSERT_NE(nullptr, asset);
  ASSERT_NE(nullptr, asset);
@@ -59,7 +58,6 @@ TEST(ApkAssetsTest, LoadApkFromFd) {


  const LoadedPackage* loaded_package = loaded_arsc->GetPackageForId(0x7f010000);
  const LoadedPackage* loaded_package = loaded_arsc->GetPackageForId(0x7f010000);
  ASSERT_NE(nullptr, loaded_package);
  ASSERT_NE(nullptr, loaded_package);
  EXPECT_TRUE(loaded_package->IsVerified());


  std::unique_ptr<Asset> asset = loaded_apk->Open("res/layout/main.xml");
  std::unique_ptr<Asset> asset = loaded_apk->Open("res/layout/main.xml");
  ASSERT_NE(nullptr, asset);
  ASSERT_NE(nullptr, asset);
@@ -114,20 +112,6 @@ TEST(ApkAssetsTest, LoadApkWithIdmap) {
  ASSERT_NE(nullptr, loaded_overlay_apk);
  ASSERT_NE(nullptr, loaded_overlay_apk);
}
}


TEST(ApkAssetsTest, LoadUnverifiableApk) {
  std::unique_ptr<const ApkAssets> loaded_apk =
      ApkAssets::Load(GetTestDataPath() + "/unverified/unverified.apk");
  ASSERT_NE(nullptr, loaded_apk);

  const LoadedArsc* loaded_arsc = loaded_apk->GetLoadedArsc();
  ASSERT_NE(nullptr, loaded_arsc);

  const LoadedPackage* loaded_package = loaded_arsc->GetPackageForId(0x7f010000);
  ASSERT_NE(nullptr, loaded_package);

  EXPECT_FALSE(loaded_package->IsVerified());
}

TEST(ApkAssetsTest, CreateAndDestroyAssetKeepsApkAssetsOpen) {
TEST(ApkAssetsTest, CreateAndDestroyAssetKeepsApkAssetsOpen) {
  std::unique_ptr<const ApkAssets> loaded_apk =
  std::unique_ptr<const ApkAssets> loaded_apk =
      ApkAssets::Load(GetTestDataPath() + "/basic/basic.apk");
      ApkAssets::Load(GetTestDataPath() + "/basic/basic.apk");
+0 −32
Original line number Original line Diff line number Diff line
@@ -26,12 +26,10 @@
#include "data/basic/R.h"
#include "data/basic/R.h"
#include "data/libclient/R.h"
#include "data/libclient/R.h"
#include "data/styles/R.h"
#include "data/styles/R.h"
#include "data/unverified/R.h"


namespace app = com::android::app;
namespace app = com::android::app;
namespace basic = com::android::basic;
namespace basic = com::android::basic;
namespace libclient = com::android::libclient;
namespace libclient = com::android::libclient;
namespace unverified = com::android::unverified;


namespace android {
namespace android {


@@ -95,12 +93,6 @@ static void BM_AssetManagerGetResourceOld(benchmark::State& state) {
}
}
BENCHMARK(BM_AssetManagerGetResourceOld);
BENCHMARK(BM_AssetManagerGetResourceOld);


static void BM_AssetManagerGetResourceUnverified(benchmark::State& state) {
  GetResourceBenchmark({GetTestDataPath() + "/unverified/unverified.apk"}, nullptr /*config*/,
                       unverified::R::integer::number1, state);
}
BENCHMARK(BM_AssetManagerGetResourceUnverified);

static void BM_AssetManagerGetLibraryResource(benchmark::State& state) {
static void BM_AssetManagerGetLibraryResource(benchmark::State& state) {
  GetResourceBenchmark(
  GetResourceBenchmark(
      {GetTestDataPath() + "/lib_two/lib_two.apk", GetTestDataPath() + "/lib_one/lib_one.apk",
      {GetTestDataPath() + "/lib_two/lib_two.apk", GetTestDataPath() + "/lib_one/lib_one.apk",
@@ -183,30 +175,6 @@ static void BM_AssetManagerGetBagOld(benchmark::State& state) {
}
}
BENCHMARK(BM_AssetManagerGetBagOld);
BENCHMARK(BM_AssetManagerGetBagOld);


static void BM_AssetManagerGetBagUnverified(benchmark::State& state) {
  std::unique_ptr<const ApkAssets> apk =
      ApkAssets::Load(GetTestDataPath() + "/unverified/unverified.apk");
  if (apk == nullptr) {
    state.SkipWithError("Failed to load assets");
    return;
  }

  AssetManager2 assets;
  assets.SetApkAssets({apk.get()});

  while (state.KeepRunning()) {
    const ResolvedBag* bag = assets.GetBag(unverified::R::array::integerArray1);
    const auto bag_end = end(bag);
    for (auto iter = begin(bag); iter != bag_end; ++iter) {
      uint32_t key = iter->key;
      Res_value value = iter->value;
      benchmark::DoNotOptimize(key);
      benchmark::DoNotOptimize(value);
    }
  }
}
BENCHMARK(BM_AssetManagerGetBagUnverified);

static void BM_AssetManagerGetResourceLocales(benchmark::State& state) {
static void BM_AssetManagerGetResourceLocales(benchmark::State& state) {
  std::unique_ptr<const ApkAssets> apk = ApkAssets::Load(kFrameworkPath);
  std::unique_ptr<const ApkAssets> apk = ApkAssets::Load(kFrameworkPath);
  if (apk == nullptr) {
  if (apk == nullptr) {
Loading