diff --git a/src/entry.rs b/src/entry.rs index f99c897b..b5e35123 100644 --- a/src/entry.rs +++ b/src/entry.rs @@ -334,7 +334,18 @@ impl<'a> EntryFields<'a> { Some(Cow::Borrowed(bytes)) } } - None => self.header.link_name_bytes(), + None => { + if let Some(ref pax) = self.pax_extensions { + let pax = pax_extensions(pax) + .filter_map(|f| f.ok()) + .find(|f| f.key_bytes() == b"linkpath") + .map(|f| f.value_bytes()); + if let Some(field) = pax { + return Some(Cow::Borrowed(field)); + } + } + self.header.link_name_bytes() + } } } diff --git a/tests/all.rs b/tests/all.rs index 37816875..1abb9161 100644 --- a/tests/all.rs +++ b/tests/all.rs @@ -791,6 +791,22 @@ fn pax_path() { assert!(first.path().unwrap().ends_with("aaaaaaaaaaaaaaa")); } +#[test] +fn pax_linkpath() { + let mut ar = Archive::new(tar!("pax2.tar")); + let mut links = t!(ar.entries()).skip(3).take(2); + + let long_symlink = t!(links.next().unwrap()); + let link_name = long_symlink.link_name().unwrap().unwrap(); + assert!(link_name.to_str().unwrap().len() > 99); + assert!(link_name.ends_with("bbbbbbbbbbbbbbb")); + + let long_hardlink = t!(links.next().unwrap()); + let link_name = long_hardlink.link_name().unwrap().unwrap(); + assert!(link_name.to_str().unwrap().len() > 99); + assert!(link_name.ends_with("ccccccccccccccc")); +} + #[test] fn long_name_trailing_nul() { let mut b = Builder::new(Vec::::new()); diff --git a/tests/archives/pax2.tar b/tests/archives/pax2.tar index c0c8ed31..1131af9d 100644 Binary files a/tests/archives/pax2.tar and b/tests/archives/pax2.tar differ