Require 'exact', 'prefix', or '' for match operation in property_contexts
The previous code would lazily check for 'exact' and accept any other value as a prefix match. This should be a tighter check allowing only 'exact', 'prefix', or an empty string for this option. Test: build fails if an invalid string is used for the match operation Test: build succeeds normally Test: `getprop -Z` shows exact vs prefix is differentiated correctly Change-Id: I21dcb193810d65f468f8960967eabfd261f71e21
This commit is contained in:
parent
1ccaf2b8ee
commit
4b077c51f2
5 changed files with 22 additions and 13 deletions
|
@ -191,7 +191,7 @@ void HandlePropertyContexts(const std::string& filename,
|
|||
}
|
||||
|
||||
auto errors = std::vector<std::string>{};
|
||||
ParsePropertyInfoFile(file_contents, property_infos, &errors);
|
||||
ParsePropertyInfoFile(file_contents, true, property_infos, &errors);
|
||||
for (const auto& error : errors) {
|
||||
LOG(ERROR) << "Could not read line from '" << filename << "': " << error;
|
||||
}
|
||||
|
|
|
@ -925,7 +925,8 @@ bool LoadPropertyInfoFromFile(const std::string& filename,
|
|||
}
|
||||
|
||||
auto errors = std::vector<std::string>{};
|
||||
ParsePropertyInfoFile(file_contents, property_infos, &errors);
|
||||
bool require_prefix_or_exact = SelinuxGetVendorAndroidVersion() >= __ANDROID_API_R__;
|
||||
ParsePropertyInfoFile(file_contents, require_prefix_or_exact, property_infos, &errors);
|
||||
// Individual parsing errors are reported but do not cause a failed boot, which is what
|
||||
// returning false would do here.
|
||||
for (const auto& error : errors) {
|
||||
|
|
|
@ -14,8 +14,7 @@
|
|||
// limitations under the License.
|
||||
//
|
||||
|
||||
#ifndef PROPERTY_INFO_SERIALIZER_H
|
||||
#define PROPERTY_INFO_SERIALIZER_H
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
@ -41,11 +40,9 @@ bool BuildTrie(const std::vector<PropertyInfoEntry>& property_info,
|
|||
const std::string& default_context, const std::string& default_type,
|
||||
std::string* serialized_trie, std::string* error);
|
||||
|
||||
void ParsePropertyInfoFile(const std::string& file_contents,
|
||||
void ParsePropertyInfoFile(const std::string& file_contents, bool require_prefix_or_exact,
|
||||
std::vector<PropertyInfoEntry>* property_infos,
|
||||
std::vector<std::string>* errors);
|
||||
|
||||
} // namespace properties
|
||||
} // namespace android
|
||||
|
||||
#endif
|
||||
|
|
|
@ -56,7 +56,8 @@ bool IsTypeValid(const std::vector<std::string>& type_strings) {
|
|||
return false;
|
||||
}
|
||||
|
||||
bool ParsePropertyInfoLine(const std::string& line, PropertyInfoEntry* out, std::string* error) {
|
||||
bool ParsePropertyInfoLine(const std::string& line, bool require_prefix_or_exact,
|
||||
PropertyInfoEntry* out, std::string* error) {
|
||||
auto tokenizer = SpaceTokenizer(line);
|
||||
|
||||
auto property = tokenizer.GetNext();
|
||||
|
@ -72,7 +73,7 @@ bool ParsePropertyInfoLine(const std::string& line, PropertyInfoEntry* out, std:
|
|||
}
|
||||
|
||||
// It is not an error to not find exact_match or a type, as older files will not contain them.
|
||||
auto exact_match = tokenizer.GetNext();
|
||||
auto match_operation = tokenizer.GetNext();
|
||||
// We reformat type to be space deliminated regardless of the input whitespace for easier storage
|
||||
// and subsequent parsing.
|
||||
auto type_strings = std::vector<std::string>{};
|
||||
|
@ -82,18 +83,27 @@ bool ParsePropertyInfoLine(const std::string& line, PropertyInfoEntry* out, std:
|
|||
type = tokenizer.GetNext();
|
||||
}
|
||||
|
||||
bool exact_match = false;
|
||||
if (match_operation == "exact") {
|
||||
exact_match = true;
|
||||
} else if (match_operation != "prefix" && match_operation != "" && require_prefix_or_exact) {
|
||||
*error = "Match operation '" + match_operation +
|
||||
"' is not valid: must be either 'prefix' or 'exact'";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!type_strings.empty() && !IsTypeValid(type_strings)) {
|
||||
*error = "Type '" + Join(type_strings, " ") + "' is not valid";
|
||||
return false;
|
||||
}
|
||||
|
||||
*out = {property, context, Join(type_strings, " "), exact_match == "exact"};
|
||||
*out = {property, context, Join(type_strings, " "), exact_match};
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
void ParsePropertyInfoFile(const std::string& file_contents,
|
||||
void ParsePropertyInfoFile(const std::string& file_contents, bool require_prefix_or_exact,
|
||||
std::vector<PropertyInfoEntry>* property_infos,
|
||||
std::vector<std::string>* errors) {
|
||||
// Do not clear property_infos to allow this function to be called on multiple files, with
|
||||
|
@ -108,7 +118,8 @@ void ParsePropertyInfoFile(const std::string& file_contents,
|
|||
|
||||
auto property_info_entry = PropertyInfoEntry{};
|
||||
auto parse_error = std::string{};
|
||||
if (!ParsePropertyInfoLine(trimmed_line, &property_info_entry, &parse_error)) {
|
||||
if (!ParsePropertyInfoLine(trimmed_line, require_prefix_or_exact, &property_info_entry,
|
||||
&parse_error)) {
|
||||
errors->emplace_back(parse_error);
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -153,7 +153,7 @@ int main(int argc, char** argv) {
|
|||
}
|
||||
|
||||
auto errors = std::vector<std::string>{};
|
||||
ParsePropertyInfoFile(file_contents, &property_info_entries, &errors);
|
||||
ParsePropertyInfoFile(file_contents, true, &property_info_entries, &errors);
|
||||
if (!errors.empty()) {
|
||||
for (const auto& error : errors) {
|
||||
std::cerr << "Could not read line from '" << filename << "': " << error << std::endl;
|
||||
|
|
Loading…
Reference in a new issue