All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
- Use feature
zlib-ng
forflate2
, which is enabled when compression optionGzip
is used. This enables the backend to use zlib-ng, which is faster by default! (#562) - Remove duplicated data when addding new files to a
FilesystemWriter
. This also applies this behavior to theadd
andreplace
binaries. This is controllable withFilesystemWriter::set_no_duplicate_files
. (#603), (#594) - Increase speed of internal
HashMap
s, by switching toxxhash
and just using theinode
as the key in other places. - Changed
SuperBlock::Flags
to be public. - Add non-standard CompressionOptions support (#584)
- Add
CompressionAction::compression_options
to override the default compression options emitted during writing. - Add
FilesystemWriter::set_emit_compression_options
- Add
- Support sparse file extraction (#624)
- Add
x86_64-pc-windows-gnu
support (@Wolfyxon) (#634) - Add zlib-rs support through
--feature gzip-zlib-rs
.
- Add
--no-compression-options
toadd
andreplace
to remove compression options from image after modification. - Add
--pad-len
toreplace
andadd
to control the length of end-of-image padding (#604) - Bump MSRV to
1.77
- Bump
thiserror
from 1.0.59 to 2.0.1 (#564, #578, #615, #633) - Bump
libc
from 0.2.154 to 0.2.162 (#557, #592, #616, #630) - Bump
clap
from 4.5.4 to 4.5.13 (#569, #574, #582) - Bump
rustc-hash
from 1.1.0 to 2.0.0 (#570) - Bump
clap_complete
from 4.5.2 to 4.5.13 (#575, #595) - Bump
document-features
from 0.2.8 to 0.2.10 (#576) - Bump
zstd-safe
from 7.1.0 to 7.2.1 (#585) - Bump
flate2
from 1.0.30 to 1.0.35 (#593, #596, #617, #641) - Bump
zstd
from 0.13.1 to 0.13.2 (#601) - Bump
env_logger
from 0.11.3 to 0.11.5 (#602) - Bump
libdeflater
from 1.21.0 to 1.22.0 (#619) - Bump
tempfile
from 3.12.0 to 3.13.0 (#618) - Bump
nix
from 0.28.0 to 0.29.0 (#566)
- Update MSRV to 1.72.1 (#524)
- Bump
libc
from 0.2.153 to 0.2.154 (#546)
- Bump
flate2
from 1.0.28 to 1.0.30 (#547)
- Simplify API by removing
FilesystemReader::alloc_read_buffers()
. This is now handled internally byFilesystemReader::reader()
(#530)
- Add
x86_64-apple-darwin
support and release binary (#511) - Fix
--help
and correctly showgzip
support when usinggzip-zune-inflate
(#538) - Fix
--help
and correctly showxz
support when usingxz-static
(#541)
- Bump
zstd
from 0.13.0 to 0.13.1 (#518) - Bump
rayon
from 1.9.0 to 1.10.0 (#512) - Bump
codecov/codecov-action
from 4.1.0 to 4.3.0 (#514, #526) - Bump
obi1kenobi/cargo-semver-checks-action
from 2.3 to 2.4 (#507) - Bump
clap
from 4.5.2 to 4.5.4 (#513) - Bump
libdeflater
from 1.19.3 to 1.20.0 (#523) - Bump
dangoslen/dependabot-changelog-helper
from 3.8.1 to 3.9.0 (#516) - Bump
thiserror
from 1.0.58 to 1.0.59 (#534) - Bump
color-print
from 0.3.5 to 0.3.6 (#537) - Bump
clap_complete
from 4.5.1 to 4.5.2 (#525)
Click to expand
Removed items from the public API
=================================
-pub fn backhand::FilesystemReader<'b>::alloc_read_buffers(&self) -> (alloc::vec::Vec<u8>, alloc::vec::Vec<u8>)
Changed items in the public API
===============================
-pub fn backhand::FilesystemReaderFile<'a, 'b>::reader(&self, buf_read: &'a mut alloc::vec::Vec<u8>, buf_decompress: &'a mut alloc::vec::Vec<u8>) -> backhand::SquashfsReadFile<'a, 'b>
+pub fn backhand::FilesystemReaderFile<'a, 'b>::reader(&self) -> backhand::SquashfsReadFile<'a, 'b>
Added items to the public API
=============================
(none)
Full Diff: https://github.com/wcampbell0x2a/backhand/compare/v0.15.0...v0.16.0
- Add support for
Socket
andNamedFIFO
Inodes in library and extraction binaries. Thanks (@tnias) (#472, #470)- Add
FilesytemWriter::push_fifo
andFilesystemWriter::push_socket
- Add
- Fix panic found with fuzz testing in
NodeHeader::from_inode
(#494) - Add tests for zstd compression support. Fix bug with zstd writer and added
zstd-safe
dependency (#504) - Added
inline
s to small public functions (#504) - Changed
FilesystemReader.cache
toRwLock
to reduce blocking time during fragment reading (#504) - Increase performance of reading uncompressed fragments (small files) heavy images by removing unnecessary clones of data (#504). Found by (@bryangarza) in (!503).
- Increased performance of reading inodes (#453)
- Reduce allocations within
Squashfs.dir_blocks
(#447) - Add pre-allocate before reading
inodes
(#437) - Prevent several bounds check failures found by fuzz testing (#499)
- Bump MSRV to
1.74
forclap-4.5.1
update (#483)
- Reduced maximum allocation during testing by free'ing right after full usage (#504)
- Performance: Remove progress bar Mutex lock when
--quiet
(#430)
- Bump
actions/upload-artifact
from 4.1.0 to 4.3.1 (#435, #446, #465) - Bump
env_logger
from 0.10.1 to 0.10.2 (#432) - Bump
rayon
from 1.8.0 to 1.9.0 (#431, #496) - Bump
clap
from 4.4.17 to 4.5.2 (#428, #500) - Bump
clap_complete
from 4.4.7 to 4.5.1 (#444, #445, #482) - Bump
codecov/codecov-action
from 3.1.4 to 4.1.0 (#448, #457, #458, #462, #488, #493) - Bump
obi1kenobi/cargo-semver-checks-action
from 2.2 to 2.3 (#449) - Bump
libc
from 0.2.152 to 0.2.153 (#459) - Bump
dangoslen/dependabot-changelog-helper
from 3.7.0 to 3.8.0 (#461) - Bump
thiserror
from 1.0.56 to 1.0.58 (#476, #502) - Bump
indicatif
from 0.17.7 to 0.17.8 (#477) - Bump
libdeflater
from 1.19.0 to 1.19.3 (#486, #498) - Bump
assert_cmd
from 2.0.13 to 2.0.14 (#484) - Bump
nix
from 0.27.1 to 0.28.0 (#489) - Bump
test-log
from 0.2.14 to 0.2.15 (#492) - Bump
tempfile
from 3.9.0 to 3.10.1 (#491) - Bump
actions/checkout
from 4.1.1 to 4.1.2 (#501)
Full Diff: https://github.com/wcampbell0x2a/backhand/compare/v0.14.2...v0.15.0
- Enable overflow-checks (#421)
- Add feature
gzip-zune-inflate
to add a decompress only option with speed improvements (#419) - Remove allocation for
impl From<BackhandError> for io::Error {
(#425)
- Enable overflow-checks for dist builds (#421)
- Use feature
gzip-zune-inflate
for dist build and speed improvements (#419) - Updated benchmarks to show improvement (#419)
- Bump
clap
from 4.4.12 to 4.5.1 (#417, #424, #483) - Bump
thiserror
from 1.0.53 to 1.0.56 (#404) - Bump
actions/upload-artifact
from 4.0.0 to 4.1.0 (#423) - Bump
libc
from 0.2.151 to 0.2.152 (#408) - Bump
clap_complete
from 4.4.5 to 4.4.7 (#426) - Bump
assert_cmd
from 2.0.12 to 2.0.13 (#422) - Bump
console
from 0.15.7 to 0.15.8 (#413)
Full Diff: https://github.com/wcampbell0x2a/backhand/compare/v0.14.1...v0.14.2
- Fix path to project
README.md
forcrates.io
(#420)
Full Diff: https://github.com/wcampbell0x2a/backhand/compare/v0.14.0...v0.14.1
Major changes were made to the organization of this repo, with the library backhand
now being separated from
the backhand-cli
package, which is used to install unsquashfs
, replace
, and add
.
- Following changes were done to allow multi-threaded applications (#278)
- Change
RefCell<Box<T>>
intoArc<Mutex<T>>
- Change
RefCell<T>
intoMutex<T>
- Change
Rc<T>
intoArc<T>
- Change
dyn CompressionAction
todyn CompressionAction + Send + Sync
forKind
uses - Change
BufReadSeek: BufRead + Seek {}
toBufReadSeek: BufRead + Seek + Send {}
- Change
- Allow user provided read/write files to not be static (@rbran) (#285)
- Bump MSRV to
1.67.1
- Allow creating and reading uncompressed files (@rbran) (#365)
- Allow calling
FilesystemWriter::write
with Owned and RefMut writer (@rbran) (#361) - Push dir, file, etc, with lifetimes unrelated to reader from
from_fs_reader
(@rbran) (#361) For example, the following is now allowed:
- let mut output = File::create(&args.out).unwrap();
- if let Err(e) = filesystem.write(&mut output) {
+ let output = File::create(&args.out).unwrap();
+ if let Err(e) = filesystem.write(output) {
- When creating an empty image using
FilesystemWriter::default()
, correctly create the ID table for UID and GID entries. Reported: (@hwittenborn) (!250), Fixed: (#275) - Remove manual
Clone
impl forFilesystemReaderFile
(#277) - Increase
DirectoryIndex::name_size
length from 100 to 255. (@eatradish) (!282), Fixed: (#283) - Prevent
push_file
"file within file", will now returnInvalidFilePath
(@rbran) (#364) - Fix
gid
anduid
forpush_dir_all(..)
(#360)
strip
andLTO
are enabled for release binaries- Fix macOS builds (#260)
- Bump MSRV to
1.73.0
to use now stabilizedstd::os::unix::fs::lchown
- Add color styling to help output (#387)
- Changed name to
unsquashfs-backhand
(#356) - Add progress bar for a cleaner output when extracting files (#272)
- Add
--quiet
for not displaying progress bar and RUST_LOG output (#272) - Add multiple threads for extracting files, giving us the same performance in most cases as
squashfs-tools/unsquashfs
! (#278)
- Changed name to
add-backhand
(#356)
- Changed name to
replace-backhand
(#356)
- Add testing and release binaries for the following platforms:(#259)
aarch64-unknown-linux-musl
arm-unknown-linux-musleabi
x86_64-unknown-linux-musl
(previously already release supported)
- Testing and release binaries were not added for macOS, support was tested on that platform.
- Replace curl in test dependency
test-assets
with ureq (#264) - Replace
zune-inflate
withlibdeflater
for custom decompression testing for reliability (#325)
- Bump
flate2
from 1.0.26 to 1.0.28 (#307) - Bump
jemallocator
from 0.5.0 to 0.5.4 (#305) - Bump
env_logger
from 0.10.0 to 0.10.1 (#341) - Bump
clap
from 4.4.7 to 4.4.12 (#340, #371, #376, #399) - Bump
dangoslen/dependabot-changelog-helper
from 3.5.0 to 3.7.0 (#342, #369) - Bump
tracing-subscriber
from 0.3.17 to 0.3.18 (#347) - Bump
byte-unit
from 4.0.19 to 5.0.3 (#367) - Bump
actions/labeler
from 4 to 5 (#377) - Bump
test-log
from 0.2.13 to 0.2.14 (#378) - Bump
clap_complete
from 4.4.4 to 4.4.5 (#393) - Bump
thiserror
from 1.0.51 to 1.0.53 (#391, #401) - Bump
actions/upload-artifact
from 3.1.3 to 4.0.0 (#380) - Bump
tempfile
from 3.8.1 to 3.9.0 (#398) - Bump
document-features
from 0.2.7 to 0.2.8 (#400)
Full Diff: https://github.com/wcampbell0x2a/backhand/compare/v0.13.0...v0.14.0
- Decrease in memory usage for file reader and write (#255)
- Remove unnecessary deconstruction/reconstruction of Vec when reading inodes (@rbran) (#251)
- Only store file data compressed if it results in smaller size (@rbran) (#250)
- Remove
lzo
being a default feature because of GPL license (#240) - Add support for OpenWRT compression options (#239)
- Bump MSRV to
1.65.0
for latestclap
requirements (#253)
- Fix bug in generating Uid and Gid's with
FilesystemWriter
. All internal representation of Gid and Uid are changed to u32 (#254) - Remove case where invalid filesystem root_inode_offset would cause invalid bounds read panic. Found by fuzzer (#245)
$ cargo public-api -ss diff v0.12.0..HEAD
Click to expand
Removed items from the public API
=================================
(none)
Changed items in the public API
===============================
-pub fn backhand::FilesystemWriter<'a>::set_root_gid(&mut self, gid: u16)
+pub fn backhand::FilesystemWriter<'a>::set_root_gid(&mut self, gid: u32)
-pub fn backhand::FilesystemWriter<'a>::set_root_uid(&mut self, uid: u16)
+pub fn backhand::FilesystemWriter<'a>::set_root_uid(&mut self, uid: u32)
-pub backhand::NodeHeader::gid: u16
+pub backhand::NodeHeader::gid: u32
-pub backhand::NodeHeader::uid: u16
+pub backhand::NodeHeader::uid: u32
-pub fn backhand::NodeHeader::new(permissions: u16, uid: u16, gid: u16, mtime: u32) -> Self
+pub fn backhand::NodeHeader::new(permissions: u16, uid: u32, gid: u32, mtime: u32) -> Self
Added items to the public API
=============================
+pub backhand::compression::Xz::bit_opts: core::option::Option<u16>
+pub backhand::compression::Xz::fb: core::option::Option<u16>
+pub fn backhand::kind::Kind::magic(&self) -> [u8; 4]
+impl backhand::NodeHeader
+pub fn backhand::NodeHeader::from_inode(inode_header: InodeHeader, id_table: &[backhand::Id]) -> Self
- jemalloc is now used for
-musl
release targets for performance reasons (#254) HAVE_DECODER_ARM
,HAVE_DECODER_ARM64
, andHAVE_DECODER_ARMTHUMB
filter flags are now defined for xz2. This only effects static build created in our CI. (#254)- Add
RUST_LOG
and available Decompressors to--help
of all binaries (#242)
- Add
--dir
to create a empty directory (#242)
- Add correctly reading new file metadata from
--file
, force other arguments for--dir
(#254)
- Add
--auto-offset
for automatic finding of initial SquashFS offset in image (#241) - Add possible
kind
values to--help
output (#236) - Add
--path-filter
to limit file extraction to a path (#237)
Full Diff: https://github.com/wcampbell0x2a/backhand/compare/v0.12.0...v0.13.0
Thanks @rbran for the contributions!
Kind
has been extended to take anCompressionAction
to have a custom compression and decompression algorithm. This defaults to theDefaultCompressor
in most situations to be like the Linux kernel squashfs code. This should allow an ever greater array of custom vendor Squashfs image support. Many API changes were done to support this, Most of the following changes focus on the Public API that we expect the normal developer to be using.- Added method to allow creating image without padding:
FilesystemWriter::set_no_padding()
- Added method to allow modification to Compression options:
FilesystemCompressor::options(&mut self, options: CompressionOptions)
- Added
FilesytemWriter::push_dir_all
, following behavior ofstd::fs::create_dir_all
and create required parent directories - Added
FilesystemReader::files()
andfile()
as the new method of reading files from an image. This change also reduced allocations in use when reading.
- for node in &filesystem.nodes {
+ for node in filesystem.files() {
- Compression Options are now written to the image during
FilesystemWriter.write(..)
- Removed non-used allocation in
SquashFsReader
. No change in public API. - Changed
SquashfsReadFile::reader(..)
to reduce the amount of allocation when extracting a file. This required addingalloc_read_buffers
to initialize the re-used buffers.
+// alloc required space for file data readers
+let (mut buf_read, mut buf_decompress) = filesystem.alloc_read_buffers();
-let mut reader = filesystem.file(&file.basic).reader();
+let mut reader = filesystem
+ .file(&file.basic)
+ .reader(&mut buf_read, &mut buf_decompress);
- Removed
FilesystemReader::read_file
- Changed
FilesytemWriter::push_file<P: Into<PathBuf>>(
intopush_file<P: AsRef<Path>>(
. NOTE: The function will no longer create parent directories! Instead use newFilesytemWriter::push_dir_all
- Removed
SquashfsFileSource
- Changed
FilesystemWriter::push_*()
functions to now returnBackhandError
to avoid duplicate files and invalid file paths. The followingBackhandError
s were added to support this:DuplicatedFileName
,UndefineFileName
, andInvalidFilePath
. - Changed
FilesystemWriter::push_block_device<P: Into<PathBuf>>()
intoP: AsRef<Path>
- Changed
FilesystemWriter::push_block_device<P: Into<PathBuf>>()
intoP: AsRef<Path>
- Changed
FilesystemWriter::write_with_offset()
to now take&mut self
- Changed
FilesystemWriter::write()
to now take&mut self
- Removed trait bound from
FilesystemReader
,FilesystemReaderFile
, andFilesystemWriter
:
-pub struct backhand::FilesystemReader<R: backhand::ReadSeek>
+pub struct backhand::FilesystemReader
-pub struct backhand::FilesystemReaderFile<'a, R: backhand::ReadSeek>
+pub struct backhand::FilesystemReaderFile<'a>
-pub struct backhand::FilesystemWriter<'a, R: backhand::ReadSeek>
+pub struct backhand::FilesystemWriter<'a>
- Changed public fields in
FilesystemReader
:
-pub root_inode: SquashfsDir,
-pub nodes: Vec<Node<SquashfsFileReader>>,
+pub root: Nodes<SquashfsFileReader>,
FilesystemReader::from_reader_*()
functions now takeBufReadSeek
for an increase in performance during reading for some images.
$ cargo public-api -ss diff v0.11.0..HEAD
Click to expand
Removed items from the public API
=================================
-pub fn backhand::kind::Kind::new() -> Self
-impl core::default::Default for backhand::kind::Kind
-pub fn backhand::kind::Kind::default() -> Self
-impl deku::DekuRead<'_, backhand::kind::Kind> for backhand::Export
-impl deku::DekuRead<'_, backhand::kind::Kind> for backhand::Export
-pub fn backhand::kind::Kind::read(__deku_input_bits: &bitvec::slice::BitSlice<u8, bitvec::order::Msb0>, kind: backhand::kind::Kind) -> core::result::Result<(&bitvec::slice::BitSlice<u8, bitvec::order::Msb0>, Self), deku::error::DekuError>
-pub fn backhand::kind::Kind::read(__deku_input_bits: &bitvec::slice::BitSlice<u8, bitvec::order::Msb0>, kind: backhand::kind::Kind) -> core::result::Result<(&bitvec::slice::BitSlice<u8, bitvec::order::Msb0>, Self), deku::error::DekuError>
-pub fn backhand::kind::Kind::read(__deku_input_bits: &bitvec::slice::BitSlice<u8, bitvec::order::Msb0>, kind: backhand::kind::Kind) -> core::result::Result<(&bitvec::slice::BitSlice<u8, bitvec::order::Msb0>, Self), deku::error::DekuError>
-pub fn backhand::kind::Kind::read(__deku_input_bits: &bitvec::slice::BitSlice<u8, bitvec::order::Msb0>, kind: backhand::kind::Kind) -> core::result::Result<(&bitvec::slice::BitSlice<u8, bitvec::order::Msb0>, Self), deku::error::DekuError>
-impl deku::DekuRead<'_, backhand::kind::Kind> for backhand::Fragment
-impl deku::DekuRead<'_, backhand::kind::Kind> for backhand::Fragment
-impl deku::DekuRead<'_, backhand::kind::Kind> for backhand::Id
-impl deku::DekuRead<'_, backhand::kind::Kind> for backhand::Id
-impl deku::DekuRead<'_, backhand::kind::Kind> for backhand::SuperBlock
-impl deku::DekuRead<'_, backhand::kind::Kind> for backhand::SuperBlock
-impl deku::DekuWrite<backhand::kind::Kind> for backhand::Export
-impl deku::DekuWrite<backhand::kind::Kind> for backhand::Export
-pub fn backhand::kind::Kind::write(&self, __deku_output: &mut bitvec::vec::BitVec<u8, bitvec::order::Msb0>, kind: backhand::kind::Kind) -> core::result::Result<(), deku::error::DekuError>
-pub fn backhand::kind::Kind::write(&self, __deku_output: &mut bitvec::vec::BitVec<u8, bitvec::order::Msb0>, kind: backhand::kind::Kind) -> core::result::Result<(), deku::error::DekuError>
-pub fn backhand::kind::Kind::write(&self, __deku_output: &mut bitvec::vec::BitVec<u8, bitvec::order::Msb0>, kind: backhand::kind::Kind) -> core::result::Result<(), deku::error::DekuError>
-pub fn backhand::kind::Kind::write(&self, __deku_output: &mut bitvec::vec::BitVec<u8, bitvec::order::Msb0>, kind: backhand::kind::Kind) -> core::result::Result<(), deku::error::DekuError>
-impl deku::DekuWrite<backhand::kind::Kind> for backhand::Fragment
-impl deku::DekuWrite<backhand::kind::Kind> for backhand::Fragment
-impl deku::DekuWrite<backhand::kind::Kind> for backhand::Id
-impl deku::DekuWrite<backhand::kind::Kind> for backhand::Id
-impl deku::DekuWrite<backhand::kind::Kind> for backhand::SuperBlock
-impl deku::DekuWrite<backhand::kind::Kind> for backhand::SuperBlock
-impl core::clone::Clone for backhand::kind::Kind
-pub fn backhand::kind::Kind::clone(&self) -> backhand::kind::Kind
-impl core::cmp::Eq for backhand::kind::Kind
-impl core::cmp::PartialEq<backhand::kind::Kind> for backhand::kind::Kind
-pub fn backhand::kind::Kind::eq(&self, other: &backhand::kind::Kind) -> bool
-impl core::marker::Copy for backhand::kind::Kind
-impl core::marker::StructuralEq for backhand::kind::Kind
-impl core::marker::StructuralPartialEq for backhand::kind::Kind
-pub enum backhand::SquashfsFileSource<'a, R: backhand::ReadSeek>
-pub backhand::SquashfsFileSource::SquashfsFile(backhand::FilesystemReaderFile<'a, R>)
-pub backhand::SquashfsFileSource::UserDefined(core::cell::RefCell<alloc::boxed::Box<(dyn std::io::Read + 'a)>>)
-pub fn backhand::Export::read(__deku_input_bits: &bitvec::slice::BitSlice<u8, bitvec::order::Msb0>, kind: backhand::kind::Kind) -> core::result::Result<(&bitvec::slice::BitSlice<u8, bitvec::order::Msb0>, Self), deku::error::DekuError>
-pub fn backhand::Export::write(&self, __deku_output: &mut bitvec::vec::BitVec<u8, bitvec::order::Msb0>, kind: backhand::kind::Kind) -> core::result::Result<(), deku::error::DekuError>
-pub backhand::FilesystemReader::nodes: alloc::vec::Vec<backhand::Node<backhand::SquashfsFileReader>>
-pub backhand::FilesystemReader::root_inode: backhand::SquashfsDir
-impl<R: backhand::ReadSeek> backhand::FilesystemReader<R>
-impl<R: backhand::ReadSeek> backhand::FilesystemReader<R>
-pub fn backhand::FilesystemReader::file<'a>(&'a self, basic_file: &'a backhand::BasicFile) -> backhand::FilesystemReaderFile<'a, R>
-pub fn backhand::FilesystemReader::read_file(&self, basic_file: &backhand::BasicFile) -> core::result::Result<alloc::vec::Vec<u8>, backhand::BackhandError>
-pub fn backhand::FilesystemReader::from_reader(reader: R) -> core::result::Result<Self, backhand::BackhandError>
-impl<R: backhand::ReadSeek> backhand::FilesystemReader<SquashfsReaderWithOffset<R>>
-pub fn backhand::FilesystemReader::from_reader_with_offset(reader: R, offset: u64) -> core::result::Result<Self, backhand::BackhandError>
-pub fn backhand::FilesystemReader::from_reader_with_offset_and_kind(reader: R, offset: u64, kind: backhand::kind::Kind) -> core::result::Result<Self, backhand::BackhandError>
-impl<R: core::fmt::Debug + backhand::ReadSeek> core::fmt::Debug for backhand::FilesystemReader<R>
-pub fn backhand::FilesystemReader::fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result
-impl<'a, R: backhand::ReadSeek> backhand::FilesystemReaderFile<'a, R>
-pub fn backhand::FilesystemReaderFile::new(system: &'a backhand::FilesystemReader<R>, basic: &'a backhand::BasicFile) -> Self
-pub fn backhand::FilesystemReaderFile::reader(&self) -> SquashfsReadFile<'a, R>
-impl<'a, R: backhand::ReadSeek> core::clone::Clone for backhand::FilesystemReaderFile<'a, R>
-impl<'a, R: backhand::ReadSeek> core::iter::traits::collect::IntoIterator for backhand::FilesystemReaderFile<'a, R>
-impl<'a, R: core::marker::Copy + backhand::ReadSeek> core::marker::Copy for backhand::FilesystemReaderFile<'a, R>
-impl<'a, R: backhand::ReadSeek> backhand::FilesystemWriter<'a, R>
-pub fn backhand::FilesystemWriter::from_fs_reader(reader: &'a backhand::FilesystemReader<R>) -> core::result::Result<Self, backhand::BackhandError>
-pub fn backhand::FilesystemWriter::mut_file<S: core::convert::Into<std::path::PathBuf>>(&mut self, find_path: S) -> core::option::Option<&mut backhand::SquashfsFileWriter<'a, R>>
-pub fn backhand::FilesystemWriter::push_block_device<P: core::convert::Into<std::path::PathBuf>>(&mut self, device_number: u32, path: P, header: backhand::NodeHeader)
-pub fn backhand::FilesystemWriter::push_char_device<P: core::convert::Into<std::path::PathBuf>>(&mut self, device_number: u32, path: P, header: backhand::NodeHeader)
-pub fn backhand::FilesystemWriter::push_dir<P: core::convert::Into<std::path::PathBuf>>(&mut self, path: P, header: backhand::NodeHeader)
-pub fn backhand::FilesystemWriter::push_file<P: core::convert::Into<std::path::PathBuf>>(&mut self, reader: impl std::io::Read + 'a, path: P, header: backhand::NodeHeader)
-pub fn backhand::FilesystemWriter::push_symlink<P: core::convert::Into<std::path::PathBuf>, S: core::convert::Into<std::path::PathBuf>>(&mut self, link: S, path: P, header: backhand::NodeHeader)
-pub fn backhand::FilesystemWriter::replace_file<S: core::convert::Into<std::path::PathBuf>>(&mut self, find_path: S, reader: impl std::io::Read + 'a) -> core::result::Result<(), backhand::BackhandError>
-pub fn backhand::FilesystemWriter::write<W: std::io::Write + std::io::Seek>(&self, w: &mut W) -> core::result::Result<(backhand::SuperBlock, u64), backhand::BackhandError>
-pub fn backhand::FilesystemWriter::write_with_offset<W: std::io::Write + std::io::Seek>(&self, w: &mut W, offset: u64) -> core::result::Result<(backhand::SuperBlock, u64), backhand::BackhandError>
-impl core::default::Default for backhand::FilesystemWriter<'_>
-impl<'a, R: core::fmt::Debug + backhand::ReadSeek> core::fmt::Debug for backhand::FilesystemWriter<'a, R>
-pub fn backhand::Fragment::read(__deku_input_bits: &bitvec::slice::BitSlice<u8, bitvec::order::Msb0>, kind: backhand::kind::Kind) -> core::result::Result<(&bitvec::slice::BitSlice<u8, bitvec::order::Msb0>, Self), deku::error::DekuError>
-pub fn backhand::Fragment::write(&self, __deku_output: &mut bitvec::vec::BitVec<u8, bitvec::order::Msb0>, kind: backhand::kind::Kind) -> core::result::Result<(), deku::error::DekuError>
-pub fn backhand::Id::read(__deku_input_bits: &bitvec::slice::BitSlice<u8, bitvec::order::Msb0>, kind: backhand::kind::Kind) -> core::result::Result<(&bitvec::slice::BitSlice<u8, bitvec::order::Msb0>, Self), deku::error::DekuError>
-pub fn backhand::Id::write(&self, __deku_output: &mut bitvec::vec::BitVec<u8, bitvec::order::Msb0>, kind: backhand::kind::Kind) -> core::result::Result<(), deku::error::DekuError>
-impl deku::DekuRead<'_, (u64, u32, u16, backhand::kind::Kind)> for backhand::Inode
-pub fn backhand::Inode::read(__deku_input_bits: &bitvec::slice::BitSlice<u8, bitvec::order::Msb0>, (bytes_used, block_size, block_log, kind): (u64, u32, u16, backhand::kind::Kind)) -> core::result::Result<(&bitvec::slice::BitSlice<u8, bitvec::order::Msb0>, Self), deku::error::DekuError>
-impl deku::DekuWrite<(u64, u32, u16, backhand::kind::Kind)> for backhand::Inode
-pub fn backhand::Inode::write(&self, __deku_output: &mut bitvec::vec::BitVec<u8, bitvec::order::Msb0>, (bytes_used, block_size, block_log, kind): (u64, u32, u16, backhand::kind::Kind)) -> core::result::Result<(), deku::error::DekuError>
-pub backhand::Node::path: std::path::PathBuf
-pub fn backhand::Node::new(path: std::path::PathBuf, inner: backhand::InnerNode<T>) -> Self
-impl<T: core::cmp::Eq> core::cmp::Eq for backhand::Node<T>
-impl<T: core::cmp::PartialEq> core::cmp::PartialEq<backhand::Node<T>> for backhand::Node<T>
-pub fn backhand::Node::eq(&self, other: &backhand::Node<T>) -> bool
-impl<T> core::marker::StructuralEq for backhand::Node<T>
-impl<T> core::marker::StructuralPartialEq for backhand::Node<T>
-pub backhand::Squashfs::data_and_fragments: alloc::vec::Vec<u8>
-impl<R: backhand::ReadSeek> backhand::Squashfs<R>
-impl<R: backhand::ReadSeek> backhand::Squashfs<R>
-pub fn backhand::Squashfs::from_reader(reader: R) -> core::result::Result<backhand::Squashfs<R>, backhand::BackhandError>
-pub fn backhand::Squashfs::into_filesystem_reader(self) -> core::result::Result<backhand::FilesystemReader<R>, backhand::BackhandError>
-impl<R: backhand::ReadSeek> backhand::Squashfs<SquashfsReaderWithOffset<R>>
-pub fn backhand::Squashfs::from_reader_with_offset(reader: R, offset: u64) -> core::result::Result<backhand::Squashfs<SquashfsReaderWithOffset<R>>, backhand::BackhandError>
-pub fn backhand::Squashfs::from_reader_with_offset_and_kind(reader: R, offset: u64, kind: backhand::kind::Kind) -> core::result::Result<backhand::Squashfs<SquashfsReaderWithOffset<R>>, backhand::BackhandError>
-pub backhand::SquashfsBlockDevice::header: backhand::NodeHeader
-pub backhand::SquashfsCharacterDevice::header: backhand::NodeHeader
-pub backhand::SquashfsDir::header: backhand::NodeHeader
-pub backhand::SquashfsFileReader::header: backhand::NodeHeader
-pub struct backhand::SquashfsFileWriter<'a, R: backhand::ReadSeek>
-pub backhand::SquashfsFileWriter::header: backhand::NodeHeader
-pub backhand::SquashfsFileWriter::reader: backhand::SquashfsFileSource<'a, R>
-impl<'a, R: backhand::ReadSeek> core::fmt::Debug for backhand::SquashfsFileWriter<'a, R>
-pub backhand::SquashfsSymlink::header: backhand::NodeHeader
-pub const backhand::SuperBlock::NOT_SET: u64
-pub fn backhand::SuperBlock::read(__deku_input_bits: &bitvec::slice::BitSlice<u8, bitvec::order::Msb0>, kind: backhand::kind::Kind) -> core::result::Result<(&bitvec::slice::BitSlice<u8, bitvec::order::Msb0>, Self), deku::error::DekuError>
-pub fn backhand::SuperBlock::write(&self, __deku_output: &mut bitvec::vec::BitVec<u8, bitvec::order::Msb0>, kind: backhand::kind::Kind) -> core::result::Result<(), deku::error::DekuError>
-pub trait backhand::ReadSeek: std::io::Read + std::io::Seek
-impl<T: std::io::Read + std::io::Seek> backhand::ReadSeek for T
Changed items in the public API
===============================
-pub struct backhand::Export(pub u64)
+pub struct backhand::Export
-pub struct backhand::FilesystemReader<R: backhand::ReadSeek>
+pub struct backhand::FilesystemReader
-pub struct backhand::FilesystemReaderFile<'a, R: backhand::ReadSeek>
+pub struct backhand::FilesystemReaderFile<'a>
-pub struct backhand::FilesystemWriter<'a, R: backhand::ReadSeek>
+pub struct backhand::FilesystemWriter<'a>
-pub struct backhand::Id(pub u32)
+pub struct backhand::Id
-pub struct backhand::Squashfs<R: backhand::ReadSeek>
+pub struct backhand::Squashfs
Added items to the public API
=============================
+pub struct backhand::compression::DefaultCompressor
+impl backhand::compression::CompressionAction for backhand::compression::DefaultCompressor
+impl backhand::compression::CompressionAction for backhand::compression::DefaultCompressor
+pub fn backhand::compression::DefaultCompressor::compress(&self, bytes: &[u8], fc: backhand::FilesystemCompressor, block_size: u32) -> core::result::Result<alloc::vec::Vec<u8>, backhand::BackhandError>
+pub fn backhand::compression::DefaultCompressor::decompress(&self, bytes: &[u8], out: &mut alloc::vec::Vec<u8>, compressor: backhand::compression::Compressor) -> core::result::Result<(), backhand::BackhandError>
+impl core::clone::Clone for backhand::compression::DefaultCompressor
+pub fn backhand::compression::DefaultCompressor::clone(&self) -> backhand::compression::DefaultCompressor
+impl core::marker::Copy for backhand::compression::DefaultCompressor
+pub trait backhand::compression::CompressionAction
+pub fn backhand::compression::CompressionAction::compress(&self, bytes: &[u8], fc: backhand::FilesystemCompressor, block_size: u32) -> core::result::Result<alloc::vec::Vec<u8>, backhand::BackhandError>
+pub fn backhand::compression::CompressionAction::compress(&self, bytes: &[u8], fc: backhand::FilesystemCompressor, block_size: u32) -> core::result::Result<alloc::vec::Vec<u8>, backhand::BackhandError>
+pub fn backhand::compression::CompressionAction::decompress(&self, bytes: &[u8], out: &mut alloc::vec::Vec<u8>, compressor: backhand::compression::Compressor) -> core::result::Result<(), backhand::BackhandError>
+pub fn backhand::compression::CompressionAction::decompress(&self, bytes: &[u8], out: &mut alloc::vec::Vec<u8>, compressor: backhand::compression::Compressor) -> core::result::Result<(), backhand::BackhandError>
+pub fn backhand::kind::Kind::from_const(inner: InnerKind<dyn backhand::compression::CompressionAction>) -> core::result::Result<backhand::kind::Kind, alloc::string::String>
+pub fn backhand::kind::Kind::from_kind(kind: &backhand::kind::Kind) -> backhand::kind::Kind
+pub fn backhand::kind::Kind::from_target(s: &str) -> core::result::Result<backhand::kind::Kind, alloc::string::String>
+pub fn backhand::kind::Kind::new<C: backhand::compression::CompressionAction>(compressor: &'static C) -> Self
+pub fn backhand::kind::Kind::new_with_const<C: backhand::compression::CompressionAction>(compressor: &'static C, c: InnerKind<dyn backhand::compression::CompressionAction>) -> Self
+pub backhand::BackhandError::DuplicatedFileName
+pub backhand::BackhandError::InvalidFilePath
+pub backhand::BackhandError::UndefineFileName
+pub enum backhand::SquashfsFileWriter<'a>
+pub backhand::SquashfsFileWriter::Consumed(usize, Added)
+pub backhand::SquashfsFileWriter::SquashfsFile(backhand::FilesystemReaderFile<'a>)
+pub backhand::SquashfsFileWriter::UserDefined(core::cell::RefCell<alloc::boxed::Box<(dyn std::io::Read + 'a)>>)
+impl<'a> core::fmt::Debug for backhand::SquashfsFileWriter<'a>
+pub backhand::Export::num: u64
+impl deku::DekuRead<'_, deku::ctx::Endian> for backhand::Export
+pub fn backhand::Export::read(__deku_input_bits: &bitvec::slice::BitSlice<u8, bitvec::order::Msb0>, type_endian: deku::ctx::Endian) -> core::result::Result<(&bitvec::slice::BitSlice<u8, bitvec::order::Msb0>, Self), deku::error::DekuError>
+impl deku::DekuWrite<deku::ctx::Endian> for backhand::Export
+pub fn backhand::Export::write(&self, __deku_output: &mut bitvec::vec::BitVec<u8, bitvec::order::Msb0>, type_endian: deku::ctx::Endian) -> core::result::Result<(), deku::error::DekuError>
+pub fn backhand::FilesystemCompressor::options(&mut self, options: backhand::compression::CompressionOptions) -> core::result::Result<(), backhand::BackhandError>
+pub backhand::FilesystemReader::root: Nodes<backhand::SquashfsFileReader>
+impl backhand::FilesystemReader
+pub fn backhand::FilesystemReader::alloc_read_buffers(&self) -> (alloc::vec::Vec<u8>, alloc::vec::Vec<u8>)
+pub fn backhand::FilesystemReader::file<'a>(&'a self, basic_file: &'a backhand::BasicFile) -> backhand::FilesystemReaderFile<'_>
+pub fn backhand::FilesystemReader::files(&self) -> impl core::iter::traits::iterator::Iterator<Item = &backhand::Node<backhand::SquashfsFileReader>>
+pub fn backhand::FilesystemReader::from_reader<R: backhand::BufReadSeek + 'static>(reader: R) -> core::result::Result<Self, backhand::BackhandError>
+pub fn backhand::FilesystemReader::from_reader_with_offset<R: backhand::BufReadSeek + 'static>(reader: R, offset: u64) -> core::result::Result<Self, backhand::BackhandError>
+pub fn backhand::FilesystemReader::from_reader_with_offset_and_kind<R: backhand::BufReadSeek + 'static>(reader: R, offset: u64, kind: backhand::kind::Kind) -> core::result::Result<Self, backhand::BackhandError>
+impl<'a> backhand::FilesystemReaderFile<'a>
+pub fn backhand::FilesystemReaderFile::new(system: &'a backhand::FilesystemReader, basic: &'a backhand::BasicFile) -> Self
+pub fn backhand::FilesystemReaderFile::reader(&self, buf_read: &'a mut alloc::vec::Vec<u8>, buf_decompress: &'a mut alloc::vec::Vec<u8>) -> backhand::SquashfsReadFile<'_>
+impl<'a> core::clone::Clone for backhand::FilesystemReaderFile<'a>
+impl<'a> core::iter::traits::collect::IntoIterator for backhand::FilesystemReaderFile<'a>
+impl<'a> core::marker::Copy for backhand::FilesystemReaderFile<'a>
+impl<'a> backhand::FilesystemWriter<'a>
+pub fn backhand::FilesystemWriter::from_fs_reader(reader: &'a backhand::FilesystemReader) -> core::result::Result<Self, backhand::BackhandError>
+pub fn backhand::FilesystemWriter::mut_file<S: core::convert::AsRef<std::path::Path>>(&mut self, find_path: S) -> core::option::Option<&mut backhand::SquashfsFileWriter<'a>>
+pub fn backhand::FilesystemWriter::push_block_device<P: core::convert::AsRef<std::path::Path>>(&mut self, device_number: u32, path: P, header: backhand::NodeHeader) -> core::result::Result<(), backhand::BackhandError>
+pub fn backhand::FilesystemWriter::push_char_device<P: core::convert::AsRef<std::path::Path>>(&mut self, device_number: u32, path: P, header: backhand::NodeHeader) -> core::result::Result<(), backhand::BackhandError>
+pub fn backhand::FilesystemWriter::push_dir<P: core::convert::AsRef<std::path::Path>>(&mut self, path: P, header: backhand::NodeHeader) -> core::result::Result<(), backhand::BackhandError>
+pub fn backhand::FilesystemWriter::push_dir_all<P: core::convert::AsRef<std::path::Path>>(&mut self, path: P, header: backhand::NodeHeader) -> core::result::Result<(), backhand::BackhandError>
+pub fn backhand::FilesystemWriter::push_file<P: core::convert::AsRef<std::path::Path>>(&mut self, reader: impl std::io::Read + 'a, path: P, header: backhand::NodeHeader) -> core::result::Result<(), backhand::BackhandError>
+pub fn backhand::FilesystemWriter::push_symlink<P: core::convert::AsRef<std::path::Path>, S: core::convert::Into<std::path::PathBuf>>(&mut self, link: S, path: P, header: backhand::NodeHeader) -> core::result::Result<(), backhand::BackhandError>
+pub fn backhand::FilesystemWriter::replace_file<S: core::convert::AsRef<std::path::Path>>(&mut self, find_path: S, reader: impl std::io::Read + 'a) -> core::result::Result<(), backhand::BackhandError>
+pub fn backhand::FilesystemWriter::set_no_padding(&mut self)
+pub fn backhand::FilesystemWriter::write<W: std::io::Write + std::io::Seek>(&mut self, w: &mut W) -> core::result::Result<(backhand::SuperBlock, u64), backhand::BackhandError>
+pub fn backhand::FilesystemWriter::write_with_offset<W: std::io::Write + std::io::Seek>(&mut self, w: &mut W, offset: u64) -> core::result::Result<(backhand::SuperBlock, u64), backhand::BackhandError>
+impl<'a> core::default::Default for backhand::FilesystemWriter<'a>
+impl<'a> core::fmt::Debug for backhand::FilesystemWriter<'a>
+impl backhand::Fragment
+pub fn backhand::Fragment::new(start: u64, size: backhand::DataSize, unused: u32) -> Self
+impl deku::DekuRead<'_, deku::ctx::Endian> for backhand::Fragment
+pub fn backhand::Fragment::read(__deku_input_bits: &bitvec::slice::BitSlice<u8, bitvec::order::Msb0>, type_endian: deku::ctx::Endian) -> core::result::Result<(&bitvec::slice::BitSlice<u8, bitvec::order::Msb0>, Self), deku::error::DekuError>
+impl deku::DekuWrite<deku::ctx::Endian> for backhand::Fragment
+pub fn backhand::Fragment::write(&self, __deku_output: &mut bitvec::vec::BitVec<u8, bitvec::order::Msb0>, type_endian: deku::ctx::Endian) -> core::result::Result<(), deku::error::DekuError>
+pub backhand::Id::num: u32
+pub const backhand::Id::SIZE: usize
+pub fn backhand::Id::new(num: u32) -> backhand::Id
+impl deku::DekuRead<'_, deku::ctx::Endian> for backhand::Id
+pub fn backhand::Id::read(__deku_input_bits: &bitvec::slice::BitSlice<u8, bitvec::order::Msb0>, type_endian: deku::ctx::Endian) -> core::result::Result<(&bitvec::slice::BitSlice<u8, bitvec::order::Msb0>, Self), deku::error::DekuError>
+impl deku::DekuWrite<deku::ctx::Endian> for backhand::Id
+pub fn backhand::Id::write(&self, __deku_output: &mut bitvec::vec::BitVec<u8, bitvec::order::Msb0>, type_endian: deku::ctx::Endian) -> core::result::Result<(), deku::error::DekuError>
+impl backhand::Inode
+pub fn backhand::Inode::new(id: InodeId, header: InodeHeader, inner: InodeInner) -> Self
+impl deku::DekuRead<'_, (u64, u32, u16, deku::ctx::Endian)> for backhand::Inode
+pub fn backhand::Inode::read(__deku_input_bits: &bitvec::slice::BitSlice<u8, bitvec::order::Msb0>, (bytes_used, block_size, block_log, type_endian): (u64, u32, u16, deku::ctx::Endian)) -> core::result::Result<(&bitvec::slice::BitSlice<u8, bitvec::order::Msb0>, Self), deku::error::DekuError>
+impl deku::DekuWrite<(u64, u32, u16, deku::ctx::Endian)> for backhand::Inode
+pub fn backhand::Inode::write(&self, __deku_output: &mut bitvec::vec::BitVec<u8, bitvec::order::Msb0>, (bytes_used, block_size, block_log, type_endian): (u64, u32, u16, deku::ctx::Endian)) -> core::result::Result<(), deku::error::DekuError>
+pub backhand::Node::fullpath: std::path::PathBuf
+pub backhand::Node::header: backhand::NodeHeader
+pub fn backhand::Node::new_root(header: backhand::NodeHeader) -> Self
+impl<T> core::cmp::Eq for backhand::Node<T>
+impl<T> core::cmp::Ord for backhand::Node<T>
+pub fn backhand::Node::cmp(&self, other: &Self) -> core::cmp::Ordering
+impl<T> core::cmp::PartialEq<backhand::Node<T>> for backhand::Node<T>
+pub fn backhand::Node::eq(&self, other: &Self) -> bool
+impl<T> core::cmp::PartialOrd<backhand::Node<T>> for backhand::Node<T>
+pub fn backhand::Node::partial_cmp(&self, other: &Self) -> core::option::Option<core::cmp::Ordering>
+impl<T: core::clone::Clone> core::clone::Clone for backhand::Node<T>
+pub fn backhand::Node::clone(&self) -> backhand::Node<T>
+impl backhand::Squashfs
+pub fn backhand::Squashfs::from_reader(reader: impl backhand::BufReadSeek + 'static) -> core::result::Result<backhand::Squashfs, backhand::BackhandError>
+pub fn backhand::Squashfs::from_reader_with_offset(reader: impl backhand::BufReadSeek + 'static, offset: u64) -> core::result::Result<backhand::Squashfs, backhand::BackhandError>
+pub fn backhand::Squashfs::from_reader_with_offset_and_kind(reader: impl backhand::BufReadSeek + 'static, offset: u64, kind: backhand::kind::Kind) -> core::result::Result<backhand::Squashfs, backhand::BackhandError>
+pub fn backhand::Squashfs::into_filesystem_reader(self) -> core::result::Result<backhand::FilesystemReader, backhand::BackhandError>
+pub fn backhand::Squashfs::superblock_and_compression_options(reader: &mut alloc::boxed::Box<dyn backhand::BufReadSeek>, kind: &backhand::kind::Kind) -> core::result::Result<(backhand::SuperBlock, core::option::Option<backhand::compression::CompressionOptions>), backhand::BackhandError>
+impl core::marker::Copy for backhand::SquashfsBlockDevice
+impl core::marker::Copy for backhand::SquashfsCharacterDevice
+impl core::default::Default for backhand::SquashfsDir
+pub fn backhand::SquashfsDir::default() -> backhand::SquashfsDir
+impl core::marker::Copy for backhand::SquashfsDir
+pub struct backhand::SquashfsReadFile<'a>
+impl<'a> std::io::Read for backhand::SquashfsReadFile<'a>
+pub fn backhand::SquashfsReadFile::read(&mut self, buf: &mut [u8]) -> std::io::error::Result<usize>
+impl backhand::SuperBlock
+impl deku::DekuRead<'_, ([u8; 4], u16, u16, deku::ctx::Endian)> for backhand::SuperBlock
+pub fn backhand::SuperBlock::read(__deku_input_bits: &bitvec::slice::BitSlice<u8, bitvec::order::Msb0>, (ctx_magic, ctx_version_major, ctx_version_minor, ctx_type_endian): ([u8; 4], u16, u16, deku::ctx::Endian)) -> core::result::Result<(&bitvec::slice::BitSlice<u8, bitvec::order::Msb0>, Self), deku::error::DekuError>
+impl deku::DekuWrite<([u8; 4], u16, u16, deku::ctx::Endian)> for backhand::SuperBlock
+pub fn backhand::SuperBlock::write(&self, __deku_output: &mut bitvec::vec::BitVec<u8, bitvec::order::Msb0>, (ctx_magic, ctx_version_major, ctx_version_minor, ctx_type_endian): ([u8; 4], u16, u16, deku::ctx::Endian)) -> core::result::Result<(), deku::error::DekuError>
+pub trait backhand::BufReadSeek: std::io::BufRead + std::io::Seek
+impl<T: std::io::BufRead + std::io::Seek> backhand::BufReadSeek for T
- Added
--kind
for custom squashfs type image extraction
-k, --kind <KIND> Kind(type of image) to parse [default: le_v4_0] [possible values: be_v4_0, le_v4_0, amv_be_v4_0]
- Added
--completions
for the generation of shell completions scripts
See #145 for more details.
These are benchmarked against the SquashFS image from TP-Link AXE5400 Mesh Wi-Fi 6E Range Extender
.
For single threaded mode squashfs-tools/unsquashfs-v4.6.1
, testing on my machine lets me know that
our backhand/unsquashfs
is around the same speed performance with a single thread.
Only testing single threaded mode, peak heap memory consumption for squashfs-tools/unsquashfs-v4.6.1
is 74.8MB, while our backhand/unsquashfs
only uses 18.1MB.
- Support for Read/Write of non-standard custom squashfs images:
LE_V4_0
: (linux kernel) Little-Endian default official v4.0BE_V4_0
: Big-Endian v4.0AVM_BE_V4_0
: AVM Fritz!OS firmware support.
FilesystemWriter
: Builder pattern used when mutating an image. This includes multiple functions for the public API. Supporting both raw images and modification made to images that already exist.FilesytemCompressor
:.compressor
is nowFilesystemCompressor
, which holds the Id as well as options stored in the image as well as extra options only used when compressing when creating a new image.- Add error
InvalidCompressionOption
- Change default XZ compression level to 6
- Support custom XZ filters for
FilesystemWriter
- Return
(Superblock, bytes_written)
forFilesystemWriter::write()
- Update deku to 0.16.0
add
: now reads file details to derive the details when the file is added the imageadd
:--mtime
,--uid
,--gid
and--permission
to override file details derived from fileunsquashfs
: now correctly extracts ownership and permission details
ID
now supports multiple IDs for GUI and UID in the tableid_table
is now properly a u64 pointer- Data is now not copied when during the use of a
FilesystemWriter
you decide to change the compression used. Thanks @rbran
- Renamed
SquashfsError
toBackhandError
- Zstd compression support
FilesystemWriter
Debug impl now worksFilesystemReader::from_reader_with_offset(..)
now properly respects given offsetsFilesystemWriter::write_with_offset(..)
now properly respects given offsets
- Fuzz testing with
cargo fuzz
. Mostly fuzz bytes as bytes/image input into this library. unsquashfs
: Add-o, --out <OUT>
flag for output squashfs image destinationreplace
: Add binary to replace file in squashfs filesystems- Add support for Lzo compression, and feature
lzo
- Fixed many issues found with fuzz testing related to legal images. Checks are now added at every stop possible to prevent many soundness issues.
- Fixed
Compressor
id values for Lzo and Lzma
- Pass internal raw data by reference, improving
only_read
benchmarks by ~9%. - Invalid
Superblock.block_size
is now checked against MiB(1) instead of MB(1)
- Fix
unsquashfs
extracting wrong file data
FilesystemWriter::push_file(..)
correctly enters file into filesystem
- Remove Result return type from
FilesystemWriter::{push_file(..), push_dir(..), push_symlink(..), push_char_device(..) and push_block_devivce(..)
. - Remove unused errors:
FieldNotInitialized
andOsStringToStr
.
- Fix
src/lib.rs
version for docs.rs
- unsquashfs: Add
--stat
,--force
,--info
flags. - unsquashfs: Add support for Char and Block device file creation when superuser.
- features:
xz
andgzip
. By default both are enabled, but conditionally you may compile only one type of decompressor. SquashfsError::Unreachable
,SquashfsError::UnexpectedInode
,SquashfsError::UnsupportedInode
. These are all returned by the public API of filesystem and more panics were removed.
inode_count
is fixed, previously was +1 the actual inode count.
-
The Public API of the library has been condensed, lmk if you have lost access to a required struct/field/enum.
-
Add
FilesystemReader
andFilesystemWriter
for lazy-reading the files only when required. This significantly speeds up the initial read of the filesystem and splits the reading of the filesystem and the writing of the filesystem. The following diff will cover most common API upgrades fromv0.7.0
-let squashfs = Squashfs::from_reader(file).unwrap(); -let mut filesystem = squashfs.into_filesystem().unwrap(); +let filesystem = FilesystemReader::from_reader(file).unwrap(); +let mut filesystem = FilesystemWriter::from_fs_reader(&filesystem).unwrap();
-let filesystem = Filesystem::from_reader(file).unwrap(); +let filesystem = FilesystemReader::from_reader(file).unwrap(); +let mut filesystem = FilesystemWriter::from_fs_reader(&filesystem).unwrap();
-FilesystemHeader +NodeHeader
This releases allows massive performance improvements by only reading files from disk when required and reducing the amount of memory required to read and write an image.
Thanks @rbran for the incredible work on the performance of the library.
Before:
read/write/netgear_ax6100v2
time: [2.3553 s 2.3667 s 2.3775 s]
read/write/tplink_ax1800
time: [17.996 s 18.068 s 18.140 s]
After:
write_read/netgear_ax6100v2
time: [1.2291 s 1.2363 s 1.2433 s]
write_read/tplink_ax1800
time: [6.7506 s 6.8287 s 6.9349 s]
only_read/netgear_ax6100v2
time: [5.1153 ms 5.1234 ms 5.1305 ms]
only_read/tplink_ax1800
time: [22.383 ms 22.398 ms 22.415 ms]
- Use
block_size
as XZ defaultdict_size
when compressing data - Add
Filesystem::push_symlink(..)
- Add
Filesystem::push_dir(..)
- Add
Filesystem::push_char_device(..)
- Add
Filesystem::push_block_device(..)
- Correctly choose between storing uncompressed and compressed data on which takes the least space
- Improve
unsquashfs
andadd
cli args to matchsquashfs-tools/unsquashfs
cli Filesystem::push_file(..)
now takes for bytes anything that isinto Read
instead ofinto Vec<u8>
Node::Path
renamed toNode::Dir
SquashfsPath
renamed toSquashfsDir
Filesystem::from_reader(..)
,R
now takesRead + Seek
instead our ownReadSeek
Filesystem::from_reader_with_offset(..)
,R
now takesRead + Seek
instead our ownReadSeek
Filesystem::push_symlink(..)
now only needspath
andlink
- Fix bug in our filesystem tree causing directory header information (gui, uid, permissions)
to not be saved in resulting filesystem when calling
Filesystem::to_bytes(..)
. - Rework
filesystem::Node
to be a struct containing the path andInnerNode
. This cleans up the inner implementation of the file system tree. - Make more types public that are useful for Squashfs detailed introspection
- Improve documentation
- Fix warning when compression options isn't standard size
- In
from_reader(..)
, show info about flags used - Add
Filesystem::from_reader(..)
andFilesystem::from_reader_with_offset(..)
which callsSquashfs::from_reader(..)
andSquashfs::from_reader_with_offset(..)
andSquashfs::into_filesystem(..)
. - 5% Performance increases due to using
Vec::with_capacity(..)
forfragment_bytes
- Add Block and Char Device support for Reading and Writing
- Fix error with
inode_offset
mis-calculation - Fix tail-end fragment support for reading image
- Fix
unsquashfs
file path extraction
- Add
mod_time
fromSquashfs
toFilesystem
used in creation of new image withto_bytes(..)
- Restrict public API
- Improve docs
- Add
Filesystem::push_file(..)
for adding a file, as well as the dirs for the path - Add
Filesystem::mut_file(..)
for mutating a file at a path already in the filesystem
- Fix Cargo.toml issues
- Add
block_size
andblock_log
to Filesystem. Automatically taken fromSquashfs
when usinginto_filesystem()
- Add support for data fragments for
filesystem::to_bytes()
DirEntry
usesInodeId
instead ofu8
- Initial Release