Update of /cvsroot/mahogany/M/src/mail
In directory usw-pr-cvs1:/tmp/cvs-serv22547/src/mail
Modified Files:
AddressCC.cpp
Log Message:
better handling for the messages with invalid addresses, also don't use fixed size
buffers required by c-client any more
Index: AddressCC.cpp
===================================================================
RCS file: /cvsroot/mahogany/M/src/mail/AddressCC.cpp,v
retrieving revision 1.15
retrieving revision 1.16
diff -b -u -2 -r1.15 -r1.16
--- AddressCC.cpp 7 Jan 2002 00:21:13 -0000 1.15
+++ AddressCC.cpp 22 Feb 2002 19:55:41 -0000 1.16
@@ -48,10 +48,10 @@
// ----------------------------------------------------------------------------
-// the max size of the buffer holding the address: this is horribly dangerous
-// as there are *NO* buffer size checks in c-client which means that we just
-// die horribly if the buffer is overflown -- but what to do except
-// complaining to MRC who'd just tell me that he doesn't care about such
-// "minor" problem? #$#$^$%&^%^&!!
-static const size_t MAX_ADDRESS_LEN = 16384;
+// Adr2String parameters
+enum Adr2StringWhich
+{
+ Adr2String_All,
+ Adr2String_FirstOnly
+};
// ----------------------------------------------------------------------------
@@ -60,5 +60,11 @@
// return string containing all addresses or just the first one from this list
-static String Adr2String(ADDRESS *adr, bool all = true);
+static String Adr2String(ADDRESS *adr,
+ Adr2StringWhich which = Adr2String_All,
+ bool *error = NULL);
+
+// return the string containing just the email part of the address (this always
+// works with one address only, not the entire list)
+static String Adr2Email(ADDRESS *adr);
// ============================================================================
@@ -89,5 +95,5 @@
String AddressCC::GetAddress() const
{
- return Adr2String(m_adr, false /* just the first one */);
+ return Adr2String(m_adr, Adr2String_FirstOnly);
}
@@ -124,14 +130,5 @@
String AddressCC::GetEMail() const
{
- String email;
-
- // FIXME: again, c-client doesn't check size of the buffer!
- char *buf = email.GetWriteBuf(MAX_ADDRESS_LEN);
- *buf = '\0';
- rfc822_address(buf, m_adr);
- email.UngetWriteBuf();
- email.Shrink();
-
- return email;
+ return Adr2Email(m_adr);
}
@@ -179,14 +176,4 @@
while ( adr )
{
- // c-client generates dummy addresses when it can't parse the original
- // address, filter them out
- if ( adr->error ||
- (adr->mailbox && !strcmp(adr->mailbox, "INVALID_ADDRESS")) ||
- (adr->host && !strcmp(adr->host, ERRHOST)) )
- {
- DBGMESSAGE(("Skipping bad address '%s'.", Adr2String(adr).c_str()));
- }
- else // good address, store
- {
// c-client mungles unqualified addresses, undo it
if ( adr->host && !strcmp(adr->host, BADHOST) )
@@ -213,5 +200,4 @@
addrCur = addr;
- }
adr = adr->next;
@@ -317,5 +303,8 @@
}
- return new AddressListCC(adr);
+ AddressListCC *addrList = new AddressListCC(adr);
+ addrList->m_addressHeader = address;
+
+ return addrList;
}
@@ -345,5 +334,13 @@
if ( m_addrCC )
{
- address = Adr2String(m_addrCC->m_adr);
+ bool error;
+ address = Adr2String(m_addrCC->m_adr, Adr2String_All, &error);
+
+ // when an error occurs, prefer to show the original address as is, if we
+ // have it - this gives max info to the user
+ if ( error && !m_addressHeader.empty() )
+ {
+ address = m_addressHeader;
+ }
}
//else: no valid addresses at all
@@ -394,26 +391,156 @@
// ============================================================================
-static String Adr2String(ADDRESS *adr, bool all)
+// we reimplement rfc822_write_address() and related functions here because the
+// c-client function doesn't respect the buffer size which leads to easily
+// reproducible buffer overflows and MRC refuses to fix it! <sigh>
+
+// wspecials and rspecials string from c-client
+static const char *WORD_SPECIALS = " ()<>@,;:\\\"[]";
+const char *ALL_SPECIALS = "()<>@,;:\\\"[].";
+
+// this one is the replacement for rfc822_cat()
+static String Rfc822Quote(const char *src, const char *specials)
+{
+ String dest;
+
+ // do we have any specials at all?
+ if ( strpbrk(src, specials) )
+ {
+ // need to quote
+ dest = '"';
+
+ while ( *src )
+ {
+ switch ( *src )
+ {
+ case '\\':
+ case '"':
+ // need to quote
+ dest += '\\';
+ break;
+ }
+
+ dest += *src++;
+ }
+
+ // closing quote
+ dest += '"';
+ }
+ else // no specials at all, easy case
+ {
+ dest = src;
+ }
+
+ return dest;
+}
+
+// rfc822_address() replacement
+static String Adr2Email(ADDRESS *adr)
+{
+ String email;
+
+ // do we have email at all?
+ if ( adr && adr->host )
+ {
+ email.reserve(256);
+
+ // deal with the A-D-L
+ if ( adr->adl )
+ {
+ email << adr->adl << ':';
+ }
+
+ // and now the mailbox name: we quote all characters forbidden in a word
+ email << Rfc822Quote(adr->mailbox, WORD_SPECIALS);
+
+ // passing the NULL host suppresses printing the full address
+ if ( *adr->host != '@' )
+ {
+ email << '@' << adr->host;
+ }
+ }
+
+ return email;
+}
+
+// rfc822_write_address() replacement with some extra functionality
+static String Adr2String(ADDRESS *adr, Adr2StringWhich which, bool *error)
{
String address;
- CHECK( adr, address, "invalid address" );
+ address.reserve(1024);
+
+ if ( error )
+ {
+ // not yet
+ *error = false;
+ }
- // if we need only one address, prevent rfc822_write_address() from
- // traversing the entire address list by temporarily setting the next
- // pointer to NULL
- ADDRESS *adrNextOld = all ? NULL : adr->next;
- if ( adrNextOld )
- adr->next = NULL;
-
- // FIXME: there is no way to get the address length from c-client, how to
- // prevent it from overwriting our buffer??
- char *buf = address.GetWriteBuf(MAX_ADDRESS_LEN);
- *buf = '\0';
- rfc822_write_address(buf, adr);
- address.UngetWriteBuf();
- address.Shrink();
+ bool first = true;
+ for ( size_t groupDepth = 0; adr; adr = adr->next )
+ {
+ // is this a valid address?
+ if ( adr->host && !strcmp(adr->host, ERRHOST) )
+ {
+ // tell the caller that we had a problem
+ if ( error )
+ *error = true;
+
+ // stop at the first invalid address, there is nothing (but garbage in
+ // the worst case) following it anyhow
+ break;
+ }
- if ( adrNextOld )
- adr->next = adrNextOld;
+ if ( first )
+ {
+ // no more during the next iteration
+ first = false;
+ }
+ else // not the first address
+ {
+ // do we need the subsequent ones?
+ if ( which != Adr2String_All )
+ {
+ // no
+ break;
+ }
+
+ if ( !groupDepth )
+ {
+ // separate from the previous one
+ address << ", ";
+ }
+ }
+
+ // ordinary address?
+ if ( adr->host )
+ {
+ // simple case?
+ if ( !(adr->personal || adr->adl) )
+ {
+ address << Adr2Email(adr);
+ }
+ else // no, must use phrase <route-addr> form
+ {
+ if ( adr->personal )
+ address << Rfc822Quote(adr->personal, ALL_SPECIALS);
+
+ address << " <" << Adr2Email(adr) << '>';
+ }
+ }
+ else if ( adr->mailbox ) // start of group?
+ {
+ // yes, write group name
+ address << Rfc822Quote(adr->mailbox, ALL_SPECIALS) << ": ";
+
+ // in a group
+ groupDepth++;
+ }
+ else if ( groupDepth ) // must be end of group (but be paranoid)
+ {
+ address += ';';
+
+ groupDepth--;
+ }
+ }
return address;
_______________________________________________
Mahogany-cvsupdates mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/mahogany-cvsupdates