Enforce maximum line length for 8-bit encoded messages transmitted via SMTP (998 characters + CRLF).

Fixes issue 1176
This commit is contained in:
cketti 2010-02-13 23:45:45 +00:00
parent ab4e2ca2ec
commit 6d84f199c5
2 changed files with 106 additions and 3 deletions

View File

@ -0,0 +1,103 @@
package com.fsck.k9.mail.transport;
import java.io.FilterOutputStream;
import java.io.IOException;
import java.io.OutputStream;
public class LineWrapOutputStream extends FilterOutputStream
{
private static final byte[] CRLF = new byte[] {'\r', '\n'};
private byte[] buffer;
private int bufferStart = 0;
private int lineLength = 0;
private int endOfLastWord = 0;
public LineWrapOutputStream(OutputStream out, int maxLineLength)
{
super(out);
buffer = new byte[maxLineLength - 2];
}
@Override
public void write(int oneByte) throws IOException
{
// Buffer full?
if (lineLength == buffer.length)
{
// Usable word-boundary found earlier?
if (endOfLastWord > 0)
{
// Yes, so output everything up to that word-boundary
out.write(buffer, bufferStart, endOfLastWord - bufferStart);
out.write(CRLF);
bufferStart = 0;
// Skip the <SPACE> in the buffer
endOfLastWord++;
lineLength = buffer.length - endOfLastWord;
if (lineLength > 0)
{
// Copy rest of the buffer to the front
for (int i = 0; i < lineLength; i++)
{
buffer[i] = buffer[endOfLastWord + i];
}
}
endOfLastWord = 0;
}
else
{
// No word-boundary found, so output whole buffer
out.write(buffer, bufferStart, buffer.length - bufferStart);
out.write(CRLF);
lineLength = 0;
bufferStart = 0;
}
}
if ((oneByte == '\n') || (oneByte == '\r'))
{
// <CR> or <LF> character found, so output buffer ...
if (lineLength - bufferStart > 0)
{
out.write(buffer, bufferStart, lineLength - bufferStart);
}
// ... and that character
out.write(oneByte);
lineLength = 0;
bufferStart = 0;
endOfLastWord = 0;
}
else
{
// Remember this position as last word-boundary if <SPACE> found
if (oneByte == ' ')
{
endOfLastWord = lineLength;
}
// Write character to the buffer
buffer[lineLength] = (byte)oneByte;
lineLength++;
}
}
@Override
public void flush() throws IOException
{
// Buffer empty?
if (lineLength > bufferStart)
{
// Output everything we have up till now
out.write(buffer, bufferStart, lineLength - bufferStart);
// Mark current position as new start of the buffer
bufferStart = (lineLength == buffer.length) ? 0 : lineLength;
endOfLastWord = 0;
}
out.flush();
}
}

View File

@ -291,8 +291,6 @@ public class SmtpTransport extends Transport
if (m8bitEncodingAllowed)
{
//TODO: Make sure that we don't have lines that are longer than
// 998 bytes (don't count characters!)
message.setEncoding("8bit");
}
@ -319,7 +317,9 @@ public class SmtpTransport extends Transport
EOLConvertingOutputStream msgOut = new EOLConvertingOutputStream(
new SmtpDataStuffing(
new BufferedOutputStream(mOut, 1024)));
new LineWrapOutputStream(
new BufferedOutputStream(mOut, 1024),
1000)));
message.writeTo(msgOut);