Loading libcutils/Android.bp +2 −1 Original line number Diff line number Diff line Loading @@ -60,7 +60,6 @@ cc_library { host_supported: true, srcs: [ "config_utils.cpp", "fs_config.cpp", "canned_fs_config.cpp", "iosched_policy.cpp", "load_file.cpp", Loading @@ -80,6 +79,7 @@ cc_library { not_windows: { srcs: libcutils_nonwindows_sources + [ "ashmem-host.cpp", "fs_config.cpp", "trace-host.cpp", ], }, Loading @@ -104,6 +104,7 @@ cc_library { srcs: libcutils_nonwindows_sources + [ "android_reboot.cpp", "ashmem-dev.cpp", "fs_config.cpp", "klog.cpp", "partition_utils.cpp", "properties.cpp", Loading libcutils/fs_config.cpp +42 −26 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ #include <errno.h> #include <fcntl.h> #include <fnmatch.h> #include <stdint.h> #include <stdio.h> #include <stdlib.h> Loading @@ -31,6 +32,9 @@ #include <sys/stat.h> #include <sys/types.h> #include <string> #include <android-base/strings.h> #include <log/log.h> #include <private/android_filesystem_config.h> #include <utils/Compat.h> Loading @@ -39,6 +43,9 @@ #define O_BINARY 0 #endif using android::base::EndsWith; using android::base::StartsWith; // My kingdom for <endian.h> static inline uint16_t get2LE(const uint8_t* src) { return src[0] | (src[1] << 8); Loading Loading @@ -259,46 +266,55 @@ static int fs_config_open(int dir, int which, const char* target_out_path) { // if path is "odm/<stuff>", "oem/<stuff>", "product/<stuff>", // "product_services/<stuff>" or "vendor/<stuff>" static bool is_partition(const char* path, size_t len) { static bool is_partition(const std::string& path) { static const char* partitions[] = {"odm/", "oem/", "product/", "product_services/", "vendor/"}; for (size_t i = 0; i < (sizeof(partitions) / sizeof(partitions[0])); ++i) { size_t plen = strlen(partitions[i]); if (len <= plen) continue; if (!strncmp(path, partitions[i], plen)) return true; if (StartsWith(path, partitions[i])) return true; } 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 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; static bool fs_config_cmp(bool dir, const char* prefix, size_t len, const char* path, size_t plen) { std::string pattern(prefix, len); std::string input(path, plen); // Massage pattern and input so that they can be used by fnmatch where // directories have to end with /. if (dir) { if (!EndsWith(input, "/")) { input.append("/"); } if (!EndsWith(pattern, "/*")) { if (EndsWith(pattern, "/")) { pattern.append("*"); } else { pattern.append("/*"); } } } if (prefix_cmp(partial, prefix, len, path, plen)) return true; // no FNM_PATHNAME is set in order to match a/b/c/d with a/* // FNM_ESCAPE is set in order to prevent using \\? and \\* and maintenance issues. const int fnm_flags = FNM_NOESCAPE; if (fnmatch(pattern.c_str(), input.c_str(), fnm_flags) == 0) 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))) { static constexpr const char* kSystem = "system/"; if (StartsWith(input, kSystem)) { input.erase(0, strlen(kSystem)); } else if (input.size() <= strlen(kSystem)) { return false; } else if (StartsWith(pattern, kSystem)) { pattern.erase(0, strlen(kSystem)); } else { prefix += strlen(system); len -= strlen(system); return false; } return is_partition(prefix, len) && prefix_cmp(partial, prefix, len, path, plen); if (!is_partition(pattern)) return false; if (!is_partition(input)) return false; return fnmatch(pattern.c_str(), input.c_str(), fnm_flags) == 0; } #ifndef __ANDROID_VNDK__ auto __for_testing_only__fs_config_cmp = fs_config_cmp; Loading libcutils/tests/Android.bp +2 −1 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ cc_defaults { android: { srcs: [ "AshmemTest.cpp", "fs_config.cpp", "MemsetTest.cpp", "PropertiesTest.cpp", "sched_policy_test.cpp", Loading @@ -28,13 +29,13 @@ cc_defaults { "android_get_control_socket_test.cpp", "android_get_control_file_test.cpp", "multiuser_test.cpp", "fs_config.cpp", ], }, not_windows: { srcs: [ "test_str_parms.cpp", "fs_config.cpp", ], }, }, Loading libcutils/tests/fs_config.cpp +12 −2 Original line number Diff line number Diff line Loading @@ -47,6 +47,10 @@ static const struct fs_config_cmp_test { { 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 }, { true, "foo/*/bar/*", "foo/1/bar/2", true }, { true, "foo/*/bar/*", "foo/1/bar", true }, { true, "foo/*/bar/*", "foo/1/bar/2/3", true }, { true, "foo/*/bar/*", "foo/1/bar/2/3/", 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 }, Loading @@ -58,6 +62,12 @@ static const struct fs_config_cmp_test { { false, "vendor/bin/*", "system/vendor/bin/wifi", true }, { false, "system/bin/*", "system/bin", false }, { false, "system/vendor/bin/*", "vendor/bin/wifi", true }, { false, "foo/*/bar/*", "foo/1/bar/2", true }, { false, "foo/*/bar/*", "foo/1/bar", false }, { false, "foo/*/bar/*", "foo/1/bar/2/3", true }, { false, "foo/*/bar/*.so", "foo/1/bar/2/3", false }, { false, "foo/*/bar/*.so", "foo/1/bar/2.so", true }, { false, "foo/*/bar/*.so", "foo/1/bar/2/3.so", true }, { false, NULL, NULL, false }, // clang-format on }; Loading Loading
libcutils/Android.bp +2 −1 Original line number Diff line number Diff line Loading @@ -60,7 +60,6 @@ cc_library { host_supported: true, srcs: [ "config_utils.cpp", "fs_config.cpp", "canned_fs_config.cpp", "iosched_policy.cpp", "load_file.cpp", Loading @@ -80,6 +79,7 @@ cc_library { not_windows: { srcs: libcutils_nonwindows_sources + [ "ashmem-host.cpp", "fs_config.cpp", "trace-host.cpp", ], }, Loading @@ -104,6 +104,7 @@ cc_library { srcs: libcutils_nonwindows_sources + [ "android_reboot.cpp", "ashmem-dev.cpp", "fs_config.cpp", "klog.cpp", "partition_utils.cpp", "properties.cpp", Loading
libcutils/fs_config.cpp +42 −26 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ #include <errno.h> #include <fcntl.h> #include <fnmatch.h> #include <stdint.h> #include <stdio.h> #include <stdlib.h> Loading @@ -31,6 +32,9 @@ #include <sys/stat.h> #include <sys/types.h> #include <string> #include <android-base/strings.h> #include <log/log.h> #include <private/android_filesystem_config.h> #include <utils/Compat.h> Loading @@ -39,6 +43,9 @@ #define O_BINARY 0 #endif using android::base::EndsWith; using android::base::StartsWith; // My kingdom for <endian.h> static inline uint16_t get2LE(const uint8_t* src) { return src[0] | (src[1] << 8); Loading Loading @@ -259,46 +266,55 @@ static int fs_config_open(int dir, int which, const char* target_out_path) { // if path is "odm/<stuff>", "oem/<stuff>", "product/<stuff>", // "product_services/<stuff>" or "vendor/<stuff>" static bool is_partition(const char* path, size_t len) { static bool is_partition(const std::string& path) { static const char* partitions[] = {"odm/", "oem/", "product/", "product_services/", "vendor/"}; for (size_t i = 0; i < (sizeof(partitions) / sizeof(partitions[0])); ++i) { size_t plen = strlen(partitions[i]); if (len <= plen) continue; if (!strncmp(path, partitions[i], plen)) return true; if (StartsWith(path, partitions[i])) return true; } 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 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; static bool fs_config_cmp(bool dir, const char* prefix, size_t len, const char* path, size_t plen) { std::string pattern(prefix, len); std::string input(path, plen); // Massage pattern and input so that they can be used by fnmatch where // directories have to end with /. if (dir) { if (!EndsWith(input, "/")) { input.append("/"); } if (!EndsWith(pattern, "/*")) { if (EndsWith(pattern, "/")) { pattern.append("*"); } else { pattern.append("/*"); } } } if (prefix_cmp(partial, prefix, len, path, plen)) return true; // no FNM_PATHNAME is set in order to match a/b/c/d with a/* // FNM_ESCAPE is set in order to prevent using \\? and \\* and maintenance issues. const int fnm_flags = FNM_NOESCAPE; if (fnmatch(pattern.c_str(), input.c_str(), fnm_flags) == 0) 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))) { static constexpr const char* kSystem = "system/"; if (StartsWith(input, kSystem)) { input.erase(0, strlen(kSystem)); } else if (input.size() <= strlen(kSystem)) { return false; } else if (StartsWith(pattern, kSystem)) { pattern.erase(0, strlen(kSystem)); } else { prefix += strlen(system); len -= strlen(system); return false; } return is_partition(prefix, len) && prefix_cmp(partial, prefix, len, path, plen); if (!is_partition(pattern)) return false; if (!is_partition(input)) return false; return fnmatch(pattern.c_str(), input.c_str(), fnm_flags) == 0; } #ifndef __ANDROID_VNDK__ auto __for_testing_only__fs_config_cmp = fs_config_cmp; Loading
libcutils/tests/Android.bp +2 −1 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ cc_defaults { android: { srcs: [ "AshmemTest.cpp", "fs_config.cpp", "MemsetTest.cpp", "PropertiesTest.cpp", "sched_policy_test.cpp", Loading @@ -28,13 +29,13 @@ cc_defaults { "android_get_control_socket_test.cpp", "android_get_control_file_test.cpp", "multiuser_test.cpp", "fs_config.cpp", ], }, not_windows: { srcs: [ "test_str_parms.cpp", "fs_config.cpp", ], }, }, Loading
libcutils/tests/fs_config.cpp +12 −2 Original line number Diff line number Diff line Loading @@ -47,6 +47,10 @@ static const struct fs_config_cmp_test { { 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 }, { true, "foo/*/bar/*", "foo/1/bar/2", true }, { true, "foo/*/bar/*", "foo/1/bar", true }, { true, "foo/*/bar/*", "foo/1/bar/2/3", true }, { true, "foo/*/bar/*", "foo/1/bar/2/3/", 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 }, Loading @@ -58,6 +62,12 @@ static const struct fs_config_cmp_test { { false, "vendor/bin/*", "system/vendor/bin/wifi", true }, { false, "system/bin/*", "system/bin", false }, { false, "system/vendor/bin/*", "vendor/bin/wifi", true }, { false, "foo/*/bar/*", "foo/1/bar/2", true }, { false, "foo/*/bar/*", "foo/1/bar", false }, { false, "foo/*/bar/*", "foo/1/bar/2/3", true }, { false, "foo/*/bar/*.so", "foo/1/bar/2/3", false }, { false, "foo/*/bar/*.so", "foo/1/bar/2.so", true }, { false, "foo/*/bar/*.so", "foo/1/bar/2/3.so", true }, { false, NULL, NULL, false }, // clang-format on }; Loading