summaryrefslogtreecommitdiffstats
path: root/vendor/tar/src
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/tar/src')
-rw-r--r--vendor/tar/src/archive.rs23
-rw-r--r--vendor/tar/src/pax.rs40
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
}