aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/utility/filteredStream.cpp25
-rw-r--r--tests/utility/filteredStreamTest.cpp6
-rw-r--r--vmime/utility/filteredStream.hpp3
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 <DOT>
+ 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) // <DOT><CR><LF> 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<FILTER>("3", "foo\n..bar", "foo", "\n.bar");
testFilteredOutputStreamHelper<FILTER>("4", "foo\n..bar", "foo", "\n", ".bar");
testFilteredOutputStreamHelper<FILTER>("5", "foo\n..bar", "foo", "\n", ".", "bar");
+
+ testFilteredOutputStreamHelper<FILTER>("6", "..\nfoobar", ".\nfoobar");
+ testFilteredOutputStreamHelper<FILTER>("7", "..\r\nfoobar", ".\r\nfoobar");
+ testFilteredOutputStreamHelper<FILTER>("8", "..\r\nfoobar", ".\r", "\nfoobar");
+ testFilteredOutputStreamHelper<FILTER>("9", ".foobar", ".foobar");
+ testFilteredOutputStreamHelper<FILTER>("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;
};