diff --git a/src/chat/chat_tests.rs b/src/chat/chat_tests.rs index a82cd6305..57821f6a8 100644 --- a/src/chat/chat_tests.rs +++ b/src/chat/chat_tests.rs @@ -2632,12 +2632,6 @@ async fn test_can_send_group() -> Result<()> { /// the recipients can't see the identity of their fellow recipients. #[tokio::test(flavor = "multi_thread", worker_threads = 2)] async fn test_broadcast_members_cant_see_each_other() -> Result<()> { - fn contains(parsed: &MimeMessage, s: &str) -> bool { - assert_eq!(parsed.decrypting_failed, false); - let decoded_str = std::str::from_utf8(&parsed.decoded_data).unwrap(); - decoded_str.contains(s) - } - let mut tcm = TestContextManager::new(); let alice = &tcm.alice().await; let bob = &tcm.bob().await; @@ -2669,8 +2663,8 @@ async fn test_broadcast_members_cant_see_each_other() -> Result<()> { ); let parsed = charlie.parse_msg(&auth_required).await; assert!(parsed.get_header(HeaderDef::AutocryptGossip).is_some()); - assert!(contains(&parsed, "charlie@example.net")); - assert_eq!(contains(&parsed, "bob@example.net"), false); + assert!(parsed.decoded_data_contains("charlie@example.net")); + assert_eq!(parsed.decoded_data_contains("bob@example.net"), false); let parsed_by_bob = bob.parse_msg(&auth_required).await; assert!(parsed_by_bob.decrypting_failed); @@ -2698,8 +2692,8 @@ async fn test_broadcast_members_cant_see_each_other() -> Result<()> { ); let parsed = charlie.parse_msg(&member_added).await; assert!(parsed.get_header(HeaderDef::AutocryptGossip).is_some()); - assert!(contains(&parsed, "charlie@example.net")); - assert_eq!(contains(&parsed, "bob@example.net"), false); + assert!(parsed.decoded_data_contains("charlie@example.net")); + assert_eq!(parsed.decoded_data_contains("bob@example.net"), false); let parsed_by_bob = bob.parse_msg(&member_added).await; assert!(parsed_by_bob.decrypting_failed); @@ -2713,8 +2707,8 @@ async fn test_broadcast_members_cant_see_each_other() -> Result<()> { let hi_msg = alice.send_text(alice_broadcast_id, "hi").await; let parsed = charlie.parse_msg(&hi_msg).await; assert_eq!(parsed.header_exists(HeaderDef::AutocryptGossip), false); - assert_eq!(contains(&parsed, "charlie@example.net"), false); - assert_eq!(contains(&parsed, "bob@example.net"), false); + assert_eq!(parsed.decoded_data_contains("charlie@example.net"), false); + assert_eq!(parsed.decoded_data_contains("bob@example.net"), false); let parsed_by_bob = bob.parse_msg(&hi_msg).await; assert_eq!(parsed_by_bob.decrypting_failed, false); @@ -2730,8 +2724,8 @@ async fn test_broadcast_members_cant_see_each_other() -> Result<()> { "charlie@example.net alice@example.org" ); let parsed = charlie.parse_msg(&member_removed).await; - assert!(contains(&parsed, "charlie@example.net")); - assert_eq!(contains(&parsed, "bob@example.net"), false); + assert!(parsed.decoded_data_contains("charlie@example.net")); + assert_eq!(parsed.decoded_data_contains("bob@example.net"), false); let parsed_by_bob = bob.parse_msg(&member_removed).await; assert!(parsed_by_bob.decrypting_failed); diff --git a/src/headerdef.rs b/src/headerdef.rs index 32c2281b5..c57f05033 100644 --- a/src/headerdef.rs +++ b/src/headerdef.rs @@ -138,6 +138,9 @@ pub enum HeaderDef { /// Advertised gossip topic for one webxdc. IrohGossipTopic, + /// See . + HpOuter, + #[cfg(test)] TestHeader, } diff --git a/src/mimefactory/mimefactory_tests.rs b/src/mimefactory/mimefactory_tests.rs index ce8b12c87..da49904da 100644 --- a/src/mimefactory/mimefactory_tests.rs +++ b/src/mimefactory/mimefactory_tests.rs @@ -837,6 +837,30 @@ async fn test_protected_headers_directive() -> Result<()> { Ok(()) } +#[tokio::test(flavor = "multi_thread", worker_threads = 2)] +async fn test_hp_outer_headers() -> Result<()> { + let mut tcm = TestContextManager::new(); + let t = &tcm.alice().await; + let chat_id = t.get_self_chat().await.id; + + for std_hp_composing in [false, true] { + t.set_config_bool(Config::StdHeaderProtectionComposing, std_hp_composing) + .await?; + chat::send_text_msg(t, chat_id, "hi!".to_string()).await?; + let sent_msg = t.pop_sent_msg().await; + let msg = MimeMessage::from_bytes(t, sent_msg.payload.as_bytes(), None).await?; + assert_eq!(msg.header_exists(HeaderDef::HpOuter), std_hp_composing); + for hdr in ["Date", "From", "Message-ID"] { + assert_eq!( + msg.decoded_data_contains(&format!("HP-Outer: {hdr}:")), + std_hp_composing, + ); + } + assert!(!msg.decoded_data_contains("HP-Outer: Content-Type")); + } + Ok(()) +} + #[tokio::test(flavor = "multi_thread", worker_threads = 2)] async fn test_dont_remove_self() -> Result<()> { let mut tcm = TestContextManager::new(); diff --git a/src/mimeparser.rs b/src/mimeparser.rs index 703b16469..4b50ca2e1 100644 --- a/src/mimeparser.rs +++ b/src/mimeparser.rs @@ -1007,6 +1007,14 @@ impl MimeMessage { self.headers.contains_key(hname) || self.headers_removed.contains(hname) } + #[cfg(test)] + /// Returns whether the decrypted data contains the given `&str`. + pub(crate) fn decoded_data_contains(&self, s: &str) -> bool { + assert!(!self.decrypting_failed); + let decoded_str = str::from_utf8(&self.decoded_data).unwrap(); + decoded_str.contains(s) + } + /// Returns `Chat-Group-ID` header value if it is a valid group ID. pub fn get_chat_group_id(&self) -> Option<&str> { self.get_header(HeaderDef::ChatGroupId)