Bugfix (v0.1.2)

This commit is contained in:
Philipp Schuster 2021-10-04 12:25:53 +02:00
parent 48bfc67213
commit 47bdfd1f85
5 changed files with 59 additions and 10 deletions

View File

@ -7,7 +7,7 @@ as GNU Longname. The maximum supported file name length is 100 characters includ
The maximum supported file size is 8GiB. Also, directories are not supported yet but only flat
collections of files.
"""
version = "0.1.1"
version = "0.1.2"
edition = "2018"
keywords = ["tar", "tarball", "archive"]
categories = ["data-structures", "no-std", "parser-implementations"]

View File

@ -26,11 +26,15 @@ fn main() {
std::env::set_var("RUST_LOG", "trace");
env_logger::init();
// also works in no_std environment
// also works in no_std environment (except the println!, of course)
let archive = include_bytes!("../tests/gnu_tar_default.tar");
let archive = TarArchive::new(archive);
// Vec needs an allocator of course, but the library itself doesn't need one
let entries = archive.entries().collect::<Vec<_>>();
println!("{:#?}", entries);
println!("content of last file:");
let last_file_content = unsafe { core::str::from_utf8_unchecked(entries[2].data()) };
println!("{:#?}", last_file_content);
}
```

View File

@ -28,9 +28,13 @@ fn main() {
std::env::set_var("RUST_LOG", "trace");
env_logger::init();
// also works in no_std environment
// also works in no_std environment (except the println!, of course)
let archive = include_bytes!("../tests/gnu_tar_default.tar");
let archive = TarArchive::new(archive);
// Vec needs an allocator of course, but the library itself doesn't need one
let entries = archive.entries().collect::<Vec<_>>();
println!("{:#?}", entries);
println!("content of last file:");
let last_file_content = unsafe { core::str::from_utf8_unchecked(entries[2].data()) };
println!("{:#?}", last_file_content);
}

View File

@ -162,16 +162,20 @@ impl<'a> Iterator for ArchiveIterator<'a> {
}
// fetch data of file from next block(s)
let block_count = hdr.payload_block_count();
let i_begin = self.block_index * BLOCKSIZE;
let i_end = i_begin + block_count * BLOCKSIZE;
debug_assert!(i_end <= self.archive.data.len(), "index ouf of range!");
// +1: hdr itself + data blocks
self.block_index += block_count + 1;
let data_block_count = hdr.payload_block_count();
// +1: skip hdr block itself and start at data!
// i_begin is the byte begin index of this file in the array of the whole archive
let i_begin = (self.block_index + 1) * BLOCKSIZE;
// i_end is the exclusive byte end index of the data of the current file
let i_end = i_begin + data_block_count * BLOCKSIZE;
let file_block_bytes = &self.archive.data[i_begin..i_end];
// because each block is 512 bytes long, the file is not necessarily a multiple of 512 bytes
let file_bytes = &file_block_bytes[0..hdr.size.val()];
// in next iteration: start at next Archive entry header
// +1 for current hdr block itself + all data blocks
self.block_index += data_block_count + 1;
Some(ArchiveEntry::new(
ArrayString::from_str(hdr.name.as_string().as_str()).unwrap(),
file_bytes,
@ -182,6 +186,7 @@ impl<'a> Iterator for ArchiveIterator<'a> {
#[cfg(test)]
mod tests {
use super::*;
use core::str;
use std::vec::Vec;
#[test]
@ -230,11 +235,26 @@ mod tests {
assert_eq!(entries[0].filename().as_str(), "bye_world_513b.txt");
assert_eq!(entries[0].size(), 513);
assert_eq!(entries[0].data().len(), 513);
assert_eq!(
unsafe { str::from_utf8_unchecked(entries[0].data) },
include_str!("../tests/bye_world_513b.txt")
);
assert_eq!(entries[1].filename().as_str(), "hello_world_513b.txt");
assert_eq!(entries[1].size(), 513);
assert_eq!(entries[1].data().len(), 513);
assert_eq!(
unsafe { str::from_utf8_unchecked(entries[1].data) },
include_str!("../tests/hello_world_513b.txt")
);
assert_eq!(entries[2].filename().as_str(), "hello_world.txt");
assert_eq!(entries[2].size(), 12);
assert_eq!(entries[2].data().len(), 12);
assert_eq!(
unsafe { str::from_utf8_unchecked(entries[2].data) },
"Hello World\n",
"file content must match"
);
}
}

View File

@ -38,6 +38,27 @@ SOFTWARE.
//! GNU Extensions such as sparse files, incremental archives, and long filename extension are not supported yet.
//! [This link](https://www.gnu.org/software/tar/manual/html_section/Formats.html) gives a good overview over possible
//! archive formats and their limitations.
//!
//! # Example
//! ```rust
//! use tar_no_std::TarArchive;
//!
//! fn main() {
//! // log: not mandatory
//! std::env::set_var("RUST_LOG", "trace");
//! env_logger::init();
//!
//! // also works in no_std environment (except the println!, of course)
//! let archive = include_bytes!("../tests/gnu_tar_default.tar");
//! let archive = TarArchive::new(archive);
//! // Vec needs an allocator of course, but the library itself doesn't need one
//! let entries = archive.entries().collect::<Vec<_>>();
//! println!("{:#?}", entries);
//! println!("content of last file:");
//! let last_file_content = unsafe { core::str::from_utf8_unchecked(entries[2].data()) };
//! println!("{:#?}", last_file_content);
//! }
//! ```
#![cfg_attr(not(test), no_std)]
#![deny(rustdoc::all)]