From 2359cfc4800dd6dac8c4bdfefc0392c5c63a3e84 Mon Sep 17 00:00:00 2001 From: topjohnwu Date: Tue, 20 Jun 2023 00:19:40 -0700 Subject: [PATCH] Small refactor --- native/src/base/files.rs | 9 ++++-- native/src/core/cert.rs | 60 +++++++++++++++++++--------------------- 2 files changed, 36 insertions(+), 33 deletions(-) diff --git a/native/src/base/files.rs b/native/src/base/files.rs index 81d835843..59b12fc2d 100644 --- a/native/src/base/files.rs +++ b/native/src/base/files.rs @@ -12,7 +12,7 @@ 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, Utf8CStr}; +use crate::{bfmt_cstr, copy_cstr, cstr, errno, error, FlatData, LibcReturn, Utf8CStr}; pub fn __open_fd_impl(path: &Utf8CStr, flags: i32, mode: mode_t) -> io::Result { unsafe { @@ -101,6 +101,7 @@ pub fn mkdirs(path: &Utf8CStr, mode: mode_t) -> io::Result<()> { pub trait ReadExt { fn skip(&mut self, len: usize) -> io::Result<()>; + fn read_flat_data(&mut self, data: &mut F) -> io::Result<()>; } impl ReadExt for T { @@ -114,6 +115,10 @@ impl ReadExt for T { } Ok(()) } + + fn read_flat_data(&mut self, data: &mut F) -> io::Result<()> { + self.read_exact(data.as_raw_bytes_mut()) + } } pub trait ReadSeekExt { @@ -162,7 +167,7 @@ impl BufReadExt for T { return true; } if let Some((key, value)) = line.split_once('=') { - return f(key, value); + return f(key.trim(), value.trim()); } true }); diff --git a/native/src/core/cert.rs b/native/src/core/cert.rs index b42523d0e..409012886 100644 --- a/native/src/core/cert.rs +++ b/native/src/core/cert.rs @@ -1,6 +1,6 @@ use std::fs::File; use std::io; -use std::io::{Read, Seek, SeekFrom}; +use std::io::{Cursor, Read, Seek, SeekFrom}; use std::os::fd::{FromRawFd, RawFd}; use base::*; @@ -38,20 +38,20 @@ macro_rules! bad_apk { * within the APK v2 signature block. */ pub fn read_certificate(fd: RawFd, version: i32) -> Vec { - fn inner(apk: &mut File, version: i32) -> Result, io::Error> { - let mut u32_value = 0u32; - let mut u64_value = 0u64; + fn inner(apk: &mut File, version: i32) -> io::Result> { + let mut u32_val = 0u32; + let mut u64_val = 0u64; // Find EOCD for i in 0u16.. { let mut comment_sz = 0u16; apk.seek(SeekFrom::End(-(comment_sz.bytes_size() as i64) - i as i64))?; - apk.read_exact(comment_sz.as_raw_bytes_mut())?; + apk.read_flat_data(&mut comment_sz)?; if comment_sz == i { apk.seek(SeekFrom::Current(-22))?; let mut magic = 0u32; - apk.read_exact(magic.as_raw_bytes_mut())?; + apk.read_flat_data(&mut magic)?; if magic == EOCD_MAGIC { break; } @@ -65,20 +65,19 @@ pub fn read_certificate(fd: RawFd, version: i32) -> Vec { // Seek and read central_dir_off to find the start of the central directory let mut central_dir_off = 0u32; apk.seek(SeekFrom::Current(12))?; - - apk.read_exact(central_dir_off.as_raw_bytes_mut())?; + apk.read_flat_data(&mut central_dir_off)?; // Code for parse APK comment to get version code if version >= 0 { let mut comment_sz = 0u16; - apk.read_exact(comment_sz.as_raw_bytes_mut())?; + apk.read_flat_data(&mut comment_sz)?; let mut comment = vec![0u8; comment_sz as usize]; apk.read_exact(&mut comment)?; - let mut comment = io::Cursor::new(&comment); + let mut comment = Cursor::new(&comment); let mut apk_ver = 0; comment.foreach_props(|k, v| { if k == "versionCode" { - apk_ver = v.trim().parse::().unwrap_or(0); + apk_ver = v.parse::().unwrap_or(0); false } else { true @@ -91,54 +90,53 @@ pub fn read_certificate(fd: RawFd, version: i32) -> Vec { // Next, find the start of the APK signing block apk.seek(SeekFrom::Start((central_dir_off - 24) as u64))?; - apk.read_exact(u64_value.as_raw_bytes_mut())?; // u64_value = block_sz_ + apk.read_flat_data(&mut u64_val)?; // u64_value = block_sz_ let mut magic = [0u8; 16]; - apk.read_exact(magic.as_raw_bytes_mut())?; + apk.read_exact(&mut magic)?; if magic != APK_SIGNING_BLOCK_MAGIC { return Err(bad_apk!("invalid signing block magic")); } let mut signing_blk_sz = 0u64; apk.seek(SeekFrom::Current( - -(u64_value as i64) - (signing_blk_sz.bytes_size() as i64), + -(u64_val as i64) - (signing_blk_sz.bytes_size() as i64), ))?; - apk.read_exact(signing_blk_sz.as_raw_bytes_mut())?; - if signing_blk_sz != u64_value { + apk.read_flat_data(&mut signing_blk_sz)?; + if signing_blk_sz != u64_val { return Err(bad_apk!("invalid signing block size")); } // Finally, we are now at the beginning of the id-value pair sequence loop { - apk.read_exact(u64_value.as_raw_bytes_mut())?; // id-value pair length - if u64_value == signing_blk_sz { + apk.read_flat_data(&mut u64_val)?; // id-value pair length + if u64_val == signing_blk_sz { break; } let mut id = 0u32; - apk.read_exact(id.as_raw_bytes_mut())?; + apk.read_flat_data(&mut id)?; if id == SIGNATURE_SCHEME_V2_MAGIC { // Skip [signer sequence length] + [1st signer length] + [signed data length] - apk.seek(SeekFrom::Current((u32_value.bytes_size() * 3) as i64))?; + apk.seek(SeekFrom::Current((u32_val.bytes_size() * 3) as i64))?; - apk.read_exact(u32_value.as_raw_bytes_mut())?; // digest sequence length - apk.seek(SeekFrom::Current(u32_value as i64))?; // skip all digests + apk.read_flat_data(&mut u32_val)?; // digest sequence length + apk.seek(SeekFrom::Current(u32_val as i64))?; // skip all digests - apk.seek(SeekFrom::Current(u32_value.bytes_size() as i64))?; // cert sequence length - apk.read_exact(u32_value.as_raw_bytes_mut())?; // 1st cert length + apk.seek(SeekFrom::Current(u32_val.bytes_size() as i64))?; // cert sequence length + apk.read_flat_data(&mut u32_val)?; // 1st cert length - let mut cert = vec![0; u32_value as usize]; + let mut cert = vec![0; u32_val as usize]; apk.read_exact(cert.as_mut())?; return Ok(cert); } else { // Skip this id-value pair - apk.seek(SeekFrom::Current( - u64_value as i64 - (id.bytes_size() as i64), - ))?; + apk.seek(SeekFrom::Current(u64_val as i64 - (id.bytes_size() as i64)))?; } } Err(bad_apk!("cannot find certificate")) } - inner(unsafe { &mut File::from_raw_fd(libc::dup(fd)) }, version) - .log() - .unwrap_or(vec![]) + let mut file = unsafe { File::from_raw_fd(fd) }; + let r = inner(&mut file, version).log().unwrap_or(vec![]); + std::mem::forget(file); + r }