summaryrefslogtreecommitdiffstats
path: root/melib
diff options
context:
space:
mode:
authorManos Pitsidianakis <el13635@mail.ntua.gr>2020-11-10 17:24:04 +0200
committerManos Pitsidianakis <el13635@mail.ntua.gr>2020-11-10 17:26:06 +0200
commit2544f541071b890e579236f07b701bffe62951a2 (patch)
treedeabed58430669fc6fd2e6f145d97a44f61cc8a3 /melib
parent72084da18569df449adb16083bf2964a85c9b730 (diff)
melib/compose: prevent bare newlines in finalised drafts
Diffstat (limited to 'melib')
-rw-r--r--melib/src/email/compose.rs89
1 files changed, 51 insertions, 38 deletions
diff --git a/melib/src/email/compose.rs b/melib/src/email/compose.rs
index 4b58c6b1..24481939 100644
--- a/melib/src/email/compose.rs
+++ b/melib/src/email/compose.rs
@@ -221,7 +221,7 @@ impl Draft {
let mut ret = String::new();
for (k, v) in self.headers.deref() {
- ret.extend(format!("{}: {}\n", k, v).chars());
+ ret.push_str(&format!("{}: {}\n", k, v));
}
ret.push('\n');
@@ -246,9 +246,9 @@ impl Draft {
}
for (k, v) in self.headers.deref() {
if v.is_ascii() {
- ret.extend(format!("{}: {}\r\n", k, v).chars());
+ ret.push_str(&format!("{}: {}\r\n", k, v));
} else {
- ret.extend(format!("{}: {}\r\n", k, mime::encode_header(v)).chars());
+ ret.push_str(&format!("{}: {}\r\n", k, mime::encode_header(v)));
}
}
ret.push_str("MIME-Version: 1.0\r\n");
@@ -256,16 +256,19 @@ impl Draft {
if self.attachments.is_empty() {
let content_type: ContentType = Default::default();
let content_transfer_encoding: ContentTransferEncoding = ContentTransferEncoding::_8Bit;
- ret.extend(format!("Content-Type: {}; charset=\"utf-8\"\r\n", content_type).chars());
- ret.extend(
- format!(
- "Content-Transfer-Encoding: {}\r\n",
- content_transfer_encoding
- )
- .chars(),
- );
+ ret.push_str(&format!(
+ "Content-Type: {}; charset=\"utf-8\"\r\n",
+ content_type
+ ));
+ ret.push_str(&format!(
+ "Content-Transfer-Encoding: {}\r\n",
+ content_transfer_encoding
+ ));
ret.push_str("\r\n");
- ret.push_str(&self.body);
+ for line in self.body.lines() {
+ ret.push_str(line);
+ ret.push_str("\r\n");
+ }
} else if self.body.is_empty() && self.attachments.len() == 1 {
let attachment = std::mem::replace(&mut self.attachments, Vec::new()).remove(0);
print_attachment(&mut ret, attachment);
@@ -305,7 +308,7 @@ fn build_multipart(ret: &mut String, kind: MultipartType, parts: Vec<AttachmentB
}
ret.push_str("--");
ret.push_str(&boundary);
- ret.push_str("--\n");
+ ret.push_str("--\r\n");
}
fn print_attachment(ret: &mut String, a: AttachmentBuilder) {
@@ -317,11 +320,17 @@ fn print_attachment(ret: &mut String, a: AttachmentBuilder) {
parameters: ref v,
} if v.is_empty() => {
ret.push_str("\r\n");
- ret.push_str(&String::from_utf8_lossy(a.raw()));
+ for line in String::from_utf8_lossy(a.raw()).lines() {
+ ret.push_str(line);
+ ret.push_str("\r\n");
+ }
ret.push_str("\r\n");
}
Text { .. } => {
- ret.push_str(&a.build().into_raw());
+ for line in a.build().into_raw().lines() {
+ ret.push_str(line);
+ ret.push_str("\r\n");
+ }
ret.push_str("\r\n");
}
Multipart {
@@ -346,7 +355,10 @@ fn print_attachment(ret: &mut String, a: AttachmentBuilder) {
));
ret.push_str("Content-Disposition: attachment\r\n");
ret.push_str("\r\n");
- ret.push_str(&String::from_utf8_lossy(a.raw()));
+ for line in String::from_utf8_lossy(a.raw()).lines() {
+ ret.push_str(line);
+ ret.push_str("\r\n");
+ }
ret.push_str("\r\n");
}
PGPSignature => {
@@ -357,7 +369,10 @@ fn print_attachment(ret: &mut String, a: AttachmentBuilder) {
ret.push_str("Content-Description: Digital signature\r\n");
ret.push_str("Content-Disposition: inline\r\n");
ret.push_str("\r\n");
- ret.push_str(&String::from_utf8_lossy(a.raw()));
+ for line in String::from_utf8_lossy(a.raw()).lines() {
+ ret.push_str(line);
+ ret.push_str("\r\n");
+ }
ret.push_str("\r\n");
}
_ => {
@@ -367,33 +382,31 @@ fn print_attachment(ret: &mut String, a: AttachmentBuilder) {
ContentTransferEncoding::Base64
};
if let Some(name) = a.content_type().name() {
- ret.extend(
- format!(
- "Content-Type: {}; name=\"{}\"; charset=\"utf-8\"\r\n",
- a.content_type(),
- name
- )
- .chars(),
- );
+ ret.push_str(&format!(
+ "Content-Type: {}; name=\"{}\"; charset=\"utf-8\"\r\n",
+ a.content_type(),
+ name
+ ));
} else {
- ret.extend(
- format!("Content-Type: {}; charset=\"utf-8\"\r\n", a.content_type()).chars(),
- );
+ ret.push_str(&format!(
+ "Content-Type: {}; charset=\"utf-8\"\r\n",
+ a.content_type()
+ ));
}
ret.push_str("Content-Disposition: attachment\r\n");
- ret.extend(
- format!(
- "Content-Transfer-Encoding: {}\r\n",
- content_transfer_encoding
- )
- .chars(),
- );
+ ret.push_str(&format!(
+ "Content-Transfer-Encoding: {}\r\n",
+ content_transfer_encoding
+ ));
ret.push_str("\r\n");
if content_transfer_encoding == ContentTransferEncoding::Base64 {
- ret.push_str(&BASE64_MIME.encode(a.raw()).trim());
+ for line in BASE64_MIME.encode(a.raw()).trim().lines() {
+ ret.push_str(line);
+ ret.push_str("\r\n");
+ }
} else {
- for l in unsafe { std::str::from_utf8_unchecked(a.raw()) }.lines() {
- ret.push_str(l);
+ for line in String::from_utf8_lossy(a.raw()).lines() {
+ ret.push_str(line);
ret.push_str("\r\n");
}
}