mirror of
https://github.com/moparisthebest/k-9
synced 2025-01-12 14:18:02 -05:00
Enforce maximum line length for 8-bit encoded messages transmitted via SMTP (998 characters + CRLF).
Fixes issue 1176
This commit is contained in:
parent
ab4e2ca2ec
commit
6d84f199c5
103
src/com/fsck/k9/mail/transport/LineWrapOutputStream.java
Normal file
103
src/com/fsck/k9/mail/transport/LineWrapOutputStream.java
Normal 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();
|
||||
}
|
||||
}
|
@ -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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user