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

Commit 67e8a307 authored by Shane Farmer's avatar Shane Farmer
Browse files

AAPT2: Add validation for SDK version strings.

Ensure that the configured min max and target SDK versions of the
android-sdk configuration item are correct. This will prevent AAPT2
crashing when it tries to dereference the Android SDK version to update
the manifest.

The test for the latest development SDK version has also been made
future proof by using the SDK constants.

Test: unit tests
Test: manually split an APK
Change-Id: I1ffa90ba2d96cab0cbfa4bd75ef37a50d986852d
parent d87c6b51
Loading
Loading
Loading
Loading
+11 −3
Original line number Diff line number Diff line
@@ -519,14 +519,22 @@ ConfigurationParser::ActionHandler ConfigurationParser::android_sdk_group_handle
    } else {
      AndroidSdk entry;
      for (const auto& attr : child->attributes) {
        Maybe<int>* target = nullptr;
        if (attr.name == "minSdkVersion") {
          entry.min_sdk_version = ResourceUtils::ParseSdkVersion(attr.value);
          target = &entry.min_sdk_version;
        } else if (attr.name == "targetSdkVersion") {
          entry.target_sdk_version = ResourceUtils::ParseSdkVersion(attr.value);
          target = &entry.target_sdk_version;
        } else if (attr.name == "maxSdkVersion") {
          entry.max_sdk_version = ResourceUtils::ParseSdkVersion(attr.value);
          target = &entry.max_sdk_version;
        } else {
          diag->Warn(DiagMessage() << "Unknown attribute: " << attr.name << " = " << attr.value);
          continue;
        }

        *target = ResourceUtils::ParseSdkVersion(attr.value);
        if (!*target) {
          diag->Error(DiagMessage() << "Invalid attribute: " << attr.name << " = " << attr.value);
          valid = false;
        }
      }

+109 −17
Original line number Diff line number Diff line
@@ -18,8 +18,10 @@

#include <string>

#include "android-base/stringprintf.h"
#include "androidfw/ResourceTypes.h"

#include "SdkConstants.h"
#include "test/Test.h"
#include "xml/XmlDom.h"

@@ -35,18 +37,19 @@ void PrintTo(const AndroidSdk& sdk, std::ostream* os) {

namespace {

using ::aapt::configuration::Abi;
using ::aapt::configuration::AndroidManifest;
using ::aapt::configuration::AndroidSdk;
using ::aapt::configuration::Artifact;
using ::aapt::configuration::DeviceFeature;
using ::aapt::configuration::GlTexture;
using ::aapt::configuration::Locale;
using ::aapt::configuration::PostProcessingConfiguration;
using ::aapt::xml::Element;
using ::aapt::xml::NodeCast;
using ::android::ResTable_config;
using configuration::Abi;
using configuration::AndroidSdk;
using configuration::Artifact;
using configuration::PostProcessingConfiguration;
using configuration::DeviceFeature;
using configuration::GlTexture;
using configuration::Locale;
using configuration::AndroidManifest;
using ::android::base::StringPrintf;
using ::testing::ElementsAre;
using xml::Element;
using xml::NodeCast;

constexpr const char* kValidConfig = R"(<?xml version="1.0" encoding="utf-8" ?>
<post-process xmlns="http://schemas.android.com/tools/aapt">
@@ -421,17 +424,106 @@ TEST_F(ConfigurationParserTest, AndroidSdkGroupAction) {
  ASSERT_EQ(sdk, out);
}

TEST_F(ConfigurationParserTest, AndroidSdkGroupAction_SingleVersion) {
  {
    static constexpr const char* xml = R"xml(
      <android-sdk-group label="v19">
        <android-sdk minSdkVersion="19"></android-sdk>
      </android-sdk-group>)xml";

    auto doc = test::BuildXmlDom(xml);

    PostProcessingConfiguration config;
    bool ok = android_sdk_group_handler_(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
    ASSERT_TRUE(ok);

    ASSERT_EQ(1ul, config.android_sdk_groups.size());
    ASSERT_EQ(1u, config.android_sdk_groups.count("v19"));

    auto& out = config.android_sdk_groups["v19"];
    EXPECT_EQ(19, out.min_sdk_version.value());
    EXPECT_FALSE(out.max_sdk_version);
    EXPECT_FALSE(out.target_sdk_version);
  }

  {
    static constexpr const char* xml = R"xml(
      <android-sdk-group label="v19">
        <android-sdk maxSdkVersion="19"></android-sdk>
      </android-sdk-group>)xml";

    auto doc = test::BuildXmlDom(xml);

    PostProcessingConfiguration config;
    bool ok = android_sdk_group_handler_(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
    ASSERT_TRUE(ok);

    ASSERT_EQ(1ul, config.android_sdk_groups.size());
    ASSERT_EQ(1u, config.android_sdk_groups.count("v19"));

    auto& out = config.android_sdk_groups["v19"];
    EXPECT_EQ(19, out.max_sdk_version.value());
    EXPECT_FALSE(out.min_sdk_version);
    EXPECT_FALSE(out.target_sdk_version);
  }

  {
    static constexpr const char* xml = R"xml(
      <android-sdk-group label="v19">
        <android-sdk targetSdkVersion="19"></android-sdk>
      </android-sdk-group>)xml";

    auto doc = test::BuildXmlDom(xml);

    PostProcessingConfiguration config;
    bool ok = android_sdk_group_handler_(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
    ASSERT_TRUE(ok);

    ASSERT_EQ(1ul, config.android_sdk_groups.size());
    ASSERT_EQ(1u, config.android_sdk_groups.count("v19"));

    auto& out = config.android_sdk_groups["v19"];
    EXPECT_EQ(19, out.target_sdk_version.value());
    EXPECT_FALSE(out.min_sdk_version);
    EXPECT_FALSE(out.max_sdk_version);
  }
}

TEST_F(ConfigurationParserTest, AndroidSdkGroupAction_InvalidVersion) {
  static constexpr const char* xml = R"xml(
    <android-sdk-group label="v19">
      <android-sdk
          minSdkVersion="v19"
          targetSdkVersion="v24"
          maxSdkVersion="v25">
        <manifest>
          <!--- manifest additions here XSLT? TODO -->
        </manifest>
      </android-sdk>
    </android-sdk-group>)xml";

  auto doc = test::BuildXmlDom(xml);

  PostProcessingConfiguration config;
  bool ok = android_sdk_group_handler_(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
  ASSERT_FALSE(ok);
}

TEST_F(ConfigurationParserTest, AndroidSdkGroupAction_NonNumeric) {
  static constexpr const char* xml = R"xml(
    <android-sdk-group label="P">
      <android-sdk
          minSdkVersion="M"
          targetSdkVersion="P"
          maxSdkVersion="P">
          minSdkVersion="25"
          targetSdkVersion="%s"
          maxSdkVersion="%s">
      </android-sdk>
    </android-sdk-group>)xml";

  auto doc = test::BuildXmlDom(xml);
  const auto& dev_sdk = GetDevelopmentSdkCodeNameAndVersion();
  const char* codename = dev_sdk.first.data();
  const ApiVersion& version = dev_sdk.second;

  auto doc = test::BuildXmlDom(StringPrintf(xml, codename, codename));

  PostProcessingConfiguration config;
  bool ok = android_sdk_group_handler_(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
@@ -443,9 +535,9 @@ TEST_F(ConfigurationParserTest, AndroidSdkGroupAction_NonNumeric) {
  auto& out = config.android_sdk_groups["P"];

  AndroidSdk sdk;
  sdk.min_sdk_version = {};  // Only the latest development version is supported.
  sdk.target_sdk_version = 28;
  sdk.max_sdk_version = 28;
  sdk.min_sdk_version = 25;
  sdk.target_sdk_version = version;
  sdk.max_sdk_version = version;

  ASSERT_EQ(sdk, out);
}