Only apply match if there is something to apply
It is possible for a match to only contain a context and not a schema,
or vice versa and in this case, the previously matched values should
continue to be used. The serializer already handles this case by
setting the index of the match to ~0u if there is not one, so this
change simply has the parser skip these values.
Bug: 70858511
Test: unit tests, including new ones
Change-Id: Ibc65bd8d637e39f3b1ce7bcc2b88189b75173f88
diff --git a/property_service/libpropertyinfoparser/property_info_parser.cpp b/property_service/libpropertyinfoparser/property_info_parser.cpp
index e53c625..a8f6636 100644
--- a/property_service/libpropertyinfoparser/property_info_parser.cpp
+++ b/property_service/libpropertyinfoparser/property_info_parser.cpp
@@ -96,8 +96,12 @@
if (prefix_len > remaining_name_size) continue;
if (!strncmp(c_string(trie_node.prefix(i)->name_offset), remaining_name, prefix_len)) {
- *context_index = trie_node.prefix(i)->context_index;
- *schema_index = trie_node.prefix(i)->schema_index;
+ if (trie_node.prefix(i)->context_index != ~0u) {
+ *context_index = trie_node.prefix(i)->context_index;
+ }
+ if (trie_node.prefix(i)->schema_index != ~0u) {
+ *schema_index = trie_node.prefix(i)->schema_index;
+ }
return;
}
}
@@ -142,8 +146,20 @@
// Check exact matches
for (uint32_t i = 0; i < trie_node.num_exact_matches(); ++i) {
if (!strcmp(c_string(trie_node.exact_match(i)->name_offset), remaining_name)) {
- if (context_index != nullptr) *context_index = trie_node.exact_match(i)->context_index;
- if (schema_index != nullptr) *schema_index = trie_node.exact_match(i)->schema_index;
+ if (context_index != nullptr) {
+ if (trie_node.exact_match(i)->context_index != ~0u) {
+ *context_index = trie_node.exact_match(i)->context_index;
+ } else {
+ *context_index = return_context_index;
+ }
+ }
+ if (schema_index != nullptr) {
+ if (trie_node.exact_match(i)->schema_index != ~0u) {
+ *schema_index = trie_node.exact_match(i)->schema_index;
+ } else {
+ *schema_index = return_schema_index;
+ }
+ }
return;
}
}
diff --git a/property_service/libpropertyinfoserializer/property_info_serializer_test.cpp b/property_service/libpropertyinfoserializer/property_info_serializer_test.cpp
index b3fae26..46c2d06 100644
--- a/property_service/libpropertyinfoserializer/property_info_serializer_test.cpp
+++ b/property_service/libpropertyinfoserializer/property_info_serializer_test.cpp
@@ -844,5 +844,47 @@
EXPECT_STREQ("3rd", schema);
}
+TEST(propertyinfoserializer, GetPropertyInfo_empty_context_and_schema) {
+ auto property_info = std::vector<PropertyInfoEntry>{
+ {"persist.", "1st", "", false},
+ {"persist.dot_prefix.", "2nd", "", false},
+ {"persist.non_dot_prefix", "3rd", "", false},
+ {"persist.exact_match", "", "", true},
+ {"persist.dot_prefix2.", "", "4th", false},
+ {"persist.non_dot_prefix2", "", "5th", false},
+ };
+
+ auto serialized_trie = std::string();
+ auto build_trie_error = std::string();
+ ASSERT_TRUE(BuildTrie(property_info, "default", "default", &serialized_trie, &build_trie_error))
+ << build_trie_error;
+
+ auto property_info_area = reinterpret_cast<const PropertyInfoArea*>(serialized_trie.data());
+
+ const char* context;
+ const char* schema;
+ property_info_area->GetPropertyInfo("notpersist.radio.something", &context, &schema);
+ EXPECT_STREQ("default", context);
+ EXPECT_STREQ("default", schema);
+ property_info_area->GetPropertyInfo("persist.nomatch", &context, &schema);
+ EXPECT_STREQ("1st", context);
+ EXPECT_STREQ("default", schema);
+ property_info_area->GetPropertyInfo("persist.dot_prefix.something", &context, &schema);
+ EXPECT_STREQ("2nd", context);
+ EXPECT_STREQ("default", schema);
+ property_info_area->GetPropertyInfo("persist.non_dot_prefix.something", &context, &schema);
+ EXPECT_STREQ("3rd", context);
+ EXPECT_STREQ("default", schema);
+ property_info_area->GetPropertyInfo("persist.exact_match", &context, &schema);
+ EXPECT_STREQ("1st", context);
+ EXPECT_STREQ("default", schema);
+ property_info_area->GetPropertyInfo("persist.dot_prefix2.something", &context, &schema);
+ EXPECT_STREQ("1st", context);
+ EXPECT_STREQ("4th", schema);
+ property_info_area->GetPropertyInfo("persist.non_dot_prefix2.something", &context, &schema);
+ EXPECT_STREQ("1st", context);
+ EXPECT_STREQ("5th", schema);
+}
+
} // namespace properties
} // namespace android