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

Commit 0699f1de authored by Ryan Mitchell's avatar Ryan Mitchell
Browse files

Remove idmap path 256 length limit

Overlay and target package paths can be longer than 256 characters.
Currently, the idmap will fail to be generated if either path
is longer than 256 characters.

This change removes the 256 character limit and makes parsing variable
length strings easier in libandroidfw.

Bug: 174676094
Test: idmap2_tests && libandroidfw_tests
Change-Id: Ic240cdb8700566b2ac2ade08da58bea852e4ae0c
parent 7e8ae00d
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -39,8 +39,8 @@ Result<Unit> Verify(const std::string& idmap_path, const std::string& target_pat
    return Error("failed to parse idmap header");
  }

  const auto header_ok = header->IsUpToDate(target_path.c_str(), overlay_path.c_str(),
                                            fulfilled_policies, enforce_overlayable);
  const auto header_ok =
      header->IsUpToDate(target_path, overlay_path, fulfilled_policies, enforce_overlayable);
  if (!header_ok) {
    return Error(header_ok.GetError(), "idmap not up to date");
  }
+5 −7
Original line number Diff line number Diff line
@@ -188,29 +188,27 @@ Result<Unit> Lookup(const std::vector<std::string>& args) {
    }

    if (i == 0) {
      target_path = idmap_header->GetTargetPath().to_string();
      target_path = idmap_header->GetTargetPath();
      auto target_apk = ApkAssets::Load(target_path);
      if (!target_apk) {
        return Error("failed to read target apk from %s", target_path.c_str());
      }
      apk_assets.push_back(std::move(target_apk));

      auto manifest_info = ExtractOverlayManifestInfo(idmap_header->GetOverlayPath().to_string(),
                                                      true /* assert_overlay */);
      auto manifest_info =
          ExtractOverlayManifestInfo(idmap_header->GetOverlayPath(), true /* assert_overlay */);
      if (!manifest_info) {
        return manifest_info.GetError();
      }
      target_package_name = (*manifest_info).target_package;
    } else if (target_path != idmap_header->GetTargetPath()) {
      return Error("different target APKs (expected target APK %s but %s has target APK %s)",
                   target_path.c_str(), idmap_path.c_str(),
                   idmap_header->GetTargetPath().to_string().c_str());
                   target_path.c_str(), idmap_path.c_str(), idmap_header->GetTargetPath().c_str());
    }

    auto overlay_apk = ApkAssets::LoadOverlay(idmap_path);
    if (!overlay_apk) {
      return Error("failed to read overlay apk from %s",
                   idmap_header->GetOverlayPath().to_string().c_str());
      return Error("failed to read overlay apk from %s", idmap_header->GetOverlayPath().c_str());
    }
    apk_assets.push_back(std::move(overlay_apk));
  }
+1 −1
Original line number Diff line number Diff line
@@ -156,7 +156,7 @@ Status Idmap2Service::verifyIdmap(const std::string& target_apk_path,
  }

  auto up_to_date =
      header->IsUpToDate(target_apk_path.c_str(), overlay_apk_path.c_str(), target_crc, overlay_crc,
      header->IsUpToDate(target_apk_path overlay_apk_path, target_crc, overlay_crc,
                         ConvertAidlArgToPolicyBitmask(fulfilled_policies), enforce_overlayable);

  *_aidl_return = static_cast<bool>(up_to_date);
+0 −1
Original line number Diff line number Diff line
@@ -39,7 +39,6 @@ class BinaryStreamVisitor : public Visitor {
  void Write8(uint8_t value);
  void Write16(uint16_t value);
  void Write32(uint32_t value);
  void WriteString256(const StringPiece& value);
  void WriteString(const StringPiece& value);
  std::ostream& stream_;
};
+15 −22
Original line number Diff line number Diff line
@@ -37,13 +37,12 @@
 * overlay_entry_count        := <uint32_t>
 * overlay_id                 := <uint32_t>
 * overlay_package_id         := <uint8_t>
 * overlay_path               := string256
 * overlay_path               := string
 * padding(n)                 := <uint8_t>[n]
 * Res_value::size            := <uint16_t>
 * Res_value::type            := <uint8_t>
 * Res_value::value           := <uint32_t>
 * string                     := <uint32_t> <uint8_t>+ padding(n)
 * string256                  := <uint8_t>[256]
 * string_pool                := string
 * string_pool_index          := <uint32_t>
 * string_pool_length         := <uint32_t>
@@ -52,7 +51,7 @@
 * target_inline_entry_count  := <uint32_t>
 * target_id                  := <uint32_t>
 * target_package_id          := <uint8_t>
 * target_path                := string256
 * target_path                := string
 * value_type                 := <uint8_t>
 * value_data                 := <uint32_t>
 * version                    := <uint32_t>
@@ -87,10 +86,6 @@ static constexpr const uint32_t kIdmapMagic = android::kIdmapMagic;
// current version of the idmap binary format; must be incremented when the format is changed
static constexpr const uint32_t kIdmapCurrentVersion = android::kIdmapCurrentVersion;

// strings in the idmap are encoded char arrays of length 'kIdmapStringLength' (including mandatory
// terminating null)
static constexpr const size_t kIdmapStringLength = 256;

// Retrieves a crc generated using all of the files within the zip that can affect idmap generation.
Result<uint32_t> GetPackageCrc(const ZipFile& zip_info);

@@ -122,26 +117,26 @@ class IdmapHeader {
    return enforce_overlayable_;
  }

  inline StringPiece GetTargetPath() const {
    return StringPiece(target_path_);
  const std::string& GetTargetPath() const {
    return target_path_;
  }

  inline StringPiece GetOverlayPath() const {
    return StringPiece(overlay_path_);
  const std::string& GetOverlayPath() const {
    return overlay_path_;
  }

  inline const std::string& GetDebugInfo() const {
  const std::string& GetDebugInfo() const {
    return debug_info_;
  }

  // Invariant: anytime the idmap data encoding is changed, the idmap version
  // field *must* be incremented. Because of this, we know that if the idmap
  // header is up-to-date the entire file is up-to-date.
  Result<Unit> IsUpToDate(const char* target_path, const char* overlay_path,
  Result<Unit> IsUpToDate(const std::string& target_path, const std::string& overlay_path,
                          PolicyBitmask fulfilled_policies, bool enforce_overlayable) const;
  Result<Unit> IsUpToDate(const std::string& target_path, const std::string& overlay_path,
                          uint32_t target_crc, uint32_t overlay_crc,
                          PolicyBitmask fulfilled_policies, bool enforce_overlayable) const;
  Result<Unit> IsUpToDate(const char* target_path, const char* overlay_path, uint32_t target_crc,
                          uint32_t overlay_crc, PolicyBitmask fulfilled_policies,
                          bool enforce_overlayable) const;

  void accept(Visitor* v) const;

@@ -155,8 +150,8 @@ class IdmapHeader {
  uint32_t overlay_crc_;
  uint32_t fulfilled_policies_;
  bool enforce_overlayable_;
  char target_path_[kIdmapStringLength];
  char overlay_path_[kIdmapStringLength];
  std::string target_path_;
  std::string overlay_path_;
  std::string debug_info_;

  friend Idmap;
@@ -291,8 +286,7 @@ class Idmap {
  void accept(Visitor* v) const;

 private:
  Idmap() {
  }
  Idmap() = default;

  std::unique_ptr<const IdmapHeader> header_;
  std::vector<std::unique_ptr<const IdmapData>> data_;
@@ -302,8 +296,7 @@ class Idmap {

class Visitor {
 public:
  virtual ~Visitor() {
  }
  virtual ~Visitor() = default;
  virtual void visit(const Idmap& idmap) = 0;
  virtual void visit(const IdmapHeader& header) = 0;
  virtual void visit(const IdmapData& data) = 0;
Loading