Be more accepting in creating blobs from existing names

This is an additional fix for #768 aka
commit eac8ad8369
This commit is contained in:
Floris Bruynooghe
2019-10-31 09:53:20 +01:00
committed by holger krekel
parent 80d7e84e5d
commit b264d3be3c

View File

@@ -1,3 +1,4 @@
use std::ffi::OsStr;
use std::fmt;
use std::fs;
use std::io::Write;
@@ -145,6 +146,9 @@ impl<'a> BlobObject<'a> {
.as_ref()
.strip_prefix(context.get_blobdir())
.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
.to_str()
.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(),
false => name,
};
let (stem, ext) = BlobObject::sanitise_name(name.clone());
if format!("{}{}", stem, ext) != name.as_ref() {
if !BlobObject::is_acceptible_blob_name(&name) {
return Err(BlobError::new_wrong_name(name));
}
Ok(BlobObject {
@@ -266,6 +269,28 @@ impl<'a> BlobObject<'a> {
_ => (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> {
@@ -615,4 +640,14 @@ mod tests {
"$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"));
}
}