summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Shane Farmer <safarmer@google.com> 2017-12-06 14:39:10 -0800
committer Shane Farmer <safarmer@google.com> 2017-12-12 16:25:26 -0800
commit67e8a3074d7ef42734d44f3a8d87635e201bd660 (patch)
treecd5931f49e35ec7943f166d05f8c5410ac0b1ef7
parentd87c6b51f55985e343cf96f57b06e4adebf53d25 (diff)
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
-rw-r--r--tools/aapt2/configuration/ConfigurationParser.cpp14
-rw-r--r--tools/aapt2/configuration/ConfigurationParser_test.cpp126
2 files changed, 120 insertions, 20 deletions
diff --git a/tools/aapt2/configuration/ConfigurationParser.cpp b/tools/aapt2/configuration/ConfigurationParser.cpp
index b99240f0a40a..852ff176ed7d 100644
--- a/tools/aapt2/configuration/ConfigurationParser.cpp
+++ b/tools/aapt2/configuration/ConfigurationParser.cpp
@@ -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;
}
}
diff --git a/tools/aapt2/configuration/ConfigurationParser_test.cpp b/tools/aapt2/configuration/ConfigurationParser_test.cpp
index afa155f46eb9..f7153c822bbc 100644
--- a/tools/aapt2/configuration/ConfigurationParser_test.cpp
+++ b/tools/aapt2/configuration/ConfigurationParser_test.cpp
@@ -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);
}