SF.net SVN: mahogany:[7541] trunk/M
[email protected] Thu, 07 Aug 2008 23:57:46 +0000
| Newsgroups | gmane.mail.mahogany.cvs |
|---|---|
| Message-ID | <[email protected]> |
Revision: 7541
http://mahogany.svn.sourceforge.net/mahogany/?rev=7541&view=rev
Author: vadz
Date: 2008-08-07 23:57:45 +0000 (Thu, 07 Aug 2008)
Log Message:
-----------
encode 7 bit data with LF EOLs using CR LF when sending it
Modified Paths:
--------------
trunk/M/include/strutil.h
trunk/M/src/mail/SendMessageCC.cpp
trunk/M/src/util/strutil.cpp
Modified: trunk/M/include/strutil.h
===================================================================
--- trunk/M/include/strutil.h 2008-08-07 23:50:51 UTC (rev 7540)
+++ trunk/M/include/strutil.h 2008-08-07 23:57:45 UTC (rev 7541)
@@ -212,6 +212,16 @@
/** Enforces DOS/RFC822 CR/LF newline convention.
+ @param out the output buffer which will contain the text with CR/LF EOLs.
+ @param outLen the length of the output buffer.
+ @param in original string, with any EOLs, it must be NUL-terminated.
+ @return true if ok, false if the output buffer is too small.
+ */
+bool
+strutil_enforceCRLF(unsigned char *out, size_t outLen, const unsigned char *in);
+
+/** Enforces DOS/RFC822 CR/LF newline convention.
+
@param in string to copy
@return the DOSified string
*/
Modified: trunk/M/src/mail/SendMessageCC.cpp
===================================================================
--- trunk/M/src/mail/SendMessageCC.cpp 2008-08-07 23:50:51 UTC (rev 7540)
+++ trunk/M/src/mail/SendMessageCC.cpp 2008-08-07 23:57:45 UTC (rev 7541)
@@ -683,34 +683,77 @@
// Check if the given data can be sent without encoding it (using QP or
// Base64): for this it must not contain 8bit chars nor embedded NUL chars and
-// must not have too long lines
-static bool Is7BitText(const unsigned char *text, size_t len)
+// must not have too long lines.
+//
+// If it can be sent as 7 bit also enforce the CR LF as line end terminators as
+// c-client doesn't apply any transformation to 7 bit data and sending CR (or
+// LF) delimited data violates RFC 2822.
+static bool CanSendAs7BitText(const unsigned char *& text, size_t& len)
{
if ( !text )
return true;
- size_t lenLine = 0;
+ // check if we have 7 bit text and also find out whether we need to correct
+ // EOLs
+ bool isCRLF = true;
+ size_t lenLine = 0,
+ numLines = 0; // actually number of EOLs
for ( size_t n = 0; n < len; n++ )
{
- if ( *text == '\0' )
- return false;
+ const unsigned char ch = text[n];
- if ( *text == '\n' )
+ switch ( ch )
{
- lenLine = 0;
- text++;
- continue;
+ case '\0':
+ // text can't have embedded NULs
+ return false;
+
+ case '\r':
+ if ( n < len - 1 && text[n + 1] == '\n' )
+ {
+ lenLine = 0;
+ numLines++;
+ continue;
+ }
+ // fall through
+
+ case '\n':
+ // we get here for '\n's not preceded by '\r's and '\r's not
+ // followed by '\n's
+ lenLine = 0;
+ numLines++;
+ isCRLF = false;
+ continue;
+
+ default:
+ if ( !isascii(ch) )
+ return false;
}
- if ( !isascii(*text++) )
- return false;
-
// the real limit is bigger (~990) but chances are that anything with
// lines of such length is not plain text
if ( ++lenLine > 800 )
return false;
}
+ // it is a 7 bit text but we may need to correct its line endings
+ if ( !isCRLF )
+ {
+ const unsigned char * const textOld = text;
+
+ // we're going to add at most numLines characters for the EOLs and
+ // another one for the trailing NUL
+ len += numLines + sizeof(char);
+ text = (unsigned char *) fs_get(len);
+
+ if ( !strutil_enforceCRLF(text, len, textOld) )
+ {
+ FAIL_MSG( "buffer should have been big enough" );
+ }
+
+ fs_give((void **)&textOld);
+ }
+
return true;
}
@@ -1320,7 +1363,7 @@
// buf is already allocated with malloc() and is NUL-terminated
// (this is important of encoding it wouldn't work correctly) we
// would be able to avoid it
- unsigned char * const data = (unsigned char *) fs_get(len + sizeof(char));
+ unsigned char *data = (unsigned char *) fs_get(len + sizeof(char));
data[len] = '\0';
memcpy(data, buf, len);
@@ -1383,9 +1426,6 @@
bdy->type = type;
bdy->subtype = cpystr(subtype.c_str());
- bdy->contents.text.data = data;
- bdy->contents.text.size = len;
-
// set the transfer encoding
switch ( type )
{
@@ -1400,7 +1440,7 @@
case TYPETEXT:
// if the actual message text is in 7 bit, avoid encoding it even if
// some charset which we would have normally encoded was used
- if ( Is7BitText(data, len) )
+ if ( CanSendAs7BitText(data, len) )
{
bdy->encoding = ENC7BIT;
}
@@ -1443,9 +1483,13 @@
break;
default:
- bdy->encoding = Is7BitText(data, len) ? ENC7BIT : ENCBINARY;
+ bdy->encoding = CanSendAs7BitText(data, len) ? ENC7BIT : ENCBINARY;
}
+ bdy->contents.text.data = data;
+ bdy->contents.text.size = len;
+
+
PARAMETER *lastpar = NULL,
*par;
Modified: trunk/M/src/util/strutil.cpp
===================================================================
--- trunk/M/src/util/strutil.cpp 2008-08-07 23:50:51 UTC (rev 7540)
+++ trunk/M/src/util/strutil.cpp 2008-08-07 23:57:45 UTC (rev 7541)
@@ -493,6 +493,40 @@
+bool
+strutil_enforceCRLF(char *out, size_t outLen, const char *in)
+{
+ for ( char * const outEnd = out + outLen; out != outEnd; )
+ {
+ switch ( char ch = *in++ )
+ {
+ case '\0':
+ *out = '\0';
+ return true;
+
+ case '\r':
+ if ( *in == '\n' )
+ {
+ // this line already has CR LF
+ in++;
+ }
+ // fall through
+
+ case '\n':
+ *out++ = '\r';
+ if ( out != outEnd )
+ *out++ = '\n';
+ break;
+
+ default:
+ *out++ = ch;
+ }
+ }
+
+ // if we get here out must have reached outEnd
+ return false;
+}
+
/** Enforces CR/LF newline convention.
@param in string to copy
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/