diff --git a/cmd/soroban-cli/src/commands/tx/xdr.rs b/cmd/soroban-cli/src/commands/tx/xdr.rs index f9d0ef0c6..ead4fe89e 100644 --- a/cmd/soroban-cli/src/commands/tx/xdr.rs +++ b/cmd/soroban-cli/src/commands/tx/xdr.rs @@ -54,20 +54,77 @@ impl SkipWhitespace { impl Read for SkipWhitespace { fn read(&mut self, buf: &mut [u8]) -> std::io::Result { - let n = self.inner.read(buf)?; + loop { + let n = self.inner.read(buf)?; + if n == 0 { + return Ok(0); + } + + let mut written = 0; + for read in 0..n { + if !buf[read].is_ascii_whitespace() { + buf[written] = buf[read]; + written += 1; + } + } - let mut written = 0; - for read in 0..n { - if !buf[read].is_ascii_whitespace() { - buf[written] = buf[read]; - written += 1; + if written > 0 { + return Ok(written); } } + } +} + +#[cfg(test)] +mod tests { + use super::*; + use std::io::Cursor; + + #[test] + fn skip_whitespace_preserves_content() { + let input = Cursor::new(b"helloworld"); + let mut reader = SkipWhitespace::new(input); + let mut result = String::new(); + reader.read_to_string(&mut result).unwrap(); + assert_eq!(result, "helloworld"); + } + + #[test] + fn skip_whitespace_strips_all_whitespace_types() { + let input = Cursor::new(b"hello \t\n\r world"); + let mut reader = SkipWhitespace::new(input); + let mut result = String::new(); + reader.read_to_string(&mut result).unwrap(); + assert_eq!(result, "helloworld"); + } + + #[test] + fn skip_whitespace_handles_only_whitespace() { + let input = Cursor::new(b"\n \t \r\n"); + let mut reader = SkipWhitespace::new(input); + let mut result = String::new(); + reader.read_to_string(&mut result).unwrap(); + assert_eq!(result, ""); + } + + #[test] + fn skip_whitespace_handles_empty_input() { + let input = Cursor::new(b""); + let mut reader = SkipWhitespace::new(input); + let mut result = String::new(); + reader.read_to_string(&mut result).unwrap(); + assert_eq!(result, ""); + } - Ok(written) + #[test] + fn skip_whitespace_handles_leading_trailing_whitespace() { + let input = Cursor::new(b"\n\nhello\n\n"); + let mut reader = SkipWhitespace::new(input); + let mut result = String::new(); + reader.read_to_string(&mut result).unwrap(); + assert_eq!(result, "hello"); } } -// pub fn unwrap_envelope_v1(tx_env: TransactionEnvelope) -> Result { let TransactionEnvelope::Tx(TransactionV1Envelope { tx, .. }) = tx_env else {