From 6b168771e07e82c8321aed3042e6ac5d5143023e Mon Sep 17 00:00:00 2001 From: Cristian Thiago Moecke Date: Sat, 22 Feb 2014 13:41:42 -0300 Subject: [PATCH] Fix for bug in MailMessage reported on forum (http://pocoproject.org/forum/viewtopic.php?f=12&t=6106&sid=9283682f915ea148d86813ea140cd3c7). MailMessage was not handling encoding when no Content-Transfer-Encodign header was not present for MultiPart messages, resulting on an Exception. His fix checks if the header is present before getting is value, and defaults to 7bit encoding as in http://www.w3.org/Protocols/rfc1341/5_Content-Transfer-Encoding.html --- Net/src/MailMessage.cpp | 17 ++++--- Net/testsuite/src/MailMessageTest.cpp | 67 +++++++++++++++++++++++++++ Net/testsuite/src/MailMessageTest.h | 2 + 3 files changed, 79 insertions(+), 7 deletions(-) diff --git a/Net/src/MailMessage.cpp b/Net/src/MailMessage.cpp index 6c57c5ddf..289ed8e67 100644 --- a/Net/src/MailMessage.cpp +++ b/Net/src/MailMessage.cpp @@ -104,13 +104,16 @@ namespace { MailMessage::ContentTransferEncoding cte = MailMessage::ENCODING_7BIT; - std::string enc = header[MailMessage::HEADER_CONTENT_TRANSFER_ENCODING]; - if (enc == MailMessage::CTE_8BIT) - cte = MailMessage::ENCODING_8BIT; - else if (enc == MailMessage::CTE_QUOTED_PRINTABLE) - cte = MailMessage::ENCODING_QUOTED_PRINTABLE; - else if (enc == MailMessage::CTE_BASE64) - cte = MailMessage::ENCODING_BASE64; + if(header.has(MailMessage::HEADER_CONTENT_TRANSFER_ENCODING)) + { + std::string enc = header[MailMessage::HEADER_CONTENT_TRANSFER_ENCODING]; + if (enc == MailMessage::CTE_8BIT) + cte = MailMessage::ENCODING_8BIT; + else if (enc == MailMessage::CTE_QUOTED_PRINTABLE) + cte = MailMessage::ENCODING_QUOTED_PRINTABLE; + else if (enc == MailMessage::CTE_BASE64) + cte = MailMessage::ENCODING_BASE64; + } NameValueCollection::ConstIterator it = header.begin(); NameValueCollection::ConstIterator end = header.end(); diff --git a/Net/testsuite/src/MailMessageTest.cpp b/Net/testsuite/src/MailMessageTest.cpp index d58fcce74..5115533a0 100644 --- a/Net/testsuite/src/MailMessageTest.cpp +++ b/Net/testsuite/src/MailMessageTest.cpp @@ -358,6 +358,31 @@ void MailMessageTest::testReadQP() } +void MailMessageTest::testReadDefaultTransferEncoding() +{ + std::istringstream istr( + "Content-Type: text/plain\r\n" + "Date: Thu, 1 Jan 1970 00:00:00 GMT\r\n" + "From: poco@appinf.com\r\n" + "Subject: Test Message\r\n" + "To: John Doe \r\n" + "\r\n" + "Hello, world!\r\n" + "This is a test for the MailMessage class.\r\n" + ); + + MailMessage message; + message.read(istr); + + assert (message.getSender() == "poco@appinf.com"); + assert (message.getContentType() == "text/plain"); + assert (message.getContent() == + "Hello, world!\r\n" + "This is a test for the MailMessage class.\r\n" + ); +} + + void MailMessageTest::testRead8Bit() { std::istringstream istr( @@ -425,6 +450,46 @@ void MailMessageTest::testReadMultiPart() assert (handler.disp()[1] == "attachment; filename=sample.dat"); } +void MailMessageTest::testReadMultiPartDefaultTransferEncoding() +{ + std::istringstream istr( + "Content-Type: multipart/mixed; boundary=MIME_boundary_01234567\r\n" + "Date: Thu, 1 Jan 1970 00:00:00 GMT\r\n" + "From: poco@appinf.com\r\n" + "Mime-Version: 1.0\r\n" + "Subject: Test Message\r\n" + "To: John Doe \r\n" + "\r\n" + "\r\n" + "--MIME_boundary_01234567\r\n" + "Content-Disposition: inline\r\n" + "Content-Type: text/plain\r\n" + "\r\n" + "Hello World!\r\n" + "\r\n" + "--MIME_boundary_01234567\r\n" + "Content-Disposition: attachment; filename=sample.dat\r\n" + "Content-Transfer-Encoding: base64\r\n" + "Content-Type: application/octet-stream; name=sample\r\n" + "\r\n" + "VGhpcyBpcyBzb21lIGJpbmFyeSBkYXRhLiBSZWFsbHku\r\n" + "--MIME_boundary_01234567--\r\n" + ); + + StringPartHandler handler; + MailMessage message; + message.read(istr, handler); + + assert (handler.data().size() == 2); + assert (handler.data()[0] == "Hello World!\r\n"); + assert (handler.type()[0] == "text/plain"); + assert (handler.disp()[0] == "inline"); + + assert (handler.data()[1] == "This is some binary data. Really."); + assert (handler.type()[1] == "application/octet-stream; name=sample"); + assert (handler.disp()[1] == "attachment; filename=sample.dat"); +} + void MailMessageTest::testReadWriteMultiPart() { @@ -573,8 +638,10 @@ CppUnit::Test* MailMessageTest::suite() CppUnit_addTest(pSuite, MailMessageTest, testWriteManyRecipients); CppUnit_addTest(pSuite, MailMessageTest, testWriteMultiPart); CppUnit_addTest(pSuite, MailMessageTest, testReadQP); + CppUnit_addTest(pSuite, MailMessageTest, testReadDefaultTransferEncoding); CppUnit_addTest(pSuite, MailMessageTest, testRead8Bit); CppUnit_addTest(pSuite, MailMessageTest, testReadMultiPart); + CppUnit_addTest(pSuite, MailMessageTest, testReadMultiPartDefaultTransferEncoding); CppUnit_addTest(pSuite, MailMessageTest, testReadWriteMultiPart); CppUnit_addTest(pSuite, MailMessageTest, testReadWriteMultiPartStore); CppUnit_addTest(pSuite, MailMessageTest, testEncodeWord); diff --git a/Net/testsuite/src/MailMessageTest.h b/Net/testsuite/src/MailMessageTest.h index 2a9c3f437..7096ace12 100644 --- a/Net/testsuite/src/MailMessageTest.h +++ b/Net/testsuite/src/MailMessageTest.h @@ -53,9 +53,11 @@ public: void testWriteMultiPart(); void testReadWriteMultiPart(); void testReadWriteMultiPartStore(); + void testReadDefaultTransferEncoding(); void testReadQP(); void testRead8Bit(); void testReadMultiPart(); + void testReadMultiPartDefaultTransferEncoding(); void testEncodeWord(); void setUp();