Skip to content

Commit

Permalink
fix: throw error when asset is empty (#3379)
Browse files Browse the repository at this point in the history
* fix: throw error when asset is empty
* Use std::path::absolute to fix windows unc problems
* fix: don't use canonicalize at all on windows
  • Loading branch information
jkelleyrtp authored Dec 17, 2024
1 parent fa48016 commit 94b8647
Showing 1 changed file with 47 additions and 22 deletions.
69 changes: 47 additions & 22 deletions packages/manganis/manganis-macro/src/asset.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,19 +19,37 @@ fn resolve_path(raw: &str) -> Result<PathBuf, AssetParseError> {
// /users/dioxus/dev/app/assets/blah.css
let manifest_dir = std::env::var("CARGO_MANIFEST_DIR")
.map(PathBuf::from)
.unwrap()
.canonicalize()
.unwrap();

// 1. the input file should be a pathbuf
let input = PathBuf::from(raw);

// 2. absolute path to the asset
manifest_dir
.join(raw.trim_start_matches('/'))
.canonicalize()
.map_err(|err| AssetParseError::AssetDoesntExist {
err,
let Ok(path) = std::path::absolute(manifest_dir.join(raw.trim_start_matches('/'))) else {
return Err(AssetParseError::InvalidPath {
path: input.clone(),
})
});
};

// 3. Ensure the path exists
let Ok(path) = path.canonicalize() else {
return Err(AssetParseError::AssetDoesntExist {
path: input.clone(),
});
};

// 4. Ensure the path doesn't escape the crate dir
//
// - Note: since we called canonicalize on both paths, we can safely compare the parent dirs.
// On windows, we can only compare the prefix if both paths are canonicalized (not just absolute)
// https://github.com/rust-lang/rust/issues/42869
if path == manifest_dir || !path.starts_with(manifest_dir) {
return Err(AssetParseError::InvalidPath { path });
}

Ok(path)
}

fn hash_file_contents(file_path: &Path) -> Result<u64, AssetParseError> {
Expand All @@ -40,11 +58,10 @@ fn hash_file_contents(file_path: &Path) -> Result<u64, AssetParseError> {

// If this is a folder, hash the folder contents
if file_path.is_dir() {
let files =
std::fs::read_dir(file_path).map_err(|err| AssetParseError::AssetDoesntExist {
err,
path: file_path.to_path_buf(),
})?;
let files = std::fs::read_dir(file_path).map_err(|err| AssetParseError::IoError {
err,
path: file_path.to_path_buf(),
})?;
for file in files.flatten() {
let path = file.path();
hash_file_contents(&path)?;
Expand All @@ -53,11 +70,10 @@ fn hash_file_contents(file_path: &Path) -> Result<u64, AssetParseError> {
}

// Otherwise, open the file to get its contents
let mut file =
std::fs::File::open(file_path).map_err(|err| AssetParseError::AssetDoesntExist {
err,
path: file_path.to_path_buf(),
})?;
let mut file = std::fs::File::open(file_path).map_err(|err| AssetParseError::IoError {
err,
path: file_path.to_path_buf(),
})?;

// We add a hash to the end of the file so it is invalidated when the bundled version of the file changes
// The hash includes the file contents, the options, and the version of manganis. From the macro, we just
Expand All @@ -78,18 +94,27 @@ fn hash_file_contents(file_path: &Path) -> Result<u64, AssetParseError> {

#[derive(Debug)]
pub(crate) enum AssetParseError {
AssetDoesntExist {
err: std::io::Error,
path: std::path::PathBuf,
},
AssetDoesntExist { path: PathBuf },
IoError { err: std::io::Error, path: PathBuf },
InvalidPath { path: PathBuf },
FailedToReadAsset(std::io::Error),
}

impl std::fmt::Display for AssetParseError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
AssetParseError::AssetDoesntExist { err, path } => {
write!(f, "Asset at {} doesn't exist: {}", path.display(), err)
AssetParseError::AssetDoesntExist { path } => {
write!(f, "Asset at {} doesn't exist", path.display())
}
AssetParseError::IoError { path, err } => {
write!(f, "Failed to read file: {}; {}", path.display(), err)
}
AssetParseError::InvalidPath { path } => {
write!(
f,
"Asset path {} is invalid. Make sure the asset exists within this crate.",
path.display()
)
}
AssetParseError::FailedToReadAsset(err) => write!(f, "Failed to read asset: {}", err),
}
Expand Down

0 comments on commit 94b8647

Please sign in to comment.