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

Commit 6f698ab3 authored by Ryan Mitchell's avatar Ryan Mitchell Committed by Android (Google) Code Review
Browse files

Merge "Revert "Improve idmap2 xml parsing""

parents 88965157 09f17a6c
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -45,7 +45,7 @@ cc_library {
        "libidmap2/RawPrintVisitor.cpp",
        "libidmap2/ResourceUtils.cpp",
        "libidmap2/Result.cpp",
        "libidmap2/XmlParser.cpp",
        "libidmap2/Xml.cpp",
        "libidmap2/ZipFile.cpp",
    ],
    export_include_dirs: ["include"],
@@ -99,7 +99,7 @@ cc_test {
        "tests/RawPrintVisitorTests.cpp",
        "tests/ResourceUtilsTests.cpp",
        "tests/ResultTests.cpp",
        "tests/XmlParserTests.cpp",
        "tests/XmlTests.cpp",
        "tests/ZipFileTests.cpp",
    ],
    required: [
+31 −8
Original line number Diff line number Diff line
@@ -33,10 +33,9 @@
#include "androidfw/Util.h"
#include "idmap2/CommandLineOptions.h"
#include "idmap2/Idmap.h"
#include "idmap2/ResourceUtils.h"
#include "idmap2/Result.h"
#include "idmap2/SysTrace.h"
#include "idmap2/XmlParser.h"
#include "idmap2/Xml.h"
#include "idmap2/ZipFile.h"
#include "utils/String16.h"
#include "utils/String8.h"
@@ -58,7 +57,8 @@ using android::idmap2::IdmapHeader;
using android::idmap2::ResourceId;
using android::idmap2::Result;
using android::idmap2::Unit;
using android::idmap2::utils::ExtractOverlayManifestInfo;
using android::idmap2::Xml;
using android::idmap2::ZipFile;
using android::util::Utf16ToUtf8;

namespace {
@@ -132,6 +132,29 @@ Result<std::string> WARN_UNUSED GetValue(const AssetManager2& am, ResourceId res
  return out;
}

Result<std::string> GetTargetPackageNameFromManifest(const std::string& apk_path) {
  const auto zip = ZipFile::Open(apk_path);
  if (!zip) {
    return Error("failed to open %s as zip", apk_path.c_str());
  }
  const auto entry = zip->Uncompress("AndroidManifest.xml");
  if (!entry) {
    return Error("failed to uncompress AndroidManifest.xml in %s", apk_path.c_str());
  }
  const auto xml = Xml::Create(entry->buf, entry->size);
  if (!xml) {
    return Error("failed to create XML buffer");
  }
  const auto tag = xml->FindTag("overlay");
  if (!tag) {
    return Error("failed to find <overlay> tag");
  }
  const auto iter = tag->find("targetPackage");
  if (iter == tag->end()) {
    return Error("failed to find targetPackage attribute");
  }
  return iter->second;
}
}  // namespace

Result<Unit> Lookup(const std::vector<std::string>& args) {
@@ -179,12 +202,12 @@ Result<Unit> Lookup(const std::vector<std::string>& args) {
      }
      apk_assets.push_back(std::move(target_apk));

      auto manifest_info = ExtractOverlayManifestInfo(idmap_header->GetOverlayPath().to_string(),
                                                      true /* assert_overlay */);
      if (!manifest_info) {
        return manifest_info.GetError();
      const Result<std::string> package_name =
          GetTargetPackageNameFromManifest(idmap_header->GetOverlayPath().to_string());
      if (!package_name) {
        return Error("failed to parse android:targetPackage from overlay manifest");
      }
      target_package_name = (*manifest_info).target_package;
      target_package_name = *package_name;
    } 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(),
+1 −1
Original line number Diff line number Diff line
@@ -33,7 +33,7 @@
#include "idmap2/ResourceUtils.h"
#include "idmap2/Result.h"
#include "idmap2/SysTrace.h"
#include "idmap2/XmlParser.h"
#include "idmap2/Xml.h"
#include "idmap2/ZipFile.h"

using android::idmap2::CommandLineOptions;
+49 −0
Original line number Diff line number Diff line
/*
 * 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.
 */

#ifndef IDMAP2_INCLUDE_IDMAP2_XML_H_
#define IDMAP2_INCLUDE_IDMAP2_XML_H_

#include <map>
#include <memory>
#include <string>

#include "android-base/macros.h"
#include "androidfw/ResourceTypes.h"
#include "utils/String16.h"

namespace android::idmap2 {

class Xml {
 public:
  static std::unique_ptr<const Xml> Create(const uint8_t* data, size_t size, bool copyData = false);

  std::unique_ptr<std::map<std::string, std::string>> FindTag(const std::string& name) const;

  ~Xml();

 private:
  Xml() {
  }

  mutable ResXMLTree xml_;

  DISALLOW_COPY_AND_ASSIGN(Xml);
};

}  // namespace android::idmap2

#endif  // IDMAP2_INCLUDE_IDMAP2_XML_H_
+0 −147
Original line number Diff line number Diff line
/*
 * Copyright (C) 2019 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.
 */

#ifndef IDMAP2_INCLUDE_IDMAP2_XMLPARSER_H_
#define IDMAP2_INCLUDE_IDMAP2_XMLPARSER_H_

#include <iostream>
#include <map>
#include <memory>
#include <string>

#include "Result.h"
#include "android-base/macros.h"
#include "androidfw/ResourceTypes.h"
#include "utils/String16.h"

namespace android::idmap2 {

class XmlParser {
 public:
  using Event = ResXMLParser::event_code_t;
  class iterator;

  class Node {
   public:
    Event event() const;
    std::string name() const;

    Result<std::string> GetAttributeStringValue(const std::string& name) const;
    Result<Res_value> GetAttributeValue(const std::string& name) const;

    bool operator==(const Node& rhs) const;
    bool operator!=(const Node& rhs) const;

   private:
    explicit Node(const ResXMLTree& tree);
    Node(const ResXMLTree& tree, const ResXMLParser::ResXMLPosition& pos);

    // Retrieves/Sets the position of the position of the xml parser in the xml tree.
    ResXMLParser::ResXMLPosition get_position() const;
    void set_position(const ResXMLParser::ResXMLPosition& pos);

    // If `inner_child` is true, seek advances the parser to the first inner child of the current
    // node. Otherwise, seek advances the parser to the following node. Returns false if there is
    // no node to seek to.
    bool Seek(bool inner_child);

    ResXMLParser parser_;
    friend iterator;
  };

  class iterator {
   public:
    iterator(const iterator& other) : iterator(other.tree_, other.iter_) {
    }

    inline iterator& operator=(const iterator& rhs) {
      iter_.set_position(rhs.iter_.get_position());
      return *this;
    }

    inline bool operator==(const iterator& rhs) const {
      return iter_ == rhs.iter_;
    }

    inline bool operator!=(const iterator& rhs) const {
      return !(*this == rhs);
    }

    inline iterator operator++() {
      // Seek to the following xml node.
      iter_.Seek(false /* inner_child */);
      return *this;
    }

    iterator begin() const {
      iterator child_it(*this);
      // Seek to the first inner child of the current node.
      child_it.iter_.Seek(true /* inner_child */);
      return child_it;
    }

    iterator end() const {
      iterator child_it = begin();
      while (child_it.iter_.Seek(false /* inner_child */)) {
        // Continue iterating until the end tag is found.
      }

      return child_it;
    }

    inline const Node operator*() {
      return Node(tree_, iter_.get_position());
    }

    inline const Node* operator->() {
      return &iter_;
    }

   private:
    explicit iterator(const ResXMLTree& tree) : tree_(tree), iter_(Node(tree)) {
    }
    iterator(const ResXMLTree& tree, const Node& node)
        : tree_(tree), iter_(Node(tree, node.get_position())) {
    }

    const ResXMLTree& tree_;
    Node iter_;
    friend XmlParser;
  };

  // Creates a new xml parser beginning at the first tag.
  static Result<std::unique_ptr<const XmlParser>> Create(const void* data, size_t size,
                                                         bool copy_data = false);
  ~XmlParser();

  inline iterator tree_iterator() const {
    return iterator(tree_);
  }

  inline const ResStringPool& get_strings() const {
    return tree_.getStrings();
  }

 private:
  XmlParser() = default;
  mutable ResXMLTree tree_;

  DISALLOW_COPY_AND_ASSIGN(XmlParser);
};

}  // namespace android::idmap2

#endif  // IDMAP2_INCLUDE_IDMAP2_XMLPARSER_H_
Loading