diff --git a/src/composed/message/types.rs b/src/composed/message/types.rs index 84c33742..67a84381 100644 --- a/src/composed/message/types.rs +++ b/src/composed/message/types.rs @@ -611,7 +611,16 @@ impl Message { } /// Returns the underlying content and `None` if the message is encrypted. + /// + /// Decompresses up to one layer of compressed data. pub fn get_content(&self) -> Result>> { + self.get_content_internal(true) + } + + /// Returns the underlying content and `None` if the message is encrypted. + /// + /// If `decompress` is true, may decompress a compressed message. + fn get_content_internal(&self, decompress: bool) -> Result>> { match self { Message::Literal(ref data) => Ok(Some(data.data().to_vec())), Message::Signed { message, .. } => Ok(message @@ -619,8 +628,12 @@ impl Message { .and_then(|m| m.get_literal()) .map(|l| l.data().to_vec())), Message::Compressed(data) => { - let msg = Message::from_bytes(data.decompress()?)?; - msg.get_content() + if decompress { + let msg = Message::from_bytes(data.decompress()?)?; + msg.get_content_internal(false) + } else { + bail!("Recursive decompression not allowed"); + } } Message::Encrypted { .. } => Ok(None), } @@ -991,4 +1004,13 @@ mod tests { // verify the signature with alice's signing subkey signed_msg.verify(&verify).expect("signature seems bad"); } + + /// Tests that decompressing compression quine does not result in stack overflow. + /// quine.out comes from + /// See for details. + #[test] + fn test_compression_quine() { + let msg = Message::from_bytes(&include_bytes!("../../../tests/quine.out")[..]).unwrap(); + assert!(msg.get_content().is_err()); + } }