mirror of
https://github.com/comit-network/xmr-btc-swap.git
synced 2024-12-27 08:29:38 -05:00
351 lines
11 KiB
Rust
351 lines
11 KiB
Rust
|
extern crate tokio_tar as async_tar;
|
||
|
|
||
|
extern crate tempfile;
|
||
|
|
||
|
use tokio::{fs::File, io::AsyncReadExt};
|
||
|
use tokio_stream::*;
|
||
|
|
||
|
use tempfile::Builder;
|
||
|
|
||
|
macro_rules! t {
|
||
|
($e:expr) => {
|
||
|
match $e {
|
||
|
Ok(v) => v,
|
||
|
Err(e) => panic!("{} returned {}", stringify!($e), e),
|
||
|
}
|
||
|
};
|
||
|
}
|
||
|
|
||
|
#[tokio::test]
|
||
|
async fn absolute_symlink() {
|
||
|
let mut ar = async_tar::Builder::new(Vec::new());
|
||
|
|
||
|
let mut header = async_tar::Header::new_gnu();
|
||
|
header.set_size(0);
|
||
|
header.set_entry_type(async_tar::EntryType::Symlink);
|
||
|
t!(header.set_path("foo"));
|
||
|
t!(header.set_link_name("/bar"));
|
||
|
header.set_cksum();
|
||
|
t!(ar.append(&header, &[][..]).await);
|
||
|
|
||
|
let bytes = t!(ar.into_inner().await);
|
||
|
let mut ar = async_tar::Archive::new(&bytes[..]);
|
||
|
|
||
|
let td = t!(Builder::new().prefix("tar").tempdir());
|
||
|
t!(ar.unpack(td.path()).await);
|
||
|
|
||
|
t!(td.path().join("foo").symlink_metadata());
|
||
|
|
||
|
let mut ar = async_tar::Archive::new(&bytes[..]);
|
||
|
let mut entries = t!(ar.entries());
|
||
|
let entry = t!(entries.next().await.unwrap());
|
||
|
assert_eq!(&*entry.link_name_bytes().unwrap(), b"/bar");
|
||
|
}
|
||
|
|
||
|
#[tokio::test]
|
||
|
async fn absolute_hardlink() {
|
||
|
let td = t!(Builder::new().prefix("tar").tempdir());
|
||
|
let mut ar = async_tar::Builder::new(Vec::new());
|
||
|
|
||
|
let mut header = async_tar::Header::new_gnu();
|
||
|
header.set_size(0);
|
||
|
header.set_entry_type(async_tar::EntryType::Regular);
|
||
|
t!(header.set_path("foo"));
|
||
|
header.set_cksum();
|
||
|
t!(ar.append(&header, &[][..]).await);
|
||
|
|
||
|
let mut header = async_tar::Header::new_gnu();
|
||
|
header.set_size(0);
|
||
|
header.set_entry_type(async_tar::EntryType::Link);
|
||
|
t!(header.set_path("bar"));
|
||
|
// This absolute path under tempdir will be created at unpack time
|
||
|
t!(header.set_link_name(td.path().join("foo")));
|
||
|
header.set_cksum();
|
||
|
t!(ar.append(&header, &[][..]).await);
|
||
|
|
||
|
let bytes = t!(ar.into_inner().await);
|
||
|
let mut ar = async_tar::Archive::new(&bytes[..]);
|
||
|
|
||
|
t!(ar.unpack(td.path()).await);
|
||
|
t!(td.path().join("foo").metadata());
|
||
|
t!(td.path().join("bar").metadata());
|
||
|
}
|
||
|
|
||
|
#[tokio::test]
|
||
|
async fn relative_hardlink() {
|
||
|
let mut ar = async_tar::Builder::new(Vec::new());
|
||
|
|
||
|
let mut header = async_tar::Header::new_gnu();
|
||
|
header.set_size(0);
|
||
|
header.set_entry_type(async_tar::EntryType::Regular);
|
||
|
t!(header.set_path("foo"));
|
||
|
header.set_cksum();
|
||
|
t!(ar.append(&header, &[][..]).await);
|
||
|
|
||
|
let mut header = async_tar::Header::new_gnu();
|
||
|
header.set_size(0);
|
||
|
header.set_entry_type(async_tar::EntryType::Link);
|
||
|
t!(header.set_path("bar"));
|
||
|
t!(header.set_link_name("foo"));
|
||
|
header.set_cksum();
|
||
|
t!(ar.append(&header, &[][..]).await);
|
||
|
|
||
|
let bytes = t!(ar.into_inner().await);
|
||
|
let mut ar = async_tar::Archive::new(&bytes[..]);
|
||
|
|
||
|
let td = t!(Builder::new().prefix("tar").tempdir());
|
||
|
t!(ar.unpack(td.path()).await);
|
||
|
t!(td.path().join("foo").metadata());
|
||
|
t!(td.path().join("bar").metadata());
|
||
|
}
|
||
|
|
||
|
#[tokio::test]
|
||
|
async fn absolute_link_deref_error() {
|
||
|
let mut ar = async_tar::Builder::new(Vec::new());
|
||
|
|
||
|
let mut header = async_tar::Header::new_gnu();
|
||
|
header.set_size(0);
|
||
|
header.set_entry_type(async_tar::EntryType::Symlink);
|
||
|
t!(header.set_path("foo"));
|
||
|
t!(header.set_link_name("/"));
|
||
|
header.set_cksum();
|
||
|
t!(ar.append(&header, &[][..]).await);
|
||
|
|
||
|
let mut header = async_tar::Header::new_gnu();
|
||
|
header.set_size(0);
|
||
|
header.set_entry_type(async_tar::EntryType::Regular);
|
||
|
t!(header.set_path("foo/bar"));
|
||
|
header.set_cksum();
|
||
|
t!(ar.append(&header, &[][..]).await);
|
||
|
|
||
|
let bytes = t!(ar.into_inner().await);
|
||
|
let mut ar = async_tar::Archive::new(&bytes[..]);
|
||
|
|
||
|
let td = t!(Builder::new().prefix("tar").tempdir());
|
||
|
assert!(ar.unpack(td.path()).await.is_err());
|
||
|
t!(td.path().join("foo").symlink_metadata());
|
||
|
assert!(File::open(td.path().join("foo").join("bar")).await.is_err());
|
||
|
}
|
||
|
|
||
|
#[tokio::test]
|
||
|
async fn relative_link_deref_error() {
|
||
|
let mut ar = async_tar::Builder::new(Vec::new());
|
||
|
|
||
|
let mut header = async_tar::Header::new_gnu();
|
||
|
header.set_size(0);
|
||
|
header.set_entry_type(async_tar::EntryType::Symlink);
|
||
|
t!(header.set_path("foo"));
|
||
|
t!(header.set_link_name("../../../../"));
|
||
|
header.set_cksum();
|
||
|
t!(ar.append(&header, &[][..]).await);
|
||
|
|
||
|
let mut header = async_tar::Header::new_gnu();
|
||
|
header.set_size(0);
|
||
|
header.set_entry_type(async_tar::EntryType::Regular);
|
||
|
t!(header.set_path("foo/bar"));
|
||
|
header.set_cksum();
|
||
|
t!(ar.append(&header, &[][..]).await);
|
||
|
|
||
|
let bytes = t!(ar.into_inner().await);
|
||
|
let mut ar = async_tar::Archive::new(&bytes[..]);
|
||
|
|
||
|
let td = t!(Builder::new().prefix("tar").tempdir());
|
||
|
assert!(ar.unpack(td.path()).await.is_err());
|
||
|
t!(td.path().join("foo").symlink_metadata());
|
||
|
assert!(File::open(td.path().join("foo").join("bar")).await.is_err());
|
||
|
}
|
||
|
|
||
|
#[tokio::test]
|
||
|
#[cfg(unix)]
|
||
|
async fn directory_maintains_permissions() {
|
||
|
use ::std::os::unix::fs::PermissionsExt;
|
||
|
|
||
|
let mut ar = async_tar::Builder::new(Vec::new());
|
||
|
|
||
|
let mut header = async_tar::Header::new_gnu();
|
||
|
header.set_size(0);
|
||
|
header.set_entry_type(async_tar::EntryType::Directory);
|
||
|
t!(header.set_path("foo"));
|
||
|
header.set_mode(0o777);
|
||
|
header.set_cksum();
|
||
|
t!(ar.append(&header, &[][..]).await);
|
||
|
|
||
|
let bytes = t!(ar.into_inner().await);
|
||
|
let mut ar = async_tar::Archive::new(&bytes[..]);
|
||
|
|
||
|
let td = t!(Builder::new().prefix("tar").tempdir());
|
||
|
t!(ar.unpack(td.path()).await);
|
||
|
let f = t!(File::open(td.path().join("foo")).await);
|
||
|
let md = t!(f.metadata().await);
|
||
|
assert!(md.is_dir());
|
||
|
assert_eq!(md.permissions().mode(), 0o40777);
|
||
|
}
|
||
|
|
||
|
#[tokio::test]
|
||
|
#[cfg(not(windows))] // dangling symlinks have weird permissions
|
||
|
async fn modify_link_just_created() {
|
||
|
let mut ar = async_tar::Builder::new(Vec::new());
|
||
|
|
||
|
let mut header = async_tar::Header::new_gnu();
|
||
|
header.set_size(0);
|
||
|
header.set_entry_type(async_tar::EntryType::Symlink);
|
||
|
t!(header.set_path("foo"));
|
||
|
t!(header.set_link_name("bar"));
|
||
|
header.set_cksum();
|
||
|
t!(ar.append(&header, &[][..]).await);
|
||
|
|
||
|
let mut header = async_tar::Header::new_gnu();
|
||
|
header.set_size(0);
|
||
|
header.set_entry_type(async_tar::EntryType::Regular);
|
||
|
t!(header.set_path("bar/foo"));
|
||
|
header.set_cksum();
|
||
|
t!(ar.append(&header, &[][..]).await);
|
||
|
|
||
|
let mut header = async_tar::Header::new_gnu();
|
||
|
header.set_size(0);
|
||
|
header.set_entry_type(async_tar::EntryType::Regular);
|
||
|
t!(header.set_path("foo/bar"));
|
||
|
header.set_cksum();
|
||
|
t!(ar.append(&header, &[][..]).await);
|
||
|
|
||
|
let bytes = t!(ar.into_inner().await);
|
||
|
let mut ar = async_tar::Archive::new(&bytes[..]);
|
||
|
|
||
|
let td = t!(Builder::new().prefix("tar").tempdir());
|
||
|
t!(ar.unpack(td.path()).await);
|
||
|
|
||
|
t!(File::open(td.path().join("bar/foo")).await);
|
||
|
t!(File::open(td.path().join("bar/bar")).await);
|
||
|
t!(File::open(td.path().join("foo/foo")).await);
|
||
|
t!(File::open(td.path().join("foo/bar")).await);
|
||
|
}
|
||
|
|
||
|
#[tokio::test]
|
||
|
async fn parent_paths_error() {
|
||
|
let mut ar = async_tar::Builder::new(Vec::new());
|
||
|
|
||
|
let mut header = async_tar::Header::new_gnu();
|
||
|
header.set_size(0);
|
||
|
header.set_entry_type(async_tar::EntryType::Symlink);
|
||
|
t!(header.set_path("foo"));
|
||
|
t!(header.set_link_name(".."));
|
||
|
header.set_cksum();
|
||
|
t!(ar.append(&header, &[][..]).await);
|
||
|
|
||
|
let mut header = async_tar::Header::new_gnu();
|
||
|
header.set_size(0);
|
||
|
header.set_entry_type(async_tar::EntryType::Regular);
|
||
|
t!(header.set_path("foo/bar"));
|
||
|
header.set_cksum();
|
||
|
t!(ar.append(&header, &[][..]).await);
|
||
|
|
||
|
let bytes = t!(ar.into_inner().await);
|
||
|
let mut ar = async_tar::Archive::new(&bytes[..]);
|
||
|
|
||
|
let td = t!(Builder::new().prefix("tar").tempdir());
|
||
|
assert!(ar.unpack(td.path()).await.is_err());
|
||
|
t!(td.path().join("foo").symlink_metadata());
|
||
|
assert!(File::open(td.path().join("foo").join("bar")).await.is_err());
|
||
|
}
|
||
|
|
||
|
#[tokio::test]
|
||
|
#[cfg(unix)]
|
||
|
async fn good_parent_paths_ok() {
|
||
|
use std::path::PathBuf;
|
||
|
let mut ar = async_tar::Builder::new(Vec::new());
|
||
|
|
||
|
let mut header = async_tar::Header::new_gnu();
|
||
|
header.set_size(0);
|
||
|
header.set_entry_type(async_tar::EntryType::Symlink);
|
||
|
t!(header.set_path(PathBuf::from("foo").join("bar")));
|
||
|
t!(header.set_link_name(PathBuf::from("..").join("bar")));
|
||
|
header.set_cksum();
|
||
|
t!(ar.append(&header, &[][..]).await);
|
||
|
|
||
|
let mut header = async_tar::Header::new_gnu();
|
||
|
header.set_size(0);
|
||
|
header.set_entry_type(async_tar::EntryType::Regular);
|
||
|
t!(header.set_path("bar"));
|
||
|
header.set_cksum();
|
||
|
t!(ar.append(&header, &[][..]).await);
|
||
|
|
||
|
let bytes = t!(ar.into_inner().await);
|
||
|
let mut ar = async_tar::Archive::new(&bytes[..]);
|
||
|
|
||
|
let td = t!(Builder::new().prefix("tar").tempdir());
|
||
|
t!(ar.unpack(td.path()).await);
|
||
|
t!(td.path().join("foo").join("bar").read_link());
|
||
|
let dst = t!(td.path().join("foo").join("bar").canonicalize());
|
||
|
t!(File::open(dst).await);
|
||
|
}
|
||
|
|
||
|
#[tokio::test]
|
||
|
async fn modify_hard_link_just_created() {
|
||
|
let mut ar = async_tar::Builder::new(Vec::new());
|
||
|
|
||
|
let mut header = async_tar::Header::new_gnu();
|
||
|
header.set_size(0);
|
||
|
header.set_entry_type(async_tar::EntryType::Link);
|
||
|
t!(header.set_path("foo"));
|
||
|
t!(header.set_link_name("../test"));
|
||
|
header.set_cksum();
|
||
|
t!(ar.append(&header, &[][..]).await);
|
||
|
|
||
|
let mut header = async_tar::Header::new_gnu();
|
||
|
header.set_size(1);
|
||
|
header.set_entry_type(async_tar::EntryType::Regular);
|
||
|
t!(header.set_path("foo"));
|
||
|
header.set_cksum();
|
||
|
t!(ar.append(&header, &b"x"[..]).await);
|
||
|
|
||
|
let bytes = t!(ar.into_inner().await);
|
||
|
let mut ar = async_tar::Archive::new(&bytes[..]);
|
||
|
|
||
|
let td = t!(Builder::new().prefix("tar").tempdir());
|
||
|
|
||
|
let test = td.path().join("test");
|
||
|
t!(File::create(&test).await);
|
||
|
|
||
|
let dir = td.path().join("dir");
|
||
|
assert!(ar.unpack(&dir).await.is_err());
|
||
|
|
||
|
let mut contents = Vec::new();
|
||
|
t!(t!(File::open(&test).await).read_to_end(&mut contents).await);
|
||
|
assert_eq!(contents.len(), 0);
|
||
|
}
|
||
|
|
||
|
#[tokio::test]
|
||
|
async fn modify_symlink_just_created() {
|
||
|
let mut ar = async_tar::Builder::new(Vec::new());
|
||
|
|
||
|
let mut header = async_tar::Header::new_gnu();
|
||
|
header.set_size(0);
|
||
|
header.set_entry_type(async_tar::EntryType::Symlink);
|
||
|
t!(header.set_path("foo"));
|
||
|
t!(header.set_link_name("../test"));
|
||
|
header.set_cksum();
|
||
|
t!(ar.append(&header, &[][..]).await);
|
||
|
|
||
|
let mut header = async_tar::Header::new_gnu();
|
||
|
header.set_size(1);
|
||
|
header.set_entry_type(async_tar::EntryType::Regular);
|
||
|
t!(header.set_path("foo"));
|
||
|
header.set_cksum();
|
||
|
t!(ar.append(&header, &b"x"[..]).await);
|
||
|
|
||
|
let bytes = t!(ar.into_inner().await);
|
||
|
let mut ar = async_tar::Archive::new(&bytes[..]);
|
||
|
|
||
|
let td = t!(Builder::new().prefix("tar").tempdir());
|
||
|
|
||
|
let test = td.path().join("test");
|
||
|
t!(File::create(&test).await);
|
||
|
|
||
|
let dir = td.path().join("dir");
|
||
|
t!(ar.unpack(&dir).await);
|
||
|
|
||
|
let mut contents = Vec::new();
|
||
|
t!(t!(File::open(&test).await).read_to_end(&mut contents).await);
|
||
|
assert_eq!(contents.len(), 0);
|
||
|
}
|