Merge "libcutils: fs_config: fix "system/<partition>/" aliasing" am: 449bfd7a93
am: cd3584e90b
Change-Id: I8127f1b5f6b6b7667e65c53d0ae5ee91ba28d92e
This commit is contained in:
commit
609b4cf6a5
|
@ -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) {
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue