aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVincent Richard <[email protected]>2014-06-08 16:34:01 +0000
committerVincent Richard <[email protected]>2014-06-08 16:34:01 +0000
commita46e520902de17f1ebedbe870d8c8f3eda4203c1 (patch)
treea11017dfdb30b76acbc66a44cd744cb94fde8d38
parentRemoved useless 'virtual' inheritance (fixed issue #84). (diff)
downloadvmime-a46e520902de17f1ebedbe870d8c8f3eda4203c1.tar.gz
vmime-a46e520902de17f1ebedbe870d8c8f3eda4203c1.zip
Fixed issue #86: workaround for invalid response from Exchange server.
-rw-r--r--src/vmime/net/imap/IMAPParser.hpp64
-rw-r--r--tests/net/imap/IMAPParserTest.cpp35
2 files changed, 90 insertions, 9 deletions
diff --git a/src/vmime/net/imap/IMAPParser.hpp b/src/vmime/net/imap/IMAPParser.hpp
index d38ac14a..c71d4f93 100644
--- a/src/vmime/net/imap/IMAPParser.hpp
+++ b/src/vmime/net/imap/IMAPParser.hpp
@@ -1089,7 +1089,7 @@ public:
DECLARE_COMPONENT(xstring)
xstring(const bool canBeNIL = false, component* comp = NULL, const int data = 0)
- : m_canBeNIL(canBeNIL), m_component(comp), m_data(data)
+ : m_canBeNIL(canBeNIL), m_isNIL(true), m_component(comp), m_data(data)
{
}
@@ -1101,11 +1101,14 @@ public:
VIMAP_PARSER_TRY_CHECK_WITHARG(special_atom, "nil"))
{
// NIL
+ m_isNIL = true;
}
else
{
pos = *currentPos;
+ m_isNIL = false;
+
// quoted ::= <"> *QUOTED_CHAR <">
if (VIMAP_PARSER_TRY_CHECK(one_char <'"'>))
{
@@ -1208,6 +1211,7 @@ public:
private:
bool m_canBeNIL;
+ bool m_isNIL;
string m_value;
component* m_component;
@@ -1215,6 +1219,8 @@ public:
public:
+ bool isNIL() const { return m_isNIL; }
+
const string& value() const { return (m_value); }
void setValue(const string& val) { m_value = val; }
};
@@ -1228,6 +1234,11 @@ public:
{
public:
+ const string getComponentName() const
+ {
+ return "nstring";
+ }
+
nstring(component* comp = NULL, const int data = 0)
: xstring(true, comp, data)
{
@@ -2611,7 +2622,7 @@ public:
// header_fld_name ::= astring
//
- typedef astring header_fld_name;
+ COMPONENT_ALIAS(astring, header_fld_name);
//
@@ -3165,35 +3176,35 @@ public:
// body_fld_desc ::= nstring
//
- typedef nstring body_fld_desc;
+ COMPONENT_ALIAS(nstring, body_fld_desc);
//
// body_fld_id ::= nstring
//
- typedef nstring body_fld_id;
+ COMPONENT_ALIAS(nstring, body_fld_id);
//
// body_fld_md5 ::= nstring
//
- typedef nstring body_fld_md5;
+ COMPONENT_ALIAS(nstring, body_fld_md5);
//
// body_fld_octets ::= number
//
- typedef number body_fld_octets;
+ COMPONENT_ALIAS(number, body_fld_octets);
//
// body_fld_lines ::= number
//
- typedef number body_fld_lines;
+ COMPONENT_ALIAS(number, body_fld_lines);
//
@@ -3201,7 +3212,42 @@ public:
// "QUOTED-PRINTABLE") <">) / string
//
- typedef xstring body_fld_enc;
+ class body_fld_enc : public nstring
+ {
+ public:
+
+ const string getComponentName() const
+ {
+ return "body_fld_enc";
+ }
+
+ body_fld_enc()
+ {
+ }
+
+ bool parseImpl(IMAPParser& parser, string& line, size_t* currentPos)
+ {
+ size_t pos = *currentPos;
+
+ if (!xstring::parseImpl(parser, line, &pos))
+ return false;
+
+ // " When an IMAP4 client sends a FETCH (bodystructure) request
+ // to a server that is running the Exchange Server 2007 IMAP4
+ // service, a corrupted response is sent as a reply "
+ // (see http://support.microsoft.com/kb/975918/en-us)
+ //
+ // Fail in strict mode
+ if (isNIL() && parser.isStrict())
+ {
+ VIMAP_PARSER_FAIL();
+ }
+
+ *currentPos = pos;
+
+ return true;
+ }
+ };
//
@@ -3478,7 +3524,7 @@ public:
// ;; Defined in [MIME-IMT]
//
- typedef xstring media_subtype;
+ COMPONENT_ALIAS(xstring, media_subtype);
//
diff --git a/tests/net/imap/IMAPParserTest.cpp b/tests/net/imap/IMAPParserTest.cpp
index b93e4b58..d98e89a0 100644
--- a/tests/net/imap/IMAPParserTest.cpp
+++ b/tests/net/imap/IMAPParserTest.cpp
@@ -32,6 +32,7 @@ VMIME_TEST_SUITE_BEGIN(IMAPParserTest)
VMIME_TEST_LIST_BEGIN
VMIME_TEST(testExtraSpaceInCapaResponse)
VMIME_TEST(testContinueReqWithoutSpace)
+ VMIME_TEST(testNILValueInBodyFldEnc)
VMIME_TEST_LIST_END
@@ -107,4 +108,38 @@ VMIME_TEST_SUITE_BEGIN(IMAPParserTest)
VASSERT_THROW("strict mode", parser->readResponse(), vmime::exceptions::invalid_response);
}
+ // When an IMAP4 client sends a FETCH (bodystructure) request to a server
+ // that is running the Exchange Server 2007 IMAP4 service, a corrupted
+ // response is sent as a reply
+ // --> http://support.microsoft.com/kb/975918/en-us
+ void testNILValueInBodyFldEnc()
+ {
+ vmime::shared_ptr <testSocket> socket = vmime::make_shared <testSocket>();
+ vmime::shared_ptr <vmime::net::timeoutHandler> toh = vmime::make_shared <testTimeoutHandler>();
+
+ vmime::shared_ptr <vmime::net::imap::IMAPTag> tag =
+ vmime::make_shared <vmime::net::imap::IMAPTag>();
+
+ const char* resp = "* 7970 FETCH (UID 8036 FLAGS () BODYSTRUCTURE (\"text\" \"html\" (\"charset\" \"utf-8\") NIL NIL NIL 175501 1651 NIL NIL NIL NIL) RFC822.HEADER {3}\r\nx\r\n)\r\na001 OK FETCH complete\r\n";
+
+ socket->localSend(resp);
+
+ vmime::shared_ptr <vmime::net::imap::IMAPParser> parser =
+ vmime::make_shared <vmime::net::imap::IMAPParser>();
+
+ parser->setTag(tag);
+ parser->setSocket(socket);
+ parser->setTimeoutHandler(toh);
+
+ parser->setStrict(false);
+ VASSERT_NO_THROW("non-strict mode", parser->readResponse());
+
+ ++(*tag);
+
+ socket->localSend(resp);
+
+ parser->setStrict(true);
+ VASSERT_THROW("strict mode", parser->readResponse(), vmime::exceptions::invalid_response);
+ }
+
VMIME_TEST_SUITE_END