2
0
mirror of https://github.com/topjohnwu/Magisk synced 2025-08-22 21:07:11 +00:00

Fix compression format detection

This commit is contained in:
topjohnwu 2025-08-21 10:55:55 -07:00 committed by John Wu
parent c313812129
commit 2c39d0234d
5 changed files with 30 additions and 25 deletions

View File

@ -588,7 +588,7 @@ int split_image_dtb(rust::Utf8CStr filename, bool skip_decomp) {
if (size_t off = find_dtb_offset(img.buf(), img.sz()); off > 0) { if (size_t off = find_dtb_offset(img.buf(), img.sz()); off > 0) {
FileFormat fmt = check_fmt_lg(img.buf(), img.sz()); FileFormat fmt = check_fmt_lg(img.buf(), img.sz());
if (!skip_decomp && COMPRESSED(fmt)) { if (!skip_decomp && fmt_compressed(fmt)) {
int fd = creat(KERNEL_FILE, 0644); int fd = creat(KERNEL_FILE, 0644);
decompress(fmt, fd, img.buf(), off); decompress(fmt, fd, img.buf(), off);
close(fd); close(fd);
@ -610,7 +610,7 @@ int unpack(rust::Utf8CStr image, bool skip_decomp, bool hdr) {
boot.hdr->dump_hdr_file(); boot.hdr->dump_hdr_file();
// Dump kernel // Dump kernel
if (!skip_decomp && COMPRESSED(boot.k_fmt)) { if (!skip_decomp && fmt_compressed(boot.k_fmt)) {
if (boot.hdr->kernel_size() != 0) { if (boot.hdr->kernel_size() != 0) {
int fd = creat(KERNEL_FILE, 0644); int fd = creat(KERNEL_FILE, 0644);
decompress(boot.k_fmt, fd, boot.kernel, boot.hdr->kernel_size()); decompress(boot.k_fmt, fd, boot.kernel, boot.hdr->kernel_size());
@ -641,13 +641,13 @@ int unpack(rust::Utf8CStr image, bool skip_decomp, bool hdr) {
} }
owned_fd fd = xopenat(dirfd, file_name, O_CREAT | O_TRUNC | O_WRONLY | O_CLOEXEC, 0644); owned_fd fd = xopenat(dirfd, file_name, O_CREAT | O_TRUNC | O_WRONLY | O_CLOEXEC, 0644);
FileFormat fmt = check_fmt_lg(boot.ramdisk + it.ramdisk_offset, it.ramdisk_size); FileFormat fmt = check_fmt_lg(boot.ramdisk + it.ramdisk_offset, it.ramdisk_size);
if (!skip_decomp && COMPRESSED(fmt)) { if (!skip_decomp && fmt_compressed(fmt)) {
decompress(fmt, fd, boot.ramdisk + it.ramdisk_offset, it.ramdisk_size); decompress(fmt, fd, boot.ramdisk + it.ramdisk_offset, it.ramdisk_size);
} else { } else {
xwrite(fd, boot.ramdisk + it.ramdisk_offset, it.ramdisk_size); xwrite(fd, boot.ramdisk + it.ramdisk_offset, it.ramdisk_size);
} }
} }
} else if (!skip_decomp && COMPRESSED(boot.r_fmt)) { } else if (!skip_decomp && fmt_compressed(boot.r_fmt)) {
if (boot.hdr->ramdisk_size() != 0) { if (boot.hdr->ramdisk_size() != 0) {
int fd = creat(RAMDISK_FILE, 0644); int fd = creat(RAMDISK_FILE, 0644);
decompress(boot.r_fmt, fd, boot.ramdisk, boot.hdr->ramdisk_size()); decompress(boot.r_fmt, fd, boot.ramdisk, boot.hdr->ramdisk_size());
@ -661,7 +661,7 @@ int unpack(rust::Utf8CStr image, bool skip_decomp, bool hdr) {
dump(boot.second, boot.hdr->second_size(), SECOND_FILE); dump(boot.second, boot.hdr->second_size(), SECOND_FILE);
// Dump extra // Dump extra
if (!skip_decomp && COMPRESSED(boot.e_fmt)) { if (!skip_decomp && fmt_compressed(boot.e_fmt)) {
if (boot.hdr->extra_size() != 0) { if (boot.hdr->extra_size() != 0) {
int fd = creat(EXTRA_FILE, 0644); int fd = creat(EXTRA_FILE, 0644);
decompress(boot.e_fmt, fd, boot.extra, boot.hdr->extra_size()); decompress(boot.e_fmt, fd, boot.extra, boot.hdr->extra_size());
@ -748,7 +748,7 @@ void repack(rust::Utf8CStr src_img, rust::Utf8CStr out_img, bool skip_comp) {
} }
if (access(KERNEL_FILE, R_OK) == 0) { if (access(KERNEL_FILE, R_OK) == 0) {
mmap_data m(KERNEL_FILE); mmap_data m(KERNEL_FILE);
if (!skip_comp && !COMPRESSED_ANY(check_fmt(m.buf(), m.sz())) && COMPRESSED(boot.k_fmt)) { if (!skip_comp && !fmt_compressed_any(check_fmt(m.buf(), m.sz())) && fmt_compressed(boot.k_fmt)) {
// Always use zopfli for zImage compression // Always use zopfli for zImage compression
auto fmt = (boot.flags[ZIMAGE_KERNEL] && boot.k_fmt == FileFormat::GZIP) ? FileFormat::ZOPFLI : boot.k_fmt; auto fmt = (boot.flags[ZIMAGE_KERNEL] && boot.k_fmt == FileFormat::GZIP) ? FileFormat::ZOPFLI : boot.k_fmt;
hdr->kernel_size() = compress_len(fmt, m, fd); hdr->kernel_size() = compress_len(fmt, m, fd);
@ -816,7 +816,7 @@ void repack(rust::Utf8CStr src_img, rust::Utf8CStr out_img, bool skip_comp) {
mmap_data m(dirfd, file_name); mmap_data m(dirfd, file_name);
FileFormat fmt = check_fmt_lg(boot.ramdisk + it.ramdisk_offset, it.ramdisk_size); FileFormat fmt = check_fmt_lg(boot.ramdisk + it.ramdisk_offset, it.ramdisk_size);
it.ramdisk_offset = ramdisk_offset; it.ramdisk_offset = ramdisk_offset;
if (!skip_comp && !COMPRESSED_ANY(check_fmt(m.buf(), m.sz())) && COMPRESSED(fmt)) { if (!skip_comp && !fmt_compressed_any(check_fmt(m.buf(), m.sz())) && fmt_compressed(fmt)) {
it.ramdisk_size = compress_len(fmt, m, fd); it.ramdisk_size = compress_len(fmt, m, fd);
} else { } else {
it.ramdisk_size = xwrite(fd, m.buf(), m.sz()); it.ramdisk_size = xwrite(fd, m.buf(), m.sz());
@ -836,7 +836,7 @@ void repack(rust::Utf8CStr src_img, rust::Utf8CStr out_img, bool skip_comp) {
fprintf(stderr, "RAMDISK_FMT: [%s] -> [%s]\n", fmt2name(r_fmt), fmt2name(FileFormat::LZ4_LEGACY)); fprintf(stderr, "RAMDISK_FMT: [%s] -> [%s]\n", fmt2name(r_fmt), fmt2name(FileFormat::LZ4_LEGACY));
r_fmt = FileFormat::LZ4_LEGACY; r_fmt = FileFormat::LZ4_LEGACY;
} }
if (!skip_comp && !COMPRESSED_ANY(check_fmt(m.buf(), m.sz())) && COMPRESSED(r_fmt)) { if (!skip_comp && !fmt_compressed_any(check_fmt(m.buf(), m.sz())) && fmt_compressed(r_fmt)) {
hdr->ramdisk_size() = compress_len(r_fmt, m, fd); hdr->ramdisk_size() = compress_len(r_fmt, m, fd);
} else { } else {
hdr->ramdisk_size() = xwrite(fd, m.buf(), m.sz()); hdr->ramdisk_size() = xwrite(fd, m.buf(), m.sz());
@ -855,7 +855,7 @@ void repack(rust::Utf8CStr src_img, rust::Utf8CStr out_img, bool skip_comp) {
off.extra = lseek(fd, 0, SEEK_CUR); off.extra = lseek(fd, 0, SEEK_CUR);
if (access(EXTRA_FILE, R_OK) == 0) { if (access(EXTRA_FILE, R_OK) == 0) {
mmap_data m(EXTRA_FILE); mmap_data m(EXTRA_FILE);
if (!skip_comp && !COMPRESSED_ANY(check_fmt(m.buf(), m.sz())) && COMPRESSED(boot.e_fmt)) { if (!skip_comp && !fmt_compressed_any(check_fmt(m.buf(), m.sz())) && fmt_compressed(boot.e_fmt)) {
hdr->extra_size() = compress_len(boot.e_fmt, m, fd); hdr->extra_size() = compress_len(boot.e_fmt, m, fd);
} else { } else {
hdr->extra_size() = xwrite(fd, m.buf(), m.sz()); hdr->extra_size() = xwrite(fd, m.buf(), m.sz());

View File

@ -243,7 +243,6 @@ Supported actions:
If [outfile] is not specified, then <infile> will be replaced If [outfile] is not specified, then <infile> will be replaced
with another file suffixed with a matching file extension. with another file suffixed with a matching file extension.
Supported formats: Supported formats:
{1} {1}
decompress <infile> [outfile] decompress <infile> [outfile]
@ -252,7 +251,6 @@ Supported actions:
If [outfile] is not specified, then <infile> will be replaced If [outfile] is not specified, then <infile> will be replaced
with another file removing its archive format file extension. with another file removing its archive format file extension.
Supported formats: Supported formats:
{1} {1}
"#, "#,
cmd, cmd,

View File

@ -2,9 +2,6 @@
enum class FileFormat : ::std::uint8_t; enum class FileFormat : ::std::uint8_t;
#define COMPRESSED(fmt) ((+fmt) >= +FileFormat::GZIP && (+fmt) < +FileFormat::LZOP)
#define COMPRESSED_ANY(fmt) ((+fmt) >= +FileFormat::GZIP && (+fmt) <= +FileFormat::LZOP)
#define BUFFER_MATCH(buf, s) (memcmp(buf, s, sizeof(s) - 1) == 0) #define BUFFER_MATCH(buf, s) (memcmp(buf, s, sizeof(s) - 1) == 0)
#define BUFFER_CONTAIN(buf, sz, s) (memmem(buf, sz, s, sizeof(s) - 1) != nullptr) #define BUFFER_CONTAIN(buf, sz, s) (memmem(buf, sz, s, sizeof(s) - 1) != nullptr)
#define CHECKED_MATCH(s) (len >= (sizeof(s) - 1) && BUFFER_MATCH(buf, s)) #define CHECKED_MATCH(s) (len >= (sizeof(s) - 1) && BUFFER_MATCH(buf, s))

View File

@ -23,12 +23,12 @@ impl FromStr for FileFormat {
impl Display for FileFormat { impl Display for FileFormat {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
f.write_str(self.to_cstr()) f.write_str(self.as_cstr())
} }
} }
impl FileFormat { impl FileFormat {
fn to_cstr(&self) -> &'static Utf8CStr { fn as_cstr(&self) -> &'static Utf8CStr {
match *self { match *self {
Self::GZIP => cstr!("gzip"), Self::GZIP => cstr!("gzip"),
Self::ZOPFLI => cstr!("zopfli"), Self::ZOPFLI => cstr!("zopfli"),
@ -46,10 +46,6 @@ impl FileFormat {
} }
} }
pub fn fmt2name(fmt: FileFormat) -> *const libc::c_char {
fmt.to_cstr().as_ptr()
}
impl FileFormat { impl FileFormat {
pub fn ext(&self) -> &'static str { pub fn ext(&self) -> &'static str {
match *self { match *self {
@ -68,7 +64,6 @@ impl FileFormat {
*self, *self,
Self::GZIP Self::GZIP
| Self::ZOPFLI | Self::ZOPFLI
| Self::LZOP
| Self::XZ | Self::XZ
| Self::LZMA | Self::LZMA
| Self::BZIP2 | Self::BZIP2
@ -88,9 +83,22 @@ impl FileFormat {
Self::LZ4, Self::LZ4,
Self::LZ4_LEGACY, Self::LZ4_LEGACY,
Self::LZ4_LG, Self::LZ4_LG,
Self::LZOP,
] ]
.map(|f| f.to_string()) .map(|f| f.to_string())
.join(" ") .join(" ")
} }
} }
// C++ FFI
pub fn fmt2name(fmt: FileFormat) -> *const libc::c_char {
fmt.as_cstr().as_ptr()
}
pub fn fmt_compressed(fmt: FileFormat) -> bool {
fmt.is_compressed()
}
pub fn fmt_compressed_any(fmt: FileFormat) -> bool {
fmt.is_compressed() || matches!(fmt, FileFormat::LZOP)
}

View File

@ -5,18 +5,18 @@
pub use base; pub use base;
use compress::{compress_bytes, decompress_bytes}; use compress::{compress_bytes, decompress_bytes};
use format::fmt2name; use format::{fmt_compressed, fmt_compressed_any, fmt2name};
use sign::{SHA, get_sha, sha256_hash, sign_payload_for_cxx}; use sign::{SHA, get_sha, sha256_hash, sign_payload_for_cxx};
use std::env; use std::env;
mod cli;
mod compress; mod compress;
mod cpio; mod cpio;
mod dtb; mod dtb;
mod format;
mod patch; mod patch;
mod payload; mod payload;
// Suppress warnings in generated code // Suppress warnings in generated code
mod cli;
mod format;
#[allow(warnings)] #[allow(warnings)]
mod proto; mod proto;
mod sign; mod sign;
@ -78,6 +78,8 @@ pub mod ffi {
fn compress_bytes(format: FileFormat, in_bytes: &[u8], out_fd: i32); fn compress_bytes(format: FileFormat, in_bytes: &[u8], out_fd: i32);
fn decompress_bytes(format: FileFormat, in_bytes: &[u8], out_fd: i32); fn decompress_bytes(format: FileFormat, in_bytes: &[u8], out_fd: i32);
fn fmt2name(fmt: FileFormat) -> *const c_char; fn fmt2name(fmt: FileFormat) -> *const c_char;
fn fmt_compressed(fmt: FileFormat) -> bool;
fn fmt_compressed_any(fmt: FileFormat) -> bool;
#[cxx_name = "sign_payload"] #[cxx_name = "sign_payload"]
fn sign_payload_for_cxx(payload: &[u8]) -> Vec<u8>; fn sign_payload_for_cxx(payload: &[u8]) -> Vec<u8>;