fix panicing with long link names

This commit is contained in:
Joonas Koivunen 2020-06-16 21:21:15 +03:00
parent f3f9f26c9b
commit 92cc2ab353
2 changed files with 8 additions and 3 deletions

View File

@ -199,6 +199,7 @@ fn walk<Types: IpfsTypes>(
enum GetError { enum GetError {
NonUtf8Symlink, NonUtf8Symlink,
InvalidFileName(Vec<u8>), InvalidFileName(Vec<u8>),
InvalidLinkName(Vec<u8>),
Walk(walk::Error), Walk(walk::Error),
Loading(ipfs::Error), Loading(ipfs::Error),
} }
@ -223,6 +224,7 @@ impl fmt::Display for GetError {
Walk(e) => write!(fmt, "{}", e), Walk(e) => write!(fmt, "{}", e),
Loading(e) => write!(fmt, "loading failed: {}", e), Loading(e) => write!(fmt, "loading failed: {}", e),
InvalidFileName(x) => write!(fmt, "filename cannot be put inside tar: {:?}", x), InvalidFileName(x) => write!(fmt, "filename cannot be put inside tar: {:?}", x),
InvalidLinkName(x) => write!(fmt, "symlin link name cannot be put inside tar: {:?}", x),
} }
} }
} }

View File

@ -188,14 +188,16 @@ impl TarHelper {
ret[2] = self.pad(data.len() as u64 + 1); ret[2] = self.pad(data.len() as u64 + 1);
} }
if let Err(e) = self.header.set_link_name(target) { if let Err(_) = self.header.set_link_name(target) {
let data = path2bytes(target); let data = path2bytes(target);
if data.len() < self.header.as_old().linkname.len() { if data.len() < self.header.as_old().linkname.len() {
// this might be an /ipfs/QmFoo which we should error and not allow return Err(GetError::InvalidLinkName(data.to_vec()));
panic!("invalid link target: {:?} ({})", target, e)
} }
// this is another long header trick, but this time we have different entry type but
// similarly the long file name is written as an separate entry with own headers.
self.long_filename_header.set_size(data.len() as u64 + 1); self.long_filename_header.set_size(data.len() as u64 + 1);
self.long_filename_header self.long_filename_header
.set_entry_type(tar::EntryType::new(b'K')); .set_entry_type(tar::EntryType::new(b'K'));
@ -225,6 +227,7 @@ impl TarHelper {
Ok(ret) Ok(ret)
} }
/// Content is tar files is padded to 512 byte sectors which might be configurable as well.
pub(super) fn pad(&self, total_size: u64) -> Option<Bytes> { pub(super) fn pad(&self, total_size: u64) -> Option<Bytes> {
let padding = 512 - (total_size % 512); let padding = 512 - (total_size % 512);
if padding < 512 { if padding < 512 {