From f3c938d8c34b462209325398154175aa91698c68 Mon Sep 17 00:00:00 2001 From: Manos Pitsidianakis Date: Fri, 22 Nov 2019 14:17:09 +0200 Subject: [PATCH] Prevent OOM abort when printing large strings --- text_processing/src/lib.rs | 13 +++++++++++++ ui/src/terminal/cells.rs | 5 +++++ ui/src/workers.rs | 7 +++++-- 3 files changed, 23 insertions(+), 2 deletions(-) diff --git a/text_processing/src/lib.rs b/text_processing/src/lib.rs index 025338ff..dc8be708 100644 --- a/text_processing/src/lib.rs +++ b/text_processing/src/lib.rs @@ -7,3 +7,16 @@ pub mod wcwidth; pub use grapheme_clusters::*; pub use line_break::*; pub use wcwidth::*; + +pub trait Truncate { + fn truncate_at_boundary(self, new_len: usize); +} + +impl Truncate for &mut String { + fn truncate_at_boundary(self, mut new_len: usize) { + while new_len > 0 && !self.is_char_boundary(new_len) { + new_len -= 1; + } + String::truncate(self, new_len); + } +} diff --git a/ui/src/terminal/cells.rs b/ui/src/terminal/cells.rs index bc9c1362..926cbd19 100644 --- a/ui/src/terminal/cells.rs +++ b/ui/src/terminal/cells.rs @@ -172,6 +172,11 @@ impl CellBuffer { self.rows = newrows; return; } + + if newlen >= 200_000 { + return; + } + let mut newbuf: Vec = Vec::with_capacity(newlen); for y in 0..newrows { for x in 0..newcols { diff --git a/ui/src/workers.rs b/ui/src/workers.rs index 7aa1c996..8fe2d008 100644 --- a/ui/src/workers.rs +++ b/ui/src/workers.rs @@ -8,6 +8,7 @@ use melib::async_workers::{Work, WorkContext}; use std::sync::Arc; use std::sync::Mutex; use std::thread; +use text_processing::Truncate; const MAX_WORKER: usize = 4; @@ -235,7 +236,8 @@ impl WorkController { } } recv(set_name_rx) -> new_name => { - if let Ok((thread_id, new_name)) = new_name { + if let Ok((thread_id, mut new_name)) = new_name { + new_name.truncate_at_boundary(256); let mut threads = threads_lock.lock().unwrap(); let mut static_threads = _static_threads_lock.lock().unwrap(); if threads.contains_key(&thread_id) { @@ -249,7 +251,8 @@ impl WorkController { } } recv(set_status_rx) -> new_status => { - if let Ok((thread_id, new_status)) = new_status { + if let Ok((thread_id, mut new_status)) = new_status { + new_status.truncate_at_boundary(256); let mut threads = threads_lock.lock().unwrap(); let mut static_threads = _static_threads_lock.lock().unwrap(); if threads.contains_key(&thread_id) {