fix: check dirs and hamtshards supported
this is probably being overly strict but at least there will not be any misunderstandings.
This commit is contained in:
parent
d589e90160
commit
1d50a5195c
@ -7,6 +7,16 @@ use std::fmt;
|
||||
mod sharded_lookup;
|
||||
pub use sharded_lookup::{Cache, LookupError, ShardError, ShardedLookup};
|
||||
|
||||
mod dir;
|
||||
pub(crate) use dir::{check_directory_supported, UnexpectedDirectoryProperties};
|
||||
|
||||
pub(crate) fn check_hamtshard_supported(
|
||||
mut flat: FlatUnixFs<'_>,
|
||||
) -> Result<FlatUnixFs<'_>, ShardError> {
|
||||
ShardedLookup::check_supported(&mut flat)?;
|
||||
Ok(flat)
|
||||
}
|
||||
|
||||
/// Resolves a single path segment on `dag-pb` or UnixFS directories (normal, sharded).
|
||||
///
|
||||
/// The third parameter can always be substituted with a None but when repeatedly resolving over
|
||||
@ -30,20 +40,7 @@ pub fn resolve<'needle>(
|
||||
return Ok(ShardedLookup::lookup_or_start(hamt, needle, cache)?)
|
||||
}
|
||||
Ok(flat) if flat.data.Type == UnixFsType::Directory => {
|
||||
if flat.data.filesize.is_some()
|
||||
|| !flat.data.blocksizes.is_empty()
|
||||
|| flat.data.hashType.is_some()
|
||||
|| flat.data.fanout.is_some()
|
||||
{
|
||||
return Err(ResolveError::UnexpectedDirProperties {
|
||||
filesize: flat.data.filesize,
|
||||
blocksizes: flat.data.blocksizes,
|
||||
hash_type: flat.data.hashType,
|
||||
fanout: flat.data.fanout,
|
||||
});
|
||||
}
|
||||
|
||||
flat.links
|
||||
check_directory_supported(flat)?.links
|
||||
}
|
||||
Err(ParsingFailed::InvalidUnixFs(_, PBNode { Links: links, .. }))
|
||||
| Err(ParsingFailed::NoData(PBNode { Links: links, .. })) => links,
|
||||
@ -103,16 +100,7 @@ pub enum ResolveError {
|
||||
UnexpectedType(UnexpectedNodeType),
|
||||
/// A directory had unsupported properties. These are not encountered during walking sharded
|
||||
/// directories.
|
||||
UnexpectedDirProperties {
|
||||
/// filesize is a property of Files
|
||||
filesize: Option<u64>,
|
||||
/// blocksizes is a property of Files
|
||||
blocksizes: Vec<u64>,
|
||||
/// hash_type is a property of HAMT Shards
|
||||
hash_type: Option<u64>,
|
||||
/// fanout is a property of HAMT shards
|
||||
fanout: Option<u64>,
|
||||
},
|
||||
UnexpectedDirProperties(UnexpectedDirectoryProperties),
|
||||
/// Failed to read the block as a dag-pb node. Failure to read an inner UnixFS node is ignored
|
||||
/// and links of the outer dag-pb are processed.
|
||||
Read(quick_protobuf::Error),
|
||||
@ -120,23 +108,18 @@ pub enum ResolveError {
|
||||
Lookup(LookupError),
|
||||
}
|
||||
|
||||
impl From<UnexpectedDirectoryProperties> for ResolveError {
|
||||
fn from(e: UnexpectedDirectoryProperties) -> Self {
|
||||
ResolveError::UnexpectedDirProperties(e)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for ResolveError {
|
||||
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
use ResolveError::*;
|
||||
match self {
|
||||
UnexpectedType(ut) => write!(
|
||||
fmt,
|
||||
"unexpected type for UnixFs: {:?}",
|
||||
ut
|
||||
),
|
||||
UnexpectedDirProperties { filesize, blocksizes, hash_type, fanout } => write!(
|
||||
fmt,
|
||||
"unexpected directory properties: filesize={:?}, {} blocksizes, hash_type={:?}, fanout={:?}",
|
||||
filesize,
|
||||
blocksizes.len(),
|
||||
hash_type,
|
||||
fanout
|
||||
),
|
||||
UnexpectedType(ut) => write!(fmt, "unexpected type for UnixFs: {:?}", ut),
|
||||
UnexpectedDirProperties(udp) => write!(fmt, "unexpected directory properties: {}", udp),
|
||||
Read(e) => write!(fmt, "parsing failed: {}", e),
|
||||
Lookup(e) => write!(fmt, "{}", e),
|
||||
}
|
||||
|
@ -137,7 +137,7 @@ impl<'needle> ShardedLookup<'needle> {
|
||||
/// Takes the validated object as mutable reference to move data out of it in case of error.
|
||||
///
|
||||
/// Returns an error if we don't support the properties on the HAMTShard-typed node
|
||||
fn check_supported(hamt: &mut FlatUnixFs<'_>) -> Result<(), ShardError> {
|
||||
pub(crate) fn check_supported(hamt: &mut FlatUnixFs<'_>) -> Result<(), ShardError> {
|
||||
assert_eq!(hamt.data.Type, UnixFsType::HAMTShard);
|
||||
|
||||
if hamt.data.fanout != Some(256) || hamt.data.hashType != Some(34) {
|
||||
|
@ -1,10 +1,12 @@
|
||||
#![allow(unused, dead_code)]
|
||||
|
||||
use crate::dir::{
|
||||
check_directory_supported, check_hamtshard_supported, ShardError, UnexpectedDirectoryProperties,
|
||||
};
|
||||
use crate::file::visit::{Cache, FileVisit, IdleFileVisit};
|
||||
use crate::file::{FileError, FileReadFailed};
|
||||
use crate::pb::{FlatUnixFs, PBLink, PBNode, ParsingFailed, UnixFsType};
|
||||
use crate::Metadata;
|
||||
use crate::{InvalidCidInLink, UnexpectedNodeType};
|
||||
use crate::{InvalidCidInLink, Metadata, UnexpectedNodeType};
|
||||
use cid::Cid;
|
||||
use either::Either;
|
||||
use std::borrow::Cow;
|
||||
@ -155,6 +157,8 @@ impl Walker {
|
||||
|
||||
match flat.data.Type {
|
||||
UnixFsType::Directory => {
|
||||
let flat = crate::dir::check_directory_supported(flat)?;
|
||||
|
||||
let (cid, name, depth) = self.next.expect("validated at start and this method");
|
||||
match self.current.as_mut() {
|
||||
Some(current) => current.as_directory(cid, &name, depth, metadata),
|
||||
@ -196,6 +200,8 @@ impl Walker {
|
||||
Ok(ContinuedWalk::Directory(Item::from(state)))
|
||||
}
|
||||
UnixFsType::HAMTShard => {
|
||||
let flat = crate::dir::check_hamtshard_supported(flat)?;
|
||||
|
||||
// TODO: the first hamtshard must have metadata!
|
||||
let (cid, name, depth) = self.next.expect("validated at start and this method");
|
||||
|
||||
@ -736,6 +742,12 @@ pub enum Error {
|
||||
|
||||
/// A file has invalid structure
|
||||
File(FileError),
|
||||
|
||||
/// Directory has unsupported structure
|
||||
UnsupportedDirectory(UnexpectedDirectoryProperties),
|
||||
|
||||
/// HAMTSharded directory has unsupported properties
|
||||
UnsupportedHAMTShard(ShardError),
|
||||
}
|
||||
|
||||
impl From<ParsingFailed<'_>> for Error {
|
||||
@ -767,6 +779,18 @@ impl From<FileReadFailed> for Error {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<UnexpectedDirectoryProperties> for Error {
|
||||
fn from(e: UnexpectedDirectoryProperties) -> Self {
|
||||
Error::UnsupportedDirectory(e)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ShardError> for Error {
|
||||
fn from(e: ShardError) -> Self {
|
||||
Error::UnsupportedHAMTShard(e)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Error {
|
||||
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
use Error::*;
|
||||
@ -779,6 +803,8 @@ impl fmt::Display for Error {
|
||||
EmptyDagPbNode => write!(fmt, "failed to parse the inner UnixFs: no data"),
|
||||
InvalidCid(e) => write!(fmt, "link contained an invalid Cid: {}", e),
|
||||
File(e) => write!(fmt, "invalid file: {}", e),
|
||||
UnsupportedDirectory(udp) => write!(fmt, "unsupported directory: {}", udp),
|
||||
UnsupportedHAMTShard(se) => write!(fmt, "unsupported hamtshard: {}", se),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user