AAPT2: Fix issue where @null was wrongly encoded
@null must be encoded as TYPE_REFERENCE with a value of
0. TYPE_NULL is used by the runtime as a placeholder when resolving
style attributes. If we set a style attribute to TYPE_NULL,
the runtime will throw. The runtime will convert a TYPE_REFERENCE
with value 0 to a proper null value.
Change-Id: Id983ca7e1fbee3124dddafe32f1b5741b824225b
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 @@
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\"/>";