mirror of
https://github.com/topjohnwu/Magisk.git
synced 2026-01-17 23:26:13 -08:00
Make Utf8CStr a first class citizen in C++ codebase
Utf8CStr is in many cases a better string view class than std::string_view, because it provides "view" access to a string buffer that is guaranteed to be null terminated. It also has the additional benefit of being UTF-8 verified and can seemlessly cross FFI boundaries. We would want to start use more Utf8CStr in our existing C++ codebase.
This commit is contained in:
@@ -28,7 +28,7 @@ int main(int argc, char *argv[]) {
|
||||
cmdline_logging();
|
||||
init_argv0(argc, argv);
|
||||
|
||||
string_view argv0 = basename(argv[0]);
|
||||
Utf8CStr argv0 = basename(argv[0]);
|
||||
|
||||
umask(0);
|
||||
|
||||
@@ -63,6 +63,6 @@ int main(int argc, char *argv[]) {
|
||||
return app.fn(argc, argv);
|
||||
}
|
||||
}
|
||||
fprintf(stderr, "%s: applet not found\n", argv0.data());
|
||||
fprintf(stderr, "%s: applet not found\n", argv0.c_str());
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -389,7 +389,7 @@ int connect_daemon(int req, bool create) {
|
||||
|
||||
char buf[64];
|
||||
xreadlink("/proc/self/exe", buf, sizeof(buf));
|
||||
if (tmp[0] == '\0' || !str_starts(buf, tmp)) {
|
||||
if (tmp[0] == '\0' || !string_view(buf).starts_with(tmp)) {
|
||||
LOGE("Start daemon on magisk tmpfs\n");
|
||||
close(fd);
|
||||
return -1;
|
||||
|
||||
@@ -90,9 +90,10 @@ static void crawl_procfs(const F &fn) {
|
||||
}
|
||||
}
|
||||
|
||||
static inline bool str_eql(string_view a, string_view b) { return a == b; }
|
||||
static bool str_eql(string_view a, string_view b) { return a == b; }
|
||||
static bool str_starts_with(string_view a, string_view b) { return a.starts_with(b); }
|
||||
|
||||
template<bool str_op(string_view, string_view) = &str_eql>
|
||||
template<bool str_op(string_view, string_view) = str_eql>
|
||||
static bool proc_name_match(int pid, string_view name) {
|
||||
char buf[4019];
|
||||
sprintf(buf, "/proc/%d/cmdline", pid);
|
||||
@@ -111,7 +112,7 @@ bool proc_context_match(int pid, string_view context) {
|
||||
|
||||
sprintf(buf, "/proc/%d", pid);
|
||||
if (lgetfilecon(buf, byte_data{ con, sizeof(con) })) {
|
||||
return str_starts(con, context);
|
||||
return string_view(con).starts_with(context);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -173,7 +174,7 @@ static bool add_hide_set(const char *pkg, const char *proc) {
|
||||
return true;
|
||||
if (str_eql(pkg, ISOLATED_MAGIC)) {
|
||||
// Kill all matching isolated processes
|
||||
kill_process<&proc_name_match<str_starts>>(proc, true);
|
||||
kill_process<&proc_name_match<str_starts_with>>(proc, true);
|
||||
} else {
|
||||
kill_process(proc);
|
||||
}
|
||||
@@ -411,7 +412,7 @@ bool is_deny_target(int uid, string_view process) {
|
||||
if (app_id >= 90000) {
|
||||
if (auto it = pkg_to_procs.find(ISOLATED_MAGIC); it != pkg_to_procs.end()) {
|
||||
for (const auto &s : it->second) {
|
||||
if (str_starts(process, s))
|
||||
if (process.starts_with(s))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,10 +88,10 @@ void exec_task(std::function<void()> &&task);
|
||||
void denylist_handler(int client, const sock_cred *cred);
|
||||
|
||||
// Scripting
|
||||
void install_apk(rust::Utf8CStr apk);
|
||||
void uninstall_pkg(rust::Utf8CStr pkg);
|
||||
void exec_common_scripts(rust::Utf8CStr stage);
|
||||
void exec_module_scripts(rust::Utf8CStr stage, const rust::Vec<ModuleInfo> &module_list);
|
||||
void install_apk(Utf8CStr apk);
|
||||
void uninstall_pkg(Utf8CStr pkg);
|
||||
void exec_common_scripts(Utf8CStr stage);
|
||||
void exec_module_scripts(Utf8CStr stage, const rust::Vec<ModuleInfo> &module_list);
|
||||
void exec_script(const char *script);
|
||||
void clear_pkg(const char *pkg, int user_id);
|
||||
[[noreturn]] void install_module(const char *file);
|
||||
@@ -109,8 +109,8 @@ void update_deny_flags(int uid, rust::Str process, uint32_t &flags);
|
||||
void exec_root_shell(int client, int pid, SuRequest &req, MntNsMode mode);
|
||||
|
||||
// Rust bindings
|
||||
static inline rust::Utf8CStr get_magisk_tmp_rs() { return get_magisk_tmp(); }
|
||||
static inline rust::String resolve_preinit_dir_rs(rust::Utf8CStr base_dir) {
|
||||
static inline Utf8CStr get_magisk_tmp_rs() { return get_magisk_tmp(); }
|
||||
static inline rust::String resolve_preinit_dir_rs(Utf8CStr base_dir) {
|
||||
return resolve_preinit_dir(base_dir.c_str());
|
||||
}
|
||||
static inline void exec_script_rs(rust::Utf8CStr script) { exec_script(script.data()); }
|
||||
static inline void exec_script_rs(Utf8CStr script) { exec_script(script.data()); }
|
||||
|
||||
@@ -26,13 +26,13 @@ int set_prop(const char *name, const char *value, bool skip_svc = false);
|
||||
void load_prop_file(const char *filename, bool skip_svc = false);
|
||||
|
||||
// Rust bindings
|
||||
rust::String get_prop_rs(rust::Utf8CStr name, bool persist);
|
||||
static inline int set_prop_rs(rust::Utf8CStr name, rust::Utf8CStr value, bool skip_svc) {
|
||||
rust::String get_prop_rs(Utf8CStr name, bool persist);
|
||||
static inline int set_prop_rs(Utf8CStr name, Utf8CStr value, bool skip_svc) {
|
||||
return set_prop(name.data(), value.data(), skip_svc);
|
||||
}
|
||||
static inline void load_prop_file_rs(rust::Utf8CStr filename, bool skip_svc) {
|
||||
static inline void load_prop_file_rs(Utf8CStr filename, bool skip_svc) {
|
||||
load_prop_file(filename.data(), skip_svc);
|
||||
}
|
||||
static inline void prop_cb_exec(prop_cb &cb, rust::Utf8CStr name, rust::Utf8CStr value, uint32_t serial) {
|
||||
static inline void prop_cb_exec(prop_cb &cb, Utf8CStr name, Utf8CStr value, uint32_t serial) {
|
||||
cb.exec(name.data(), value.data(), serial);
|
||||
}
|
||||
@@ -127,7 +127,6 @@ pub mod ffi {
|
||||
}
|
||||
|
||||
unsafe extern "C++" {
|
||||
#[namespace = "rust"]
|
||||
#[cxx_name = "Utf8CStr"]
|
||||
type Utf8CStrRef<'a> = base::ffi::Utf8CStrRef<'a>;
|
||||
#[cxx_name = "ucred"]
|
||||
|
||||
@@ -143,6 +143,10 @@ template<> void prop_to_string<rust::String>::exec(const char *, const char *val
|
||||
serial = s;
|
||||
}
|
||||
|
||||
static bool str_starts(std::string_view s, std::string_view ss) {
|
||||
return s.starts_with(ss);
|
||||
}
|
||||
|
||||
static int set_prop(const char *name, const char *value, PropFlags flags) {
|
||||
if (!check_legal_property_name(name))
|
||||
return 1;
|
||||
@@ -429,7 +433,7 @@ static StringType get_prop_impl(const char *name, bool persist) {
|
||||
return get_prop<StringType>(name, flags);
|
||||
}
|
||||
|
||||
rust::String get_prop_rs(rust::Utf8CStr name, bool persist) {
|
||||
rust::String get_prop_rs(Utf8CStr name, bool persist) {
|
||||
return get_prop_impl<rust::String>(name.data(), persist);
|
||||
}
|
||||
|
||||
|
||||
@@ -74,7 +74,7 @@ if (pfs) { \
|
||||
exit(0); \
|
||||
}
|
||||
|
||||
void exec_common_scripts(rust::Utf8CStr stage) {
|
||||
void exec_common_scripts(Utf8CStr stage) {
|
||||
LOGI("* Running %s.d scripts\n", stage.c_str());
|
||||
char path[4096];
|
||||
char *name = path + sprintf(path, SECURE_DIR "/%s.d", stage.c_str());
|
||||
@@ -116,12 +116,12 @@ static bool operator>(const timespec &a, const timespec &b) {
|
||||
return a.tv_nsec > b.tv_nsec;
|
||||
}
|
||||
|
||||
void exec_module_scripts(rust::Utf8CStr stage, const rust::Vec<ModuleInfo> &module_list) {
|
||||
void exec_module_scripts(Utf8CStr stage, const rust::Vec<ModuleInfo> &module_list) {
|
||||
LOGI("* Running module %s scripts\n", stage.c_str());
|
||||
if (module_list.empty())
|
||||
return;
|
||||
|
||||
bool pfs = (string_view) stage == "post-fs-data";
|
||||
bool pfs = stage == "post-fs-data";
|
||||
if (pfs) {
|
||||
timespec now{};
|
||||
clock_gettime(CLOCK_MONOTONIC, &now);
|
||||
@@ -157,7 +157,7 @@ appops set %s REQUEST_INSTALL_PACKAGES allow
|
||||
rm -f $APK
|
||||
)EOF";
|
||||
|
||||
void install_apk(rust::Utf8CStr apk) {
|
||||
void install_apk(Utf8CStr apk) {
|
||||
setfilecon(apk.c_str(), MAGISK_FILE_CON);
|
||||
char cmds[sizeof(install_script) + 4096];
|
||||
ssprintf(cmds, sizeof(cmds), install_script, apk.c_str(), JAVA_PACKAGE_NAME);
|
||||
@@ -170,7 +170,7 @@ log -t Magisk "pm_uninstall: $PKG"
|
||||
log -t Magisk "pm_uninstall: $(pm uninstall $PKG 2>&1)"
|
||||
)EOF";
|
||||
|
||||
void uninstall_pkg(rust::Utf8CStr pkg) {
|
||||
void uninstall_pkg(Utf8CStr pkg) {
|
||||
char cmds[sizeof(uninstall_script) + 256];
|
||||
ssprintf(cmds, sizeof(cmds), uninstall_script, pkg.c_str());
|
||||
exec_command_async("/system/bin/sh", "-c", cmds);
|
||||
|
||||
@@ -301,7 +301,8 @@ static bool proc_is_restricted(pid_t pid) {
|
||||
uint32_t data[_LINUX_CAPABILITY_U32S_3] = {};
|
||||
ssprintf(buf, sizeof(buf), "/proc/%d/status", pid);
|
||||
owned_fd status_fd = xopen(buf, O_RDONLY | O_CLOEXEC);
|
||||
file_readline(status_fd, [&](string_view line) -> bool {
|
||||
file_readline(status_fd, [&](Utf8CStr s) -> bool {
|
||||
string_view line = s;
|
||||
if (line.starts_with(bnd)) {
|
||||
auto p = line.begin();
|
||||
advance(p, bnd.size());
|
||||
|
||||
Reference in New Issue
Block a user