diff options
Diffstat (limited to 'vendor/tar/src')
-rw-r--r-- | vendor/tar/src/archive.rs | 23 | ||||
-rw-r--r-- | vendor/tar/src/pax.rs | 40 |
2 files changed, 51 insertions, 12 deletions
diff --git a/vendor/tar/src/archive.rs b/vendor/tar/src/archive.rs index c7a9d9803..760b2cb82 100644 --- a/vendor/tar/src/archive.rs +++ b/vendor/tar/src/archive.rs @@ -10,7 +10,7 @@ use std::path::Path; use crate::entry::{EntryFields, EntryIo}; use crate::error::TarError; use crate::other; -use crate::pax::pax_extensions_size; +use crate::pax::*; use crate::{Entry, GnuExtSparseHeader, GnuSparseHeader, Header}; /// A top-level representation of an archive file. @@ -275,7 +275,7 @@ impl<'a, R: Read> Iterator for Entries<'a, R> { impl<'a> EntriesFields<'a> { fn next_entry_raw( &mut self, - pax_size: Option<u64>, + pax_extensions: Option<&[u8]>, ) -> io::Result<Option<Entry<'a, io::Empty>>> { let mut header = Header::new_old(); let mut header_pos = self.next; @@ -315,6 +315,19 @@ impl<'a> EntriesFields<'a> { return Err(other("archive header checksum mismatch")); } + let mut pax_size: Option<u64> = None; + if let Some(pax_extensions_ref) = &pax_extensions { + pax_size = pax_extensions_value(pax_extensions_ref, PAX_SIZE); + + if let Some(pax_uid) = pax_extensions_value(pax_extensions_ref, PAX_UID) { + header.set_uid(pax_uid); + } + + if let Some(pax_gid) = pax_extensions_value(pax_extensions_ref, PAX_GID) { + header.set_gid(pax_gid); + } + } + let file_pos = self.next; let mut size = header.entry_size()?; if size == 0 { @@ -360,11 +373,10 @@ impl<'a> EntriesFields<'a> { let mut gnu_longname = None; let mut gnu_longlink = None; let mut pax_extensions = None; - let mut pax_size = None; let mut processed = 0; loop { processed += 1; - let entry = match self.next_entry_raw(pax_size)? { + let entry = match self.next_entry_raw(pax_extensions.as_deref())? { Some(entry) => entry, None if processed > 1 => { return Err(other( @@ -408,9 +420,6 @@ impl<'a> EntriesFields<'a> { )); } pax_extensions = Some(EntryFields::from(entry).read_all()?); - if let Some(pax_extensions_ref) = &pax_extensions { - pax_size = pax_extensions_size(pax_extensions_ref); - } continue; } diff --git a/vendor/tar/src/pax.rs b/vendor/tar/src/pax.rs index 80ca3e9b4..6e83edce8 100644 --- a/vendor/tar/src/pax.rs +++ b/vendor/tar/src/pax.rs @@ -1,9 +1,39 @@ +#![allow(dead_code)] use std::io; use std::slice; use std::str; use crate::other; +// Keywords for PAX extended header records. +pub const PAX_NONE: &str = ""; // Indicates that no PAX key is suitable +pub const PAX_PATH: &str = "path"; +pub const PAX_LINKPATH: &str = "linkpath"; +pub const PAX_SIZE: &str = "size"; +pub const PAX_UID: &str = "uid"; +pub const PAX_GID: &str = "gid"; +pub const PAX_UNAME: &str = "uname"; +pub const PAX_GNAME: &str = "gname"; +pub const PAX_MTIME: &str = "mtime"; +pub const PAX_ATIME: &str = "atime"; +pub const PAX_CTIME: &str = "ctime"; // Removed from later revision of PAX spec, but was valid +pub const PAX_CHARSET: &str = "charset"; // Currently unused +pub const PAX_COMMENT: &str = "comment"; // Currently unused + +pub const PAX_SCHILYXATTR: &str = "SCHILY.xattr."; + +// Keywords for GNU sparse files in a PAX extended header. +pub const PAX_GNUSPARSE: &str = "GNU.sparse."; +pub const PAX_GNUSPARSENUMBLOCKS: &str = "GNU.sparse.numblocks"; +pub const PAX_GNUSPARSEOFFSET: &str = "GNU.sparse.offset"; +pub const PAX_GNUSPARSENUMBYTES: &str = "GNU.sparse.numbytes"; +pub const PAX_GNUSPARSEMAP: &str = "GNU.sparse.map"; +pub const PAX_GNUSPARSENAME: &str = "GNU.sparse.name"; +pub const PAX_GNUSPARSEMAJOR: &str = "GNU.sparse.major"; +pub const PAX_GNUSPARSEMINOR: &str = "GNU.sparse.minor"; +pub const PAX_GNUSPARSESIZE: &str = "GNU.sparse.size"; +pub const PAX_GNUSPARSEREALSIZE: &str = "GNU.sparse.realsize"; + /// An iterator over the pax extensions in an archive entry. /// /// This iterator yields structures which can themselves be parsed into @@ -30,13 +60,13 @@ pub struct PaxExtension<'entry> { value: &'entry [u8], } -pub fn pax_extensions_size(a: &[u8]) -> Option<u64> { +pub fn pax_extensions_value(a: &[u8], key: &str) -> Option<u64> { for extension in PaxExtensions::new(a) { let current_extension = match extension { Ok(ext) => ext, Err(_) => return None, }; - if current_extension.key() != Ok("size") { + if current_extension.key() != Ok(key) { continue; } @@ -44,11 +74,11 @@ pub fn pax_extensions_size(a: &[u8]) -> Option<u64> { Ok(value) => value, Err(_) => return None, }; - let size = match value.parse::<u64>() { - Ok(size) => size, + let result = match value.parse::<u64>() { + Ok(result) => result, Err(_) => return None, }; - return Some(size); + return Some(result); } None } |