Sophie

Sophie

distrib > Fedora > 13 > i386 > media > updates-src > by-pkgid > e548512dcc847653815f1b7adc710b15 > files > 20

libvmime07-0.7.1-4.fc13.src.rpm

Patch by Zarafa <http://www.zarafa.com/> - fixes attachment names in Outlook Express which are long and
have high characters.

--- libvmime-0.7.1/src/defaultParameter.cpp				2007-01-26 14:44:10.243562750 +0100
+++ libvmime-0.7.1/src/defaultParameter.cpp.vmime-oe-compatibility	2007-04-24 13:43:36.579203500 +0200
@@ -186,18 +186,18 @@
 {
 	const string& name = getName();
 	const string& value = m_value.getBuffer();
+	string tmpbuf;
+	utility::outputStreamStringAdapter tmpos(tmpbuf);
 
 	// For compatibility with implementations that do not understand RFC-2231,
 	// also generate a normal "7bit/us-ascii" parameter
 	string::size_type pos = curLinePos;
 
-	if (pos + name.length() + 10 + value.length() > maxLineLength)
-	{
-		os << NEW_LINE_SEQUENCE;
+		tmpos << 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
@@ -228,35 +228,50 @@
 			needQuoting = true;
 			break;
 		}
+		if (!parserHelpers::isAscii(value[i]))
+		{
+			needQuotedPrintable = true;
+			needQuoting = true;
+		}
 	}
 
 	const bool cutValue = (valueLength != value.length());  // has the value been cut?
 
 	if (needQuoting)
 	{
-		os << name << "=\"";
+		tmpos << name << "=\"";
 		pos += name.length() + 2;
 	}
 	else
 	{
-		os << name << "=";
+		tmpos << name << "=";
 		pos += name.length() + 1;
 	}
 
 	bool extended = false;
-
-	for (string::size_type i = 0 ; (i < value.length()) && (pos < maxLineLength - 4) ; ++i)
+	if (needQuotedPrintable)
+	{
+		// send the name in quoted-printable, so outlook express et.al. will understand the real filename
+		size_t oldlen = tmpbuf.length();
+		m_value.generate(tmpos);
+		pos += tmpbuf.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()) /*&& (pos < maxLineLength - 4) */ ; ++i)
 	{
 		const char_t c = value[i];
 
 		if (/* needQuoting && */ (c == '"' || c == '\\'))  // 'needQuoting' is implicit
 		{
-			os << '\\' << value[i];  // escape 'x' with '\x'
+			tmpos << '\\' << value[i];  // escape 'x' with '\x'
 			pos += 2;
 		}
 		else if (parserHelpers::isAscii(c))
 		{
-			os << value[i];
+			tmpos << value[i];
 			++pos;
 		}
 		else
@@ -264,10 +279,11 @@
 			extended = true;
 		}
 	}
+	}
 
 	if (needQuoting)
 	{
-		os << '"';
+		tmpos << '"';
 		++pos;
 	}
 
@@ -275,7 +291,7 @@
 	// or is too long for a single line
 	if (extended || cutValue)
 	{
-		os << ';';
+		tmpos << ';';
 		++pos;
 
 		/* RFC-2231
@@ -301,11 +317,8 @@
 			  name.length() + 4 /* *0*= */ + 2 /* '' */
 			+ m_value.getCharset().getName().length();
 
-		if (pos + firstSectionLength + 5 >= maxLineLength)
-		{
-			os << NEW_LINE_SEQUENCE;
+			tmpos << NEW_LINE_SEQUENCE;
 			pos = NEW_LINE_SEQUENCE_LENGTH;
-		}
 
 		// Split text into multiple sections that fit on one line
 		int sectionCount = 0;
@@ -384,33 +397,36 @@
 		// Output sections
 		for (int sectionNumber = 0 ; sectionNumber < sectionCount ; ++sectionNumber)
 		{
-			os << name;
+			tmpos << name;
 
 			if (sectionCount != 1) // no section specifier when only a single one
 			{
-				os << '*';
-				os << sectionNumber;
+				tmpos << '*';
+				tmpos << sectionNumber;
 			}
 
-			os << "*=";
+			tmpos << "*=";
 
 			if (sectionNumber == 0)
 			{
-				os << m_value.getCharset().getName();
-				os << '\'' << /* No language */ '\'';
+				tmpos << m_value.getCharset().getName();
+				tmpos << '\'' << /* No language */ '\'';
 			}
 
-			os << sectionText[sectionNumber];
+			tmpos << sectionText[sectionNumber];
 
 			if (sectionNumber + 1 < sectionCount)
 			{
-				os << ';';
-				os << NEW_LINE_SEQUENCE;
+				tmpos << ';';
+				tmpos << NEW_LINE_SEQUENCE;
 				pos = NEW_LINE_SEQUENCE_LENGTH;
 			}
 		}
 	}
 
+	// write the complete header
+	os << tmpbuf;
+
 	if (newLinePos)
 		*newLinePos = pos;
 }