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

Commit 4b077c51 authored by Tom Cherry's avatar Tom Cherry
Browse files

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
parent 1ccaf2b8
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -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;
    }
+2 −1
Original line number Diff line number Diff line
@@ -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) {
+2 −5
Original line number Diff line number Diff line
@@ -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
+16 −5
Original line number Diff line number Diff line
@@ -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;
    }
+1 −1
Original line number Diff line number Diff line
@@ -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;