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

Commit 09f17a6c authored by Ryan Mitchell's avatar Ryan Mitchell
Browse files

Revert "Improve idmap2 xml parsing"

This reverts commit 58cdc2a8.

Reason for revert: <aosp/1129572 caused a build failure>

Change-Id: Iecae19877dacf9ec5c2b2bc59dca362f573e9a7a
parent 58cdc2a8
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