diff --git a/src/archive.rs b/src/archive.rs index 924e54a2..77413e8d 100644 --- a/src/archive.rs +++ b/src/archive.rs @@ -9,6 +9,7 @@ use std::path::Path; use crate::entry::{EntryFields, EntryIo}; use crate::error::TarError; +use crate::header::BLOCK_SIZE; use crate::other; use crate::pax::*; use crate::{Entry, GnuExtSparseHeader, GnuSparseHeader, Header}; @@ -302,14 +303,14 @@ impl<'a> EntriesFields<'a> { // Otherwise, check if we are ignoring zeros and continue, or break as if this is the // end of the archive. if !header.as_bytes().iter().all(|i| *i == 0) { - self.next += 512; + self.next += BLOCK_SIZE; break; } if !self.archive.inner.ignore_zeros { return Ok(None); } - self.next += 512; + self.next += BLOCK_SIZE; header_pos = self.next; } @@ -364,11 +365,11 @@ impl<'a> EntriesFields<'a> { // Store where the next entry is, rounding up by 512 bytes (the size of // a header); let size = size - .checked_add(511) + .checked_add(BLOCK_SIZE - 1) .ok_or_else(|| other("size overflow"))?; self.next = self .next - .checked_add(size & !(512 - 1)) + .checked_add(size & !(BLOCK_SIZE - 1)) .ok_or_else(|| other("size overflow"))?; Ok(Some(ret.into_entry())) @@ -483,7 +484,7 @@ impl<'a> EntriesFields<'a> { } let off = block.offset()?; let len = block.length()?; - if len != 0 && (size - remaining) % 512 != 0 { + if len != 0 && (size - remaining) % BLOCK_SIZE != 0 { return Err(other( "previous block in sparse file was not \ aligned to 512-byte boundary", @@ -520,7 +521,7 @@ impl<'a> EntriesFields<'a> { return Err(other("failed to read extension")); } - self.next += 512; + self.next += BLOCK_SIZE; for block in ext.sparse.iter() { add_block(block)?; } diff --git a/src/builder.rs b/src/builder.rs index 569b14e6..54413605 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -4,6 +4,7 @@ use std::io::prelude::*; use std::path::Path; use std::str; +use crate::header::BLOCK_SIZE; use crate::header::GNU_SPARSE_HEADERS_COUNT; use crate::header::{path2bytes, HeaderMode}; use crate::GnuExtSparseHeader; @@ -518,7 +519,7 @@ impl EntryWriter<'_> { prepare_header_path(obj.as_write(), header, path)?; // Reserve space for header, will be overwritten once data is written. - obj.write_all([0u8; 512].as_ref())?; + obj.write_all([0u8; BLOCK_SIZE as usize].as_ref())?; Ok(EntryWriter { obj, @@ -544,13 +545,14 @@ impl EntryWriter<'_> { fn do_finish(&mut self) -> io::Result<()> { // Pad with zeros if necessary. - let buf = [0u8; 512]; - let remaining = u64::wrapping_sub(512, self.written) % 512; + let buf = [0u8; BLOCK_SIZE as usize]; + let remaining = BLOCK_SIZE.wrapping_sub(self.written) % BLOCK_SIZE; self.obj.write_all(&buf[..remaining as usize])?; let written = (self.written + remaining) as i64; // Seek back to the header position. - self.obj.seek(io::SeekFrom::Current(-written - 512))?; + self.obj + .seek(io::SeekFrom::Current(-written - BLOCK_SIZE as i64))?; self.header.set_size(self.written); self.header.set_cksum(); @@ -589,9 +591,9 @@ fn append(mut dst: &mut dyn Write, header: &Header, mut data: &mut dyn Read) -> } fn pad_zeroes(dst: &mut dyn Write, len: u64) -> io::Result<()> { - let buf = [0; 512]; - let remaining = 512 - (len % 512); - if remaining < 512 { + let buf = [0; BLOCK_SIZE as usize]; + let remaining = BLOCK_SIZE - (len % BLOCK_SIZE); + if remaining < BLOCK_SIZE { dst.write_all(&buf[..remaining as usize])?; } Ok(()) diff --git a/src/header.rs b/src/header.rs index e0f561c8..0c577b9a 100644 --- a/src/header.rs +++ b/src/header.rs @@ -24,6 +24,8 @@ use crate::EntryType; #[cfg(any(unix, windows))] const DETERMINISTIC_TIMESTAMP: u64 = 1153704088; +pub(crate) const BLOCK_SIZE: u64 = 512; + pub(crate) const GNU_SPARSE_HEADERS_COUNT: usize = 4; pub(crate) const GNU_EXT_SPARSE_HEADERS_COUNT: usize = 21; @@ -32,7 +34,7 @@ pub(crate) const GNU_EXT_SPARSE_HEADERS_COUNT: usize = 21; #[repr(C)] #[allow(missing_docs)] pub struct Header { - bytes: [u8; 512], + bytes: [u8; BLOCK_SIZE as usize], } /// Declares the information that should be included when filling a Header @@ -151,7 +153,9 @@ impl Header { /// extensions such as long path names, long link names, and setting the /// atime/ctime metadata attributes of files. pub fn new_gnu() -> Header { - let mut header = Header { bytes: [0; 512] }; + let mut header = Header { + bytes: [0; BLOCK_SIZE as usize], + }; unsafe { let gnu = cast_mut::<_, GnuHeader>(&mut header); gnu.magic = *b"ustar "; @@ -169,7 +173,9 @@ impl Header { /// /// UStar is also the basis used for pax archives. pub fn new_ustar() -> Header { - let mut header = Header { bytes: [0; 512] }; + let mut header = Header { + bytes: [0; BLOCK_SIZE as usize], + }; unsafe { let gnu = cast_mut::<_, UstarHeader>(&mut header); gnu.magic = *b"ustar\0"; @@ -186,7 +192,9 @@ impl Header { /// format limits the path name limit and isn't able to contain extra /// metadata like atime/ctime. pub fn new_old() -> Header { - let mut header = Header { bytes: [0; 512] }; + let mut header = Header { + bytes: [0; BLOCK_SIZE as usize], + }; header.set_mtime(0); header } @@ -276,12 +284,12 @@ impl Header { } /// Returns a view into this header as a byte array. - pub fn as_bytes(&self) -> &[u8; 512] { + pub fn as_bytes(&self) -> &[u8; BLOCK_SIZE as usize] { &self.bytes } /// Returns a view into this header as a byte array. - pub fn as_mut_bytes(&mut self) -> &mut [u8; 512] { + pub fn as_mut_bytes(&mut self) -> &mut [u8; BLOCK_SIZE as usize] { &mut self.bytes } @@ -1406,14 +1414,14 @@ impl GnuExtSparseHeader { } /// Returns a view into this header as a byte array. - pub fn as_bytes(&self) -> &[u8; 512] { - debug_assert_eq!(mem::size_of_val(self), 512); + pub fn as_bytes(&self) -> &[u8; BLOCK_SIZE as usize] { + debug_assert_eq!(mem::size_of_val(self), BLOCK_SIZE as usize); unsafe { mem::transmute(self) } } /// Returns a view into this header as a byte array. - pub fn as_mut_bytes(&mut self) -> &mut [u8; 512] { - debug_assert_eq!(mem::size_of_val(self), 512); + pub fn as_mut_bytes(&mut self) -> &mut [u8; BLOCK_SIZE as usize] { + debug_assert_eq!(mem::size_of_val(self), BLOCK_SIZE as usize); unsafe { mem::transmute(self) } }