Skip to content
Permalink
Browse files
Email body should not be mime encoded
Reviewed-by: ehelin
  • Loading branch information
rwestberg committed Sep 30, 2019
1 parent 527967e commit ffc5e6cad1af25ec58c56b94d5531a7168577a21
@@ -111,10 +111,11 @@ public static Email parse(String raw) {
.filter(entry -> !entry.getKey().equalsIgnoreCase("From"))
.filter(entry -> !entry.getKey().equalsIgnoreCase("Sender"))
.filter(entry -> !entry.getKey().equalsIgnoreCase("To"))
.filter(entry -> !entry.getKey().equalsIgnoreCase("Content-type"))
.collect(Collectors.toMap(Map.Entry::getKey,
entry -> MimeText.decode(entry.getValue())));

return new Email(id, date, recipients, author, sender, subject, MimeText.decode(message.body), filteredHeaders);
return new Email(id, date, recipients, author, sender, subject, message.body, filteredHeaders);
}

public static EmailBuilder create(EmailAddress author, String subject, String body) {
@@ -24,6 +24,7 @@

import java.io.*;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
import java.time.format.DateTimeFormatter;
import java.util.regex.Pattern;

@@ -47,8 +48,8 @@ public static void send(String server, EmailAddress recipient, Email email) thro
port = Integer.parseInt(parts[1]);
}
try (var socket = new Socket(server, port);
var out = new OutputStreamWriter(socket.getOutputStream());
var in = new InputStreamReader(socket.getInputStream())) {
var out = new OutputStreamWriter(socket.getOutputStream(), StandardCharsets.UTF_8);
var in = new InputStreamReader(socket.getInputStream(), StandardCharsets.UTF_8)) {

var session = new SMTPSession(in, out);

@@ -66,8 +67,9 @@ public static void send(String server, EmailAddress recipient, Email email) thro
session.sendCommand(header + ": " + MimeText.encode(email.headerValue(header)));
}
session.sendCommand("Subject: " + MimeText.encode(email.subject()));
session.sendCommand("Content-type: text/plain; charset=utf-8");
session.sendCommand("");
session.sendCommand(MimeText.encode(email.body()));
session.sendCommand(email.body());
session.sendCommand(".", doneReply);
session.sendCommand("QUIT");
}
@@ -129,7 +129,7 @@ public static String fromMail(Email mail) {
mboxMail.println("Message-Id: " + mail.id());
mail.headers().forEach(header -> mboxMail.println(header + ": " + MimeText.encode(mail.headerValue(header))));
mboxMail.println();
mboxMail.println(encodeFromStrings(MimeText.encode(mail.body())));
mboxMail.println(encodeFromStrings(mail.body()));

return mboxString.toString();
}
@@ -55,10 +55,10 @@ private void postNewConversation(Email mail) {
}
}
try {
Files.writeString(file, mboxMail, StandardCharsets.US_ASCII, StandardOpenOption.APPEND);
Files.writeString(file, mboxMail, StandardCharsets.UTF_8, StandardOpenOption.APPEND);
} catch (IOException e) {
try {
Files.writeString(file, mboxMail, StandardCharsets.US_ASCII, StandardOpenOption.CREATE_NEW);
Files.writeString(file, mboxMail, StandardCharsets.UTF_8, StandardOpenOption.CREATE_NEW);
} catch (IOException e1) {
throw new UncheckedIOException(e);
}
@@ -68,7 +68,7 @@ private void postNewConversation(Email mail) {
private void postReply(Email mail) {
var mboxMail = Mbox.fromMail(mail);
try {
Files.writeString(file, mboxMail, StandardCharsets.US_ASCII, StandardOpenOption.APPEND);
Files.writeString(file, mboxMail, StandardCharsets.UTF_8, StandardOpenOption.APPEND);
} catch (IOException e) {
throw new UncheckedIOException(e);
}
@@ -87,7 +87,7 @@ public void post(Email email) {
public List<Conversation> conversations(Duration maxAge) {
String mbox;
try {
mbox = Files.readString(file, StandardCharsets.US_ASCII);
mbox = Files.readString(file, StandardCharsets.UTF_8);
} catch (IOException e) {
log.info("Failed to open mbox file");
log.throwing("MboxFileList", "conversations", e);
@@ -43,6 +43,7 @@ public class SMTPServer implements AutoCloseable {
private static Pattern quitPattern = Pattern.compile("^QUIT$");

private final static Pattern encodeQuotedPrintablePattern = Pattern.compile("([^\\x00-\\x7f]+)");
private final static Pattern headerPattern = Pattern.compile("[^A-Za-z0-9-]+: .+");

private class AcceptThread implements Runnable {
private void handleSession(SMTPSession session) throws IOException {
@@ -54,11 +55,27 @@ private void handleSession(SMTPSession session) throws IOException {
var message = session.readLinesUntil(messageEndPattern);
session.sendCommand("250 MESSAGE OK", quitPattern);

// SMTP is only 7-bit safe, ensure that we break any high ascii passing through here
var quoteMatcher = encodeQuotedPrintablePattern.matcher(String.join("\n", message));
var ascii7message = quoteMatcher.replaceAll(mo -> "HIGH_ASCII");
// Email headers are only 7-bit safe, ensure that we break any high ascii passing through
var inHeader = true;
var mailBody = new StringBuilder();
for (var line : message) {
if (inHeader) {
var headerMatcher = headerPattern.matcher(line);
if (headerMatcher.matches()) {
var quoteMatcher = encodeQuotedPrintablePattern.matcher(String.join("\n", message));
var ascii7line = quoteMatcher.replaceAll(mo -> "HIGH_ASCII");
mailBody.append(ascii7line);
mailBody.append("\n");
continue;
} else {
inHeader = false;
}
}
mailBody.append(line);
mailBody.append("\n");
}

var email = Email.parse(ascii7message);
var email = Email.parse(mailBody.toString());
emails.addLast(email);
}

0 comments on commit ffc5e6c

Please sign in to comment.