mirror of
https://github.com/chatmail/core.git
synced 2026-05-20 15:26:30 +03:00
Be more accepting in creating blobs from existing names
This is an additional fix for #768 aka
commit eac8ad8369
This commit is contained in:
committed by
holger krekel
parent
80d7e84e5d
commit
b264d3be3c
39
src/blob.rs
39
src/blob.rs
@@ -1,3 +1,4 @@
|
|||||||
|
use std::ffi::OsStr;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
@@ -145,6 +146,9 @@ impl<'a> BlobObject<'a> {
|
|||||||
.as_ref()
|
.as_ref()
|
||||||
.strip_prefix(context.get_blobdir())
|
.strip_prefix(context.get_blobdir())
|
||||||
.map_err(|_| BlobError::new_wrong_blobdir(context.get_blobdir(), path.as_ref()))?;
|
.map_err(|_| BlobError::new_wrong_blobdir(context.get_blobdir(), path.as_ref()))?;
|
||||||
|
if !BlobObject::is_acceptible_blob_name(&rel_path) {
|
||||||
|
return Err(BlobError::new_wrong_name(path.as_ref()));
|
||||||
|
}
|
||||||
let name = rel_path
|
let name = rel_path
|
||||||
.to_str()
|
.to_str()
|
||||||
.ok_or_else(|| BlobError::new_wrong_name(path.as_ref()))?;
|
.ok_or_else(|| BlobError::new_wrong_name(path.as_ref()))?;
|
||||||
@@ -171,8 +175,7 @@ impl<'a> BlobObject<'a> {
|
|||||||
true => name.splitn(2, '/').last().unwrap().to_string(),
|
true => name.splitn(2, '/').last().unwrap().to_string(),
|
||||||
false => name,
|
false => name,
|
||||||
};
|
};
|
||||||
let (stem, ext) = BlobObject::sanitise_name(name.clone());
|
if !BlobObject::is_acceptible_blob_name(&name) {
|
||||||
if format!("{}{}", stem, ext) != name.as_ref() {
|
|
||||||
return Err(BlobError::new_wrong_name(name));
|
return Err(BlobError::new_wrong_name(name));
|
||||||
}
|
}
|
||||||
Ok(BlobObject {
|
Ok(BlobObject {
|
||||||
@@ -266,6 +269,28 @@ impl<'a> BlobObject<'a> {
|
|||||||
_ => (stem, format!(".{}", ext).to_lowercase()),
|
_ => (stem, format!(".{}", ext).to_lowercase()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Checks whether a name is a valid blob name.
|
||||||
|
///
|
||||||
|
/// This is slightly less strict than stanitise_name, presumably
|
||||||
|
/// someone already created a file with such a name so we just
|
||||||
|
/// ensure it's not actually a path in disguise is actually utf-8.
|
||||||
|
fn is_acceptible_blob_name(name: impl AsRef<OsStr>) -> bool {
|
||||||
|
let uname = match name.as_ref().to_str() {
|
||||||
|
Some(name) => name,
|
||||||
|
None => return false,
|
||||||
|
};
|
||||||
|
if uname.find('/').is_some() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if uname.find('\\').is_some() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if uname.find('\0').is_some() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> fmt::Display for BlobObject<'a> {
|
impl<'a> fmt::Display for BlobObject<'a> {
|
||||||
@@ -615,4 +640,14 @@ mod tests {
|
|||||||
"$BLOBDIR/autocrypt-setup-message-4137848473.html"
|
"$BLOBDIR/autocrypt-setup-message-4137848473.html"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_is_blob_name() {
|
||||||
|
assert!(BlobObject::is_acceptible_blob_name("foo"));
|
||||||
|
assert!(BlobObject::is_acceptible_blob_name("foo.txt"));
|
||||||
|
assert!(BlobObject::is_acceptible_blob_name("f".repeat(128)));
|
||||||
|
assert!(!BlobObject::is_acceptible_blob_name("foo/bar"));
|
||||||
|
assert!(!BlobObject::is_acceptible_blob_name("foo\\bar"));
|
||||||
|
assert!(!BlobObject::is_acceptible_blob_name("foo\x00bar"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user