mirror of
https://github.com/chenxiaolong/avbroot.git
synced 2026-07-03 14:05:11 +02:00
Compare commits
30 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 237f59fd9b | |||
| b0b00a4c54 | |||
| b9a70efb15 | |||
| aeef2936d8 | |||
| 3adab80893 | |||
| 4069429361 | |||
| 74193c1c9f | |||
| 0f8cef2daa | |||
| 8731df4504 | |||
| fda11b4262 | |||
| f0970aa80c | |||
| 4f0db5a7c4 | |||
| 57374e2e41 | |||
| f4e5c55fe9 | |||
| 850ce86388 | |||
| c16636a68c | |||
| 26812cd43a | |||
| 135cd320ce | |||
| 919f621833 | |||
| 2c1d86cd96 | |||
| 91074ae4c8 | |||
| a5c628b66f | |||
| 156c96d3d4 | |||
| 2460d1807d | |||
| 728d333951 | |||
| 39661a994d | |||
| d6b19b69f7 | |||
| 96806cba36 | |||
| 5c474a1e98 | |||
| 4cf546e5ca |
@@ -28,8 +28,12 @@ jobs:
|
||||
artifact:
|
||||
- os: ubuntu-latest
|
||||
name: x86_64-unknown-linux-gnu
|
||||
- os: ubuntu-24.04-arm
|
||||
name: aarch64-unknown-linux-gnu
|
||||
- os: windows-latest
|
||||
name: x86_64-pc-windows-msvc
|
||||
- os: windows-11-arm
|
||||
name: aarch64-pc-windows-msvc
|
||||
- os: macos-latest
|
||||
name: universal-apple-darwin
|
||||
targets:
|
||||
@@ -43,7 +47,7 @@ jobs:
|
||||
android_api: '31'
|
||||
steps:
|
||||
- name: Check out repository
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
|
||||
with:
|
||||
# For git describe
|
||||
fetch-depth: 0
|
||||
@@ -85,7 +89,7 @@ jobs:
|
||||
done
|
||||
|
||||
- name: Cache Rust dependencies
|
||||
uses: Swatinem/rust-cache@98c8021b550208e191a6a3145459bfc9fb29c4c0 # v2.8.0
|
||||
uses: Swatinem/rust-cache@779680da715d629ac1d338a641029a2f4372abb5 # v2.8.2
|
||||
with:
|
||||
key: ${{ matrix.artifact.name }}
|
||||
|
||||
@@ -156,7 +160,7 @@ jobs:
|
||||
run: cp LICENSE README.md target/output/
|
||||
|
||||
- name: Archive executable
|
||||
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
|
||||
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
|
||||
with:
|
||||
name: avbroot-${{ steps.get_version.outputs.version }}-${{ matrix.artifact.name }}
|
||||
path: |
|
||||
|
||||
@@ -10,7 +10,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Check out repository
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
|
||||
|
||||
- name: Run cargo-deny
|
||||
uses: EmbarkStudios/cargo-deny-action@30f817c6f72275c6d54dc744fbca09ebc958599f # v2.0.12
|
||||
uses: EmbarkStudios/cargo-deny-action@76cd80eb775d7bbbd2d80292136d74d39e1b4918 # v2.0.14
|
||||
|
||||
@@ -24,10 +24,10 @@ jobs:
|
||||
echo "version=${version}" >> "${GITHUB_OUTPUT}"
|
||||
|
||||
- name: Check out repository
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
|
||||
|
||||
- name: Create release
|
||||
uses: softprops/action-gh-release@72f2c25fcb47643c292f7107632f7a47c1df5cd8 # v2.3.2
|
||||
uses: softprops/action-gh-release@a06a81a03ee405af7f2048a818ed3f03bbf83c7b # v2.5.0
|
||||
with:
|
||||
tag_name: v${{ steps.get_version.outputs.version }}
|
||||
name: Version ${{ steps.get_version.outputs.version }}
|
||||
|
||||
@@ -7,6 +7,32 @@
|
||||
to update the actual links at the bottom of the file.
|
||||
-->
|
||||
|
||||
### Version 3.23.3
|
||||
|
||||
* Add support for Magisk 30600 ([PR #529])
|
||||
* Update dependencies ([PR #530])
|
||||
|
||||
### Version 3.23.2
|
||||
|
||||
* Add prebuilt binaries for aarch64 GNU/Linux ([PR #523])
|
||||
* Add prebuilt binaries for aarch64 Windows ([PR #524])
|
||||
|
||||
### Version 3.23.1
|
||||
|
||||
* Add support for Magisk 30400 ([PR #521])
|
||||
|
||||
### Version 3.23.0
|
||||
|
||||
* Update dependencies and fix Rust 1.90 clippy lints ([PR #517], [PR #520])
|
||||
* Add support for Magisk 30300 ([PR #519])
|
||||
|
||||
### Version 3.22.0
|
||||
|
||||
* Fix CoW size estimates not being set when running `avbroot payload pack` ([PR #509])
|
||||
* Add support for only unpacking metadata in `avbroot {avb,boot,cpio,lp,payload} unpack` ([PR #510])
|
||||
* Specify minimum supported compiler version for building from source ([PR #511])
|
||||
* Update dependencies ([PR #512])
|
||||
|
||||
### Version 3.21.0
|
||||
|
||||
* Switch to using rawzip for zip parsing and writing ([PR #489])
|
||||
@@ -602,3 +628,15 @@ Behind-the-scenes changes:
|
||||
[PR #503]: https://github.com/chenxiaolong/avbroot/pull/503
|
||||
[PR #504]: https://github.com/chenxiaolong/avbroot/pull/504
|
||||
[PR #505]: https://github.com/chenxiaolong/avbroot/pull/505
|
||||
[PR #509]: https://github.com/chenxiaolong/avbroot/pull/509
|
||||
[PR #510]: https://github.com/chenxiaolong/avbroot/pull/510
|
||||
[PR #511]: https://github.com/chenxiaolong/avbroot/pull/511
|
||||
[PR #512]: https://github.com/chenxiaolong/avbroot/pull/512
|
||||
[PR #517]: https://github.com/chenxiaolong/avbroot/pull/517
|
||||
[PR #519]: https://github.com/chenxiaolong/avbroot/pull/519
|
||||
[PR #520]: https://github.com/chenxiaolong/avbroot/pull/520
|
||||
[PR #521]: https://github.com/chenxiaolong/avbroot/pull/521
|
||||
[PR #523]: https://github.com/chenxiaolong/avbroot/pull/523
|
||||
[PR #524]: https://github.com/chenxiaolong/avbroot/pull/524
|
||||
[PR #529]: https://github.com/chenxiaolong/avbroot/pull/529
|
||||
[PR #530]: https://github.com/chenxiaolong/avbroot/pull/530
|
||||
|
||||
Generated
+269
-321
File diff suppressed because it is too large
Load Diff
+3
-1
@@ -4,10 +4,12 @@ members = ["avbroot", "e2e", "fuzz", "xtask"]
|
||||
resolver = "2"
|
||||
|
||||
[workspace.package]
|
||||
version = "3.21.0"
|
||||
version = "3.23.3"
|
||||
license = "GPL-3.0-only"
|
||||
edition = "2024"
|
||||
repository = "https://github.com/chenxiaolong/avbroot"
|
||||
publish = false
|
||||
rust-version = "1.88.0"
|
||||
|
||||
[workspace.lints.clippy]
|
||||
cast_lossless = "deny"
|
||||
|
||||
+6
-4
@@ -4,7 +4,8 @@ version.workspace = true
|
||||
license.workspace = true
|
||||
edition.workspace = true
|
||||
repository.workspace = true
|
||||
publish = false
|
||||
publish.workspace = true
|
||||
rust-version.workspace = true
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
@@ -26,13 +27,14 @@ dlv-list = "0.6.0"
|
||||
flate2 = { version = "1.0.29", features = ["zlib-rs"] }
|
||||
gf256 = { version = "0.3.0", features = ["rs"] }
|
||||
hex = { version = "0.4.3", features = ["serde"] }
|
||||
lz4_flex = "0.11.1"
|
||||
lzma-rust2 = "0.10.0"
|
||||
lz4_flex = "0.12.0"
|
||||
lzma-rust2 = "0.15.2"
|
||||
memchr = "2.6.0"
|
||||
# We can't upgrade to 0.9.0 until rsa updates its dependency.
|
||||
num-bigint-dig = "0.8.4"
|
||||
num-traits = "0.2.16"
|
||||
passterm = "2.0.3"
|
||||
phf = { version = "0.12.1", features = ["macros"] }
|
||||
phf = { version = "0.13.1", features = ["macros"] }
|
||||
pkcs8 = { version = "0.10.2", features = ["encryption", "pem"] }
|
||||
prost = "0.14.1"
|
||||
# We can't upgrade to 0.9.0 until rsa updates its rand_core dependency.
|
||||
|
||||
@@ -40,19 +40,14 @@ pub enum Command {
|
||||
MagiskInfo(boot::MagiskInfoCli),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, ValueEnum)]
|
||||
#[derive(Clone, Copy, Debug, Default, ValueEnum)]
|
||||
pub enum LogFormat {
|
||||
#[default]
|
||||
Short,
|
||||
Medium,
|
||||
Long,
|
||||
}
|
||||
|
||||
impl Default for LogFormat {
|
||||
fn default() -> Self {
|
||||
Self::Short
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for LogFormat {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.write_str(self.to_possible_value().ok_or(fmt::Error)?.get_name())
|
||||
|
||||
@@ -735,7 +735,7 @@ fn unpack_subcommand(cli: &UnpackCli, cancel_signal: &AtomicBool) -> Result<()>
|
||||
|
||||
write_info(&cli.output_info, &info)?;
|
||||
|
||||
if info.footer.is_some() {
|
||||
if info.footer.is_some() && !cli.no_output_raw {
|
||||
write_raw_and_verify(
|
||||
&cli.output_raw,
|
||||
&mut reader,
|
||||
@@ -1025,6 +1025,10 @@ struct UnpackCli {
|
||||
#[arg(long, value_name = "FILE", value_parser, default_value = "raw.img")]
|
||||
output_raw: PathBuf,
|
||||
|
||||
/// Do not output raw image.
|
||||
#[arg(long, conflicts_with = "output_raw")]
|
||||
no_output_raw: bool,
|
||||
|
||||
/// Ignore invalid digests or FEC data.
|
||||
#[arg(long)]
|
||||
ignore_invalid: bool,
|
||||
|
||||
+53
-11
@@ -1,4 +1,4 @@
|
||||
// SPDX-FileCopyrightText: 2023 Andrew Gunnerson
|
||||
// SPDX-FileCopyrightText: 2023-2025 Andrew Gunnerson
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
|
||||
use std::{
|
||||
@@ -164,30 +164,44 @@ fn unpack_subcommand(boot_cli: &BootCli, cli: &UnpackCli) -> Result<()> {
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(data) = kernel {
|
||||
if let Some(data) = kernel
|
||||
&& !cli.no_output_kernel
|
||||
{
|
||||
write_data_if_not_empty(&cli.output_kernel, data)?;
|
||||
}
|
||||
if let Some(data) = second {
|
||||
if let Some(data) = second
|
||||
&& !cli.no_output_second
|
||||
{
|
||||
write_data_if_not_empty(&cli.output_second, data)?;
|
||||
}
|
||||
if let Some(data) = recovery_dtbo {
|
||||
if let Some(data) = recovery_dtbo
|
||||
&& !cli.no_output_recovery_dtbo
|
||||
{
|
||||
write_data_if_not_empty(&cli.output_recovery_dtbo, data)?;
|
||||
}
|
||||
if let Some(data) = dtb {
|
||||
if let Some(data) = dtb
|
||||
&& !cli.no_output_dtb
|
||||
{
|
||||
write_data_if_not_empty(&cli.output_dtb, data)?;
|
||||
}
|
||||
if let Some(header) = vts_signature {
|
||||
if let Some(header) = vts_signature
|
||||
&& !cli.no_output_vts_signature
|
||||
{
|
||||
write_avb_header(&cli.output_vts_signature, header)?;
|
||||
}
|
||||
if let Some(text) = bootconfig {
|
||||
if let Some(text) = bootconfig
|
||||
&& !cli.no_output_bootconfig
|
||||
{
|
||||
write_text_if_not_empty(&cli.output_bootconfig, text)?;
|
||||
}
|
||||
|
||||
for (i, data) in ramdisks.iter().enumerate() {
|
||||
let mut path = cli.output_ramdisk_prefix.as_os_str().to_owned();
|
||||
path.push(i.to_string());
|
||||
if !cli.no_output_ramdisk {
|
||||
for (i, data) in ramdisks.iter().enumerate() {
|
||||
let mut path = cli.output_ramdisk_prefix.as_os_str().to_owned();
|
||||
path.push(i.to_string());
|
||||
|
||||
write_data_if_not_empty(Path::new(&path), data)?;
|
||||
write_data_if_not_empty(Path::new(&path), data)?;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@@ -339,6 +353,10 @@ struct UnpackCli {
|
||||
#[arg(long, value_name = "FILE", value_parser, default_value = "kernel.img")]
|
||||
output_kernel: PathBuf,
|
||||
|
||||
/// Do not output kernel image.
|
||||
#[arg(long, conflicts_with = "output_kernel")]
|
||||
no_output_kernel: bool,
|
||||
|
||||
/// Path prefix for output ramdisk images.
|
||||
#[arg(
|
||||
long,
|
||||
@@ -348,10 +366,18 @@ struct UnpackCli {
|
||||
)]
|
||||
output_ramdisk_prefix: PathBuf,
|
||||
|
||||
/// Do not output ramdisk images.
|
||||
#[arg(long, conflicts_with = "output_ramdisk_prefix")]
|
||||
no_output_ramdisk: bool,
|
||||
|
||||
/// Path to output second stage bootloader image.
|
||||
#[arg(long, value_name = "FILE", value_parser, default_value = "second.img")]
|
||||
output_second: PathBuf,
|
||||
|
||||
/// Do not output second stage bootloader image.
|
||||
#[arg(long, conflicts_with = "output_second")]
|
||||
no_output_second: bool,
|
||||
|
||||
/// Path to output recovery dtbo/acpio image.
|
||||
#[arg(
|
||||
long,
|
||||
@@ -361,10 +387,18 @@ struct UnpackCli {
|
||||
)]
|
||||
output_recovery_dtbo: PathBuf,
|
||||
|
||||
/// Do not output recovery dtbo/acpio image.
|
||||
#[arg(long, conflicts_with = "output_recovery_dtbo")]
|
||||
no_output_recovery_dtbo: bool,
|
||||
|
||||
/// Path to output device tree blob image.
|
||||
#[arg(long, value_name = "FILE", value_parser, default_value = "dtb.img")]
|
||||
output_dtb: PathBuf,
|
||||
|
||||
/// Do not output device tree blob image.
|
||||
#[arg(long, conflicts_with = "output_dtb")]
|
||||
no_output_dtb: bool,
|
||||
|
||||
/// Path to output VTS signature.
|
||||
#[arg(
|
||||
long,
|
||||
@@ -374,6 +408,10 @@ struct UnpackCli {
|
||||
)]
|
||||
output_vts_signature: PathBuf,
|
||||
|
||||
/// Do not output VTS signature.
|
||||
#[arg(long, conflicts_with = "output_vts_signature")]
|
||||
no_output_vts_signature: bool,
|
||||
|
||||
/// Path to output bootconfig text.
|
||||
#[arg(
|
||||
long,
|
||||
@@ -382,6 +420,10 @@ struct UnpackCli {
|
||||
default_value = "bootconfig.txt"
|
||||
)]
|
||||
output_bootconfig: PathBuf,
|
||||
|
||||
/// Do not output bootconfig text.
|
||||
#[arg(long, conflicts_with = "output_bootconfig")]
|
||||
no_output_bootconfig: bool,
|
||||
}
|
||||
|
||||
/// Pack a boot image.
|
||||
|
||||
+17
-11
@@ -170,22 +170,24 @@ fn unpack_subcommand(
|
||||
|
||||
display_format(cpio_cli, format);
|
||||
|
||||
fs::create_dir_all(&cli.output_tree)
|
||||
.with_context(|| format!("Failed to create directory: {:?}", cli.output_tree))?;
|
||||
if !cli.no_output_tree {
|
||||
fs::create_dir_all(&cli.output_tree)
|
||||
.with_context(|| format!("Failed to create directory: {:?}", cli.output_tree))?;
|
||||
|
||||
while let Some(entry) = reader.next_entry().context("Failed to read cpio entry")? {
|
||||
display_entry(cpio_cli, &entry);
|
||||
while let Some(entry) = reader.next_entry().context("Failed to read cpio entry")? {
|
||||
display_entry(cpio_cli, &entry);
|
||||
|
||||
if let Some(mut writer) = create_tree_file(&cli.output_tree, &entry)? {
|
||||
let file_size = entry.data.size()?;
|
||||
if let Some(mut writer) = create_tree_file(&cli.output_tree, &entry)? {
|
||||
let file_size = entry.data.size()?;
|
||||
|
||||
stream::copy_n(&mut reader, &mut writer, file_size.into(), cancel_signal)
|
||||
.context("Failed to copy data")?;
|
||||
stream::copy_n(&mut reader, &mut writer, file_size.into(), cancel_signal)
|
||||
.context("Failed to copy data")?;
|
||||
|
||||
writer.into_inner().context("Failed to flush data")?;
|
||||
writer.into_inner().context("Failed to flush data")?;
|
||||
}
|
||||
|
||||
info.entries.push(entry);
|
||||
}
|
||||
|
||||
info.entries.push(entry);
|
||||
}
|
||||
|
||||
write_info(&cli.output_info, &info)?;
|
||||
@@ -300,6 +302,10 @@ struct UnpackCli {
|
||||
/// Path to output files directory.
|
||||
#[arg(long, value_name = "DIR", value_parser, default_value = "cpio_tree")]
|
||||
output_tree: PathBuf,
|
||||
|
||||
/// Do not output files.
|
||||
#[arg(long, conflicts_with = "output_tree")]
|
||||
no_output_tree: bool,
|
||||
}
|
||||
|
||||
/// Pack a cpio archive.
|
||||
|
||||
@@ -179,7 +179,7 @@ fn unpack_subcommand(lp_cli: &LpCli, cli: &UnpackCli, cancel_signal: &AtomicBool
|
||||
write_info(&cli.output_info, &metadata)?;
|
||||
|
||||
// For empty images, there's no data to unpack.
|
||||
if metadata.image_type == ImageType::Empty {
|
||||
if metadata.image_type == ImageType::Empty || cli.no_output_images {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
@@ -535,6 +535,10 @@ struct UnpackCli {
|
||||
#[arg(long, value_name = "DIR", value_parser, default_value = "lp_images")]
|
||||
output_images: PathBuf,
|
||||
|
||||
/// Do not output images.
|
||||
#[arg(long, conflicts_with = "output_images")]
|
||||
no_output_images: bool,
|
||||
|
||||
/// The LP metadata slot to use.
|
||||
///
|
||||
/// This slot is the only slot where data extents are copied from. Any data
|
||||
|
||||
@@ -830,7 +830,7 @@ pub fn compress_image(
|
||||
|
||||
/// Recompute the CoW estimate for an image and update the OTA manifest
|
||||
/// partition entry appropriately. The input file is not modified.
|
||||
fn recow_image(
|
||||
pub fn recow_image(
|
||||
name: &str,
|
||||
file: &File,
|
||||
header: &mut PayloadHeader,
|
||||
|
||||
+43
-17
@@ -113,24 +113,26 @@ fn unpack_subcommand(
|
||||
|
||||
write_info(&cli.output_info, &header)?;
|
||||
|
||||
fs::create_dir_all(&cli.output_images)
|
||||
.with_context(|| format!("Failed to create directory: {:?}", cli.output_images))?;
|
||||
if !cli.no_output_images {
|
||||
fs::create_dir_all(&cli.output_images)
|
||||
.with_context(|| format!("Failed to create directory: {:?}", cli.output_images))?;
|
||||
|
||||
ota::extract_payload(
|
||||
&reader.into_inner(),
|
||||
&cli.output_images,
|
||||
0,
|
||||
payload_size,
|
||||
&header,
|
||||
&header
|
||||
.manifest
|
||||
.partitions
|
||||
.iter()
|
||||
.map(|p| &p.partition_name)
|
||||
.cloned()
|
||||
.collect(),
|
||||
cancel_signal,
|
||||
)?;
|
||||
ota::extract_payload(
|
||||
&reader.into_inner(),
|
||||
&cli.output_images,
|
||||
0,
|
||||
payload_size,
|
||||
&header,
|
||||
&header
|
||||
.manifest
|
||||
.partitions
|
||||
.iter()
|
||||
.map(|p| &p.partition_name)
|
||||
.cloned()
|
||||
.collect(),
|
||||
cancel_signal,
|
||||
)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -160,6 +162,26 @@ fn pack_subcommand(
|
||||
})
|
||||
.collect::<Result<HashMap<_, _>>>()?;
|
||||
|
||||
for (name, input_file) in &input_files {
|
||||
let Some(dpm) = &header.manifest.dynamic_partition_metadata else {
|
||||
continue;
|
||||
};
|
||||
|
||||
if !dpm.groups.iter().any(|g| g.partition_names.contains(name)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
header
|
||||
.manifest
|
||||
.partitions
|
||||
.iter_mut()
|
||||
.find(|p| p.partition_name == *name)
|
||||
.unwrap()
|
||||
.estimate_cow_size = Some(0);
|
||||
|
||||
ota::recow_image(name, input_file, &mut header, cancel_signal)?;
|
||||
}
|
||||
|
||||
// Compress the images and compute the list of install operations for
|
||||
// insertion into the payload header. The compressed data is stored in new
|
||||
// temp files and the original input files are dropped.
|
||||
@@ -366,6 +388,10 @@ struct UnpackCli {
|
||||
default_value = "payload_images"
|
||||
)]
|
||||
output_images: PathBuf,
|
||||
|
||||
/// Do not output images.
|
||||
#[arg(long, conflicts_with = "output_images")]
|
||||
no_output_images: bool,
|
||||
}
|
||||
|
||||
/// Pack a payload binary.
|
||||
|
||||
@@ -9,7 +9,7 @@ use flate2::{
|
||||
write::{DeflateEncoder, GzEncoder},
|
||||
};
|
||||
use lz4_flex::frame::FrameDecoder;
|
||||
use lzma_rust2::{CheckType, XZOptions, XZReader, XZWriter};
|
||||
use lzma_rust2::{CheckType, XzOptions, XzReader, XzWriter};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use thiserror::Error;
|
||||
|
||||
@@ -121,8 +121,8 @@ pub enum CompressedReader<R: Read> {
|
||||
Deflate(DeflateDecoder<R>),
|
||||
Gzip(GzDecoder<R>),
|
||||
Lz4(FrameDecoder<R>),
|
||||
/// Boxed because the [`XZReader`] is nearly 4 KiB.
|
||||
Xz(Box<XZReader<R>>),
|
||||
/// Boxed because the [`XzReader`] is nearly 4 KiB.
|
||||
Xz(Box<XzReader<R>>),
|
||||
}
|
||||
|
||||
impl<R: Read> CompressedReader<R> {
|
||||
@@ -132,7 +132,7 @@ impl<R: Read> CompressedReader<R> {
|
||||
CompressedFormat::Deflate => Self::Deflate(DeflateDecoder::new(reader)),
|
||||
CompressedFormat::Gzip => Self::Gzip(GzDecoder::new(reader)),
|
||||
CompressedFormat::Lz4Legacy => Self::Lz4(FrameDecoder::new(reader)),
|
||||
CompressedFormat::Xz => Self::Xz(Box::new(XZReader::new(reader, false))),
|
||||
CompressedFormat::Xz => Self::Xz(Box::new(XzReader::new(reader, false))),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -168,7 +168,7 @@ impl<R: Read + Seek> CompressedReader<R> {
|
||||
} else if &magic[0..4] == LZ4_LEGACY_MAGIC {
|
||||
Ok(Self::Lz4(FrameDecoder::new(reader)))
|
||||
} else if &magic == XZ_MAGIC {
|
||||
Ok(Self::Xz(Box::new(XZReader::new(reader, false))))
|
||||
Ok(Self::Xz(Box::new(XzReader::new(reader, false))))
|
||||
} else if raw_if_unknown {
|
||||
Ok(Self::None(reader))
|
||||
} else {
|
||||
@@ -195,7 +195,7 @@ pub enum CompressedWriter<W: Write> {
|
||||
Deflate(DeflateEncoder<W>),
|
||||
Gzip(GzEncoder<W>),
|
||||
Lz4Legacy(Lz4LegacyEncoder<W>),
|
||||
Xz(XZWriter<W>),
|
||||
Xz(XzWriter<W>),
|
||||
}
|
||||
|
||||
impl<W: Write> CompressedWriter<W> {
|
||||
@@ -215,10 +215,10 @@ impl<W: Write> CompressedWriter<W> {
|
||||
}
|
||||
CompressedFormat::Xz => {
|
||||
// Some kernels are compiled without support for the default CRC64.
|
||||
let mut options = XZOptions::with_preset(6);
|
||||
let mut options = XzOptions::with_preset(6);
|
||||
options.set_check_sum_type(CheckType::Crc32);
|
||||
|
||||
let xz_writer = XZWriter::new(writer, options).map_err(Error::XzInit)?;
|
||||
let xz_writer = XzWriter::new(writer, options).map_err(Error::XzInit)?;
|
||||
Ok(Self::Xz(xz_writer))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ use base64::Engine;
|
||||
use base64::engine::general_purpose::STANDARD;
|
||||
use bzip2::write::BzDecoder;
|
||||
use flate2::{Compression, write::GzEncoder};
|
||||
use lzma_rust2::{CheckType, XZOptions, XZReader, XZWriter};
|
||||
use lzma_rust2::{CheckType, XzOptions, XzReader, XzWriter};
|
||||
use num_traits::CheckedAdd;
|
||||
use prost::Message;
|
||||
use rayon::{
|
||||
@@ -814,7 +814,7 @@ pub fn apply_operation(
|
||||
// reader and read till EOF.
|
||||
let limited_reader = (&mut *reader).take(data_length);
|
||||
let hashing_reader = HashingReader::new(limited_reader, hasher);
|
||||
let mut decoder = XZReader::new(hashing_reader, false);
|
||||
let mut decoder = XzReader::new(hashing_reader, false);
|
||||
stream::copy(&mut decoder, &mut *writer, cancel_signal)
|
||||
.map_err(error_fn)?;
|
||||
|
||||
@@ -922,9 +922,9 @@ fn compress_chunk(raw_data: &[u8], cancel_signal: &AtomicBool) -> Result<(Vec<u8
|
||||
// decompression. Also, we intentionally pick the lowest compression level
|
||||
// since we primarily care about squishing zeros. The non-zero portions of
|
||||
// boot images are usually already-compressed kernels and ramdisks.
|
||||
let mut options = XZOptions::with_preset(0);
|
||||
let mut options = XzOptions::with_preset(0);
|
||||
options.set_check_sum_type(CheckType::None);
|
||||
let mut xz_writer = XZWriter::new(hashing_writer, options).map_err(Error::XzInit)?;
|
||||
let mut xz_writer = XzWriter::new(hashing_writer, options).map_err(Error::XzInit)?;
|
||||
|
||||
stream::copy_n(reader, &mut xz_writer, raw_data.len() as u64, cancel_signal)
|
||||
.map_err(Error::XzCompress)?;
|
||||
|
||||
@@ -520,14 +520,14 @@ impl ChunkList {
|
||||
// Find the chunk to insert before. We save the last used index to
|
||||
// optimize for sequential insertion and avoid needing to search the
|
||||
// entire list every time.
|
||||
let mut insert_before = self.chunks.front_index();
|
||||
|
||||
if let Some(last_used) = self.last_used
|
||||
let mut insert_before = if let Some(last_used) = self.last_used
|
||||
&& chunk.bounds.start >= self.chunks.get(last_used).unwrap().bounds.start
|
||||
{
|
||||
// The new chunk starts after the last used chunk.
|
||||
insert_before = Some(last_used);
|
||||
}
|
||||
Some(last_used)
|
||||
} else {
|
||||
self.chunks.front_index()
|
||||
};
|
||||
|
||||
while let Some(index) = insert_before {
|
||||
if self.chunks.get(index).unwrap().bounds.start >= chunk.bounds.start {
|
||||
|
||||
@@ -330,28 +330,6 @@ struct ZipLocalHeader {
|
||||
extra_field_len: little_endian::U16,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, FromBytes, IntoBytes, KnownLayout, Immutable, Unaligned)]
|
||||
#[repr(C, packed)]
|
||||
struct ZipCentralHeader {
|
||||
pub signature: little_endian::U32,
|
||||
pub version_made_by: little_endian::U16,
|
||||
pub version_needed: little_endian::U16,
|
||||
pub flags: little_endian::U16,
|
||||
pub compression_method: little_endian::U16,
|
||||
pub last_mod_time: little_endian::U16,
|
||||
pub last_mod_date: little_endian::U16,
|
||||
pub crc32: little_endian::U32,
|
||||
pub compressed_size: little_endian::U32,
|
||||
pub uncompressed_size: little_endian::U32,
|
||||
pub file_name_len: little_endian::U16,
|
||||
pub extra_field_len: little_endian::U16,
|
||||
pub file_comment_len: little_endian::U16,
|
||||
pub disk_number_start: little_endian::U16,
|
||||
pub internal_file_attrs: little_endian::U16,
|
||||
pub external_file_attrs: little_endian::U32,
|
||||
pub local_header_offset: little_endian::U32,
|
||||
}
|
||||
|
||||
/// Convert a streaming zip into a non-streaming one. If any entry uses ZIP64,
|
||||
/// the local header must contain an [`ExtraFieldId::ANDROID_ZIP_ALIGNMENT`]
|
||||
/// extra field with sufficient size (16 bytes to be safe). This is used as
|
||||
|
||||
@@ -16,7 +16,7 @@ use std::{
|
||||
};
|
||||
|
||||
use bstr::ByteSlice;
|
||||
use lzma_rust2::{CheckType, XZOptions, XZWriter};
|
||||
use lzma_rust2::{CheckType, XzOptions, XzWriter};
|
||||
use rawzip::{RECOMMENDED_BUFFER_SIZE, ZipArchive};
|
||||
use rayon::iter::{IntoParallelRefIterator, IntoParallelRefMutIterator, ParallelIterator};
|
||||
use regex::bytes::Regex;
|
||||
@@ -196,11 +196,12 @@ impl MagiskRootPatcher {
|
||||
// replaced by PREINITDEVICE
|
||||
// - Versions newer than the latest supported version are assumed to support
|
||||
// the same features as the latest version
|
||||
const VERS_SUPPORTED: &'static [Range<u32>] = &[25102..25207, 25211..30300];
|
||||
const VERS_SUPPORTED: &'static [Range<u32>] = &[25102..25207, 25211..30700];
|
||||
const VER_PREINIT_DEVICE: RangeFrom<u32> = 25211..;
|
||||
const VER_RANDOM_SEED: Range<u32> = 25211..26103;
|
||||
const VER_PATCH_VBMETA: Range<u32> = Self::VERS_SUPPORTED[0].start..26202;
|
||||
const VER_XZ_BACKUP: RangeFrom<u32> = 26403..;
|
||||
const VER_VENDOR_BOOT: RangeFrom<u32> = 30300..;
|
||||
|
||||
const ZIP_INIT_LD: &'static str = "lib/arm64-v8a/libinit-ld.so";
|
||||
const ZIP_LIBMAGISK: &'static str = "lib/arm64-v8a/libmagisk.so";
|
||||
@@ -301,11 +302,11 @@ impl MagiskRootPatcher {
|
||||
}
|
||||
|
||||
fn xz_compress(name: &[u8], reader: impl Read, cancel_signal: &AtomicBool) -> Result<Vec<u8>> {
|
||||
let mut options = XZOptions::with_preset(9);
|
||||
let mut options = XzOptions::with_preset(9);
|
||||
options.set_check_sum_type(CheckType::None);
|
||||
|
||||
let raw_writer = Cursor::new(Vec::new());
|
||||
let mut writer = XZWriter::new(raw_writer, options).map_err(Error::XzInit)?;
|
||||
let mut writer = XzWriter::new(raw_writer, options).map_err(Error::XzInit)?;
|
||||
|
||||
let raw_writer = stream::copy(reader, &mut writer, cancel_signal)
|
||||
.and_then(|_| writer.finish())
|
||||
@@ -391,15 +392,15 @@ impl MagiskRootPatcher {
|
||||
let mut new_path = b".backup/".to_vec();
|
||||
new_path.extend(&old_entry.path);
|
||||
|
||||
let mut new_data = None;
|
||||
|
||||
if xz_compress && let CpioEntryData::Data(data) = &old_entry.data {
|
||||
let new_data = if xz_compress && let CpioEntryData::Data(data) = &old_entry.data {
|
||||
new_path.extend(b".xz");
|
||||
|
||||
let reader = Cursor::new(data);
|
||||
let buf = Self::xz_compress(&new_path, reader, cancel_signal)?;
|
||||
new_data = Some(CpioEntryData::Data(buf));
|
||||
}
|
||||
Some(CpioEntryData::Data(buf))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
new_entries.push(CpioEntry {
|
||||
path: new_path,
|
||||
@@ -586,6 +587,13 @@ impl BootImagePatch for MagiskRootPatcher {
|
||||
|
||||
magisk_config.push_str("RECOVERYMODE=false\n");
|
||||
|
||||
// We never install Magisk into the init_boot.cpio within the
|
||||
// vendor_boot ramdisk. This config option was introduced in commit
|
||||
// 742913ebcb10cf819a54699497359535047874f7.
|
||||
if Self::VER_VENDOR_BOOT.contains(&self.version) {
|
||||
magisk_config.push_str("VENDORBOOT=false\n");
|
||||
}
|
||||
|
||||
if Self::VER_PREINIT_DEVICE.contains(&self.version)
|
||||
&& let Some(device) = &self.preinit_device
|
||||
{
|
||||
|
||||
@@ -34,20 +34,13 @@ allow = [
|
||||
"Apache-2.0 WITH LLVM-exception",
|
||||
"BSD-3-Clause",
|
||||
"bzip2-1.0.6",
|
||||
"GPL-3.0",
|
||||
"GPL-3.0-only",
|
||||
"ISC",
|
||||
"MIT",
|
||||
"Unicode-3.0",
|
||||
"Zlib",
|
||||
]
|
||||
|
||||
[[licenses.clarify]]
|
||||
name = "ring"
|
||||
expression = "MIT AND ISC AND OpenSSL"
|
||||
license-files = [
|
||||
{ path = "LICENSE", hash = 0xbd0eed23 },
|
||||
]
|
||||
|
||||
[bans]
|
||||
multiple-versions = "warn"
|
||||
multiple-versions-include-dev = true
|
||||
|
||||
+2
-1
@@ -4,7 +4,8 @@ version.workspace = true
|
||||
license.workspace = true
|
||||
edition.workspace = true
|
||||
repository.workspace = true
|
||||
publish = false
|
||||
publish.workspace = true
|
||||
rust-version.workspace = true
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
|
||||
+2
-1
@@ -4,7 +4,8 @@ version.workspace = true
|
||||
license.workspace = true
|
||||
edition.workspace = true
|
||||
repository.workspace = true
|
||||
publish = false
|
||||
publish.workspace = true
|
||||
rust-version.workspace = true
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
|
||||
+2
-1
@@ -4,7 +4,8 @@ version.workspace = true
|
||||
license.workspace = true
|
||||
edition.workspace = true
|
||||
repository.workspace = true
|
||||
publish = false
|
||||
publish.workspace = true
|
||||
rust-version.workspace = true
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
|
||||
Reference in New Issue
Block a user