From 21b88281ce6d70d2473fdbf02b6642d67bba8a0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Palenica?= Date: Wed, 7 Jul 2021 23:14:50 -0700 Subject: [PATCH] Add test case for malformed input and detect too long messages --- zellij-server/src/decorating_pipe.rs | 33 ++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/zellij-server/src/decorating_pipe.rs b/zellij-server/src/decorating_pipe.rs index 49517629..0d5d2f51 100644 --- a/zellij-server/src/decorating_pipe.rs +++ b/zellij-server/src/decorating_pipe.rs @@ -7,6 +7,8 @@ use log::{error, info}; use serde::{Deserialize, Serialize}; use wasmer_wasi::{WasiFile, WasiFsError}; +// 16kB log buffer +const ZELLIJ_MAX_PIPE_BUFFER_SIZE: usize = 16_384; #[derive(Debug, Serialize, Deserialize)] pub struct DecoratingPipe { buffer: VecDeque, @@ -37,6 +39,19 @@ impl Write for DecoratingPipe { fn write(&mut self, buf: &[u8]) -> std::io::Result { self.buffer.extend(buf); + if self.buffer.len() > ZELLIJ_MAX_PIPE_BUFFER_SIZE { + let error_msg = + "Exceeded log buffer size. Make sure that your plugin calls flush on stderr on \ + valid UTF-8 symbol boundary. Aditionally, make sure that your log message contains \ + endline \\n symbol."; + error!("{}: {}", self.plugin_name, error_msg); + self.buffer.clear(); + return Err(std::io::Error::new( + std::io::ErrorKind::InvalidData, + error_msg, + )); + } + Ok(buf.len()) } @@ -184,4 +199,22 @@ mod decorating_pipe_test { assert_eq!(pipe.buffer.len(), 0); } + + #[test] + fn write_with_incorrect_byte_boundary_does_not_crash() { + let mut pipe = DecoratingPipe::new("TestPipe"); + + let test_buffer = "😱".as_bytes(); + + // make sure it's not valid utf-8 string if we drop last symbol + assert!(std::str::from_utf8(&test_buffer[..test_buffer.len() - 1]).is_err()); + + pipe.write(&test_buffer[..test_buffer.len() - 1]) + .expect("Err write"); + pipe.flush().expect("Err flush"); + + assert_eq!(pipe.buffer.len(), test_buffer.len() - 1); + + println!("len: {}, buf: {:?}", test_buffer.len(), test_buffer); + } }