From d3f539bf92cc48dc448347fe83ccaa9f7fab121a Mon Sep 17 00:00:00 2001 From: Vincent Richard Date: Wed, 20 Feb 2013 16:07:00 +0100 Subject: [PATCH] Fixed SMTP dot stuffing at the beginning of content. --- src/utility/filteredStream.cpp | 25 ++++++++++++++++++++++++- tests/utility/filteredStreamTest.cpp | 6 ++++++ vmime/utility/filteredStream.hpp | 3 ++- 3 files changed, 32 insertions(+), 2 deletions(-) diff --git a/src/utility/filteredStream.cpp b/src/utility/filteredStream.cpp index 526ee79c..9af7b32a 100644 --- a/src/utility/filteredStream.cpp +++ b/src/utility/filteredStream.cpp @@ -137,7 +137,7 @@ stream::size_type dotFilteredInputStream::skip(const size_type /* count */) // dotFilteredOutputStream dotFilteredOutputStream::dotFilteredOutputStream(outputStream& os) - : m_stream(os), m_previousChar('\0') + : m_stream(os), m_previousChar('\0'), m_start(true) { } @@ -158,6 +158,17 @@ void dotFilteredOutputStream::write const value_type* end = data + count; const value_type* start = data; + if (m_previousChar == '.') + { + if (data[0] == '\n' || data[0] == '\r') + { + m_stream.write(".", 1); // extra + m_stream.write(data, 1); + + pos = data + 1; + } + } + // Replace "\n." with "\n.." while ((pos = std::find(pos, end, '.')) != end) { @@ -171,12 +182,24 @@ void dotFilteredOutputStream::write start = pos + 1; } + else if (pos == data && m_start) // at the beginning of content + { + m_stream.write(start, pos - start); + + if (pos + 1 < end && (*(pos + 1) == '\n' || *(pos + 1) == '\r')) + m_stream.write("..", 2); + else + m_stream.write(".", 1); + + start = pos + 1; + } ++pos; } m_stream.write(start, end - start); m_previousChar = data[count - 1]; + m_start = false; } diff --git a/tests/utility/filteredStreamTest.cpp b/tests/utility/filteredStreamTest.cpp index 27ec458f..8dc4d182 100644 --- a/tests/utility/filteredStreamTest.cpp +++ b/tests/utility/filteredStreamTest.cpp @@ -163,6 +163,12 @@ VMIME_TEST_SUITE_BEGIN testFilteredOutputStreamHelper("3", "foo\n..bar", "foo", "\n.bar"); testFilteredOutputStreamHelper("4", "foo\n..bar", "foo", "\n", ".bar"); testFilteredOutputStreamHelper("5", "foo\n..bar", "foo", "\n", ".", "bar"); + + testFilteredOutputStreamHelper("6", "..\nfoobar", ".\nfoobar"); + testFilteredOutputStreamHelper("7", "..\r\nfoobar", ".\r\nfoobar"); + testFilteredOutputStreamHelper("8", "..\r\nfoobar", ".\r", "\nfoobar"); + testFilteredOutputStreamHelper("9", ".foobar", ".foobar"); + testFilteredOutputStreamHelper("10", ".foobar", ".", "foobar"); } void testCRLFToLFFilteredOutputStream() diff --git a/vmime/utility/filteredStream.hpp b/vmime/utility/filteredStream.hpp index eb46143f..b7ec010f 100644 --- a/vmime/utility/filteredStream.hpp +++ b/vmime/utility/filteredStream.hpp @@ -123,8 +123,9 @@ public: private: - outputStream& m_stream; + outputStream& m_stream; value_type m_previousChar; + bool m_start; };