Index: src/mail.rs
==================================================================
--- src/mail.rs
+++ src/mail.rs
@@ -7,11 +7,10 @@
validate,
},
};
use std::{
- borrow::Cow,
collections::{
HashMap,
HashSet,
},
io::Error,
@@ -160,15 +159,11 @@
&& let Some(date) = mail.date()
{
reply.push(format!("Date: {date}"));
}
reply.push("
".into());
- //let header_size = reply.join(" ").len();
- let mut header_size = 0;
- for i in reply.iter() {
- header_size += i.len() + 1;
- }
+ let reply = reply.join("\n");
let html_parts = mail.html_body_count();
let text_parts = mail.text_body_count();
let attachments = mail.attachment_count();
if html_parts != text_parts {
@@ -176,11 +171,11 @@
}
//let mut html_num = 0;
let mut text_num = 0;
let mut file_num = 0;
// let's display first html or text part as body
- let mut body: Cow<'_, str> = "".into();
+ let mut body: String = "".into();
/*
* actually I don't wanna parse that html stuff
if html_parts > 0 {
let text = mail.body_html(0).stack()?;
if text.len() < 4096 - header_size {
@@ -189,22 +184,22 @@
}
};
*/
if body.is_empty() && text_parts > 0 {
let text = mail.body_text(0)
- .context("Failed to extract text from message")?;
- // 7:
+ .context("Failed to extract text from message")?
+ .replace("\r\n", "\n");
+ // 6:
+ // - (headers)
// - (mail text)
- // - 1 trailing newline
// - 6:
- if text.len() < 4096 - ( header_size + 7 ) {
+ if text.len() < 4096 - ( reply.len() + 7 ) {
body = text;
text_num = 1;
}
};
- reply.extend(body.lines().map(|x| x.into()));
- reply.push("".into());
+ let msg = format!("{}{}", reply, validate(&body).stack()?);
// and let's collect all other attachment parts
let mut files_to_send = vec![];
/*
* let's just skip html parts for now, they just duplicate text?
@@ -222,11 +217,10 @@
files_to_send.push(mail.attachment(file_num.try_into().stack()?)
.context("Failed to get file part from message.")?);
file_num += 1;
}
- let msg = reply.join("\n");
for chat in rcpt {
if !files_to_send.is_empty() {
let mut files = vec![];
// let mut first_one = true;
for chunk in &files_to_send {
Index: src/main.rs
==================================================================
--- src/main.rs
+++ src/main.rs
@@ -3,10 +3,13 @@
//! available in configuration, everything else is sent to default address.
mod mail;
mod telegram;
mod utils;
+
+#[cfg(test)]
+mod tests;
use crate::mail::MailServer;
use async_compat::Compat;
use just_getopt::{
@@ -50,11 +53,11 @@
let parsed = specs.getopt(args);
for u in &parsed.unknown {
println!("Unknown option: {u}");
}
if !(parsed.unknown.is_empty()) || parsed.options_first("help").is_some() {
- println!("SMTP2TG v{}, (C) 2024 - 2025\n\n\
+ println!("SMTP2TG v{}, (C) 2024 - 2026\n\n\
\t-h|--help\tDisplay this help\n\
\t-c|--config …\tSet configuration file location.",
env!("CARGO_PKG_VERSION"));
return Ok(());
};
Index: src/telegram.rs
==================================================================
--- src/telegram.rs
+++ src/telegram.rs
@@ -1,6 +1,9 @@
-use crate::utils::Attachment;
+use crate::utils::{
+ Attachment,
+ validate,
+};
use std::{
collections::HashMap,
fmt::Debug,
};
@@ -55,11 +58,11 @@
})
}
/// Send message to default user, used for debug/log/info purposes
pub async fn debug (&self, msg: &str) -> Result{msg}")).await
+ self.send(&self.default, format!("{}", validate(msg).stack()?)).await
}
/// Get recipient by address
pub fn get (&self, name: &str) -> Result<&ChatPeerId> {
self.recipients.get(name)
ADDED src/tests.rs
Index: src/tests.rs
==================================================================
--- /dev/null
+++ src/tests.rs
@@ -0,0 +1,22 @@
+use crate::utils::validate;
+
+use stacked_errors::{
+ Result,
+ StackableErr,
+};
+
+#[test]
+fn check_valid () -> Result<()> {
+ let html = "Some valid HTML
"; + let res = validate(html).stack()?; + assert_eq!(res, html); + Ok(()) +} + +#[test] +#[should_panic = "Found special tag while closing generic tag"] +fn check_invalid () -> () { + let html = "Some valid HTML
Link injection!"; + let _ = validate(html).unwrap(); + () +} Index: src/utils.rs ================================================================== --- src/utils.rs +++ src/utils.rs @@ -23,9 +23,8 @@ /// Pass any text here to be validated as HTML, breaks on validation errors pub fn validate (text: &str) -> Result<&str> { let fragment = Html::parse_fragment(text); if !fragment.errors.is_empty() { bail!(fragment.errors.join("\n")); - } else { - Ok(text) } + Ok(text) }