AAPT2: Fix issue with enums and integer attributes

When an attribute had the format "enum|integer", and a max or min
allowed value set, any value set for this attribute would have its
enum symbol's value checked against the valid integer range.

This would lead to the following:

android:numColumns="autofit"

being interpreted as an integer value of -1, which violated the minimum
expected value for numColumns, which was 0.

Bug: 62358540
Test: make aapt2_tests
Change-Id: I3150410448a533d3595a08ac6b2966264db874d8
diff --git a/tools/aapt2/ResourceValues_test.cpp b/tools/aapt2/ResourceValues_test.cpp
index 69f8e67..06c3404 100644
--- a/tools/aapt2/ResourceValues_test.cpp
+++ b/tools/aapt2/ResourceValues_test.cpp
@@ -190,4 +190,52 @@
   EXPECT_EQ(0x0u, value.data);
 }
 
+TEST(ResourcesValuesTest, AttributeMatches) {
+  constexpr const uint32_t TYPE_DIMENSION = android::ResTable_map::TYPE_DIMENSION;
+  constexpr const uint32_t TYPE_ENUM = android::ResTable_map::TYPE_ENUM;
+  constexpr const uint32_t TYPE_FLAGS = android::ResTable_map::TYPE_FLAGS;
+  constexpr const uint32_t TYPE_INTEGER = android::ResTable_map::TYPE_INTEGER;
+  constexpr const uint8_t TYPE_INT_DEC = android::Res_value::TYPE_INT_DEC;
+
+  Attribute attr1(false /*weak*/, TYPE_DIMENSION);
+  EXPECT_FALSE(attr1.Matches(*ResourceUtils::TryParseColor("#7fff00")));
+  EXPECT_TRUE(attr1.Matches(*ResourceUtils::TryParseFloat("23dp")));
+  EXPECT_TRUE(attr1.Matches(*ResourceUtils::TryParseReference("@android:string/foo")));
+
+  Attribute attr2(false /*weak*/, TYPE_INTEGER | TYPE_ENUM);
+  attr2.min_int = 0;
+  attr2.symbols.push_back(Attribute::Symbol{Reference(test::ParseNameOrDie("android:id/foo")),
+                                            static_cast<uint32_t>(-1)});
+  EXPECT_FALSE(attr2.Matches(*ResourceUtils::TryParseColor("#7fff00")));
+  EXPECT_TRUE(attr2.Matches(BinaryPrimitive(TYPE_INT_DEC, static_cast<uint32_t>(-1))));
+  EXPECT_TRUE(attr2.Matches(BinaryPrimitive(TYPE_INT_DEC, 1u)));
+  EXPECT_FALSE(attr2.Matches(BinaryPrimitive(TYPE_INT_DEC, static_cast<uint32_t>(-2))));
+
+  Attribute attr3(false /*weak*/, TYPE_INTEGER | TYPE_FLAGS);
+  attr3.max_int = 100;
+  attr3.symbols.push_back(
+      Attribute::Symbol{Reference(test::ParseNameOrDie("android:id/foo")), 0x01u});
+  attr3.symbols.push_back(
+      Attribute::Symbol{Reference(test::ParseNameOrDie("android:id/bar")), 0x02u});
+  attr3.symbols.push_back(
+      Attribute::Symbol{Reference(test::ParseNameOrDie("android:id/baz")), 0x04u});
+  attr3.symbols.push_back(
+      Attribute::Symbol{Reference(test::ParseNameOrDie("android:id/bat")), 0x80u});
+  EXPECT_FALSE(attr3.Matches(*ResourceUtils::TryParseColor("#7fff00")));
+  EXPECT_TRUE(attr3.Matches(BinaryPrimitive(TYPE_INT_DEC, 0x01u | 0x02u)));
+  EXPECT_TRUE(attr3.Matches(BinaryPrimitive(TYPE_INT_DEC, 0x01u | 0x02u | 0x80u)));
+
+  // Not a flag, but a value less than max_int.
+  EXPECT_TRUE(attr3.Matches(BinaryPrimitive(TYPE_INT_DEC, 0x08u)));
+
+  // Not a flag and greater than max_int.
+  EXPECT_FALSE(attr3.Matches(BinaryPrimitive(TYPE_INT_DEC, 127u)));
+
+  Attribute attr4(false /*weak*/, TYPE_ENUM);
+  attr4.symbols.push_back(
+      Attribute::Symbol{Reference(test::ParseNameOrDie("android:id/foo")), 0x01u});
+  EXPECT_TRUE(attr4.Matches(BinaryPrimitive(TYPE_INT_DEC, 0x01u)));
+  EXPECT_FALSE(attr4.Matches(BinaryPrimitive(TYPE_INT_DEC, 0x02u)));
+}
+
 } // namespace aapt