Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 7 additions & 6 deletions src/archive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -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()))
Expand Down Expand Up @@ -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",
Expand Down Expand Up @@ -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)?;
}
Expand Down
16 changes: 9 additions & 7 deletions src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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,
Expand All @@ -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();
Expand Down Expand Up @@ -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(())
Expand Down
28 changes: 18 additions & 10 deletions src/header.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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
Expand Down Expand Up @@ -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 ";
Expand All @@ -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";
Expand All @@ -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
}
Expand Down Expand Up @@ -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
}

Expand Down Expand Up @@ -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) }
}

Expand Down