mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-10-24 17:56:50 -06:00
Fix clipboard read-policy bypass and lock-held file checks
- copied_file: check the read policy on the real path when it is valid UTF-8; skip non-UTF-8 paths while automation roots are active instead of checking a lossy name (path traversal via symlink, CodeRabbit #3872 thread 1). - full_bytes_cached: collect matching cache candidates under the FULL lock, then run the read checks after releasing it, so filesystem walks no longer stall other FULL users (thread 2).
This commit is contained in:
committed by
bflatastic
parent
cd043f650b
commit
42f8b513a2
@@ -144,7 +144,12 @@ fn copied_file(paths: Vec<PathBuf>, mimes: &[&'static str]) -> Option<Flavour> {
|
||||
_ => path,
|
||||
};
|
||||
// A paste sent by automation reads only what its roots allow.
|
||||
vectorcraft_engine::file_access::check_read(&path.to_string_lossy()).ok()?;
|
||||
match path.to_str() {
|
||||
Some(p) => vectorcraft_engine::file_access::check_read(p).ok()?,
|
||||
// A lossy name would check another file than the one opened.
|
||||
None if vectorcraft_engine::file_access::current().is_none() => {}
|
||||
None => return None,
|
||||
}
|
||||
let mut head = Vec::with_capacity(FILE_HEAD);
|
||||
std::fs::File::open(&path).ok()?.take(FILE_HEAD as u64).read_to_end(&mut head).ok()?;
|
||||
let mime = file_flavour(&path.to_string_lossy(), &head, mimes)?;
|
||||
|
||||
@@ -320,7 +320,10 @@ pub fn full_bytes_cached(p: &PlacedDocument, blob: &ImageBlob) -> Option<Arc<Vec
|
||||
return Some(blob.bytes.clone());
|
||||
}
|
||||
let allowed = |path: &str| READ_CHECK.get().is_none_or(|ok| ok(path));
|
||||
full().iter().rev().find(|(k, path, _)| *k == p.key && allowed(path)).map(|(_, _, b)| b.clone())
|
||||
// Copy the candidates, newest first, so the filesystem checks run without the lock.
|
||||
let candidates: Vec<(String, Arc<Vec<u8>>)> =
|
||||
full().iter().rev().filter(|(k, _, _)| *k == p.key).map(|(_, path, b)| (path.clone(), b.clone())).collect();
|
||||
candidates.into_iter().find(|(path, _)| allowed(path)).map(|(_, b)| b)
|
||||
}
|
||||
|
||||
/// The file's bytes: stored, read again already, or read again now ([`set_file_reader`]). `None`
|
||||
|
||||
Reference in New Issue
Block a user