Merge "libcutils: fs_config: fix "system/<partition>/" aliasing" am: 449bfd7a93

am: cd3584e90b

Change-Id: I8127f1b5f6b6b7667e65c53d0ae5ee91ba28d92e
This commit is contained in:
Ben Fennema 2017-06-26 22:52:09 +00:00 committed by android-build-merger
commit 609b4cf6a5
2 changed files with 66 additions and 20 deletions

View File

@ -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))) {
@ -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) {

View File

@ -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;
@ -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) {
@ -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));
}