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

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

Merge "AAPT2: Fail on invalid id names in compiled xml"

parents 921f354c 79848547
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -133,11 +133,19 @@ class SourcePathDiagnostics : public IDiagnostics {
  void Log(Level level, DiagMessageActual& actual_msg) override {
    actual_msg.source.path = source_.path;
    diag_->Log(level, actual_msg);
    if (level == Level::Error) {
      error = true;
    }
  }

  bool HadError() {
    return error;
  }

 private:
  Source source_;
  IDiagnostics* diag_;
  bool error = false;

  DISALLOW_COPY_AND_ASSIGN(SourcePathDiagnostics);
};
+18 −10
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@

#include "ResourceUtils.h"
#include "ResourceValues.h"
#include "text/Unicode.h"
#include "xml/XmlDom.h"

namespace aapt {
@@ -35,8 +36,9 @@ struct IdCollector : public xml::Visitor {
 public:
  using xml::Visitor::Visit;

  explicit IdCollector(std::vector<SourcedResourceName>* out_symbols)
      : out_symbols_(out_symbols) {}
  explicit IdCollector(std::vector<SourcedResourceName>* out_symbols,
                       SourcePathDiagnostics* source_diag) : out_symbols_(out_symbols),
                                                             source_diag_(source_diag) {}

  void Visit(xml::Element* element) override {
    for (xml::Attribute& attr : element->attributes) {
@@ -44,31 +46,37 @@ struct IdCollector : public xml::Visitor {
      bool create = false;
      if (ResourceUtils::ParseReference(attr.value, &name, &create, nullptr)) {
        if (create && name.type == ResourceType::kId) {
          if (!text::IsValidResourceEntryName(name.entry)) {
            source_diag_->Error(DiagMessage(element->line_number)
                                   << "id '" << name << "' has an invalid entry name");
          } else {
            auto iter = std::lower_bound(out_symbols_->begin(),
                                         out_symbols_->end(), name, cmp_name);
            if (iter == out_symbols_->end() || iter->name != name) {
            out_symbols_->insert(iter,
                                 SourcedResourceName{name.ToResourceName(),
              out_symbols_->insert(iter, SourcedResourceName{name.ToResourceName(),
                                                             element->line_number});
            }
          }
        }
      }
    }

    xml::Visitor::Visit(element);
  }

 private:
  std::vector<SourcedResourceName>* out_symbols_;
  SourcePathDiagnostics* source_diag_;
};

}  // namespace

bool XmlIdCollector::Consume(IAaptContext* context, xml::XmlResource* xmlRes) {
  xmlRes->file.exported_symbols.clear();
  IdCollector collector(&xmlRes->file.exported_symbols);
  SourcePathDiagnostics source_diag(xmlRes->file.source, context->GetDiagnostics());
  IdCollector collector(&xmlRes->file.exported_symbols, &source_diag);
  xmlRes->root->Accept(&collector);
  return true;
  return !source_diag.HadError();
}

}  // namespace aapt
+10 −0
Original line number Diff line number Diff line
@@ -64,4 +64,14 @@ TEST(XmlIdCollectorTest, DontCollectNonIds) {
  EXPECT_TRUE(doc->file.exported_symbols.empty());
}

TEST(XmlIdCollectorTest, ErrorOnInvalidIds) {
  std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build();

  std::unique_ptr<xml::XmlResource> doc =
      test::BuildXmlDom("<View foo=\"@+id/foo$bar\"/>");

  XmlIdCollector collector;
  ASSERT_FALSE(collector.Consume(context.get(), doc.get()));
}

}  // namespace aapt