melib: set upper limit for bincode deserialize

If struct memory layout changes, bincode deserialize fails with memory
allocation error of an obscene amount of bytes. Set upper limit to
deserialized bytes in each place deserialize happens.
jmap-eventsource
Manos Pitsidianakis 2020-11-06 19:05:09 +02:00
parent 6c07046b66
commit 353ac2d029
Signed by: Manos Pitsidianakis
GPG Key ID: 73627C2F690DF710
2 changed files with 23 additions and 4 deletions

View File

@ -114,8 +114,16 @@ impl MaildirStream {
.to_path_buf();
if let Some(cached) = cache_dir.find_cache_file(&file_name) {
/* Cached struct exists, try to load it */
let reader = io::BufReader::new(fs::File::open(&cached)?);
let result: result::Result<Envelope, _> = bincode::deserialize_from(reader);
let cached_file = fs::File::open(&cached)?;
let filesize = cached_file.metadata()?.len();
let reader = io::BufReader::new(cached_file);
let result: result::Result<Envelope, _> = bincode::Options::deserialize_from(
bincode::Options::with_limit(
bincode::config::DefaultOptions::new(),
2 * filesize,
),
reader,
);
if let Ok(env) = result {
let mut map = map.lock().unwrap();
let map = map.entry(mailbox_hash).or_default();
@ -128,6 +136,8 @@ impl MaildirStream {
local_r.push(env);
continue;
}
/* Try delete invalid file */
let _ = fs::remove_file(&cached);
};
let env_hash = get_file_hash(&file);
{

View File

@ -144,8 +144,17 @@ impl ToSql for Envelope {
impl FromSql for Envelope {
fn column_result(value: rusqlite::types::ValueRef) -> FromSqlResult<Self> {
use std::convert::TryFrom;
let b: Vec<u8> = FromSql::column_result(value)?;
Ok(bincode::deserialize(&b)
.map_err(|e| FromSqlError::Other(Box::new(MeliError::new(e.to_string()))))?)
Ok(bincode::Options::deserialize(
bincode::Options::with_limit(
bincode::config::DefaultOptions::new(),
2 * u64::try_from(b.len()).map_err(|e| FromSqlError::Other(Box::new(e)))?,
),
&b,
)
.map_err(|e| FromSqlError::Other(Box::new(e)))?)
}
}