Version: 2.0.89 (using KDE 4.5.85) OS: Linux I just tried to send an Email to an Emailadress with an Umlaut-Domain. The Mail was rejected by the server of my provider. I asked my provider and he told me that it must be kmails fault. If there is an Umlaut, the domain must be send in an "IDN-/punycode"-encoding to the server. Reproducible: Always OS: Linux (i686) release 2.6.37-7-generic-pae Compiler: cc
commit 1420731e8bdc5f4b76d5990ab60a88650b679781 branch master Author: Tobias Koenig <tokoe@kde.org> Date: Fri Dec 31 15:01:36 2010 +0100 Encode IDN before passing to KMime or MessageQueueJob Encode email addresses with IDN to puny code before passing them to KMime::MailBox::fromUnicodeString() or setting the recipient addresses on the MessageQueueJob, because both expect a domain part without special characters. BUG: 260615 diff --git a/messagecomposer/composerviewbase.cpp b/messagecomposer/composerviewbase.cpp index 22020ac..45d0fec 100644 --- a/messagecomposer/composerviewbase.cpp +++ b/messagecomposer/composerviewbase.cpp @@ -66,6 +66,15 @@ #include "messagecomposersettings.h" #include "messagehelper.h" +static QStringList encodeIdn( const QStringList &emails ) +{ + QStringList encoded; + foreach ( const QString &email, emails ) + encoded << KPIMUtils::normalizeAddressesAndEncodeIdn( email ); + + return encoded; +} + Message::ComposerViewBase::ComposerViewBase ( QObject* parent ) : QObject ( parent ) , m_msg( KMime::Message::Ptr( new KMime::Message ) ) @@ -721,21 +730,21 @@ void Message::ComposerViewBase::fillQueueJobHeaders( MailTransport::MessageQueue { MailTransport::Transport *transport = MailTransport::TransportManager::self()->transportById( infoPart->transportId() ); if ( transport && transport->specifySenderOverwriteAddress() ) - qjob->addressAttribute().setFrom( KPIMUtils::extractEmailAddress( transport->senderOverwriteAddress() ) ); + qjob->addressAttribute().setFrom( KPIMUtils::extractEmailAddress( KPIMUtils::normalizeAddressesAndEncodeIdn( transport->senderOverwriteAddress() ) ) ); else - qjob->addressAttribute().setFrom( KPIMUtils::extractEmailAddress( infoPart->from() ) ); + qjob->addressAttribute().setFrom( KPIMUtils::extractEmailAddress( KPIMUtils::normalizeAddressesAndEncodeIdn( infoPart->from() ) ) ); // if this header is not empty, it contains the real recipient of the message, either the primary or one of the // secondary recipients. so we set that to the transport job, while leaving the message itself alone. if( message->hasHeader( "X-KMail-EncBccRecipients" ) ) { KMime::Headers::Base* realTo = message->headerByType( "X-KMail-EncBccRecipients" ); - qjob->addressAttribute().setTo( cleanEmailList( realTo->asUnicodeString().split( QLatin1String( "%" ) ) ) ); + qjob->addressAttribute().setTo( cleanEmailList( encodeIdn( realTo->asUnicodeString().split( QLatin1String( "%" ) ) ) ) ); message->removeHeader( "X-KMail-EncBccRecipients" ); message->assemble(); kDebug() << "sending with-bcc encr mail to a/n recipient:" << qjob->addressAttribute().to(); } else { - qjob->addressAttribute().setTo( cleanEmailList( infoPart->to() ) ); - qjob->addressAttribute().setCc( cleanEmailList( infoPart->cc() ) ); - qjob->addressAttribute().setBcc( cleanEmailList( infoPart->bcc() ) ); + qjob->addressAttribute().setTo( cleanEmailList( encodeIdn( infoPart->to() ) ) ); + qjob->addressAttribute().setCc( cleanEmailList( encodeIdn( infoPart->cc() ) ) ); + qjob->addressAttribute().setBcc( cleanEmailList( encodeIdn( infoPart->bcc() ) ) ); } } void Message::ComposerViewBase::initAutoSave() diff --git a/messagecomposer/skeletonmessagejob.cpp b/messagecomposer/skeletonmessagejob.cpp index aec1bbe..69b8c3e 100644 --- a/messagecomposer/skeletonmessagejob.cpp +++ b/messagecomposer/skeletonmessagejob.cpp @@ -33,6 +33,7 @@ #include <KProtocolManager> #include <kmime/kmime_message.h> +#include <kpimutils/email.h> using namespace Message; @@ -68,17 +69,17 @@ void SkeletonMessageJobPrivate::doStart() { KMime::Headers::From *from = new KMime::Headers::From( message ); KMime::Types::Mailbox address; - address.fromUnicodeString( infoPart->from() ); + address.fromUnicodeString( KPIMUtils::normalizeAddressesAndEncodeIdn( infoPart->from() ) ); from->addAddress( address ); message->setHeader( from ); } - + // To: { KMime::Headers::To *to = new KMime::Headers::To( message ); foreach( const QString &a, infoPart->to() ) { KMime::Types::Mailbox address; - address.fromUnicodeString( a ); + address.fromUnicodeString( KPIMUtils::normalizeAddressesAndEncodeIdn( a ) ); to->addAddress( address ); } message->setHeader( to ); @@ -89,7 +90,7 @@ void SkeletonMessageJobPrivate::doStart() { KMime::Headers::ReplyTo *replyTo = new KMime::Headers::ReplyTo( message ); KMime::Types::Mailbox address; - address.fromUnicodeString( infoPart->replyTo() ); + address.fromUnicodeString( KPIMUtils::normalizeAddressesAndEncodeIdn( infoPart->replyTo() ) ); replyTo->addAddress( address ); message->setHeader( replyTo ); } @@ -99,7 +100,7 @@ void SkeletonMessageJobPrivate::doStart() KMime::Headers::Cc *cc = new KMime::Headers::Cc( message ); foreach( const QString &a, infoPart->cc() ) { KMime::Types::Mailbox address; - address.fromUnicodeString( a ); + address.fromUnicodeString( KPIMUtils::normalizeAddressesAndEncodeIdn( a ) ); cc->addAddress( address ); } message->setHeader( cc ); @@ -110,7 +111,7 @@ void SkeletonMessageJobPrivate::doStart() KMime::Headers::Bcc *bcc = new KMime::Headers::Bcc( message ); foreach( const QString &a, infoPart->bcc() ) { KMime::Types::Mailbox address; - address.fromUnicodeString( a ); + address.fromUnicodeString( KPIMUtils::normalizeAddressesAndEncodeIdn( a ) ); bcc->addAddress( address ); } message->setHeader( bcc );