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

Commit 11f9867c authored by Adam Lesinski's avatar Adam Lesinski Committed by Android Git Automerger
Browse files

am 4ee67bc7: Merge "AAPT2: Fix issue where @null was wrongly encoded" into mnc-dev

* commit '4ee67bc7':
  AAPT2: Fix issue where @null was wrongly encoded
parents 093dec3d 4ee67bc7
Loading
Loading
Loading
Loading
+1 −2
Original line number Diff line number Diff line
@@ -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);
    }

+7 −7
Original line number Diff line number Diff line
@@ -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);
}

+26 −0
Original line number Diff line number Diff line
@@ -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\"/>";