From 353ac2d029592d647c4d218d13e06c031e12b8fc Mon Sep 17 00:00:00 2001 From: Manos Pitsidianakis Date: Fri, 6 Nov 2020 19:05:09 +0200 Subject: [PATCH] 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. --- melib/src/backends/maildir/stream.rs | 14 ++++++++++++-- melib/src/sqlite3.rs | 13 +++++++++++-- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/melib/src/backends/maildir/stream.rs b/melib/src/backends/maildir/stream.rs index 6a674d378..24207708c 100644 --- a/melib/src/backends/maildir/stream.rs +++ b/melib/src/backends/maildir/stream.rs @@ -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 = 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 = 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); { diff --git a/melib/src/sqlite3.rs b/melib/src/sqlite3.rs index ec87dd160..8d221a980 100644 --- a/melib/src/sqlite3.rs +++ b/melib/src/sqlite3.rs @@ -144,8 +144,17 @@ impl ToSql for Envelope { impl FromSql for Envelope { fn column_result(value: rusqlite::types::ValueRef) -> FromSqlResult { + use std::convert::TryFrom; + let b: Vec = 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)))?) } }