mirror of
https://github.com/storytold/figcraft.git
synced 2026-11-11 02:30:58 +00:00
fix(engine): check the opened file, not the looked-up path, before reading it
read_capped checked the path's metadata (type and size) and then opened the path again, so an entry swapped between the two steps was read without those checks. The opened handle's metadata is checked as well; the path check stays, so a pipe is still refused before it is opened.
This commit is contained in:
@@ -277,6 +277,14 @@ pub fn read_capped(path: impl AsRef<Path>, max: u64) -> Result<Vec<u8>> {
|
||||
return Err(refuse(format!("is {}, more than the {} allowed here", size(meta.len()), size(max))));
|
||||
}
|
||||
let f = std::fs::File::open(p).map_err(io(path))?;
|
||||
// What was opened, not what was looked at: the path could have been swapped in between.
|
||||
let meta = f.metadata().map_err(io(path))?;
|
||||
if !meta.is_file() {
|
||||
return Err(refuse("isn't a regular file (a device or a pipe?), so it isn't read".into()));
|
||||
}
|
||||
if meta.len() > max {
|
||||
return Err(refuse(format!("is {}, more than the {} allowed here", size(meta.len()), size(max))));
|
||||
}
|
||||
let mut bytes = Vec::with_capacity(usize::try_from(meta.len()).unwrap_or(0));
|
||||
f.take(max.saturating_add(1)).read_to_end(&mut bytes).map_err(io(path))?;
|
||||
// It grew after it was looked at.
|
||||
|
||||
Reference in New Issue
Block a user