Loading tools/aapt2/BinaryResourceParser.cpp +1 −2 Original line number Diff line number Diff line Loading @@ -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); } Loading tools/aapt2/ResourceParser.cpp +7 −7 Original line number Diff line number Diff line Loading @@ -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); } Loading tools/aapt2/ResourceParser_test.cpp +26 −0 Original line number Diff line number Diff line Loading @@ -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\"/>"; Loading Loading
tools/aapt2/BinaryResourceParser.cpp +1 −2 Original line number Diff line number Diff line Loading @@ -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); } Loading
tools/aapt2/ResourceParser.cpp +7 −7 Original line number Diff line number Diff line Loading @@ -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); } Loading
tools/aapt2/ResourceParser_test.cpp +26 −0 Original line number Diff line number Diff line Loading @@ -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\"/>"; Loading