From 81ddac4ead4e39c6aff934c62fedd9f4e757f751 Mon Sep 17 00:00:00 2001 From: Guenter Obiltschnig Date: Thu, 31 Aug 2006 09:33:39 +0000 Subject: [PATCH] bugfixes for upcoming 1.2.2 release --- Net/include/Poco/Net/MailMessage.h | 3 +- Net/include/Poco/Net/MultipartReader.h | 6 ++- Net/src/HTMLForm.cpp | 4 +- Net/src/MailMessage.cpp | 17 +++++++-- Net/src/MultipartReader.cpp | 4 +- Net/src/SocketNotifier.cpp | 4 +- Net/testsuite/src/MultipartReaderTest.cpp | 46 ++++++++++++++++++++++- Net/testsuite/src/MultipartReaderTest.h | 3 +- 8 files changed, 74 insertions(+), 13 deletions(-) diff --git a/Net/include/Poco/Net/MailMessage.h b/Net/include/Poco/Net/MailMessage.h index b5760ab95..2de8f1dae 100644 --- a/Net/include/Poco/Net/MailMessage.h +++ b/Net/include/Poco/Net/MailMessage.h @@ -1,7 +1,7 @@ // // MailMessage.h // -// $Id: //poco/1.2/Net/include/Poco/Net/MailMessage.h#1 $ +// $Id: //poco/1.2/Net/include/Poco/Net/MailMessage.h#2 $ // // Library: Net // Package: Mail @@ -200,6 +200,7 @@ protected: void readHeader(std::istream& istr); void readMultipart(std::istream& istr, PartHandler& handler); void readPart(std::istream& istr, const MessageHeader& header, PartHandler& handler); + void handlePart(std::istream& istr, const MessageHeader& header, PartHandler& handler); static const std::string& contentTransferEncodingToString(ContentTransferEncoding encoding); static int lineLength(const std::string& str); static void appendRecipient(const MailRecipient& recipient, std::string& str); diff --git a/Net/include/Poco/Net/MultipartReader.h b/Net/include/Poco/Net/MultipartReader.h index f8dd7c34c..805166c27 100644 --- a/Net/include/Poco/Net/MultipartReader.h +++ b/Net/include/Poco/Net/MultipartReader.h @@ -1,7 +1,7 @@ // // MultipartReader.h // -// $Id: //poco/1.2/Net/include/Poco/Net/MultipartReader.h#1 $ +// $Id: //poco/1.2/Net/include/Poco/Net/MultipartReader.h#2 $ // // Library: Net // Package: Messages @@ -112,6 +112,10 @@ class Net_API MultipartReader /// an input stream and optionally a boundary string. /// - while hasNextPart() returns true, call nextPart() /// and read the part from stream(). + /// + /// Always ensure that you read all data from the part + /// stream, otherwise the MultipartReader will fail to + /// find the next part. { public: explicit MultipartReader(std::istream& istr); diff --git a/Net/src/HTMLForm.cpp b/Net/src/HTMLForm.cpp index c7b3f3f7e..f021a62a0 100644 --- a/Net/src/HTMLForm.cpp +++ b/Net/src/HTMLForm.cpp @@ -1,7 +1,7 @@ // // HTMLForm.cpp // -// $Id: //poco/1.2/Net/src/HTMLForm.cpp#1 $ +// $Id: //poco/1.2/Net/src/HTMLForm.cpp#2 $ // // Library: Net // Package: HTML @@ -288,6 +288,8 @@ void HTMLForm::readMultipart(std::istream& istr, PartHandler& handler) if (params.has("filename")) { handler.handlePart(header, reader.stream()); + // Ensure that the complete part has been read. + while (reader.stream().good()) reader.stream().get(); } else { diff --git a/Net/src/MailMessage.cpp b/Net/src/MailMessage.cpp index 1c4d9b126..184c54adf 100644 --- a/Net/src/MailMessage.cpp +++ b/Net/src/MailMessage.cpp @@ -1,7 +1,7 @@ // // MailMessage.cpp // -// $Id: //poco/1.2/Net/src/MailMessage.cpp#1 $ +// $Id: //poco/1.2/Net/src/MailMessage.cpp#2 $ // // Library: Net // Package: Mail @@ -405,20 +405,29 @@ void MailMessage::readPart(std::istream& istr, const MessageHeader& header, Part if (icompare(encoding, CTE_QUOTED_PRINTABLE) == 0) { QuotedPrintableDecoder decoder(istr); - handler.handlePart(header, decoder); + handlePart(decoder, header, handler); } else if (icompare(encoding, CTE_BASE64) == 0) { Base64Decoder decoder(istr); - handler.handlePart(header, decoder); + handlePart(decoder, header, handler); } else { - handler.handlePart(header, istr); + handlePart(istr, header, handler); } } +void MailMessage::handlePart(std::istream& istr, const MessageHeader& header, PartHandler& handler) +{ + handler.handlePart(header, istr); + // Read remaining characters from stream in case + // the handler failed to read the complete stream. + while (istr.good()) istr.get(); +} + + void MailMessage::setRecipientHeaders(MessageHeader& headers) const { std::string to; diff --git a/Net/src/MultipartReader.cpp b/Net/src/MultipartReader.cpp index 060e47c8f..cf987a672 100644 --- a/Net/src/MultipartReader.cpp +++ b/Net/src/MultipartReader.cpp @@ -1,7 +1,7 @@ // // MultipartReader.cpp // -// $Id: //poco/1.2/Net/src/MultipartReader.cpp#1 $ +// $Id: //poco/1.2/Net/src/MultipartReader.cpp#2 $ // // Library: Net // Package: Messages @@ -106,8 +106,8 @@ int MultipartStreamBuf::readFromDevice(char* buffer, std::streamsize length) if (ch == '\r') { ch = _istr.get(); // '\n' - return 0; } + return 0; } else if (ch == '-' && _istr.peek() == '-') { diff --git a/Net/src/SocketNotifier.cpp b/Net/src/SocketNotifier.cpp index a95c54988..ab5704045 100644 --- a/Net/src/SocketNotifier.cpp +++ b/Net/src/SocketNotifier.cpp @@ -1,7 +1,7 @@ // // SocketNotifier.cpp // -// $Id: //poco/1.2/Net/src/SocketNotifier.cpp#1 $ +// $Id: //poco/1.2/Net/src/SocketNotifier.cpp#2 $ // // Library: Net // Package: Reactor @@ -64,7 +64,7 @@ void SocketNotifier::addObserver(SocketReactor* pReactor, const Poco::AbstractOb else if (observer.accepts(pReactor->_pErrorNotification)) _events.insert(pReactor->_pErrorNotification.get()); else if (observer.accepts(pReactor->_pTimeoutNotification)) - _events.insert(pReactor->_pErrorNotification.get()); + _events.insert(pReactor->_pTimeoutNotification.get()); } diff --git a/Net/testsuite/src/MultipartReaderTest.cpp b/Net/testsuite/src/MultipartReaderTest.cpp index ddcaaea78..09f190ec7 100644 --- a/Net/testsuite/src/MultipartReaderTest.cpp +++ b/Net/testsuite/src/MultipartReaderTest.cpp @@ -1,7 +1,7 @@ // // MultipartReaderTest.cpp // -// $Id: //poco/1.2/Net/testsuite/src/MultipartReaderTest.cpp#1 $ +// $Id: //poco/1.2/Net/testsuite/src/MultipartReaderTest.cpp#2 $ // // Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH. // and Contributors. @@ -329,6 +329,49 @@ void MultipartReaderTest::testRobustness() } +void MultipartReaderTest::testUnixLineEnds() +{ + std::string s("\n--MIME_boundary_01234567\nname1: value1\n\nthis is part 1\n--MIME_boundary_01234567\n\nthis is part 2\n\n--MIME_boundary_01234567--\n"); + std::istringstream istr(s); + MultipartReader r(istr, "MIME_boundary_01234567"); + assert (r.hasNextPart()); + MessageHeader h; + r.nextPart(h); + assert (h.size() == 1); + assert (h["name1"] == "value1"); + std::istream& i = r.stream(); + int ch = i.get(); + std::string part; + while (ch >= 0) + { + part += (char) ch; + ch = i.get(); + } + assert (part == "this is part 1"); + assert (r.hasNextPart()); + r.nextPart(h); + assert (h.empty()); + std::istream& ii = r.stream(); + part.clear(); + ch = ii.get(); + while (ch >= 0) + { + part += (char) ch; + ch = ii.get(); + } + assert (part == "this is part 2\n"); + + try + { + r.nextPart(h); + fail("no more parts - must throw"); + } + catch (MultipartException&) + { + } +} + + void MultipartReaderTest::setUp() { } @@ -351,6 +394,7 @@ CppUnit::Test* MultipartReaderTest::suite() CppUnit_addTest(pSuite, MultipartReaderTest, testPreamble); CppUnit_addTest(pSuite, MultipartReaderTest, testBadBoundary); CppUnit_addTest(pSuite, MultipartReaderTest, testRobustness); + CppUnit_addTest(pSuite, MultipartReaderTest, testUnixLineEnds); return pSuite; } diff --git a/Net/testsuite/src/MultipartReaderTest.h b/Net/testsuite/src/MultipartReaderTest.h index fe58a7d06..d0e01f5d4 100644 --- a/Net/testsuite/src/MultipartReaderTest.h +++ b/Net/testsuite/src/MultipartReaderTest.h @@ -1,7 +1,7 @@ // // MultipartReaderTest.h // -// $Id: //poco/1.2/Net/testsuite/src/MultipartReaderTest.h#1 $ +// $Id: //poco/1.2/Net/testsuite/src/MultipartReaderTest.h#2 $ // // Definition of the MultipartReaderTest class. // @@ -54,6 +54,7 @@ public: void testPreamble(); void testBadBoundary(); void testRobustness(); + void testUnixLineEnds(); void setUp(); void tearDown();