From 6864fd014995a39a9a1ef01a68bfbf17fbcaa29a Mon Sep 17 00:00:00 2001 From: Dominik Csapak Date: Mon, 25 Jan 2021 12:32:29 +0100 Subject: [PATCH] server/worker_task: improve newline handling in upid_read_status improves upid_read_status with: * ignore multiple newlines at the end * remove all code that could panic (array index access) the one place where we access with '[pos+1..]' is ok since we explicitely test the len of the vector, this is done to let rust optimize away the range checks, so it cannot panic Signed-off-by: Dominik Csapak --- src/server/worker_task.rs | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/src/server/worker_task.rs b/src/server/worker_task.rs index 967814c9..4a73ff0b 100644 --- a/src/server/worker_task.rs +++ b/src/server/worker_task.rs @@ -190,20 +190,15 @@ pub fn upid_read_status(upid: &UPID) -> Result { let mut data = Vec::with_capacity(8192); file.read_to_end(&mut data)?; - // task logs should end with newline, we do not want it here - if !data.is_empty() && data[data.len()-1] == b'\n' { + // strip newlines at the end of the task logs + while data.last() == Some(&b'\n') { data.pop(); } - let last_line = { - let mut start = 0; - for pos in (0..data.len()).rev() { - if data[pos] == b'\n' { - start = data.len().min(pos + 1); - break; - } - } - &data[start..] + let last_line = match data.iter().rposition(|c| *c == b'\n') { + Some(start) if data.len() > (start+1) => &data[start+1..], + Some(_) => &data, // should not happen, since we removed all trailing newlines + None => &data, }; let last_line = std::str::from_utf8(last_line)