diff options
author | Adam Lesinski <adamlesinski@google.com> | 2015-05-13 21:42:57 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2015-05-13 21:43:00 +0000 |
commit | 4ee67bc7a7bb84da1c92dc08427f9737ff8252d6 (patch) | |
tree | 1cde9191650b0264f6f4e831a563bcadbecc848c | |
parent | ae8fcaf4c320dbf68db7dc032269692806150d99 (diff) | |
parent | dfa5e0705ff82f15e228ba076bc192893bcbe118 (diff) | |
download | frameworks_base-4ee67bc7a7bb84da1c92dc08427f9737ff8252d6.zip frameworks_base-4ee67bc7a7bb84da1c92dc08427f9737ff8252d6.tar.gz frameworks_base-4ee67bc7a7bb84da1c92dc08427f9737ff8252d6.tar.bz2 |
Merge "AAPT2: Fix issue where @null was wrongly encoded" into mnc-dev
-rw-r--r-- | tools/aapt2/BinaryResourceParser.cpp | 3 | ||||
-rw-r--r-- | tools/aapt2/ResourceParser.cpp | 14 | ||||
-rw-r--r-- | tools/aapt2/ResourceParser_test.cpp | 26 |
3 files changed, 34 insertions, 9 deletions
diff --git a/tools/aapt2/BinaryResourceParser.cpp b/tools/aapt2/BinaryResourceParser.cpp index 620f0fe..3559f43 100644 --- a/tools/aapt2/BinaryResourceParser.cpp +++ b/tools/aapt2/BinaryResourceParser.cpp @@ -697,8 +697,7 @@ std::unique_ptr<Item> BinaryResourceParser::parseValue(const ResourceNameRef& na // This is not an unresolved symbol, so it must be the magic @null reference. Res_value nullType = {}; - nullType.dataType = Res_value::TYPE_NULL; - nullType.data = Res_value::DATA_NULL_UNDEFINED; + nullType.dataType = Res_value::TYPE_REFERENCE; return util::make_unique<BinaryPrimitive>(nullType); } diff --git a/tools/aapt2/ResourceParser.cpp b/tools/aapt2/ResourceParser.cpp index 59915a2..13f916b 100644 --- a/tools/aapt2/ResourceParser.cpp +++ b/tools/aapt2/ResourceParser.cpp @@ -193,18 +193,18 @@ std::unique_ptr<Reference> ResourceParser::tryParseReference(const StringPiece16 std::unique_ptr<BinaryPrimitive> ResourceParser::tryParseNullOrEmpty(const StringPiece16& str) { StringPiece16 trimmedStr(util::trimWhitespace(str)); - uint32_t data = 0; + android::Res_value value = {}; if (trimmedStr == u"@null") { - data = android::Res_value::DATA_NULL_UNDEFINED; + // TYPE_NULL with data set to 0 is interpreted by the runtime as an error. + // Instead we set the data type to TYPE_REFERENCE with a value of 0. + value.dataType = android::Res_value::TYPE_REFERENCE; } else if (trimmedStr == u"@empty") { - data = android::Res_value::DATA_NULL_EMPTY; + // TYPE_NULL with value of DATA_NULL_EMPTY is handled fine by the runtime. + value.dataType = android::Res_value::TYPE_NULL; + value.data = android::Res_value::DATA_NULL_EMPTY; } else { return {}; } - - android::Res_value value = {}; - value.dataType = android::Res_value::TYPE_NULL; - value.data = data; return util::make_unique<BinaryPrimitive>(value); } diff --git a/tools/aapt2/ResourceParser_test.cpp b/tools/aapt2/ResourceParser_test.cpp index 3d8a2f0..a93d0ff 100644 --- a/tools/aapt2/ResourceParser_test.cpp +++ b/tools/aapt2/ResourceParser_test.cpp @@ -191,6 +191,32 @@ TEST_F(ResourceParserTest, ParseEscapedString) { EXPECT_EQ(std::u16string(u"?123"), *str->value); } +TEST_F(ResourceParserTest, ParseNull) { + std::string input = "<integer name=\"foo\">@null</integer>"; + ASSERT_TRUE(testParse(input)); + + // The Android runtime treats a value of android::Res_value::TYPE_NULL as + // a non-existing value, and this causes problems in styles when trying to resolve + // an attribute. Null values must be encoded as android::Res_value::TYPE_REFERENCE + // with a data value of 0. + const BinaryPrimitive* integer = findResource<BinaryPrimitive>(ResourceName{ + u"android", ResourceType::kInteger, u"foo" }); + ASSERT_NE(nullptr, integer); + EXPECT_EQ(uint16_t(android::Res_value::TYPE_REFERENCE), integer->value.dataType); + EXPECT_EQ(0u, integer->value.data); +} + +TEST_F(ResourceParserTest, ParseEmpty) { + std::string input = "<integer name=\"foo\">@empty</integer>"; + ASSERT_TRUE(testParse(input)); + + const BinaryPrimitive* integer = findResource<BinaryPrimitive>(ResourceName{ + u"android", ResourceType::kInteger, u"foo" }); + ASSERT_NE(nullptr, integer); + EXPECT_EQ(uint16_t(android::Res_value::TYPE_NULL), integer->value.dataType); + EXPECT_EQ(uint32_t(android::Res_value::DATA_NULL_EMPTY), integer->value.data); +} + TEST_F(ResourceParserTest, ParseAttr) { std::string input = "<attr name=\"foo\" format=\"string\"/>\n" "<attr name=\"bar\"/>"; |