Bug 98079

Summary: Change charset must be applied on subject and attachment names too
Product: [Unmaintained] kmail Reporter: Andrey Cherepanov <sibskull>
Component: generalAssignee: kdepim bugs <kdepim-bugs>
Status: RESOLVED FIXED    
Severity: normal    
Priority: NOR    
Version: 1.7.2   
Target Milestone: ---   
Platform: unspecified   
OS: Linux   
Latest Commit: Version Fixed In:
Sentry Crash Report:
Attachments: Suppose headers charset from content type charset field
Suppose headers charset from content type charset field

Description Andrey Cherepanov 2005-01-28 15:45:59 UTC
Version:           1.7.2 (using KDE 3.3.2, compiled sources)
Compiler:          gcc version 3.2.2 20030222 (Red Hat Linux 3.2.2-5)
OS:                Linux (i686) release 2.4.26-01-NeTraverse-i686-SMP-64GB

I receive a lot of mails created in TheBat mail client. This client store subject and attachments names in plain cp1251 text instead rfc2047/2231. I can read text of such mails but I cannot read subject/attachment names on Russian. Charset change is applied only on mail body, but subject/attachment stays unreadable. Please, use 'fallback charset' for such subject/attachment or apply selected charset on subject/attachment too. Thanks.
Comment 1 Thiago Macieira 2005-01-28 22:54:50 UTC
I believe this is a duplicate.

The Subject, From, To, and all the other headers MUST specify their charset when not using us-ascii.
Comment 2 Andrey Cherepanov 2005-01-29 10:02:54 UTC
Some proprietary developers doesn't read standarts... :)
Comment 3 Petrov Dmithriy 2006-09-08 13:04:04 UTC
>The Subject, From, To, and all the other headers MUST specify their charset when not using us-ascii.

MUST, but... but "fallback charset" is a good idea.
Comment 4 Dmitry Morozhnikov 2006-11-07 22:03:59 UTC
Created attachment 18461 [details]
Suppose headers charset from content type charset field

Patch for kdepim-3.5.5+ branch which suppose headers charset from charset
specified in content-type header.

To see effect of it on local folders, index files need to be deleted.

Rationale:

Charset should be specified for all message headers which is not us-ascii. But
there are still many software which does not do this. Really, there are very
few web-based applications which create correct mail messages.

For example, bugs.kde.org send emails in utf-8 and does not encode subject
header properly. There are many peoples around who don`t switch to utf-8 yet
(like me) and who see a whole garbage in subject field sometimes. So this is
not only problem for peoples from Russia :-)

Anyway, i think what current default charset setting isn`t enough.
Comment 5 Dmitry Morozhnikov 2006-11-07 23:14:59 UTC
Created attachment 18462 [details]
Suppose headers charset from content type charset field

More correct one which really work for messages from bugs.kde.org
Comment 6 Dmitry Morozhnikov 2006-11-08 00:14:24 UTC
SVN commit 603142 by dmiceman:

Suppose headers charset from content-type header if headers not 
properly encoded. If content-type charset is "us-ascii", use "utf-8" 
instead. Write maildir and mbox indexes in right encoding.

CCBUG:98079


 M  +30 -1     branches/work/kdepim-3.5.5+/kmail/kmfoldermaildir.cpp  
 M  +30 -1     branches/work/kdepim-3.5.5+/kmail/kmfoldermbox.cpp  
 M  +3 -2      branches/work/kdepim-3.5.5+/kmail/kmmessage.cpp  
 M  +14 -4     branches/work/kdepim-3.5.5+/kmail/kmmsgbase.cpp  
 M  +1 -1      branches/work/kdepim-3.5.5+/kmail/kmmsgbase.h  
 M  +6 -4      branches/work/kdepim-3.5.5+/kmail/kmmsginfo.cpp  
 M  +2 -0      branches/work/kdepim-3.5.5+/kmail/kmmsginfo.h  
 M  +2 -2      branches/work/kdepim-3.5.5+/kmail/kmmsgpart.cpp  


--- branches/work/kdepim-3.5.5+/kmail/kmfoldermaildir.cpp #603141:603142
@@ -653,6 +653,7 @@
   QCString dateStr, fromStr, toStr, subjStr;
   QCString xmarkStr, replyToIdStr, msgIdStr, referencesStr;
   QCString statusStr, replyToAuxIdStr, uidStr;
+  QCString contentTypeStr, charset;
 
   // iterate through this file until done
   while (!atEof)
@@ -725,6 +726,29 @@
           status |= KMMsgStatusFlag;
       }
 
+      contentTypeStr = contentTypeStr.stripWhiteSpace();
+      charset = "";
+      if ( !contentTypeStr.isEmpty() )
+      {
+        int cidx = contentTypeStr.find( "charset=" );
+        if ( cidx != -1 ) {
+          charset = contentTypeStr.mid( cidx + 8 );
+          if ( charset[0] == '"' ) {
+            charset = charset.mid( 1 );
+          }
+          cidx = 0;
+          while ( (unsigned int) cidx < charset.length() ) {
+            if ( charset[cidx] == '"' || ( !isalnum(charset[cidx]) &&
+                 charset[cidx] != '-' && charset[cidx] != '_' ) )
+              break;
+            ++cidx;
+          }
+          charset.truncate( cidx );
+          // kdDebug() << "KMFolderMaildir::readFileHeaderIntern() charset found: " <<
+          //              charset << " from " << contentTypeStr << endl;
+        }
+      }
+
       KMMsgInfo *mi = new KMMsgInfo(folder());
       mi->init( subjStr.stripWhiteSpace(),
                 fromStr.stripWhiteSpace(),
@@ -734,7 +758,7 @@
                 replyToIdStr, replyToAuxIdStr, msgIdStr,
 				file.local8Bit(),
                 KMMsgEncryptionStateUnknown, KMMsgSignatureStateUnknown,
-                KMMsgMDNStateUnknown, f.size() );
+                KMMsgMDNStateUnknown, charset, f.size() );
 
       dateStr = dateStr.stripWhiteSpace();
       if (!dateStr.isEmpty())
@@ -823,6 +847,11 @@
       uidStr = QCString(line+6);
       lastStr = &uidStr;
     }
+    else if (strncasecmp(line, "Content-Type:", 13) == 0)
+    {
+      contentTypeStr = QCString(line+13);
+      lastStr = &contentTypeStr;
+    }
 
   }
 
--- branches/work/kdepim-3.5.5+/kmail/kmfoldermbox.cpp #603141:603142
@@ -552,6 +552,7 @@
   QCString subjStr, dateStr, fromStr, toStr, xmarkStr, *lastStr=0;
   QCString replyToIdStr, replyToAuxIdStr, referencesStr, msgIdStr;
   QCString sizeServerStr, uidStr;
+  QCString contentTypeStr, charset;
   bool atEof = false;
   bool inHeader = true;
   KMMsgInfo* mi;
@@ -652,6 +653,29 @@
               replyToAuxIdStr.truncate( rightAngle + 1 );
           }
 
+          contentTypeStr = contentTypeStr.stripWhiteSpace();
+          charset = "";
+          if ( !contentTypeStr.isEmpty() )
+          {
+            int cidx = contentTypeStr.find( "charset=" );
+            if ( cidx != -1 ) {
+              charset = contentTypeStr.mid( cidx + 8 );
+              if ( charset[0] == '"' ) {
+                charset = charset.mid( 1 );
+              }
+              cidx = 0;
+              while ( (unsigned int) cidx < charset.length() ) {
+                if ( charset[cidx] == '"' || ( !isalnum(charset[cidx]) &&
+                    charset[cidx] != '-' && charset[cidx] != '_' ) )
+                  break;
+                ++cidx;
+              }
+              charset.truncate( cidx );
+              // kdDebug() << "KMFolderMaildir::readFileHeaderIntern() charset found: " <<
+              //              charset << " from " << contentTypeStr << endl;
+            }
+          }
+
           mi = new KMMsgInfo(folder());
           mi->init( subjStr.stripWhiteSpace(),
                     fromStr.stripWhiteSpace(),
@@ -660,7 +684,7 @@
                     xmarkStr.stripWhiteSpace(),
                     replyToIdStr, replyToAuxIdStr, msgIdStr,
                     KMMsgEncryptionStateUnknown, KMMsgSignatureStateUnknown,
-                    KMMsgMDNStateUnknown, offs, size, sizeServer, uid );
+                    KMMsgMDNStateUnknown, charset, offs, size, sizeServer, uid );
           mi->setStatus(status, xstatus);
           mi->setDate( dateStr.stripWhiteSpace() );
           mi->setDirty(false);
@@ -766,6 +790,11 @@
       uid = uidStr.toULong();
       lastStr = &uidStr;
     }
+    else if (strncasecmp(line, "Content-Type:", 13) == 0)
+    {
+      contentTypeStr = QCString(line+13);
+      lastStr = &contentTypeStr;
+    }
   }
 
   if (mAutoCreateIndex)
--- branches/work/kdepim-3.5.5+/kmail/kmmessage.cpp #603141:603142
@@ -2251,7 +2251,8 @@
   if ( !mMsg->Headers().FindField( aName ) )
     return QString::null;
 
-  return decodeRFC2047String( mMsg->Headers().FieldBody( aName.data() ).AsString().c_str() );
+  return decodeRFC2047String( mMsg->Headers().FieldBody( aName.data() ).AsString().c_str(),
+                              charset() );
 }
 
 QStringList KMMessage::headerFields( const QCString& field ) const
@@ -2262,7 +2263,7 @@
   std::vector<DwFieldBody*> v = mMsg->Headers().AllFieldBodies( field.data() );
   QStringList headerFields;
   for ( uint i = 0; i < v.size(); ++i ) {
-    headerFields.append( decodeRFC2047String( v[i]->AsString().c_str() ) );
+    headerFields.append( decodeRFC2047String( v[i]->AsString().c_str(), charset() ) );
   }
 
   return headerFields;
--- branches/work/kdepim-3.5.5+/kmail/kmmsgbase.cpp #603141:603142
@@ -662,7 +662,7 @@
 
 
 //-----------------------------------------------------------------------------
-QString KMMsgBase::decodeRFC2047String(const QCString& aStr)
+QString KMMsgBase::decodeRFC2047String(const QCString& aStr, QCString prefCharset)
 {
   if ( aStr.isEmpty() )
     return QString::null;
@@ -672,9 +672,19 @@
   if ( str.isEmpty() )
     return QString::null;
 
-  if ( str.find( "=?" ) < 0 )
-    return KMMsgBase::codecForName( GlobalSettings::self()->
-                                    fallbackCharacterEncoding().latin1() )->toUnicode( str );
+  if ( str.find( "=?" ) < 0 ) {
+    if ( !prefCharset.isEmpty() ) {
+      if ( prefCharset == "us-ascii" ) {
+        // isn`t this foolproof?
+        return KMMsgBase::codecForName( "utf-8" )->toUnicode( str );
+      } else {
+        return KMMsgBase::codecForName( prefCharset )->toUnicode( str );
+      }
+    } else {
+      return KMMsgBase::codecForName( GlobalSettings::self()->
+                                      fallbackCharacterEncoding().latin1() )->toUnicode( str );
+    }
+  }
 
   QString result;
   QCString LWSP_buffer;
--- branches/work/kdepim-3.5.5+/kmail/kmmsgbase.h #603141:603142
@@ -354,7 +354,7 @@
 
   /** This function handles both encodings described in RFC2047:
     Base64 ("=?iso-8859-1?b?...?=") and quoted-printable */
-  static QString decodeRFC2047String(const QCString& aStr);
+  static QString decodeRFC2047String(const QCString& aStr, const QCString prefCharset = "");
 
   /** Encode given string as described in RFC2047:
     using quoted-printable. */
--- branches/work/kdepim-3.5.5+/kmail/kmmsginfo.cpp #603141:603142
@@ -199,6 +199,7 @@
                      KMMsgEncryptionState encryptionState,
                      KMMsgSignatureState signatureState,
                      KMMsgMDNSentState mdnSentState,
+                     const QCString& prefCharset,
              off_t aFolderOffset, size_t aMsgSize,
              size_t aMsgSizeServer, ulong aUID)
 {
@@ -207,9 +208,9 @@
     if(!kd)
         kd = new KMMsgInfoPrivate;
     kd->modifiers = KMMsgInfoPrivate::ALL_SET;
-    kd->subject = decodeRFC2047String(aSubject);
-    kd->from = decodeRFC2047String( KMMessage::stripEmailAddr( aFrom ) );
-    kd->to = decodeRFC2047String( KMMessage::stripEmailAddr( aTo ) );
+    kd->subject = decodeRFC2047String(aSubject, prefCharset);
+    kd->from = decodeRFC2047String( KMMessage::stripEmailAddr( aFrom ), prefCharset );
+    kd->to = decodeRFC2047String( KMMessage::stripEmailAddr( aTo ), prefCharset );
     kd->replyToIdMD5 = base64EncodedMD5( replyToId );
     kd->replyToAuxIdMD5 = base64EncodedMD5( replyToAuxId );
     kd->strippedSubjectMD5 = base64EncodedMD5( KMMessage::stripOffPrefixes( kd->subject ), true /*utf8*/ );
@@ -237,12 +238,13 @@
                      KMMsgEncryptionState encryptionState,
                      KMMsgSignatureState signatureState,
                      KMMsgMDNSentState mdnSentState,
+                     const QCString& prefCharset,
                      size_t aMsgSize,
              size_t aMsgSizeServer, ulong aUID)
 {
   // use the "normal" init for most stuff
   init( aSubject, aFrom, aTo, aDate, aStatus, aXMark, replyToId, replyToAuxId,
-        msgId, encryptionState, signatureState, mdnSentState,
+        msgId, encryptionState, signatureState, mdnSentState, prefCharset,
         (unsigned long)0, aMsgSize, aMsgSizeServer, aUID );
   kd->file = aFileName;
 }
--- branches/work/kdepim-3.5.5+/kmail/kmmsginfo.h #603141:603142
@@ -46,6 +46,7 @@
 		    KMMsgEncryptionState encryptionState,
 		    KMMsgSignatureState signatureState,
 		    KMMsgMDNSentState mdnSentState,
+                    const QCString& prefCharset,
 		    off_t folderOffset=0, size_t msgSize=0,
             size_t msgSizeServer = 0, ulong UID = 0);
 
@@ -60,6 +61,7 @@
 		    KMMsgEncryptionState encryptionState,
 		    KMMsgSignatureState signatureState,
 		    KMMsgMDNSentState mdnSentState,
+                    const QCString& prefCharset,
 		    size_t msgSize=0,
             size_t msgSizeServer = 0, ulong UID = 0);
 
--- branches/work/kdepim-3.5.5+/kmail/kmmsgpart.cpp #603141:603142
@@ -476,7 +476,7 @@
 //-----------------------------------------------------------------------------
 QString KMMessagePart::contentDescription(void) const
 {
-  return KMMsgBase::decodeRFC2047String(mContentDescription);
+  return KMMsgBase::decodeRFC2047String(mContentDescription, charset());
 }
 
 
@@ -527,7 +527,7 @@
   if (bRFC2231encoded)
     return KMMsgBase::decodeRFC2231String(str);
   else
-    return KMMsgBase::decodeRFC2047String(str);
+    return KMMsgBase::decodeRFC2047String(str, charset());
 }
 
 
Comment 7 Allen Winter 2006-12-16 06:26:18 UTC
SVN commit 614058 by winterz:

merge SVN commit 603142 by dmiceman:

Suppose headers charset from content-type header if headers not 
properly encoded. If content-type charset is "us-ascii", use "utf-8" 
instead. Write maildir and mbox indexes in right encoding.

BUGS:98079


 M  +33 -4     kmfoldermaildir.cpp  
 M  +32 -3     kmfoldermbox.cpp  
 M  +4 -2      kmmessage.cpp  
 M  +14 -4     kmmsgbase.cpp  
 M  +2 -2      kmmsgbase.h  
 M  +6 -4      kmmsginfo.cpp  
 M  +3 -1      kmmsginfo.h  
 M  +6 -6      kmmsgpart.cpp  


--- branches/KDE/3.5/kdepim/kmail/kmfoldermaildir.cpp #614057:614058
@@ -426,7 +426,7 @@
   tmp_file += filename;
 
   if (!KPIM::kCStringToFile(msgText, tmp_file, false, false, false))
-    kmkernel->emergencyExit( i18n("Message could not be added to the folder, possibly disk space is low.") ); 
+    kmkernel->emergencyExit( i18n("Message could not be added to the folder, possibly disk space is low.") );
 
   QFile file(tmp_file);
   size = msgText.length();
@@ -477,10 +477,10 @@
   }
   ++mTotalMsgs;
 
-  if ( aMsg->attachmentState() == KMMsgAttachmentUnknown && 
+  if ( aMsg->attachmentState() == KMMsgAttachmentUnknown &&
        aMsg->readyToShow() )
     aMsg->updateAttachmentState();
-  
+
   // store information about the position in the folder file in the message
   aMsg->setParent(folder());
   aMsg->setMsgSize(size);
@@ -653,6 +653,7 @@
   QCString dateStr, fromStr, toStr, subjStr;
   QCString xmarkStr, replyToIdStr, msgIdStr, referencesStr;
   QCString statusStr, replyToAuxIdStr, uidStr;
+  QCString contentTypeStr, charset;
 
   // iterate through this file until done
   while (!atEof)
@@ -725,6 +726,29 @@
           status |= KMMsgStatusFlag;
       }
 
+      contentTypeStr = contentTypeStr.stripWhiteSpace();
+      charset = "";
+      if ( !contentTypeStr.isEmpty() )
+      {
+        int cidx = contentTypeStr.find( "charset=" );
+        if ( cidx != -1 ) {
+          charset = contentTypeStr.mid( cidx + 8 );
+          if ( charset[0] == '"' ) {
+            charset = charset.mid( 1 );
+          }
+          cidx = 0;
+          while ( (unsigned int) cidx < charset.length() ) {
+            if ( charset[cidx] == '"' || ( !isalnum(charset[cidx]) &&
+                 charset[cidx] != '-' && charset[cidx] != '_' ) )
+              break;
+            ++cidx;
+          }
+          charset.truncate( cidx );
+          // kdDebug() << "KMFolderMaildir::readFileHeaderIntern() charset found: " <<
+          //              charset << " from " << contentTypeStr << endl;
+        }
+      }
+
       KMMsgInfo *mi = new KMMsgInfo(folder());
       mi->init( subjStr.stripWhiteSpace(),
                 fromStr.stripWhiteSpace(),
@@ -734,7 +758,7 @@
                 replyToIdStr, replyToAuxIdStr, msgIdStr,
 				file.local8Bit(),
                 KMMsgEncryptionStateUnknown, KMMsgSignatureStateUnknown,
-                KMMsgMDNStateUnknown, f.size() );
+                KMMsgMDNStateUnknown, charset, f.size() );
 
       dateStr = dateStr.stripWhiteSpace();
       if (!dateStr.isEmpty())
@@ -823,6 +847,11 @@
       uidStr = QCString(line+6);
       lastStr = &uidStr;
     }
+    else if (strncasecmp(line, "Content-Type:", 13) == 0)
+    {
+      contentTypeStr = QCString(line+13);
+      lastStr = &contentTypeStr;
+    }
 
   }
 
--- branches/KDE/3.5/kdepim/kmail/kmfoldermbox.cpp #614057:614058
@@ -552,6 +552,7 @@
   QCString subjStr, dateStr, fromStr, toStr, xmarkStr, *lastStr=0;
   QCString replyToIdStr, replyToAuxIdStr, referencesStr, msgIdStr;
   QCString sizeServerStr, uidStr;
+  QCString contentTypeStr, charset;
   bool atEof = false;
   bool inHeader = true;
   KMMsgInfo* mi;
@@ -652,6 +653,29 @@
               replyToAuxIdStr.truncate( rightAngle + 1 );
           }
 
+          contentTypeStr = contentTypeStr.stripWhiteSpace();
+          charset = "";
+          if ( !contentTypeStr.isEmpty() )
+          {
+            int cidx = contentTypeStr.find( "charset=" );
+            if ( cidx != -1 ) {
+              charset = contentTypeStr.mid( cidx + 8 );
+              if ( charset[0] == '"' ) {
+                charset = charset.mid( 1 );
+              }
+              cidx = 0;
+              while ( (unsigned int) cidx < charset.length() ) {
+                if ( charset[cidx] == '"' || ( !isalnum(charset[cidx]) &&
+                    charset[cidx] != '-' && charset[cidx] != '_' ) )
+                  break;
+                ++cidx;
+              }
+              charset.truncate( cidx );
+              // kdDebug() << "KMFolderMaildir::readFileHeaderIntern() charset found: " <<
+              //              charset << " from " << contentTypeStr << endl;
+            }
+          }
+
           mi = new KMMsgInfo(folder());
           mi->init( subjStr.stripWhiteSpace(),
                     fromStr.stripWhiteSpace(),
@@ -660,7 +684,7 @@
                     xmarkStr.stripWhiteSpace(),
                     replyToIdStr, replyToAuxIdStr, msgIdStr,
                     KMMsgEncryptionStateUnknown, KMMsgSignatureStateUnknown,
-                    KMMsgMDNStateUnknown, offs, size, sizeServer, uid );
+                    KMMsgMDNStateUnknown, charset, offs, size, sizeServer, uid );
           mi->setStatus(status, xstatus);
           mi->setDate( dateStr.stripWhiteSpace() );
           mi->setDirty(false);
@@ -766,6 +790,11 @@
       uid = uidStr.toULong();
       lastStr = &uidStr;
     }
+    else if (strncasecmp(line, "Content-Type:", 13) == 0)
+    {
+      contentTypeStr = QCString(line+13);
+      lastStr = &contentTypeStr;
+    }
   }
 
   if (mAutoCreateIndex)
@@ -1071,10 +1100,10 @@
   }
   ++mTotalMsgs;
 
-  if ( aMsg->attachmentState() == KMMsgAttachmentUnknown && 
+  if ( aMsg->attachmentState() == KMMsgAttachmentUnknown &&
        aMsg->readyToShow() )
     aMsg->updateAttachmentState();
-  
+
   // store information about the position in the folder file in the message
   aMsg->setParent(folder());
   aMsg->setFolderOffset(offs);
--- branches/KDE/3.5/kdepim/kmail/kmmessage.cpp #614057:614058
@@ -2216,7 +2216,9 @@
   if ( !mMsg->Headers().FindField( aName ) )
     return QString::null;
 
-  return decodeRFC2047String( mMsg->Headers().FieldBody( aName.data() ).AsString().c_str() );
+  return decodeRFC2047String( mMsg->Headers().FieldBody( aName.data() ).AsString().c_str(),
+                              charset() );
+
 }
 
 QStringList KMMessage::headerFields( const QCString& field ) const
@@ -2227,7 +2229,7 @@
   std::vector<DwFieldBody*> v = mMsg->Headers().AllFieldBodies( field.data() );
   QStringList headerFields;
   for ( uint i = 0; i < v.size(); ++i ) {
-    headerFields.append( decodeRFC2047String( v[i]->AsString().c_str() ) );
+    headerFields.append( decodeRFC2047String( v[i]->AsString().c_str(), charset() ) );
   }
 
   return headerFields;
--- branches/KDE/3.5/kdepim/kmail/kmmsgbase.cpp #614057:614058
@@ -646,7 +646,7 @@
 
 
 //-----------------------------------------------------------------------------
-QString KMMsgBase::decodeRFC2047String(const QCString& aStr)
+QString KMMsgBase::decodeRFC2047String(const QCString& aStr, QCString prefCharset)
 {
   if ( aStr.isEmpty() )
     return QString::null;
@@ -656,9 +656,19 @@
   if ( str.isEmpty() )
     return QString::null;
 
-  if ( str.find( "=?" ) < 0 )
-    return KMMsgBase::codecForName( GlobalSettings::self()->
-                                    fallbackCharacterEncoding().latin1() )->toUnicode( str );
+  if ( str.find( "=?" ) < 0 ) {
+    if ( !prefCharset.isEmpty() ) {
+      if ( prefCharset == "us-ascii" ) {
+        // isn`t this foolproof?
+        return KMMsgBase::codecForName( "utf-8" )->toUnicode( str );
+      } else {
+        return KMMsgBase::codecForName( prefCharset )->toUnicode( str );
+      }
+    } else {
+      return KMMsgBase::codecForName( GlobalSettings::self()->
+                                      fallbackCharacterEncoding().latin1() )->toUnicode( str );
+    }
+  }
 
   QString result;
   QCString LWSP_buffer;
--- branches/KDE/3.5/kdepim/kmail/kmmsgbase.h #614057:614058
@@ -32,7 +32,7 @@
 class KMFolder;
 class KMFolderIndex;
 
-/** The new status format. These can be or'd together. 
+/** The new status format. These can be or'd together.
     Note, that the KMMsgStatusIgnored implies the
     status to be Read even if the flags are set
     to Unread or New. This is done in KMMsgBase::isRead()
@@ -341,7 +341,7 @@
 
   /** This function handles both encodings described in RFC2047:
     Base64 ("=?iso-8859-1?b?...?=") and quoted-printable */
-  static QString decodeRFC2047String(const QCString& aStr);
+  static QString decodeRFC2047String(const QCString& aStr, const QCString prefCharset = "");
 
   /** Encode given string as described in RFC2047:
     using quoted-printable. */
--- branches/KDE/3.5/kdepim/kmail/kmmsginfo.cpp #614057:614058
@@ -186,6 +186,7 @@
                      KMMsgEncryptionState encryptionState,
                      KMMsgSignatureState signatureState,
                      KMMsgMDNSentState mdnSentState,
+                     const QCString& prefCharset,
              off_t aFolderOffset, size_t aMsgSize,
              size_t aMsgSizeServer, ulong aUID)
 {
@@ -194,9 +195,9 @@
     if(!kd)
         kd = new KMMsgInfoPrivate;
     kd->modifiers = KMMsgInfoPrivate::ALL_SET;
-    kd->subject = decodeRFC2047String(aSubject);
-    kd->from = decodeRFC2047String( KMMessage::stripEmailAddr( aFrom ) );
-    kd->to = decodeRFC2047String( KMMessage::stripEmailAddr( aTo ) );
+    kd->subject = decodeRFC2047String(aSubject, prefCharset);
+    kd->from = decodeRFC2047String( KMMessage::stripEmailAddr( aFrom ), prefCharset );
+    kd->to = decodeRFC2047String( KMMessage::stripEmailAddr( aTo ), prefCharset );
     kd->replyToIdMD5 = base64EncodedMD5( replyToId );
     kd->replyToAuxIdMD5 = base64EncodedMD5( replyToAuxId );
     kd->strippedSubjectMD5 = base64EncodedMD5( KMMessage::stripOffPrefixes( kd->subject ), true /*utf8*/ );
@@ -224,12 +225,13 @@
                      KMMsgEncryptionState encryptionState,
                      KMMsgSignatureState signatureState,
                      KMMsgMDNSentState mdnSentState,
+                     const QCString& prefCharset,
                      size_t aMsgSize,
              size_t aMsgSizeServer, ulong aUID)
 {
   // use the "normal" init for most stuff
   init( aSubject, aFrom, aTo, aDate, aStatus, aXMark, replyToId, replyToAuxId,
-        msgId, encryptionState, signatureState, mdnSentState,
+        msgId, encryptionState, signatureState, mdnSentState, prefCharset,
         (unsigned long)0, aMsgSize, aMsgSizeServer, aUID );
   kd->file = aFileName;
 }
--- branches/KDE/3.5/kdepim/kmail/kmmsginfo.h #614057:614058
@@ -46,6 +46,7 @@
 		    KMMsgEncryptionState encryptionState,
 		    KMMsgSignatureState signatureState,
 		    KMMsgMDNSentState mdnSentState,
+                    const QCString& prefCharset,
 		    off_t folderOffset=0, size_t msgSize=0,
             size_t msgSizeServer = 0, ulong UID = 0);
 
@@ -60,7 +61,8 @@
 		    KMMsgEncryptionState encryptionState,
 		    KMMsgSignatureState signatureState,
 		    KMMsgMDNSentState mdnSentState,
-		    size_t msgSize=0,
+		    const QCString& prefCharset,
+                    size_t msgSize=0,
             size_t msgSizeServer = 0, ulong UID = 0);
 
   /** Inherited methods (see KMMsgBase for description): */
--- branches/KDE/3.5/kdepim/kmail/kmmsgpart.cpp #614057:614058
@@ -390,14 +390,14 @@
   QString fileName =
     KMimeType::mimeType( mimeType )->icon( QString::null, false );
   if ( fileName.isEmpty() )
-  { 
-    fileName = this->fileName(); 
-    if ( fileName.isEmpty() ) fileName = this->name(); 
+  {
+    fileName = this->fileName();
+    if ( fileName.isEmpty() ) fileName = this->name();
     if ( !fileName.isEmpty() )
     {
       fileName = KMimeType::findByPath( "/tmp/"+fileName, 0, true )->icon( QString::null, true );
     }
-  } 
+  }
 
   fileName =
     KGlobal::instance()->iconLoader()->iconPath( fileName, KIcon::Desktop );
@@ -487,7 +487,7 @@
 //-----------------------------------------------------------------------------
 QString KMMessagePart::contentDescription(void) const
 {
-  return KMMsgBase::decodeRFC2047String(mContentDescription);
+  return KMMsgBase::decodeRFC2047String(mContentDescription, charset());
 }
 
 
@@ -538,7 +538,7 @@
   if (bRFC2231encoded)
     return KMMsgBase::decodeRFC2231String(str);
   else
-    return KMMsgBase::decodeRFC2047String(str);
+    return KMMsgBase::decodeRFC2047String(str, charset());
 }