mirror of
https://github.com/topjohnwu/Magisk.git
synced 2024-12-22 07:57:39 +00:00
Replace all CStr usage to Utf8CStr
This commit is contained in:
parent
caae932117
commit
cb3ab63815
@ -1,6 +1,5 @@
|
||||
// Functions listed here are just to export to C++
|
||||
|
||||
use std::ffi::CStr;
|
||||
use std::io;
|
||||
use std::os::fd::{BorrowedFd, OwnedFd, RawFd};
|
||||
|
||||
@ -10,6 +9,7 @@ use libc::mode_t;
|
||||
|
||||
use crate::{
|
||||
fd_path, map_fd, map_file, mkdirs, realpath, rm_rf, slice_from_ptr_mut, Directory, ResultExt,
|
||||
Utf8CStr,
|
||||
};
|
||||
|
||||
pub(crate) fn fd_path_for_cxx(fd: RawFd, buf: &mut [u8]) -> isize {
|
||||
@ -21,17 +21,26 @@ pub(crate) fn fd_path_for_cxx(fd: RawFd, buf: &mut [u8]) -> isize {
|
||||
|
||||
#[no_mangle]
|
||||
unsafe extern "C" fn canonical_path(path: *const c_char, buf: *mut u8, bufsz: usize) -> isize {
|
||||
realpath(CStr::from_ptr(path), slice_from_ptr_mut(buf, bufsz)).map_or(-1, |v| v as isize)
|
||||
match Utf8CStr::from_ptr(path) {
|
||||
Ok(p) => realpath(p, slice_from_ptr_mut(buf, bufsz)).map_or(-1, |v| v as isize),
|
||||
Err(_) => -1,
|
||||
}
|
||||
}
|
||||
|
||||
#[export_name = "mkdirs"]
|
||||
unsafe extern "C" fn mkdirs_for_cxx(path: *const c_char, mode: mode_t) -> i32 {
|
||||
mkdirs(CStr::from_ptr(path), mode).map_or(-1, |_| 0)
|
||||
match Utf8CStr::from_ptr(path) {
|
||||
Ok(p) => mkdirs(p, mode).map_or(-1, |_| 0),
|
||||
Err(_) => -1,
|
||||
}
|
||||
}
|
||||
|
||||
#[export_name = "rm_rf"]
|
||||
unsafe extern "C" fn rm_rf_for_cxx(path: *const c_char) -> bool {
|
||||
rm_rf(CStr::from_ptr(path)).map_or(false, |_| true)
|
||||
match Utf8CStr::from_ptr(path) {
|
||||
Ok(p) => rm_rf(p).map_or(false, |_| true),
|
||||
Err(_) => false,
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
@ -44,7 +53,7 @@ unsafe extern "C" fn frm_rf(fd: OwnedFd) -> bool {
|
||||
|
||||
pub(crate) fn map_file_for_cxx(path: &[u8], rw: bool) -> &'static mut [u8] {
|
||||
unsafe {
|
||||
map_file(CStr::from_bytes_with_nul_unchecked(path), rw)
|
||||
map_file(Utf8CStr::from_bytes_unchecked(path), rw)
|
||||
.log()
|
||||
.unwrap_or(&mut [])
|
||||
}
|
||||
|
@ -10,9 +10,9 @@ use std::{io, mem, ptr, slice};
|
||||
|
||||
use libc::{c_char, c_uint, dirent, mode_t, EEXIST, ENOENT, O_CLOEXEC, O_PATH, O_RDONLY, O_RDWR};
|
||||
|
||||
use crate::{bfmt_cstr, copy_cstr, cstr, errno, error, LibcReturn};
|
||||
use crate::{bfmt_cstr, copy_cstr, cstr, errno, error, LibcReturn, Utf8CStr};
|
||||
|
||||
pub fn __open_fd_impl(path: &CStr, flags: i32, mode: mode_t) -> io::Result<OwnedFd> {
|
||||
pub fn __open_fd_impl(path: &Utf8CStr, flags: i32, mode: mode_t) -> io::Result<OwnedFd> {
|
||||
unsafe {
|
||||
let fd = libc::open(path.as_ptr(), flags, mode as c_uint).check_os_err()?;
|
||||
Ok(OwnedFd::from_raw_fd(fd))
|
||||
@ -37,7 +37,7 @@ pub unsafe fn readlink_unsafe(path: *const c_char, buf: *mut u8, bufsz: usize) -
|
||||
r
|
||||
}
|
||||
|
||||
pub fn readlink(path: &CStr, data: &mut [u8]) -> io::Result<usize> {
|
||||
pub fn readlink(path: &Utf8CStr, data: &mut [u8]) -> io::Result<usize> {
|
||||
let r =
|
||||
unsafe { readlink_unsafe(path.as_ptr(), data.as_mut_ptr(), data.len()) }.check_os_err()?;
|
||||
Ok(r as usize)
|
||||
@ -50,7 +50,7 @@ pub fn fd_path(fd: RawFd, buf: &mut [u8]) -> io::Result<usize> {
|
||||
}
|
||||
|
||||
// Inspired by https://android.googlesource.com/platform/bionic/+/master/libc/bionic/realpath.cpp
|
||||
pub fn realpath(path: &CStr, buf: &mut [u8]) -> io::Result<usize> {
|
||||
pub fn realpath(path: &Utf8CStr, buf: &mut [u8]) -> io::Result<usize> {
|
||||
let fd = open_fd!(path, O_PATH | O_CLOEXEC)?;
|
||||
let mut st1: libc::stat;
|
||||
let mut st2: libc::stat;
|
||||
@ -75,7 +75,7 @@ pub fn realpath(path: &CStr, buf: &mut [u8]) -> io::Result<usize> {
|
||||
Ok(len)
|
||||
}
|
||||
|
||||
pub fn mkdirs(path: &CStr, mode: mode_t) -> io::Result<()> {
|
||||
pub fn mkdirs(path: &Utf8CStr, mode: mode_t) -> io::Result<()> {
|
||||
let mut buf = [0_u8; 4096];
|
||||
let len = copy_cstr(&mut buf, path);
|
||||
let buf = &mut buf[..len];
|
||||
@ -277,7 +277,7 @@ pub enum WalkResult {
|
||||
}
|
||||
|
||||
impl Directory {
|
||||
pub fn open(path: &CStr) -> io::Result<Directory> {
|
||||
pub fn open(path: &Utf8CStr) -> io::Result<Directory> {
|
||||
let dirp = unsafe { libc::opendir(path.as_ptr()) }.check_os_err()?;
|
||||
Ok(Directory { dirp })
|
||||
}
|
||||
@ -420,7 +420,7 @@ impl Drop for Directory {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn rm_rf(path: &CStr) -> io::Result<()> {
|
||||
pub fn rm_rf(path: &Utf8CStr) -> io::Result<()> {
|
||||
unsafe {
|
||||
let mut stat: libc::stat = mem::zeroed();
|
||||
libc::lstat(path.as_ptr(), &mut stat).check_os_err()?;
|
||||
@ -490,11 +490,11 @@ impl<T: AsRawFd> FdExt for T {
|
||||
pub struct MappedFile(&'static mut [u8]);
|
||||
|
||||
impl MappedFile {
|
||||
pub fn open(path: &CStr) -> io::Result<MappedFile> {
|
||||
pub fn open(path: &Utf8CStr) -> io::Result<MappedFile> {
|
||||
Ok(MappedFile(map_file(path, false)?))
|
||||
}
|
||||
|
||||
pub fn open_rw(path: &CStr) -> io::Result<MappedFile> {
|
||||
pub fn open_rw(path: &Utf8CStr) -> io::Result<MappedFile> {
|
||||
Ok(MappedFile(map_file(path, true)?))
|
||||
}
|
||||
|
||||
@ -524,7 +524,7 @@ impl Drop for MappedFile {
|
||||
}
|
||||
|
||||
// We mark the returned slice static because it is valid until explicitly unmapped
|
||||
pub(crate) fn map_file(path: &CStr, rw: bool) -> io::Result<&'static mut [u8]> {
|
||||
pub(crate) fn map_file(path: &Utf8CStr, rw: bool) -> io::Result<&'static mut [u8]> {
|
||||
let flag = if rw { O_RDWR } else { O_RDONLY };
|
||||
let fd = open_fd!(path, flag | O_CLOEXEC)?;
|
||||
map_fd(fd.as_fd(), fd.size()?, rw)
|
||||
|
@ -17,8 +17,8 @@ pub fn copy_str<T: AsRef<[u8]>>(dest: &mut [u8], src: T) -> usize {
|
||||
len
|
||||
}
|
||||
|
||||
pub fn copy_cstr(dest: &mut [u8], src: &CStr) -> usize {
|
||||
let src = src.to_bytes_with_nul();
|
||||
pub fn copy_cstr<T: AsRef<CStr> + ?Sized>(dest: &mut [u8], src: &T) -> usize {
|
||||
let src = src.as_ref().to_bytes_with_nul();
|
||||
let len = min(src.len(), dest.len());
|
||||
dest[..len].copy_from_slice(&src[..len]);
|
||||
len
|
||||
@ -69,7 +69,9 @@ macro_rules! bfmt_cstr {
|
||||
($buf:expr, $($args:tt)*) => {{
|
||||
let len = $crate::fmt_to_buf($buf, format_args!($($args)*));
|
||||
#[allow(unused_unsafe)]
|
||||
unsafe { std::ffi::CStr::from_bytes_with_nul_unchecked(&$buf[..(len + 1)]) }
|
||||
unsafe {
|
||||
$crate::Utf8CStr::from_bytes_unchecked($buf.get_unchecked(..(len + 1)))
|
||||
}
|
||||
}};
|
||||
}
|
||||
|
||||
@ -84,7 +86,7 @@ macro_rules! cstr {
|
||||
);
|
||||
#[allow(unused_unsafe)]
|
||||
unsafe {
|
||||
std::ffi::CStr::from_bytes_with_nul_unchecked(concat!($str, "\0").as_bytes())
|
||||
$crate::Utf8CStr::from_bytes_unchecked(concat!($str, "\0").as_bytes())
|
||||
}
|
||||
}};
|
||||
}
|
||||
@ -135,6 +137,7 @@ impl Utf8CStr {
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub unsafe fn from_bytes_unchecked(buf: &[u8]) -> &Utf8CStr {
|
||||
&*(buf as *const [u8] as *const Utf8CStr)
|
||||
}
|
||||
@ -146,35 +149,46 @@ impl Utf8CStr {
|
||||
Self::from_cstr(unsafe { CStr::from_ptr(ptr) })
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn as_bytes(&self) -> &[u8] {
|
||||
// The length of the slice is at least 1 due to null termination check
|
||||
unsafe { self.inner.get_unchecked(..self.inner.len() - 1) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn as_bytes_with_nul(&self) -> &[u8] {
|
||||
&self.inner
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn as_ptr(&self) -> *const c_char {
|
||||
self.inner.as_ptr().cast()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn as_cstr(&self) -> &CStr {
|
||||
self.as_ref()
|
||||
}
|
||||
}
|
||||
|
||||
impl Deref for Utf8CStr {
|
||||
type Target = str;
|
||||
|
||||
#[inline]
|
||||
fn deref(&self) -> &str {
|
||||
self.as_ref()
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for Utf8CStr {
|
||||
#[inline]
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
||||
Display::fmt(self.deref(), f)
|
||||
}
|
||||
}
|
||||
|
||||
impl Debug for Utf8CStr {
|
||||
#[inline]
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
||||
Debug::fmt(self.deref(), f)
|
||||
}
|
||||
@ -199,24 +213,42 @@ impl AsRef<str> for Utf8CStr {
|
||||
impl AsRef<OsStr> for Utf8CStr {
|
||||
#[inline]
|
||||
fn as_ref(&self) -> &OsStr {
|
||||
OsStr::new(self as &str)
|
||||
OsStr::new(self.deref())
|
||||
}
|
||||
}
|
||||
|
||||
impl AsRef<Path> for Utf8CStr {
|
||||
#[inline]
|
||||
fn as_ref(&self) -> &Path {
|
||||
Path::new(self)
|
||||
Path::new(self.deref())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn ptr_to_str_result<'a, T>(ptr: *const T) -> Result<&'a str, StrErr> {
|
||||
if ptr.is_null() {
|
||||
Err(StrErr::NullPointerError)
|
||||
} else {
|
||||
unsafe { CStr::from_ptr(ptr.cast()) }
|
||||
.to_str()
|
||||
.map_err(StrErr::from)
|
||||
impl PartialEq<CStr> for Utf8CStr {
|
||||
#[inline]
|
||||
fn eq(&self, other: &CStr) -> bool {
|
||||
self.as_cstr() == other
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq<str> for Utf8CStr {
|
||||
#[inline]
|
||||
fn eq(&self, other: &str) -> bool {
|
||||
self.deref() == other
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq<Utf8CStr> for CStr {
|
||||
#[inline]
|
||||
fn eq(&self, other: &Utf8CStr) -> bool {
|
||||
self == other.as_cstr()
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq<Utf8CStr> for str {
|
||||
#[inline]
|
||||
fn eq(&self, other: &Utf8CStr) -> bool {
|
||||
self == other.deref()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
use std::ffi::CStr;
|
||||
use std::os::unix::io::RawFd;
|
||||
use std::ptr;
|
||||
|
||||
@ -8,10 +7,9 @@ use libc::{
|
||||
ssize_t, SYS_dup3,
|
||||
};
|
||||
|
||||
use crate::{cstr, errno, error, mkdirs, perror, ptr_to_str, raw_cstr, ResultExt};
|
||||
use crate::{cstr, errno, error, mkdirs, perror, ptr_to_str, raw_cstr, ResultExt, Utf8CStr};
|
||||
|
||||
mod unsafe_impl {
|
||||
use std::ffi::CStr;
|
||||
use std::os::unix::io::RawFd;
|
||||
|
||||
use anyhow::Context;
|
||||
@ -19,8 +17,8 @@ mod unsafe_impl {
|
||||
use libc::{c_char, nfds_t, off_t, pollfd};
|
||||
|
||||
use crate::{
|
||||
perror, ptr_to_str, readlink, readlink_unsafe, slice_from_ptr, slice_from_ptr_mut,
|
||||
ResultExt,
|
||||
perror, ptr_to_str, readlink_unsafe, realpath, slice_from_ptr, slice_from_ptr_mut,
|
||||
ResultExt, Utf8CStr,
|
||||
};
|
||||
|
||||
#[no_mangle]
|
||||
@ -40,10 +38,13 @@ mod unsafe_impl {
|
||||
|
||||
#[no_mangle]
|
||||
unsafe extern "C" fn xrealpath(path: *const c_char, buf: *mut u8, bufsz: usize) -> isize {
|
||||
readlink(CStr::from_ptr(path), slice_from_ptr_mut(buf, bufsz))
|
||||
.with_context(|| format!("realpath {} failed", ptr_to_str(path)))
|
||||
match Utf8CStr::from_ptr(path) {
|
||||
Ok(p) => realpath(p, slice_from_ptr_mut(buf, bufsz))
|
||||
.with_context(|| format!("realpath {} failed", p))
|
||||
.log()
|
||||
.map_or(-1, |v| v as isize)
|
||||
.map_or(-1, |v| v as isize),
|
||||
Err(_) => -1,
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
@ -475,16 +476,6 @@ pub extern "C" fn xdup3(oldfd: RawFd, newfd: RawFd, flags: i32) -> RawFd {
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn xreadlink(path: &CStr, data: &mut [u8]) -> isize {
|
||||
unsafe { unsafe_impl::xreadlink(path.as_ptr(), data.as_mut_ptr(), data.len()) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn xreadlinkat(dirfd: RawFd, path: &CStr, data: &mut [u8]) -> isize {
|
||||
unsafe { unsafe_impl::xreadlinkat(dirfd, path.as_ptr(), data.as_mut_ptr(), data.len()) }
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn xsymlink(target: *const c_char, linkpath: *const c_char) -> i32 {
|
||||
let r = libc::symlink(target, linkpath);
|
||||
@ -579,10 +570,13 @@ pub unsafe extern "C" fn xmkdir(path: *const c_char, mode: mode_t) -> i32 {
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn xmkdirs(path: *const c_char, mode: mode_t) -> i32 {
|
||||
mkdirs(CStr::from_ptr(path), mode)
|
||||
.with_context(|| format!("mkdirs {}", ptr_to_str(path)))
|
||||
match Utf8CStr::from_ptr(path) {
|
||||
Ok(p) => mkdirs(p, mode)
|
||||
.with_context(|| format!("mkdirs {} failed", p))
|
||||
.log()
|
||||
.map_or(-1, |_| 0)
|
||||
.map_or(-1, |_| 0),
|
||||
Err(_) => -1,
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
|
@ -155,8 +155,8 @@ impl Cpio {
|
||||
|
||||
pub(crate) fn load_from_file(path: &Utf8CStr) -> anyhow::Result<Self> {
|
||||
eprintln!("Loading cpio: [{}]", path);
|
||||
let data = MappedFile::open(path.as_ref())?;
|
||||
Self::load_from_data(data.as_ref())
|
||||
let file = MappedFile::open(path)?;
|
||||
Self::load_from_data(file.as_ref())
|
||||
}
|
||||
|
||||
fn dump(&self, path: &str) -> anyhow::Result<()> {
|
||||
|
@ -7,7 +7,7 @@ use byteorder::{BigEndian, ReadBytesExt};
|
||||
use protobuf::{EnumFull, Message};
|
||||
|
||||
use base::libc::c_char;
|
||||
use base::{ptr_to_str_result, ReadSeekExt, StrErr};
|
||||
use base::{ReadSeekExt, StrErr, Utf8CStr};
|
||||
use base::{ResultExt, WriteExt};
|
||||
|
||||
use crate::ffi;
|
||||
@ -26,9 +26,9 @@ macro_rules! bad_payload {
|
||||
const PAYLOAD_MAGIC: &str = "CrAU";
|
||||
|
||||
fn do_extract_boot_from_payload(
|
||||
in_path: &str,
|
||||
partition_name: Option<&str>,
|
||||
out_path: Option<&str>,
|
||||
in_path: &Utf8CStr,
|
||||
partition_name: Option<&Utf8CStr>,
|
||||
out_path: Option<&Utf8CStr>,
|
||||
) -> anyhow::Result<()> {
|
||||
let mut reader = BufReader::new(if in_path == "-" {
|
||||
unsafe { File::from_raw_fd(0) }
|
||||
@ -193,13 +193,13 @@ pub fn extract_boot_from_payload(
|
||||
partition: *const c_char,
|
||||
out_path: *const c_char,
|
||||
) -> anyhow::Result<()> {
|
||||
let in_path = ptr_to_str_result(in_path)?;
|
||||
let partition = match ptr_to_str_result(partition) {
|
||||
let in_path = unsafe { Utf8CStr::from_ptr(in_path) }?;
|
||||
let partition = match unsafe { Utf8CStr::from_ptr(partition) } {
|
||||
Ok(s) => Some(s),
|
||||
Err(StrErr::NullPointerError) => None,
|
||||
Err(e) => Err(e)?,
|
||||
};
|
||||
let out_path = match ptr_to_str_result(out_path) {
|
||||
let out_path = match unsafe { Utf8CStr::from_ptr(out_path) } {
|
||||
Ok(s) => Some(s),
|
||||
Err(StrErr::NullPointerError) => None,
|
||||
Err(e) => Err(e)?,
|
||||
|
@ -1,8 +1,8 @@
|
||||
#![allow(clippy::missing_safety_doc)]
|
||||
|
||||
use base::Utf8CStr;
|
||||
use daemon::*;
|
||||
use logging::*;
|
||||
use std::ffi::CStr;
|
||||
|
||||
#[path = "../include/consts.rs"]
|
||||
mod consts;
|
||||
@ -39,6 +39,6 @@ pub mod ffi {
|
||||
|
||||
fn rust_test_entry() {}
|
||||
|
||||
pub fn get_prop(name: &CStr, persist: bool) -> String {
|
||||
pub fn get_prop(name: &Utf8CStr, persist: bool) -> String {
|
||||
unsafe { ffi::get_prop_rs(name.as_ptr(), persist) }
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user