Loading libcutils/fs_config.cpp +19 −20 Original line number Diff line number Diff line Loading @@ -266,14 +266,27 @@ static bool is_partition(const char* path, size_t len) { return false; } static inline bool prefix_cmp(bool partial, const char* prefix, size_t len, const char* path, size_t plen) { return ((partial && plen >= len) || (plen == len)) && !strncmp(prefix, path, len); } // alias prefixes of "<partition>/<stuff>" to "system/<partition>/<stuff>" or // "system/<partition>/<stuff>" to "<partition>/<stuff>" static bool prefix_cmp(const char* prefix, const char* path, size_t len) { if (!strncmp(prefix, path, len)) return true; static bool fs_config_cmp(bool partial, const char* prefix, size_t len, const char* path, size_t plen) { // If name ends in * then allow partial matches. if (!partial && prefix[len - 1] == '*') { len--; partial = true; } if (prefix_cmp(partial, prefix, len, path, plen)) return true; static const char system[] = "system/"; if (!strncmp(path, system, strlen(system))) { path += strlen(system); plen -= strlen(system); } else if (len <= strlen(system)) { return false; } else if (strncmp(prefix, system, strlen(system))) { Loading @@ -282,25 +295,11 @@ static bool prefix_cmp(const char* prefix, const char* path, size_t len) { prefix += strlen(system); len -= strlen(system); } return is_partition(prefix, len) && !strncmp(prefix, path, len); } static bool fs_config_cmp(bool dir, const char* prefix, size_t len, const char* path, size_t plen) { if (dir) { if (plen < len) { return false; } } else { // If name ends in * then allow partial matches. if (prefix[len - 1] == '*') { return prefix_cmp(prefix, path, len - 1); } if (plen != len) { return false; } } return prefix_cmp(prefix, path, len); return is_partition(prefix, len) && prefix_cmp(partial, prefix, len, path, plen); } #ifndef __ANDROID_VNDK__ auto __for_testing_only__fs_config_cmp = fs_config_cmp; #endif void fs_config(const char* path, int dir, const char* target_out_path, unsigned* uid, unsigned* gid, unsigned* mode, uint64_t* capabilities) { Loading libcutils/tests/fs_config.cpp +47 −0 Original line number Diff line number Diff line Loading @@ -29,12 +29,39 @@ extern const fs_path_config* __for_testing_only__android_dirs; extern const fs_path_config* __for_testing_only__android_files; extern bool (*__for_testing_only__fs_config_cmp)(bool, const char*, size_t, const char*, size_t); // Maximum entries in system/core/libcutils/fs_config.cpp:android_* before we // hit a nullptr termination, before we declare the list is just too big or // could be missing the nullptr. static constexpr size_t max_idx = 4096; static const struct fs_config_cmp_test { bool dir; const char* prefix; const char* path; bool match; } fs_config_cmp_tests[] = { // clang-format off { true, "system/lib", "system/lib/hw", true }, { true, "vendor/lib", "system/vendor/lib/hw", true }, { true, "system/vendor/lib", "vendor/lib/hw", true }, { true, "system/vendor/lib", "system/vendor/lib/hw", true }, { false, "vendor/bin/wifi", "system/vendor/bin/w", false }, { false, "vendor/bin/wifi", "system/vendor/bin/wifi", true }, { false, "vendor/bin/wifi", "system/vendor/bin/wifi2", false }, { false, "system/vendor/bin/wifi", "system/vendor/bin/wifi", true, }, { false, "odm/bin/wifi", "system/odm/bin/wifi", true }, { false, "oem/bin/wifi", "system/oem/bin/wifi", true }, { false, "data/bin/wifi", "system/data/bin/wifi", false }, { false, "system/bin/*", "system/bin/wifi", true }, { false, "vendor/bin/*", "system/vendor/bin/wifi", true }, { false, "system/bin/*", "system/bin", false }, { false, "system/vendor/bin/*", "vendor/bin/wifi", true }, { false, NULL, NULL, false }, // clang-format on }; static bool check_unique(std::vector<const char*>& paths, const std::string& config_name, const std::string& prefix) { bool retval = false; Loading Loading @@ -106,6 +133,22 @@ static bool check_unique(const fs_path_config* paths, const char* type_name, return check_unique(paths_tmp, config, prefix) || retval; } static bool check_fs_config_cmp(const fs_config_cmp_test* tests) { bool match, retval = false; for (size_t idx = 0; tests[idx].prefix; ++idx) { match = __for_testing_only__fs_config_cmp(tests[idx].dir, tests[idx].prefix, strlen(tests[idx].prefix), tests[idx].path, strlen(tests[idx].path)); if (match != tests[idx].match) { GTEST_LOG_(ERROR) << tests[idx].path << (match ? " matched " : " didn't match ") << tests[idx].prefix; retval = true; break; } } return retval; } #define endof(pointer, field) (offsetof(typeof(*(pointer)), field) + sizeof((pointer)->field)) static bool check_unique(const std::string& config, const std::string& prefix) { Loading Loading @@ -199,3 +242,7 @@ TEST(fs_config, odm_dirs_alias) { TEST(fs_config, odm_files_alias) { check_two(__for_testing_only__android_files, "files", "odm/"); } TEST(fs_config, system_alias) { EXPECT_FALSE(check_fs_config_cmp(fs_config_cmp_tests)); } Loading
libcutils/fs_config.cpp +19 −20 Original line number Diff line number Diff line Loading @@ -266,14 +266,27 @@ static bool is_partition(const char* path, size_t len) { return false; } static inline bool prefix_cmp(bool partial, const char* prefix, size_t len, const char* path, size_t plen) { return ((partial && plen >= len) || (plen == len)) && !strncmp(prefix, path, len); } // alias prefixes of "<partition>/<stuff>" to "system/<partition>/<stuff>" or // "system/<partition>/<stuff>" to "<partition>/<stuff>" static bool prefix_cmp(const char* prefix, const char* path, size_t len) { if (!strncmp(prefix, path, len)) return true; static bool fs_config_cmp(bool partial, const char* prefix, size_t len, const char* path, size_t plen) { // If name ends in * then allow partial matches. if (!partial && prefix[len - 1] == '*') { len--; partial = true; } if (prefix_cmp(partial, prefix, len, path, plen)) return true; static const char system[] = "system/"; if (!strncmp(path, system, strlen(system))) { path += strlen(system); plen -= strlen(system); } else if (len <= strlen(system)) { return false; } else if (strncmp(prefix, system, strlen(system))) { Loading @@ -282,25 +295,11 @@ static bool prefix_cmp(const char* prefix, const char* path, size_t len) { prefix += strlen(system); len -= strlen(system); } return is_partition(prefix, len) && !strncmp(prefix, path, len); } static bool fs_config_cmp(bool dir, const char* prefix, size_t len, const char* path, size_t plen) { if (dir) { if (plen < len) { return false; } } else { // If name ends in * then allow partial matches. if (prefix[len - 1] == '*') { return prefix_cmp(prefix, path, len - 1); } if (plen != len) { return false; } } return prefix_cmp(prefix, path, len); return is_partition(prefix, len) && prefix_cmp(partial, prefix, len, path, plen); } #ifndef __ANDROID_VNDK__ auto __for_testing_only__fs_config_cmp = fs_config_cmp; #endif void fs_config(const char* path, int dir, const char* target_out_path, unsigned* uid, unsigned* gid, unsigned* mode, uint64_t* capabilities) { Loading
libcutils/tests/fs_config.cpp +47 −0 Original line number Diff line number Diff line Loading @@ -29,12 +29,39 @@ extern const fs_path_config* __for_testing_only__android_dirs; extern const fs_path_config* __for_testing_only__android_files; extern bool (*__for_testing_only__fs_config_cmp)(bool, const char*, size_t, const char*, size_t); // Maximum entries in system/core/libcutils/fs_config.cpp:android_* before we // hit a nullptr termination, before we declare the list is just too big or // could be missing the nullptr. static constexpr size_t max_idx = 4096; static const struct fs_config_cmp_test { bool dir; const char* prefix; const char* path; bool match; } fs_config_cmp_tests[] = { // clang-format off { true, "system/lib", "system/lib/hw", true }, { true, "vendor/lib", "system/vendor/lib/hw", true }, { true, "system/vendor/lib", "vendor/lib/hw", true }, { true, "system/vendor/lib", "system/vendor/lib/hw", true }, { false, "vendor/bin/wifi", "system/vendor/bin/w", false }, { false, "vendor/bin/wifi", "system/vendor/bin/wifi", true }, { false, "vendor/bin/wifi", "system/vendor/bin/wifi2", false }, { false, "system/vendor/bin/wifi", "system/vendor/bin/wifi", true, }, { false, "odm/bin/wifi", "system/odm/bin/wifi", true }, { false, "oem/bin/wifi", "system/oem/bin/wifi", true }, { false, "data/bin/wifi", "system/data/bin/wifi", false }, { false, "system/bin/*", "system/bin/wifi", true }, { false, "vendor/bin/*", "system/vendor/bin/wifi", true }, { false, "system/bin/*", "system/bin", false }, { false, "system/vendor/bin/*", "vendor/bin/wifi", true }, { false, NULL, NULL, false }, // clang-format on }; static bool check_unique(std::vector<const char*>& paths, const std::string& config_name, const std::string& prefix) { bool retval = false; Loading Loading @@ -106,6 +133,22 @@ static bool check_unique(const fs_path_config* paths, const char* type_name, return check_unique(paths_tmp, config, prefix) || retval; } static bool check_fs_config_cmp(const fs_config_cmp_test* tests) { bool match, retval = false; for (size_t idx = 0; tests[idx].prefix; ++idx) { match = __for_testing_only__fs_config_cmp(tests[idx].dir, tests[idx].prefix, strlen(tests[idx].prefix), tests[idx].path, strlen(tests[idx].path)); if (match != tests[idx].match) { GTEST_LOG_(ERROR) << tests[idx].path << (match ? " matched " : " didn't match ") << tests[idx].prefix; retval = true; break; } } return retval; } #define endof(pointer, field) (offsetof(typeof(*(pointer)), field) + sizeof((pointer)->field)) static bool check_unique(const std::string& config, const std::string& prefix) { Loading Loading @@ -199,3 +242,7 @@ TEST(fs_config, odm_dirs_alias) { TEST(fs_config, odm_files_alias) { check_two(__for_testing_only__android_files, "files", "odm/"); } TEST(fs_config, system_alias) { EXPECT_FALSE(check_fs_config_cmp(fs_config_cmp_tests)); }