view src/vmime-1-fixes.patch @ 2333:f653602a0500

Rebrand to new project name MXE
author Volker Grabsch <vog@notjusthosting.com>
date Wed, 28 Mar 2012 15:46:58 +0200
parents 4fac77c58ab7
children 99516e73b368
line wrap: on
line source

This file is part of MXE.
See doc/index.html for further information.

Cherry picked fixes from svn
http://sourceforge.net/projects/vmime/develop

Produced with this script:
#--------------------------------------------------------------------#
#!/usr/bin/env bash

(
  echo "This file is part of MXE."
  echo "See doc/index.html for further information."
  echo
  echo "Cherry picked fixes from svn"
  echo "http://sourceforge.net/projects/vmime/develop"
  echo
  echo "Produced with this script:"
  echo "#--------------------------------------------------------------------#"
  cat "$0"
  echo "#--------------------------------------------------------------------#"
) > src/vmime-1-fixes.patch

# setup git svn clone
#cd ~/projects/vmime/git
#git svn clone -s https://vmime.svn.sourceforge.net/svnroot/vmime
#git reset --hard
# get updates
#git svn fetch
#git svn rebase

GITDIR=~/projects/vmime/git/vmime

(
  cd $GITDIR
  echo
  git format-patch -p --relative=vmime --stdout ":/Version 0.9.1"..master-fixed
) >> src/vmime-1-fixes.patch
#--------------------------------------------------------------------#

From ed4451fd3c86faf9ecc03a59ba9f1ad78417a9f9 Mon Sep 17 00:00:00 2001
From: vincent-richard <vincent-richard@5301114d-f842-0410-bbdd-996ee0417009>
Date: Tue, 16 Nov 2010 13:28:05 +0000
Subject: [PATCH 01/27] Started version 0.9.2.

git-svn-id: https://vmime.svn.sourceforge.net/svnroot/vmime/trunk@576 5301114d-f842-0410-bbdd-996ee0417009

diff --git a/ChangeLog b/ChangeLog
index 871d055..8fdcdb0 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,12 @@
 
+VERSION 0.9.2svn
+================
+
+2010-11-16  Vincent Richard  <vincent@vincent-richard.net>
+
+ * Started version 0.9.2.
+
+
 VERSION 0.9.1
 =============
 
diff --git a/SConstruct b/SConstruct
index fb01edf..55f9223 100644
--- a/SConstruct
+++ b/SConstruct
@@ -29,7 +29,7 @@ import string
 # Package version number
 packageVersionMajor = 0
 packageVersionMinor = 9
-packageVersionMicro = 1
+packageVersionMicro = 2
 
 # API version number (libtool)
 #
-- 
1.7.7.3


From bf282a05cdbbb538a1cafbd7305cece14f5b1571 Mon Sep 17 00:00:00 2001
From: vincent-richard <vincent-richard@5301114d-f842-0410-bbdd-996ee0417009>
Date: Tue, 30 Nov 2010 14:57:03 +0000
Subject: [PATCH 02/27] Initialize and delete object.

git-svn-id: https://vmime.svn.sourceforge.net/svnroot/vmime/trunk@577 5301114d-f842-0410-bbdd-996ee0417009

diff --git a/vmime/net/imap/IMAPParser.hpp b/vmime/net/imap/IMAPParser.hpp
index 0f3e9ec..d71c3ca 100644
--- a/vmime/net/imap/IMAPParser.hpp
+++ b/vmime/net/imap/IMAPParser.hpp
@@ -3823,7 +3823,9 @@ public:
 
 		msg_att_item()
 			: m_date_time(NULL), m_number(NULL), m_envelope(NULL),
-			  m_uniqueid(NULL), m_nstring(NULL), m_body(NULL), m_flag_list(NULL)
+			  m_uniqueid(NULL), m_nstring(NULL), m_body(NULL), m_flag_list(NULL),
+			  m_section(NULL)
+              
 		{
 		}
 
@@ -3836,6 +3838,7 @@ public:
 			delete (m_nstring);
 			delete (m_body);
 			delete (m_flag_list);
+ 			delete (m_section);
 		}
 
 		void go(IMAPParser& parser, string& line, string::size_type* currentPos)
-- 
1.7.7.3


From 941b10bca8e89ca61eebee1345ee3e5cbebd7530 Mon Sep 17 00:00:00 2001
From: vincent-richard <vincent-richard@5301114d-f842-0410-bbdd-996ee0417009>
Date: Mon, 6 Dec 2010 11:57:44 +0000
Subject: [PATCH 03/27] Updated deprecated function.

git-svn-id: https://vmime.svn.sourceforge.net/svnroot/vmime/trunk@578 5301114d-f842-0410-bbdd-996ee0417009

SKIPPED
-- 
1.7.7.3


From 4a4c3a94db671ff7750b32ebf2c998a914717367 Mon Sep 17 00:00:00 2001
From: vincent-richard <vincent-richard@5301114d-f842-0410-bbdd-996ee0417009>
Date: Wed, 8 Dec 2010 08:52:54 +0000
Subject: [PATCH 04/27] No extra space between ':' and '<' in MAIL FROM and
 RCPT TO. Wait for server response after QUIT and
 before closing connection.

git-svn-id: https://vmime.svn.sourceforge.net/svnroot/vmime/trunk@579 5301114d-f842-0410-bbdd-996ee0417009

diff --git a/src/net/smtp/SMTPTransport.cpp b/src/net/smtp/SMTPTransport.cpp
index 204daae..d9fb7b8 100644
--- a/src/net/smtp/SMTPTransport.cpp
+++ b/src/net/smtp/SMTPTransport.cpp
@@ -516,6 +516,7 @@ void SMTPTransport::internalDisconnect()
 	try
 	{
 		sendRequest("QUIT");
+		readResponse();
 	}
 	catch (exception&)
 	{
@@ -565,7 +566,7 @@ void SMTPTransport::send(const mailbox& expeditor, const mailboxList& recipients
 	// Emit the "MAIL" command
 	ref <SMTPResponse> resp;
 
-	sendRequest("MAIL FROM: <" + expeditor.getEmail() + ">");
+	sendRequest("MAIL FROM:<" + expeditor.getEmail() + ">");
 
 	if ((resp = readResponse())->getCode() != 250)
 	{
@@ -578,7 +579,7 @@ void SMTPTransport::send(const mailbox& expeditor, const mailboxList& recipients
 	{
 		const mailbox& mbox = *recipients.getMailboxAt(i);
 
-		sendRequest("RCPT TO: <" + mbox.getEmail() + ">");
+		sendRequest("RCPT TO:<" + mbox.getEmail() + ">");
 
 		if ((resp = readResponse())->getCode() != 250)
 		{
-- 
1.7.7.3


From 4ea325c953f0cdc669b932aa4961a434656f3ecf Mon Sep 17 00:00:00 2001
From: vincent-richard <vincent-richard@5301114d-f842-0410-bbdd-996ee0417009>
Date: Fri, 10 Dec 2010 16:24:06 +0000
Subject: [PATCH 05/27] Fixed unit test after bug fix.

git-svn-id: https://vmime.svn.sourceforge.net/svnroot/vmime/trunk@580 5301114d-f842-0410-bbdd-996ee0417009

diff --git a/tests/net/smtp/SMTPTransportTest.cpp b/tests/net/smtp/SMTPTransportTest.cpp
index 5015552..6552f9e 100644
--- a/tests/net/smtp/SMTPTransportTest.cpp
+++ b/tests/net/smtp/SMTPTransportTest.cpp
@@ -165,7 +165,7 @@ public:
 			}
 			else if (cmd == "MAIL")
 			{
-				VASSERT_EQ("MAIL", std::string("MAIL FROM: <expeditor@test.vmime.org>"), line);
+				VASSERT_EQ("MAIL", std::string("MAIL FROM:<expeditor@test.vmime.org>"), line);
 
 				localSend("250 OK\r\n");
 			}
-- 
1.7.7.3


From ff207927a5aab002f38af0224133b345ab458144 Mon Sep 17 00:00:00 2001
From: vincent-richard <vincent-richard@5301114d-f842-0410-bbdd-996ee0417009>
Date: Fri, 10 Dec 2010 16:54:38 +0000
Subject: [PATCH 06/27] Fixed boundary parsing (thanks to John van der Kamp,
 Zarafa).

git-svn-id: https://vmime.svn.sourceforge.net/svnroot/vmime/trunk@581 5301114d-f842-0410-bbdd-996ee0417009

diff --git a/src/body.cpp b/src/body.cpp
index 13dff6b..738d3e7 100644
--- a/src/body.cpp
+++ b/src/body.cpp
@@ -127,10 +127,30 @@ void body::parse(const string& buffer, const string::size_type position,
 		const string boundarySep("--" + boundary);
 
 		string::size_type partStart = position;
-		string::size_type pos = buffer.find(boundarySep, position);
+		string::size_type pos = position;
 
 		bool lastPart = false;
 
+		while (pos != string::npos && pos < end)
+		{
+			pos = buffer.find(boundarySep, pos);
+
+			if (pos == string::npos ||
+			    ((pos == 0 || buffer[pos - 1] == '\n') &&
+			     (buffer[pos + boundarySep.length()] == '\r' ||
+			      buffer[pos + boundarySep.length()] == '\n' ||
+			      buffer[pos + boundarySep.length()] == '-'
+			     )
+			    )
+			   )
+			{
+				break;
+			}
+
+			// boundary not a beginning of line, or just a prefix of another, continue the search.
+			pos++;
+		}
+
 		if (pos != string::npos && pos < end)
 		{
 			m_prologText = string(buffer.begin() + position, buffer.begin() + pos);
@@ -181,7 +201,26 @@ void body::parse(const string& buffer, const string::size_type position,
 			}
 
 			partStart = pos;
-			pos = buffer.find(boundarySep, partStart);
+
+			while (pos != string::npos && pos < end)
+			{
+				pos = buffer.find(boundarySep, pos);
+
+				if (pos == string::npos ||
+				    ((pos == 0 || buffer[pos - 1] == '\n') &&
+				     (buffer[pos + boundarySep.length()] == '\r' ||
+				      buffer[pos + boundarySep.length()] == '\n' ||
+					buffer[pos + boundarySep.length()] == '-'
+				     )
+				    )
+				   )
+				{
+					break;
+				}
+
+				// boundary not a beginning of line, or just a prefix of another, continue the search.
+				pos++;
+			}
 		}
 
 		m_contents = vmime::create <emptyContentHandler>();
diff --git a/tests/parser/bodyPartTest.cpp b/tests/parser/bodyPartTest.cpp
index 12c4f74..df2bf85 100644
--- a/tests/parser/bodyPartTest.cpp
+++ b/tests/parser/bodyPartTest.cpp
@@ -84,7 +84,7 @@ VMIME_TEST_SUITE_BEGIN
 		vmime::string str =
 			"Content-Type: multipart/mixed; boundary=\"MY-BOUNDARY\""
 			"\r\n\r\n"
-			"--MY-BOUNDARY\r\nHEADER1\r\n\r\nBODY1"
+			"--MY-BOUNDARY\r\nHEADER1\r\n\r\nBODY1\r\n"
 			"--MY-BOUNDARY\r\nHEADER2\r\n\r\nBODY2";
 
 		vmime::bodyPart p;
-- 
1.7.7.3


From 3f5172e47f75f64952adef349bec875416ae9b89 Mon Sep 17 00:00:00 2001
From: vincent-richard <vincent-richard@5301114d-f842-0410-bbdd-996ee0417009>
Date: Fri, 21 Jan 2011 15:28:06 +0000
Subject: [PATCH 07/27] Fixed possible infinite loop (thanks to John van der
 Kamp, Zarafa).

git-svn-id: https://vmime.svn.sourceforge.net/svnroot/vmime/trunk@582 5301114d-f842-0410-bbdd-996ee0417009

diff --git a/src/word.cpp b/src/word.cpp
index db720dc..1c1c1a6 100644
--- a/src/word.cpp
+++ b/src/word.cpp
@@ -386,7 +386,7 @@ void word::generate(utility::outputStream& os, const string::size_type maxLineLe
 
 		maxRunLength = std::max(maxRunLength, curRunLength);
 
-		if (maxRunLength >= maxLineLength - 3)
+		if (((flags & text::FORCE_NO_ENCODING) == 0) && maxRunLength >= maxLineLength - 3)
 		{
 			// Generate with encoding forced
 			generate(os, maxLineLength, curLinePos, newLinePos, flags | text::FORCE_ENCODING, state);
diff --git a/tests/parser/textTest.cpp b/tests/parser/textTest.cpp
index b84f376..746ac94 100644
--- a/tests/parser/textTest.cpp
+++ b/tests/parser/textTest.cpp
@@ -52,6 +52,7 @@ VMIME_TEST_SUITE_BEGIN
 		VMIME_TEST(testWhitespaceMBox)
 
 		VMIME_TEST(testFoldingAscii)
+		VMIME_TEST(testForcedNonEncoding)
 	VMIME_TEST_LIST_END
 
 
@@ -442,5 +443,15 @@ VMIME_TEST_SUITE_BEGIN
 			" =?us-ascii?Q?9012345678901234567890123456789?=", w.generate(50));
 	}
 
+	void testForcedNonEncoding()
+	{
+		// Testing long unbreakable and unencodable header
+		vmime::relay r;
+		r.parse(" from User (Ee9GMqZQ8t7IQwftfAFHd2KyScCYRrFSJ50tKEoXv2bVCG4HcPU80GGWiFabAvG77FekpGgF1h@[127.0.0.1]) by servername.hostname.com\n\t"
+				"with esmtp id 1NGTS9-2C0sqG0; Fri, 4 Dec 2009 09:23:49 +0100");
+
+		VASSERT_EQ("received.long", "from User\r\n (Ee9GMqZQ8t7IQwftfAFHd2KyScCYRrFSJ50tKEoXv2bVCG4HcPU80GGWiFabAvG77FekpGgF1h@[127.0.0.1])\r\n by servername.hostname.com with esmtp id 1NGTS9-2C0sqG0; Fri, 4 Dec 2009\r\n 09:23:49 +0100", r.generate(78));
+	}
+
 VMIME_TEST_SUITE_END
 
-- 
1.7.7.3


From 4e9eb3191066dec7f17592c2ce099b16e6329941 Mon Sep 17 00:00:00 2001
From: vincent-richard <vincent-richard@5301114d-f842-0410-bbdd-996ee0417009>
Date: Fri, 28 Jan 2011 12:11:08 +0000
Subject: [PATCH 08/27] Fixed possible read to invalid memory location (thanks
 to Alexander Konovalov).

git-svn-id: https://vmime.svn.sourceforge.net/svnroot/vmime/trunk@583 5301114d-f842-0410-bbdd-996ee0417009

diff --git a/src/word.cpp b/src/word.cpp
index 1c1c1a6..fa08d33 100644
--- a/src/word.cpp
+++ b/src/word.cpp
@@ -460,7 +460,7 @@ void word::generate(utility::outputStream& os, const string::size_type maxLineLe
 
 					os << string(curLineStart, p);
 
-					if (parserHelpers::isSpace(*(p - 1)))
+					if (p != m_buffer.begin() && parserHelpers::isSpace(*(p - 1)))
 						state->lastCharIsSpace = true;
 					else
 						state->lastCharIsSpace = false;
-- 
1.7.7.3


From 07ebf241115eba44675223e307d212c772e1cc08 Mon Sep 17 00:00:00 2001
From: vincent-richard <vincent-richard@5301114d-f842-0410-bbdd-996ee0417009>
Date: Wed, 9 Mar 2011 18:03:31 +0000
Subject: [PATCH 09/27] Fixed bug #3174903. Fixed word parsing when buffer
 does not end with NL. Fixed 'no encoding' when
 forced.

git-svn-id: https://vmime.svn.sourceforge.net/svnroot/vmime/trunk@584 5301114d-f842-0410-bbdd-996ee0417009

diff --git a/src/body.cpp b/src/body.cpp
index 738d3e7..8596833 100644
--- a/src/body.cpp
+++ b/src/body.cpp
@@ -153,7 +153,10 @@ void body::parse(const string& buffer, const string::size_type position,
 
 		if (pos != string::npos && pos < end)
 		{
-			m_prologText = string(buffer.begin() + position, buffer.begin() + pos);
+			vmime::text text;
+			text.parse(buffer, position, pos);
+
+			m_prologText = text.getWholeBuffer();
 		}
 
 		for (int index = 0 ; !lastPart && (pos != string::npos) && (pos < end) ; ++index)
@@ -246,7 +249,10 @@ void body::parse(const string& buffer, const string::size_type position,
 		// Treat remaining text as epilog
 		else if (partStart < end)
 		{
-			m_epilogText = string(buffer.begin() + partStart, buffer.begin() + end);
+			vmime::text text;
+			text.parse(buffer, partStart, end);
+
+			m_epilogText = text.getWholeBuffer();
 		}
 	}
 	// Treat the contents as 'simple' data
@@ -333,7 +339,7 @@ void body::generate(utility::outputStream& os, const string::size_type maxLineLe
 
 		if (!prologText.empty())
 		{
-			text prolog(word(prologText, getCharset()));
+			text prolog(prologText, vmime::charset("us-ascii"));
 
 			prolog.encodeAndFold(os, maxLineLength, 0,
 				NULL, text::FORCE_NO_ENCODING | text::NO_NEW_LINE_SEQUENCE);
@@ -356,7 +362,7 @@ void body::generate(utility::outputStream& os, const string::size_type maxLineLe
 
 		if (!epilogText.empty())
 		{
-			text epilog(word(epilogText, getCharset()));
+			text epilog(epilogText, vmime::charset("us-ascii"));
 
 			epilog.encodeAndFold(os, maxLineLength, 0,
 				NULL, text::FORCE_NO_ENCODING | text::NO_NEW_LINE_SEQUENCE);
diff --git a/src/word.cpp b/src/word.cpp
index fa08d33..aeaa737 100644
--- a/src/word.cpp
+++ b/src/word.cpp
@@ -102,7 +102,9 @@ ref <word> word::parseNext(const string& buffer, const string::size_type positio
 				++pos;
 
 			unencoded += buffer.substr(startPos, endPos - startPos);
-			unencoded += ' ';
+
+			if (pos != end)  // ignore white-spaces at end
+				unencoded += ' ';
 
 			startPos = pos;
 			continue;
@@ -191,14 +193,15 @@ ref <word> word::parseNext(const string& buffer, const string::size_type positio
 		++pos;
 	}
 
-	// Treat unencoded text at the end of the buffer
-	if (end != startPos)
-	{
-		if (startPos != pos && !isFirst && prevIsEncoded)
-			unencoded += whiteSpaces;
+	if (startPos != end && !isFirst && prevIsEncoded)
+		unencoded += whiteSpaces;
 
+	if (startPos != end)
 		unencoded += buffer.substr(startPos, end - startPos);
 
+	// Treat unencoded text at the end of the buffer
+	if (!unencoded.empty())
+	{
 		ref <word> w = vmime::create <word>(unencoded, charset(charsets::US_ASCII));
 		w->setParsedBounds(position, end);
 
@@ -337,12 +340,14 @@ void word::generate(utility::outputStream& os, const string::size_type maxLineLe
 		state = &defaultGeneratorState;
 
 	// Find out if encoding is forced or required by contents + charset
-	bool encodingNeeded = (flags & text::FORCE_ENCODING) != 0;
+	bool encodingNeeded = false;
 
-	if (encodingNeeded == false)
-		encodingNeeded = wordEncoder::isEncodingNeeded(m_buffer, m_charset);
-	else if ((flags & text::FORCE_NO_ENCODING) != 0)
+	if ((flags & text::FORCE_NO_ENCODING) != 0)
 		encodingNeeded = false;
+	else if ((flags & text::FORCE_ENCODING) != 0)
+		encodingNeeded = true;
+	else  // auto-detect
+		encodingNeeded = wordEncoder::isEncodingNeeded(m_buffer, m_charset);
 
 	// If possible and requested (with flag), quote the buffer (no folding is performed).
 	// Quoting is possible if and only if:
diff --git a/tests/parser/bodyPartTest.cpp b/tests/parser/bodyPartTest.cpp
index df2bf85..b129913 100644
--- a/tests/parser/bodyPartTest.cpp
+++ b/tests/parser/bodyPartTest.cpp
@@ -34,6 +34,8 @@ VMIME_TEST_SUITE_BEGIN
 		VMIME_TEST(testParse)
 		VMIME_TEST(testGenerate)
 		VMIME_TEST(testParseMissingLastBoundary)
+		VMIME_TEST(testPrologEpilog)
+		VMIME_TEST(testPrologEncoding)
 	VMIME_TEST_LIST_END
 
 
@@ -105,5 +107,79 @@ VMIME_TEST_SUITE_BEGIN
 		VASSERT_EQ("1", "Foo: bar\r\n\r\nBaz", p1.generate());
 	}
 
+	void testPrologEpilog()
+	{
+		const char testMail[] =
+			"To: test@vmime.org\r\n"
+			"From: test@vmime.org\r\n"
+			"Subject: Prolog and epilog test\r\n"
+			"Content-Type: multipart/mixed; \r\n"
+			" boundary=\"=_boundary\"\r\n"
+			"\r\n"
+			"Prolog text\r\n"
+			"--=_boundary\r\n"
+			"Content-Type: text/plain\r\n"
+			"\r\n"
+			"Part1\r\n"
+			"--=_boundary--\r\n"
+			"Epilog text";
+
+		vmime::bodyPart part;
+		part.parse(testMail);
+
+		VASSERT_EQ("prolog", "Prolog text", part.getBody()->getPrologText());
+		VASSERT_EQ("epilog", "Epilog text", part.getBody()->getEpilogText());
+	}
+
+	// Test for bug fix: prolog should not be encoded
+	// http://sourceforge.net/tracker/?func=detail&atid=525568&aid=3174903&group_id=69724
+	void testPrologEncoding()
+	{
+		const char testmail[] =
+			"To: test@vmime.org\r\n"
+			"From: test@vmime.org\r\n"
+			"Subject: Prolog encoding test\r\n"
+			"Content-Type: multipart/mixed; \r\n"
+			" boundary=\"=_+ZWjySayKqSf2CyrfnNpaAcO6-G1HpoXdHZ4YyswAWqEY39Q\"\r\n"
+			"\r\n"
+			"This is a multi-part message in MIME format. Your mail reader does not\r\n"
+			"understand MIME message format.\r\n"
+			"--=_+ZWjySayKqSf2CyrfnNpaAcO6-G1HpoXdHZ4YyswAWqEY39Q\r\n"
+			"Content-Type: text/html; charset=windows-1251\r\n"
+			"Content-Transfer-Encoding: quoted-printable\r\n"
+			"\r\n"
+			"=DD=F2=EE =F2=E5=EA=F1=F2=EE=E2=E0=FF =F7=E0=F1=F2=FC =F1=EB=EE=E6=ED=EE=E3=\r\n"
+			"=EE =F1=EE=EE=E1=F9=E5=ED=E8=FF\r\n"
+			"--=_+ZWjySayKqSf2CyrfnNpaAcO6-G1HpoXdHZ4YyswAWqEY39Q\r\n"
+			"Content-Type: application/octet-stream; charset=windows-1251\r\n"
+			"Content-Disposition: attachment; filename=FNS.zip\r\n"
+			"Content-Transfer-Encoding: base64\r\n"
+			"\r\n"
+			"UEsDBB...snap...EEAAAAAA==\r\n"
+			"--=_+ZWjySayKqSf2CyrfnNpaAcO6-G1HpoXdHZ4YyswAWqEY39Q--\r\n"
+			"Epilog text";
+
+		vmime::ref<vmime::message> msg = vmime::create<vmime::message>();
+
+		std::string istr(testmail);
+
+		std::string ostr;
+		vmime::utility::outputStreamStringAdapter out(ostr);
+
+		for (int i = 0 ; i < 10 ; ++i)
+		{
+			ostr.clear();
+
+			msg->parse(istr);
+			msg->generate(out);
+
+			istr = ostr;
+		}
+
+		VASSERT_EQ("prolog", "This is a multi-part message in MIME format. Your mail reader"
+					   " does not understand MIME message format.", msg->getBody()->getPrologText());
+		VASSERT_EQ("epilog", "Epilog text", msg->getBody()->getEpilogText());
+	}
+
 VMIME_TEST_SUITE_END
 
-- 
1.7.7.3


From 22ca7dc23b6bbbc8cc6aedd569ec938ecae96e92 Mon Sep 17 00:00:00 2001
From: vincent-richard <vincent-richard@5301114d-f842-0410-bbdd-996ee0417009>
Date: Sun, 27 Mar 2011 11:26:55 +0000
Subject: [PATCH 10/27] Allow static linking in MXE. Added 'iconv'
 and uses 'ws2_32' instead of 'winsock32' (#3213487).

git-svn-id: https://vmime.svn.sourceforge.net/svnroot/vmime/trunk@585 5301114d-f842-0410-bbdd-996ee0417009

diff --git a/SConstruct b/SConstruct
index 55f9223..177f5b4 100644
--- a/SConstruct
+++ b/SConstruct
@@ -1089,7 +1089,7 @@ def generateAutotools(target, source, env):
 	vmime_pc_in.write("Description: " + packageDescription + "\n")
 	vmime_pc_in.write("Version: @VERSION@\n")
 	vmime_pc_in.write("Requires: @GSASL_REQUIRED@\n")
-	vmime_pc_in.write("Libs: -L${libdir} -l@GENERIC_VERSIONED_LIBRARY_NAME@ @GSASL_LIBS@ @LIBGNUTLS_LIBS@ @VMIME_ADDITIONAL_PC_LIBS@\n")
+	vmime_pc_in.write("Libs: -L${libdir} -l@GENERIC_VERSIONED_LIBRARY_NAME@ @GSASL_LIBS@ @LIBGNUTLS_LIBS@ @LIBICONV@ @PTHREAD_LIBS@ @VMIME_ADDITIONAL_PC_LIBS@\n")
 	#vmime_pc_in.write("Cflags: -I${includedir}/@GENERIC_VERSIONED_LIBRARY_NAME@\n")
 	vmime_pc_in.write("Cflags: -I${includedir}/ @LIBGNUTLS_CFLAGS@\n")
 	vmime_pc_in.close()
@@ -1709,7 +1709,7 @@ fi
 
 # -- Link with Winsock (Windows)
 if test "x$VMIME_DETECT_PLATFORM" = "xwindows"; then
-	VMIME_ADDITIONAL_PC_LIBS="$VMIME_ADDITIONAL_PC_LIBS -lwsock32"
+	VMIME_ADDITIONAL_PC_LIBS="$VMIME_ADDITIONAL_PC_LIBS -lws2_32"
 fi
 
 # -- getaddrinfo (POSIX)
-- 
1.7.7.3


From 9e06cc39d47e2eba8f554b337d472cc995be0d9d Mon Sep 17 00:00:00 2001
From: vincent-richard <vincent-richard@5301114d-f842-0410-bbdd-996ee0417009>
Date: Thu, 31 Mar 2011 19:13:03 +0000
Subject: [PATCH 11/27] Flush stateful data from iconv (thanks to John van der
 Kamp, Zarafa).

git-svn-id: https://vmime.svn.sourceforge.net/svnroot/vmime/trunk@586 5301114d-f842-0410-bbdd-996ee0417009

diff --git a/src/charsetConverter.cpp b/src/charsetConverter.cpp
index 38b9e5e..2135788 100644
--- a/src/charsetConverter.cpp
+++ b/src/charsetConverter.cpp
@@ -119,6 +119,7 @@ void charsetConverter::convert(utility::inputStream& in, utility::outputStream&
 	size_t inPos = 0;
 
 	bool prevIsInvalid = false;
+	bool breakAfterNext = false;
 
 	while (true)
 	{
@@ -126,11 +127,12 @@ void charsetConverter::convert(utility::inputStream& in, utility::outputStream&
 		size_t inLength = static_cast <size_t>(in.read(inBuffer + inPos, sizeof(inBuffer) - inPos) + inPos);
 		size_t outLength = sizeof(outBuffer);
 
-		const char* inPtr = inBuffer;
+		const char* inPtr = breakAfterNext ? NULL : inBuffer;
+		size_t *ptrLength = breakAfterNext ? NULL : &inLength;
 		char* outPtr = outBuffer;
 
 		// Convert input bytes
-		if (iconv(cd, ICONV_HACK(&inPtr), &inLength,
+		if (iconv(cd, ICONV_HACK(&inPtr), ptrLength,
 			      &outPtr, &outLength) == static_cast <size_t>(-1))
 		{
 			// Illegal input sequence or input sequence has no equivalent
@@ -170,9 +172,12 @@ void charsetConverter::convert(utility::inputStream& in, utility::outputStream&
 			prevIsInvalid = false;
 		}
 
-		// Check for end of data
-		if (in.eof() && inPos == 0)
+		if (breakAfterNext)
 			break;
+
+		// Check for end of data, loop again to flush stateful data from iconv
+		if (in.eof() && inPos == 0)
+			breakAfterNext = true;
 	}
 }
 
diff --git a/tests/parser/charsetTest.cpp b/tests/parser/charsetTest.cpp
index 8ad71d7..54a09a7 100644
--- a/tests/parser/charsetTest.cpp
+++ b/tests/parser/charsetTest.cpp
@@ -100,6 +100,7 @@ VMIME_TEST_SUITE_BEGIN
 		VMIME_TEST(testFilterValid1)
 		VMIME_TEST(testFilterValid2)
 		VMIME_TEST(testFilterValid3)
+		VMIME_TEST(testEncodingHebrew1255)
 
 		// Test invalid input
 		VMIME_TEST(testFilterInvalid1)
@@ -227,6 +228,15 @@ VMIME_TEST_SUITE_BEGIN
 		VASSERT_EQ("1", toHex(expectedOut), toHex(actualOut));
 	}
 
+	void testEncodingHebrew1255()
+	{
+		// hewbrew string in windows-1255 charset
+		const char data[] = "\xe9\xf9\xf7\xf8\xe9\xf9\xf8\xf7\xe9\xe9\xf9";
+		vmime::word w = vmime::word(data, "windows-1255");
+		vmime::string encoded = w.generate();
+		// less than 60% ascii, base64 received
+		VASSERT_EQ("1", "=?windows-1255?B?6fn3+On5+Pfp6fk=?=", encoded);
+	}
 
 	// Conversion to hexadecimal for easier debugging
 	static const vmime::string toHex(const vmime::string str)
-- 
1.7.7.3


From 418a39a7d33921672bd1c4beb31c8a31bc87d8dd Mon Sep 17 00:00:00 2001
From: vincent-richard <vincent-richard@5301114d-f842-0410-bbdd-996ee0417009>
Date: Fri, 10 Jun 2011 19:39:09 +0000
Subject: [PATCH 12/27] Requested email change.

git-svn-id: https://vmime.svn.sourceforge.net/svnroot/vmime/trunk@587 5301114d-f842-0410-bbdd-996ee0417009

diff --git a/AUTHORS b/AUTHORS
index 20a0181..bbddb30 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -21,7 +21,7 @@ AUTHORS file.
  - Rafael Fernandez <prf@adinet.com.uy>
  - Xin Li <lixin3@staff.sina.com.cn>
  - Benjamin Biron <benbiron@gmail.com>
- - Bertrand Benoit <bsquare@bsquare.levillage.org>
+ - Bertrand Benoit <projettwk@users.sourceforge.net>
  - Tim Teulings <rael@edge.ping.de>
  - Georg Sauthoff <gsauthof@techfak.uni-bielefeld.de>
  - Pierre Thierry <nowhere.man@levallois.eu.org> (patches for STL algorithms)
-- 
1.7.7.3


From 4008955783ef566b98b16762c7bfa28df26e9198 Mon Sep 17 00:00:00 2001
From: vincent-richard <vincent-richard@5301114d-f842-0410-bbdd-996ee0417009>
Date: Tue, 14 Jun 2011 18:37:54 +0000
Subject: [PATCH 13/27] Fixed compilation issue following namespace change.

git-svn-id: https://vmime.svn.sourceforge.net/svnroot/vmime/trunk@588 5301114d-f842-0410-bbdd-996ee0417009

diff --git a/examples/example7.cpp b/examples/example7.cpp
index 1ddb3d0..243b1da 100644
--- a/examples/example7.cpp
+++ b/examples/example7.cpp
@@ -43,18 +43,18 @@ int main()
 	vmime::platform::setHandler<vmime::platforms::posix::posixHandler>();
 
 	// Enumerate encoders
-	vmime::encoderFactory* ef = vmime::encoderFactory::getInstance();
+	vmime::utility::encoder::encoderFactory* ef = vmime::utility::encoder::encoderFactory::getInstance();
 
 	std::cout << "Available encoders:" << std::endl;
 
 	for (int i = 0 ; i < ef->getEncoderCount() ; ++i)
 	{
-		vmime::ref <const vmime::encoderFactory::registeredEncoder>
+		vmime::ref <const vmime::utility::encoder::encoderFactory::registeredEncoder>
 			enc = ef->getEncoderAt(i);
 
 		std::cout << "  * " << enc->getName() << std::endl;
 
-		vmime::ref <vmime::encoder> e = enc->create();
+		vmime::ref <vmime::utility::encoder::encoder> e = enc->create();
 
 		std::vector <vmime::string> props = e->getAvailableProperties();
 
-- 
1.7.7.3


From e80db1ce802a45b71659d16d77ea47368beeabc1 Mon Sep 17 00:00:00 2001
From: vincent-richard <vincent-richard@5301114d-f842-0410-bbdd-996ee0417009>
Date: Sun, 19 Jun 2011 17:51:33 +0000
Subject: [PATCH 14/27] Fixed parsing of an attachment filename that is
 between 66 and 76 characters long (Zarafa).

git-svn-id: https://vmime.svn.sourceforge.net/svnroot/vmime/trunk@589 5301114d-f842-0410-bbdd-996ee0417009

diff --git a/src/parameter.cpp b/src/parameter.cpp
index 91a7e5c..f59d5ab 100644
--- a/src/parameter.cpp
+++ b/src/parameter.cpp
@@ -281,7 +281,8 @@ void parameter::generate(utility::outputStream& os, const string::size_type maxL
 	bool needQuoting = false;
 	string::size_type valueLength = 0;
 
-	for (string::size_type i = 0 ; (i < value.length()) && (pos + valueLength < maxLineLength - 4) ; ++i, ++valueLength)
+	// Use worst-case length name.length()+2 for 'name=' part of line
+	for (string::size_type i = 0 ; (i < value.length()) && (pos + name.length() + 2 + valueLength < maxLineLength - 4) ; ++i, ++valueLength)
 	{
 		switch (value[i])
 		{
-- 
1.7.7.3


From 58316dddddbfe8a7c582aa52e9abff8ca3a227b6 Mon Sep 17 00:00:00 2001
From: vincent-richard <vincent-richard@5301114d-f842-0410-bbdd-996ee0417009>
Date: Sun, 19 Jun 2011 18:08:12 +0000
Subject: [PATCH 15/27] Correctly generate attachment names which are long and
 have high characters for Outlook Express (Zarafa).

git-svn-id: https://vmime.svn.sourceforge.net/svnroot/vmime/trunk@590 5301114d-f842-0410-bbdd-996ee0417009

diff --git a/src/parameter.cpp b/src/parameter.cpp
index f59d5ab..d757e1b 100644
--- a/src/parameter.cpp
+++ b/src/parameter.cpp
@@ -268,17 +268,19 @@ void parameter::generate(utility::outputStream& os, const string::size_type maxL
 	// value is to be generated.
 
 	// A stream for a temporary storage
-	std::ostringstream sevenBitBuffer;
+	std::string sevenBitBuffer;
+	utility::outputStreamStringAdapter sevenBitStream(sevenBitBuffer);
 
 	string::size_type pos = curLinePos;
 
 	if (pos + name.length() + 10 + value.length() > maxLineLength)
 	{
-		sevenBitBuffer << NEW_LINE_SEQUENCE;
+		sevenBitStream << NEW_LINE_SEQUENCE;
 		pos = NEW_LINE_SEQUENCE_LENGTH;
 	}
 
 	bool needQuoting = false;
+	bool needQuotedPrintable = false;
 	string::size_type valueLength = 0;
 
 	// Use worst-case length name.length()+2 for 'name=' part of line
@@ -308,6 +310,16 @@ void parameter::generate(utility::outputStream& os, const string::size_type maxL
 
 			needQuoting = true;
 			break;
+
+		default:
+
+			if (!parserHelpers::isAscii(value[i]))
+			{
+				needQuotedPrintable = true;
+				needQuoting = true;
+			}
+
+			break;
 		}
 	}
 
@@ -315,12 +327,12 @@ void parameter::generate(utility::outputStream& os, const string::size_type maxL
 
 	if (needQuoting)
 	{
-		sevenBitBuffer << name << "=\"";
+		sevenBitStream << name << "=\"";
 		pos += name.length() + 2;
 	}
 	else
 	{
-		sevenBitBuffer << name << "=";
+		sevenBitStream << name << "=";
 		pos += name.length() + 1;
 	}
 
@@ -332,29 +344,43 @@ void parameter::generate(utility::outputStream& os, const string::size_type maxL
 	const bool alwaysEncode = m_value.getCharset().getRecommendedEncoding(recommendedEnc);
 	bool extended = alwaysEncode;
 
-	for (string::size_type i = 0 ; (i < value.length()) && (pos < maxLineLength - 4) ; ++i)
+	if (needQuotedPrintable)
 	{
-		const char_t c = value[i];
-
-		if (/* needQuoting && */ (c == '"' || c == '\\'))  // 'needQuoting' is implicit
-		{
-			sevenBitBuffer << '\\' << value[i];  // escape 'x' with '\x'
-			pos += 2;
-		}
-		else if (parserHelpers::isAscii(c))
-		{
-			sevenBitBuffer << value[i];
-			++pos;
-		}
-		else
+		// Send the name in quoted-printable, so outlook express et.al.
+		// will understand the real filename
+		size_t oldLen = sevenBitBuffer.length();
+		m_value.generate(sevenBitStream);
+		pos += sevenBitBuffer.length() - oldLen;
+		extended = true;		// also send with RFC-2231 encoding
+	}
+	else
+	{
+		// Do not chop off this value, but just add the complete name as one header line.
+		for (string::size_type i = 0 ; i < value.length() ; ++i)
 		{
-			extended = true;
+			const char_t c = value[i];
+
+			if (/* needQuoting && */ (c == '"' || c == '\\'))  // 'needQuoting' is implicit
+			{
+				sevenBitStream << '\\' << value[i];  // escape 'x' with '\x'
+				pos += 2;
+			}
+			else if (parserHelpers::isAscii(c))
+			{
+				sevenBitStream << value[i];
+				++pos;
+			}
+			else
+			{
+				extended = true;
+			}
 		}
-	}
+
+	} // !needQuotedPrintable
 
 	if (needQuoting)
 	{
-		sevenBitBuffer << '"';
+		sevenBitStream << '"';
 		++pos;
 	}
 
@@ -532,7 +558,7 @@ void parameter::generate(utility::outputStream& os, const string::size_type maxL
 		// "7bit/us-ascii" will suffice in this case.
 
 		// Output what has been stored in temporary buffer so far
-		os << sevenBitBuffer.str();
+		os << sevenBitBuffer;
 	}
 #endif // !VMIME_ALWAYS_GENERATE_7BIT_PARAMETER
 
-- 
1.7.7.3


From f7ad17cffea462faf8cbe4f785644da0f3ee812a Mon Sep 17 00:00:00 2001
From: vincent-richard <vincent-richard@5301114d-f842-0410-bbdd-996ee0417009>
Date: Sun, 19 Jun 2011 18:16:49 +0000
Subject: [PATCH 16/27] Alias for UTF-7 charset.

git-svn-id: https://vmime.svn.sourceforge.net/svnroot/vmime/trunk@591 5301114d-f842-0410-bbdd-996ee0417009

diff --git a/src/charset.cpp b/src/charset.cpp
index e043186..0fda450 100644
--- a/src/charset.cpp
+++ b/src/charset.cpp
@@ -45,6 +45,9 @@ charset::charset()
 charset::charset(const string& name)
 	: m_name(name)
 {
+	// If we receive this rfc-1642 valid MIME charset, convert it to something usefull for iconv
+	if (utility::stringUtils::isStringEqualNoCase(m_name, "unicode-1-1-utf-7"))
+		m_name = "utf-7";
 }
 
 
@@ -60,6 +63,10 @@ void charset::parse(const string& buffer, const string::size_type position,
 	m_name = utility::stringUtils::trim
 		(string(buffer.begin() + position, buffer.begin() + end));
 
+	// If we parsed this rfc-1642 valid MIME charset, convert it to something usefull for iconv
+	if (utility::stringUtils::isStringEqualNoCase(m_name, "unicode-1-1-utf-7"))
+		m_name = "utf-7";
+
 	setParsedBounds(position, end);
 
 	if (newPosition)
-- 
1.7.7.3


From eac20f47a33a7fdd617f9fd905b8029621259269 Mon Sep 17 00:00:00 2001
From: vincent-richard <vincent-richard@5301114d-f842-0410-bbdd-996ee0417009>
Date: Sun, 19 Jun 2011 18:39:35 +0000
Subject: [PATCH 17/27] Fixed messageBuilder to accept an empty mailbox group
 in 'To:' field, to allow for undisclosed-recipients
 (Zarafa).

git-svn-id: https://vmime.svn.sourceforge.net/svnroot/vmime/trunk@592 5301114d-f842-0410-bbdd-996ee0417009

diff --git a/src/messageBuilder.cpp b/src/messageBuilder.cpp
index 870d59e..3597b3a 100644
--- a/src/messageBuilder.cpp
+++ b/src/messageBuilder.cpp
@@ -51,17 +51,15 @@ ref <message> messageBuilder::construct() const
 	// Generate the header fields
 	msg->getHeader()->Subject()->setValue(m_subject);
 
-	if (m_from.isEmpty())
-		throw exceptions::no_expeditor();
-
-	if ((m_to.isEmpty() || m_to.getAddressAt(0)->isEmpty()) &&
+	if (((m_to.isEmpty()) || (m_to.getAddressAt(0)->isEmpty() && !m_to.getAddressAt(0)->isGroup())) &&
 	    (m_cc.isEmpty() || m_cc.getAddressAt(0)->isEmpty()) &&
 	    (m_bcc.isEmpty() || m_bcc.getAddressAt(0)->isEmpty()))
 	{
 		throw exceptions::no_recipient();
 	}
 
-	msg->getHeader()->From()->setValue(m_from);
+	if (!m_from.isEmpty())
+		msg->getHeader()->From()->setValue(m_from);
 
 	if (!m_to.isEmpty())
 		msg->getHeader()->To()->setValue(m_to);
-- 
1.7.7.3


From 1e5dfa80a63b0a7fe90406ce4a3de1593f2e4045 Mon Sep 17 00:00:00 2001
From: vincent-richard <vincent-richard@5301114d-f842-0410-bbdd-996ee0417009>
Date: Sun, 19 Jun 2011 18:49:55 +0000
Subject: [PATCH 18/27] Added support for mailboxes that specify an (encoded)
 full name with an empty email address, set by a <>
 marker (Zarafa).

git-svn-id: https://vmime.svn.sourceforge.net/svnroot/vmime/trunk@593 5301114d-f842-0410-bbdd-996ee0417009

diff --git a/src/mailbox.cpp b/src/mailbox.cpp
index 5cb0139..fea7479 100644
--- a/src/mailbox.cpp
+++ b/src/mailbox.cpp
@@ -88,6 +88,7 @@ void mailbox::parse(const string& buffer, const string::size_type position,
 	// Temporary buffers for extracted name and address
 	string name;
 	string address;
+	bool hadBrackets = false;
 
 	while (p < pend)
 	{
@@ -283,6 +284,7 @@ void mailbox::parse(const string& buffer, const string::size_type position,
 				}
 				else if (*p == '>')
 				{
+					hadBrackets = true;
 					break;
 				}
 				else if (!parserHelpers::isSpace(*p))
@@ -309,7 +311,7 @@ void mailbox::parse(const string& buffer, const string::size_type position,
 
 	// Swap name and address when no address was found
 	// (email address is mandatory, whereas name is optional).
-	if (address.empty() && !name.empty())
+	if (address.empty() && !name.empty() && !hadBrackets)
 	{
 		m_email.clear();
 		m_email.reserve(name.size());
diff --git a/tests/parser/mailboxTest.cpp b/tests/parser/mailboxTest.cpp
index 8411daa..9ebadca 100644
--- a/tests/parser/mailboxTest.cpp
+++ b/tests/parser/mailboxTest.cpp
@@ -32,6 +32,7 @@ VMIME_TEST_SUITE_BEGIN
 
 	VMIME_TEST_LIST_BEGIN
 		VMIME_TEST(testParse)
+		VMIME_TEST(testEmptyEmailAddress)
 	VMIME_TEST_LIST_END
 
 
@@ -113,5 +114,19 @@ VMIME_TEST_SUITE_BEGIN
 		}
 	}
 
+	void testEmptyEmailAddress()
+	{
+		vmime::addressList addrList;
+		addrList.parse("\"Full Name\" <>");
+
+		VASSERT_EQ("count", 1, addrList.getAddressCount());
+		VASSERT_EQ("!group", false, addrList.getAddressAt(0)->isGroup());
+
+		vmime::ref <vmime::mailbox> mbox = addrList.getAddressAt(0).dynamicCast <vmime::mailbox>();
+
+		VASSERT_EQ("name", "Full Name", mbox->getName());
+		VASSERT_EQ("email", "", mbox->getEmail());
+	}
+
 VMIME_TEST_SUITE_END
 
-- 
1.7.7.3


From 960f2195516eb776eea7b7e4f92612192edfdcd9 Mon Sep 17 00:00:00 2001
From: vincent-richard <vincent-richard@5301114d-f842-0410-bbdd-996ee0417009>
Date: Fri, 24 Jun 2011 15:46:23 +0000
Subject: [PATCH 19/27] Added missing libs in pkg-config file.

git-svn-id: https://vmime.svn.sourceforge.net/svnroot/vmime/trunk@594 5301114d-f842-0410-bbdd-996ee0417009

diff --git a/SConstruct b/SConstruct
index 177f5b4..37c0ac6 100644
--- a/SConstruct
+++ b/SConstruct
@@ -1089,7 +1089,7 @@ def generateAutotools(target, source, env):
 	vmime_pc_in.write("Description: " + packageDescription + "\n")
 	vmime_pc_in.write("Version: @VERSION@\n")
 	vmime_pc_in.write("Requires: @GSASL_REQUIRED@\n")
-	vmime_pc_in.write("Libs: -L${libdir} -l@GENERIC_VERSIONED_LIBRARY_NAME@ @GSASL_LIBS@ @LIBGNUTLS_LIBS@ @LIBICONV@ @PTHREAD_LIBS@ @VMIME_ADDITIONAL_PC_LIBS@\n")
+	vmime_pc_in.write("Libs: -L${libdir} -l@GENERIC_VERSIONED_LIBRARY_NAME@ @GSASL_LIBS@ @LIBGNUTLS_LIBS@ @LIBICONV@ @PTHREAD_LIBS@ @LIBICONV@ @PTHREAD_LIBS@ @VMIME_ADDITIONAL_PC_LIBS@\n")
 	#vmime_pc_in.write("Cflags: -I${includedir}/@GENERIC_VERSIONED_LIBRARY_NAME@\n")
 	vmime_pc_in.write("Cflags: -I${includedir}/ @LIBGNUTLS_CFLAGS@\n")
 	vmime_pc_in.close()
-- 
1.7.7.3


From 9f9084b71b4e3c96edc6513020984ef76fe26e0c Mon Sep 17 00:00:00 2001
From: vincent-richard <vincent-richard@5301114d-f842-0410-bbdd-996ee0417009>
Date: Sat, 25 Jun 2011 17:07:53 +0000
Subject: [PATCH 20/27] Fixed parsing of empty body parts (thanks to John van
 der Kamp, from Zarafa).

git-svn-id: https://vmime.svn.sourceforge.net/svnroot/vmime/trunk@595 5301114d-f842-0410-bbdd-996ee0417009

diff --git a/src/body.cpp b/src/body.cpp
index 8596833..9d7d57f 100644
--- a/src/body.cpp
+++ b/src/body.cpp
@@ -197,6 +197,11 @@ void body::parse(const string& buffer, const string::size_type position,
 			{
 				ref <bodyPart> part = vmime::create <bodyPart>();
 
+				// End before start may happen on empty bodyparts (directly
+				// successive boundaries without even a line-break)
+				if (partEnd < partStart)
+					std::swap(partStart, partEnd);
+
 				part->parse(buffer, partStart, partEnd, NULL);
 				part->m_parent = m_part;
 
diff --git a/tests/parser/bodyPartTest.cpp b/tests/parser/bodyPartTest.cpp
index b129913..075b8f9 100644
--- a/tests/parser/bodyPartTest.cpp
+++ b/tests/parser/bodyPartTest.cpp
@@ -36,6 +36,7 @@ VMIME_TEST_SUITE_BEGIN
 		VMIME_TEST(testParseMissingLastBoundary)
 		VMIME_TEST(testPrologEpilog)
 		VMIME_TEST(testPrologEncoding)
+		VMIME_TEST(testSuccessiveBoundaries)
 	VMIME_TEST_LIST_END
 
 
@@ -181,5 +182,23 @@ VMIME_TEST_SUITE_BEGIN
 		VASSERT_EQ("epilog", "Epilog text", msg->getBody()->getEpilogText());
 	}
 
+	void testSuccessiveBoundaries()
+	{
+		vmime::string str =
+			"Content-Type: multipart/mixed; boundary=\"MY-BOUNDARY\""
+			"\r\n\r\n"
+			"--MY-BOUNDARY\r\nHEADER1\r\n\r\nBODY1\r\n"
+			"--MY-BOUNDARY\r\n"
+			"--MY-BOUNDARY--\r\n";
+
+		vmime::bodyPart p;
+		p.parse(str);
+
+		VASSERT_EQ("count", 2, p.getBody()->getPartCount());
+
+		VASSERT_EQ("part1-body", "BODY1", extractContents(p.getBody()->getPartAt(0)->getBody()->getContents()));
+		VASSERT_EQ("part2-body", "", extractContents(p.getBody()->getPartAt(1)->getBody()->getContents()));
+	}
+
 VMIME_TEST_SUITE_END
 
-- 
1.7.7.3


From 318848aa87761214a6f21c1ea1a9776a7bcbf83c Mon Sep 17 00:00:00 2001
From: vincent-richard <vincent-richard@5301114d-f842-0410-bbdd-996ee0417009>
Date: Sun, 26 Jun 2011 08:19:11 +0000
Subject: [PATCH 21/27] Use gnutls_priority_set_direct() instead of GNUTLS
 deprecated functions.

git-svn-id: https://vmime.svn.sourceforge.net/svnroot/vmime/trunk@596 5301114d-f842-0410-bbdd-996ee0417009

diff --git a/SConstruct b/SConstruct
index 37c0ac6..01ad3f3 100644
--- a/SConstruct
+++ b/SConstruct
@@ -816,6 +816,7 @@ else:
 config_hpp.write('// -- TLS/SSL support\n')
 if env['with_tls'] == 'yes':
 	config_hpp.write('#define VMIME_HAVE_TLS_SUPPORT 1\n')
+	config_hpp.write('#define HAVE_GNUTLS_PRIORITY_FUNCS 1\n')
 else:
 	config_hpp.write('#define VMIME_HAVE_TLS_SUPPORT 0\n')
 
@@ -1626,11 +1627,42 @@ if test "x$conf_tls" = "xyes"; then
 	else
 		AC_MSG_ERROR(can't find an usable version of GNU TLS library)
 	fi
+
+	# -- check for gnutls_priority_set_direct() function
+	if test "x$have_gnutls" = "xyes"; then
+		AC_MSG_CHECKING(for gnutls_priority_set_direct)
+
+		LIBS_save="$LIBS"
+		LIBS="$LIBS $LIBGNUTLS_LIBS"
+		CPPFLAGS_save="$CPPFLAGS"
+		CPPFLAGS="$CPPFLAGS $LIBGNUTLS_CFLAGS"
+
+		AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <gnutls/gnutls.h>],
+		                                [gnutls_session s; gnutls_priority_set_direct(s, NULL, NULL);])],
+		               [have_gnutls_priority_funcs=yes],
+		               [have_gnutls_priority_funcs=no])
+
+		CPPFLAGS="$CPPFLAGS_save"
+		LIBS="$LIBS_save"
+
+		AC_MSG_RESULT([$have_gnutls_priority_funcs])
+
+		if test "x$have_gnutls_priority_funcs" = "xyes"; then
+			AM_CONDITIONAL(HAVE_GNUTLS_PRIORITY_FUNCS, true)
+			HAVE_GNUTLS_PRIORITY_FUNCS=1
+		else
+			AM_CONDITIONAL(HAVE_GNUTLS_PRIORITY_FUNCS, false)
+			HAVE_GNUTLS_PRIORITY_FUNCS=0
+		fi
+	fi
 else
 	AM_CONDITIONAL(VMIME_HAVE_TLS_SUPPORT, false)
 	VMIME_HAVE_TLS_SUPPORT=0
 fi
 
+AC_SUBST(LIBGNUTLS_CFLAGS)
+AC_SUBST(LIBGNUTLS_LIBS)
+
 # ** platform handlers
 
 VMIME_BUILTIN_PLATFORMS=''
@@ -1919,6 +1951,7 @@ typedef unsigned ${VMIME_TYPE_INT32} vmime_uint32;
 #define VMIME_HAVE_SASL_SUPPORT ${VMIME_HAVE_SASL_SUPPORT}
 // -- TLS support
 #define VMIME_HAVE_TLS_SUPPORT ${VMIME_HAVE_TLS_SUPPORT}
+#define HAVE_GNUTLS_PRIORITY_FUNCS ${HAVE_GNUTLS_PRIORITY_FUNCS}
 // -- Messaging support
 #define VMIME_HAVE_MESSAGING_FEATURES ${VMIME_HAVE_MESSAGING_FEATURES}
 """)
diff --git a/src/net/tls/TLSSession.cpp b/src/net/tls/TLSSession.cpp
index 010c007..af73a05 100644
--- a/src/net/tls/TLSSession.cpp
+++ b/src/net/tls/TLSSession.cpp
@@ -123,6 +123,21 @@ TLSSession::TLSSession(ref <security::cert::certificateVerifier> cv)
 
 	// Sets some default priority on the ciphers, key exchange methods,
 	// macs and compression methods.
+#if HAVE_GNUTLS_PRIORITY_FUNCS
+
+	if ((res = gnutls_priority_set_direct
+		(*m_gnutlsSession, "NORMAL:%SSL3_RECORD_VERSION", NULL)) != 0)
+	{
+		if ((res = gnutls_priority_set_direct
+			(*m_gnutlsSession, "NORMAL", NULL)) != 0)
+		{
+			throwTLSException
+				("gnutls_priority_set_direct", res);
+		}
+	}
+
+#else  // !HAVE_GNUTLS_PRIORITY_FUNCS
+
 	gnutls_set_default_priority(*m_gnutlsSession);
 
 	// Sets the priority on the certificate types supported by gnutls.
@@ -197,6 +212,8 @@ TLSSession::TLSSession(ref <security::cert::certificateVerifier> cv)
 
 	gnutls_compression_set_priority(*m_gnutlsSession, compressionPriority);
 
+#endif // !HAVE_GNUTLS_PRIORITY_FUNCS
+
 	// Initialize credentials
 	gnutls_credentials_set(*m_gnutlsSession,
 		GNUTLS_CRD_ANON, g_gnutlsGlobal.anonCred);
-- 
1.7.7.3


From 70a0282a3f96febf973475a298ac95ffaab82c3c Mon Sep 17 00:00:00 2001
From: vincent-richard <vincent-richard@5301114d-f842-0410-bbdd-996ee0417009>
Date: Sun, 26 Jun 2011 12:47:25 +0000
Subject: [PATCH 22/27] Fixed encoding of whitespace. Fixed old test case.

git-svn-id: https://vmime.svn.sourceforge.net/svnroot/vmime/trunk@597 5301114d-f842-0410-bbdd-996ee0417009

diff --git a/src/text.cpp b/src/text.cpp
index 2454456..66c3b35 100644
--- a/src/text.cpp
+++ b/src/text.cpp
@@ -320,12 +320,6 @@ void text::createFromString(const string& in, const charset& ch)
 					}
 					else
 					{
-						if (count)
-						{
-							ref <word> w = getWordAt(getWordCount() - 1);
-							w->getBuffer() += ' ';
-						}
-
 						appendWord(vmime::create <word>
 							(chunk, charset(charsets::US_ASCII)));
 
diff --git a/tests/parser/textTest.cpp b/tests/parser/textTest.cpp
index 746ac94..43ec836 100644
--- a/tests/parser/textTest.cpp
+++ b/tests/parser/textTest.cpp
@@ -53,6 +53,8 @@ VMIME_TEST_SUITE_BEGIN
 
 		VMIME_TEST(testFoldingAscii)
 		VMIME_TEST(testForcedNonEncoding)
+
+		VMIME_TEST(testBugFix20110511)
 	VMIME_TEST_LIST_END
 
 
@@ -149,7 +151,7 @@ VMIME_TEST_SUITE_BEGIN
 		VASSERT_EQ("2.1", 3, t2.getWordCount());
 		VASSERT_EQ("2.2", "some ASCII characters and special chars: ", t2.getWordAt(0)->getBuffer());
 		VASSERT_EQ("2.3", vmime::charset(vmime::charsets::US_ASCII), t2.getWordAt(0)->getCharset());
-		VASSERT_EQ("2.4", "\xf1\xf2\xf3\xf4 ", t2.getWordAt(1)->getBuffer());
+		VASSERT_EQ("2.4", "\xf1\xf2\xf3\xf4", t2.getWordAt(1)->getBuffer());
 		VASSERT_EQ("2.5", c2, t2.getWordAt(1)->getCharset());
 		VASSERT_EQ("2.6", "and then more ASCII chars.", t2.getWordAt(2)->getBuffer());
 		VASSERT_EQ("2.7", vmime::charset(vmime::charsets::US_ASCII), t2.getWordAt(2)->getCharset());
@@ -453,5 +455,43 @@ VMIME_TEST_SUITE_BEGIN
 		VASSERT_EQ("received.long", "from User\r\n (Ee9GMqZQ8t7IQwftfAFHd2KyScCYRrFSJ50tKEoXv2bVCG4HcPU80GGWiFabAvG77FekpGgF1h@[127.0.0.1])\r\n by servername.hostname.com with esmtp id 1NGTS9-2C0sqG0; Fri, 4 Dec 2009\r\n 09:23:49 +0100", r.generate(78));
 	}
 
+	void testBugFix20110511()
+	{
+		/*
+
+		 Using the latest version of vmime (0.9.1), encoding the following string: Jean
+		 Gwenaël Dutourd will result in:
+		 Jean =?utf-8?Q?Gwena=C3=ABl_?= Dutourd
+		 However, decoding this will result in Jean Gwenaël  Dutourd (notice two spaces
+		 between the last 2 words).  The encoder adds a _ after the second word, but
+		 since the last word is not encoded, the space between them is not ignored, and
+		 is decoded into an additional space.
+
+		 See: http://sourceforge.net/projects/vmime/forums/forum/237357/topic/4531365
+
+		*/
+
+		const std::string DECODED_TEXT = "Jean Gwenaël Dutourd";
+		const std::string ENCODED_TEXT = "Jean =?utf-8?Q?Gwena=C3=ABl?= Dutourd";
+
+		// Encode
+		VASSERT_EQ("encode", ENCODED_TEXT,
+			vmime::text::newFromString(DECODED_TEXT, vmime::charset("utf-8"))->generate());
+
+		// Decode
+		vmime::text t;
+		t.parse(ENCODED_TEXT);
+
+		// -- words
+		std::ostringstream oss; oss << t;
+		VASSERT_EQ("decode1",
+			"[text: [[word: charset=us-ascii, buffer=Jean ],"
+			        "[word: charset=utf-8, buffer=Gwenaël],"
+				  "[word: charset=us-ascii, buffer= Dutourd]]]", oss.str());
+
+		// -- getWholeBuffer
+		VASSERT_EQ("decode2", DECODED_TEXT, t.getWholeBuffer());
+	}
+
 VMIME_TEST_SUITE_END
 
-- 
1.7.7.3


From 7d399583a458abe5cd16ce0974bd4dc11daba9f6 Mon Sep 17 00:00:00 2001
From: vincent-richard <vincent-richard@5301114d-f842-0410-bbdd-996ee0417009>
Date: Sat, 20 Aug 2011 06:35:06 +0000
Subject: [PATCH 23/27] Use gnutls_strerror() for reporting errors.

git-svn-id: https://vmime.svn.sourceforge.net/svnroot/vmime/trunk@598 5301114d-f842-0410-bbdd-996ee0417009

diff --git a/src/net/tls/TLSSession.cpp b/src/net/tls/TLSSession.cpp
index af73a05..7426a73 100644
--- a/src/net/tls/TLSSession.cpp
+++ b/src/net/tls/TLSSession.cpp
@@ -41,6 +41,9 @@
 //#define GNUTLS_DEBUG 1
 
 
+#include <sstream>
+#include <iomanip>
+
 #if VMIME_DEBUG && GNUTLS_DEBUG
 	#include <iostream>
 #endif // VMIME_DEBUG && GNUTLS_DEBUG
@@ -257,119 +260,14 @@ ref <security::cert::certificateVerifier> TLSSession::getCertificateVerifier()
 
 void TLSSession::throwTLSException(const string& fname, const int code)
 {
-	string msg = fname + "() returned ";
-
-#define ERROR(x) \
-	case x: msg += #x; break;
-
-	switch (code)
-	{
-	ERROR(GNUTLS_E_SUCCESS)
-	ERROR(GNUTLS_E_UNKNOWN_COMPRESSION_ALGORITHM)
-	ERROR(GNUTLS_E_UNKNOWN_CIPHER_TYPE)
-	ERROR(GNUTLS_E_LARGE_PACKET)
-	ERROR(GNUTLS_E_UNSUPPORTED_VERSION_PACKET)
-	ERROR(GNUTLS_E_UNEXPECTED_PACKET_LENGTH)
-	ERROR(GNUTLS_E_INVALID_SESSION)
-	ERROR(GNUTLS_E_FATAL_ALERT_RECEIVED)
-	ERROR(GNUTLS_E_UNEXPECTED_PACKET)
-	ERROR(GNUTLS_E_WARNING_ALERT_RECEIVED)
-	ERROR(GNUTLS_E_ERROR_IN_FINISHED_PACKET)
-	ERROR(GNUTLS_E_UNEXPECTED_HANDSHAKE_PACKET)
-	ERROR(GNUTLS_E_UNKNOWN_CIPHER_SUITE)
-	ERROR(GNUTLS_E_UNWANTED_ALGORITHM)
-	ERROR(GNUTLS_E_MPI_SCAN_FAILED)
-	ERROR(GNUTLS_E_DECRYPTION_FAILED)
-	ERROR(GNUTLS_E_MEMORY_ERROR)
-	ERROR(GNUTLS_E_DECOMPRESSION_FAILED)
-	ERROR(GNUTLS_E_COMPRESSION_FAILED)
-	ERROR(GNUTLS_E_AGAIN)
-	ERROR(GNUTLS_E_EXPIRED)
-	ERROR(GNUTLS_E_DB_ERROR)
-	ERROR(GNUTLS_E_SRP_PWD_ERROR)
-	ERROR(GNUTLS_E_INSUFFICIENT_CREDENTIALS)
-	ERROR(GNUTLS_E_HASH_FAILED)
-	ERROR(GNUTLS_E_BASE64_DECODING_ERROR)
-	ERROR(GNUTLS_E_MPI_PRINT_FAILED)
-	ERROR(GNUTLS_E_REHANDSHAKE)
-	ERROR(GNUTLS_E_GOT_APPLICATION_DATA)
-	ERROR(GNUTLS_E_RECORD_LIMIT_REACHED)
-	ERROR(GNUTLS_E_ENCRYPTION_FAILED)
-	ERROR(GNUTLS_E_PK_ENCRYPTION_FAILED)
-	ERROR(GNUTLS_E_PK_DECRYPTION_FAILED)
-	ERROR(GNUTLS_E_PK_SIGN_FAILED)
-	ERROR(GNUTLS_E_X509_UNSUPPORTED_CRITICAL_EXTENSION)
-	ERROR(GNUTLS_E_KEY_USAGE_VIOLATION)
-	ERROR(GNUTLS_E_NO_CERTIFICATE_FOUND)
-	ERROR(GNUTLS_E_INVALID_REQUEST)
-	ERROR(GNUTLS_E_SHORT_MEMORY_BUFFER)
-	ERROR(GNUTLS_E_INTERRUPTED)
-	ERROR(GNUTLS_E_PUSH_ERROR)
-	ERROR(GNUTLS_E_PULL_ERROR)
-	ERROR(GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER)
-	ERROR(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
-	ERROR(GNUTLS_E_PKCS1_WRONG_PAD)
-	ERROR(GNUTLS_E_RECEIVED_ILLEGAL_EXTENSION)
-	ERROR(GNUTLS_E_INTERNAL_ERROR)
-	ERROR(GNUTLS_E_DH_PRIME_UNACCEPTABLE)
-	ERROR(GNUTLS_E_FILE_ERROR)
-	ERROR(GNUTLS_E_TOO_MANY_EMPTY_PACKETS)
-	ERROR(GNUTLS_E_UNKNOWN_PK_ALGORITHM)
-	ERROR(GNUTLS_E_INIT_LIBEXTRA)
-	ERROR(GNUTLS_E_LIBRARY_VERSION_MISMATCH)
-	ERROR(GNUTLS_E_NO_TEMPORARY_RSA_PARAMS)
-	ERROR(GNUTLS_E_LZO_INIT_FAILED)
-	ERROR(GNUTLS_E_NO_COMPRESSION_ALGORITHMS)
-	ERROR(GNUTLS_E_NO_CIPHER_SUITES)
-	ERROR(GNUTLS_E_OPENPGP_GETKEY_FAILED)
-	ERROR(GNUTLS_E_PK_SIG_VERIFY_FAILED)
-	ERROR(GNUTLS_E_ILLEGAL_SRP_USERNAME)
-	ERROR(GNUTLS_E_SRP_PWD_PARSING_ERROR)
-	ERROR(GNUTLS_E_NO_TEMPORARY_DH_PARAMS)
-	ERROR(GNUTLS_E_ASN1_ELEMENT_NOT_FOUND)
-	ERROR(GNUTLS_E_ASN1_IDENTIFIER_NOT_FOUND)
-	ERROR(GNUTLS_E_ASN1_DER_ERROR)
-	ERROR(GNUTLS_E_ASN1_VALUE_NOT_FOUND)
-	ERROR(GNUTLS_E_ASN1_GENERIC_ERROR)
-	ERROR(GNUTLS_E_ASN1_VALUE_NOT_VALID)
-	ERROR(GNUTLS_E_ASN1_TAG_ERROR)
-	ERROR(GNUTLS_E_ASN1_TAG_IMPLICIT)
-	ERROR(GNUTLS_E_ASN1_TYPE_ANY_ERROR)
-	ERROR(GNUTLS_E_ASN1_SYNTAX_ERROR)
-	ERROR(GNUTLS_E_ASN1_DER_OVERFLOW)
-	//ERROR(GNUTLS_E_OPENPGP_TRUSTDB_VERSION_UNSUPPORTED)
-	ERROR(GNUTLS_E_OPENPGP_UID_REVOKED)
-	ERROR(GNUTLS_E_CERTIFICATE_ERROR)
-	//ERROR(GNUTLS_E_X509_CERTIFICATE_ERROR)
-	ERROR(GNUTLS_E_CERTIFICATE_KEY_MISMATCH)
-	ERROR(GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE)
-	ERROR(GNUTLS_E_X509_UNKNOWN_SAN)
-	ERROR(GNUTLS_E_OPENPGP_FINGERPRINT_UNSUPPORTED)
-	ERROR(GNUTLS_E_X509_UNSUPPORTED_ATTRIBUTE)
-	ERROR(GNUTLS_E_UNKNOWN_HASH_ALGORITHM)
-	ERROR(GNUTLS_E_UNKNOWN_PKCS_CONTENT_TYPE)
-	ERROR(GNUTLS_E_UNKNOWN_PKCS_BAG_TYPE)
-	ERROR(GNUTLS_E_INVALID_PASSWORD)
-	ERROR(GNUTLS_E_MAC_VERIFY_FAILED)
-	ERROR(GNUTLS_E_CONSTRAINT_ERROR)
-	ERROR(GNUTLS_E_BASE64_ENCODING_ERROR)
-	ERROR(GNUTLS_E_INCOMPATIBLE_GCRYPT_LIBRARY)
-	//ERROR(GNUTLS_E_INCOMPATIBLE_CRYPTO_LIBRARY)
-	ERROR(GNUTLS_E_INCOMPATIBLE_LIBTASN1_LIBRARY)
-	ERROR(GNUTLS_E_OPENPGP_KEYRING_ERROR)
-	ERROR(GNUTLS_E_X509_UNSUPPORTED_OID)
-	//ERROR(GNUTLS_E_RANDOM_FAILED)
-	ERROR(GNUTLS_E_UNIMPLEMENTED_FEATURE)
-
-	default:
-
-		msg += "unknown error";
-		break;
-	}
+	std::ostringstream msg;
 
-#undef ERROR
+	msg << fname + "() returned code ";
+	msg << std::hex << code;
+	msg << ": ";
+	msg << gnutls_strerror(code);
 
-	throw exceptions::tls_exception(msg);
+	throw exceptions::tls_exception(msg.str());
 }
 
 
-- 
1.7.7.3


From aae321dede5e725140534a08a8b2ee997faa30be Mon Sep 17 00:00:00 2001
From: vincent-richard <vincent-richard@5301114d-f842-0410-bbdd-996ee0417009>
Date: Sun, 21 Aug 2011 08:55:46 +0000
Subject: [PATCH 24/27] Removed dependency on gcrypt for gnutls version >=
 2.12.

git-svn-id: https://vmime.svn.sourceforge.net/svnroot/vmime/trunk@599 5301114d-f842-0410-bbdd-996ee0417009

diff --git a/src/net/tls/TLSSession.cpp b/src/net/tls/TLSSession.cpp
index 7426a73..d3f6d49 100644
--- a/src/net/tls/TLSSession.cpp
+++ b/src/net/tls/TLSSession.cpp
@@ -26,9 +26,17 @@
 
 #include "vmime/config.hpp"
 
+// Dependency on gcrypt is not needed since GNU TLS version 2.12.
+// See here: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=638651
+#if GNUTLS_VERSION_NUMBER <= 0x020b00
+#	define VMIME_GNUTLS_NEEDS_GCRYPT  1
+#endif
+
 #if VMIME_HAVE_PTHREAD
 #	include <pthread.h>
-#	include <gcrypt.h>
+#	if VMIME_GNUTLS_NEEDS_GCRYPT
+#		include <gcrypt.h>
+#	endif
 #	include <errno.h>
 #endif // VMIME_HAVE_PTHREAD
 
@@ -49,7 +57,7 @@
 #endif // VMIME_DEBUG && GNUTLS_DEBUG
 
 
-#if VMIME_HAVE_PTHREAD && defined(GCRY_THREAD_OPTION_PTHREAD_IMPL)
+#if VMIME_HAVE_PTHREAD && VMIME_GNUTLS_NEEDS_GCRYPT && defined(GCRY_THREAD_OPTION_PTHREAD_IMPL)
 extern "C"
 {
 	GCRY_THREAD_OPTION_PTHREAD_IMPL;
@@ -70,7 +78,9 @@ struct TLSGlobal
 	TLSGlobal()
 	{
 #if VMIME_HAVE_PTHREAD && defined(GCRY_THREAD_OPTION_PTHREAD_IMPL)
+	#if VMIME_GNUTLS_NEEDS_GCRYPT
 		gcry_control(GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread);
+	#endif // VMIME_GNUTLS_NEEDS_GCRYPT
 #endif // VMIME_HAVE_PTHREAD && defined(GCRY_THREAD_OPTION_PTHREAD_IMPL
 
 		gnutls_global_init();
-- 
1.7.7.3


From af1e5664afb663fb7d26d468adf675fb1b3f8737 Mon Sep 17 00:00:00 2001
From: vincent-richard <vincent-richard@5301114d-f842-0410-bbdd-996ee0417009>
Date: Sun, 21 Aug 2011 09:04:46 +0000
Subject: [PATCH 25/27] Fixed HAVE_GNUTLS_PRIORITY_FUNCS never defined when
 configured with no TLS support.

git-svn-id: https://vmime.svn.sourceforge.net/svnroot/vmime/trunk@600 5301114d-f842-0410-bbdd-996ee0417009

diff --git a/SConstruct b/SConstruct
index 01ad3f3..11e884b 100644
--- a/SConstruct
+++ b/SConstruct
@@ -1654,10 +1654,16 @@ if test "x$conf_tls" = "xyes"; then
 			AM_CONDITIONAL(HAVE_GNUTLS_PRIORITY_FUNCS, false)
 			HAVE_GNUTLS_PRIORITY_FUNCS=0
 		fi
+	else
+		AM_CONDITIONAL(HAVE_GNUTLS_PRIORITY_FUNCS, false)
+		HAVE_GNUTLS_PRIORITY_FUNCS=0
 	fi
 else
 	AM_CONDITIONAL(VMIME_HAVE_TLS_SUPPORT, false)
 	VMIME_HAVE_TLS_SUPPORT=0
+
+	AM_CONDITIONAL(HAVE_GNUTLS_PRIORITY_FUNCS, false)
+	HAVE_GNUTLS_PRIORITY_FUNCS=0
 fi
 
 AC_SUBST(LIBGNUTLS_CFLAGS)
-- 
1.7.7.3


From 41079b2f188bb4a6d8aea9ec1328653faee3e2c9 Mon Sep 17 00:00:00 2001
From: vincent-richard <vincent-richard@5301114d-f842-0410-bbdd-996ee0417009>
Date: Tue, 15 Nov 2011 11:40:42 +0000
Subject: [PATCH 26/27] GNU TLS 3 has no 'extra' (thanks to mabrand).

git-svn-id: https://vmime.svn.sourceforge.net/svnroot/vmime/trunk@601 5301114d-f842-0410-bbdd-996ee0417009

diff --git a/src/net/tls/TLSSession.cpp b/src/net/tls/TLSSession.cpp
index d3f6d49..cb50acc 100644
--- a/src/net/tls/TLSSession.cpp
+++ b/src/net/tls/TLSSession.cpp
@@ -22,7 +22,9 @@
 //
 
 #include <gnutls/gnutls.h>
+#if GNUTLS_VERSION_NUMBER < 0x030000
 #include <gnutls/extra.h>
+#endif
 
 #include "vmime/config.hpp"
 
-- 
1.7.7.3


From eafae52d9b8ec9682c229090b6208092b1d1e6f1 Mon Sep 17 00:00:00 2001
From: vincent-richard <vincent-richard@5301114d-f842-0410-bbdd-996ee0417009>
Date: Tue, 15 Nov 2011 11:46:07 +0000
Subject: [PATCH 27/27] Set Diffie-Hellman prime size (bug SF#3434852).

git-svn-id: https://vmime.svn.sourceforge.net/svnroot/vmime/trunk@602 5301114d-f842-0410-bbdd-996ee0417009

diff --git a/src/net/tls/TLSSession.cpp b/src/net/tls/TLSSession.cpp
index cb50acc..0606808 100644
--- a/src/net/tls/TLSSession.cpp
+++ b/src/net/tls/TLSSession.cpp
@@ -139,6 +139,7 @@ TLSSession::TLSSession(ref <security::cert::certificateVerifier> cv)
 	// Sets some default priority on the ciphers, key exchange methods,
 	// macs and compression methods.
 #if HAVE_GNUTLS_PRIORITY_FUNCS
+	gnutls_dh_set_prime_bits(*m_gnutlsSession, 128);
 
 	if ((res = gnutls_priority_set_direct
 		(*m_gnutlsSession, "NORMAL:%SSL3_RECORD_VERSION", NULL)) != 0)
-- 
1.7.7.3