diff --git a/mailnews/db/msgdb/src/nsDBFolderInfo.cpp b/mailnews/db/msgdb/src/nsDBFolderInfo.cpp index 952185115e7..c09b2edcd54 100644 --- a/mailnews/db/msgdb/src/nsDBFolderInfo.cpp +++ b/mailnews/db/msgdb/src/nsDBFolderInfo.cpp @@ -613,7 +613,14 @@ nsDBFolderInfo::GetCharacterSet(nsString *result, PRBool *usedDefault) NS_IMETHODIMP nsDBFolderInfo::GetCharPtrCharacterSet(char **result) { - return GetCharPtrProperty(kCharacterSetColumnName, result); + nsresult rv = GetCharPtrProperty(kCharacterSetColumnName, result); + + if (NS_SUCCEEDED(rv) && *result == nsnull) + { + *result = gDefaultCharacterSet.ToNewCString(); + } + + return rv; } NS_IMETHODIMP nsDBFolderInfo::SetCharacterSet(nsString *charSet) diff --git a/mailnews/db/msgdb/src/nsMsgDatabase.cpp b/mailnews/db/msgdb/src/nsMsgDatabase.cpp index cd18bb8afdd..9e27b9b377a 100644 --- a/mailnews/db/msgdb/src/nsMsgDatabase.cpp +++ b/mailnews/db/msgdb/src/nsMsgDatabase.cpp @@ -2647,90 +2647,69 @@ nsIMimeConverter *nsMsgDatabase::GetMimeConverter() nsresult nsMsgDatabase::RowCellColumnToMime2DecodedString(nsIMdbRow *row, mdb_token columnToken, PRUnichar* *resultStr) { - nsresult err = NS_OK; - nsAutoString nakedString; - err = RowCellColumnTonsString(row, columnToken, nakedString); - if (NS_SUCCEEDED(err) && nakedString.Length() > 0) - { - GetMimeConverter(); - if (m_mimeConverter) - { - nsAutoString charset; - nsAutoString decodedStr; - PRBool usedDefault; - PRBool characterSetOverride; - m_dbFolderInfo->GetCharacterSet(&charset, &usedDefault); - m_dbFolderInfo->GetCharacterSetOverride(&characterSetOverride); - if (!characterSetOverride) - { - err = m_mimeConverter->DecodeMimePartIIStr(nakedString, charset, resultStr); - } - else - { - // if folder charset override is 'ON' then ignore the MIME header and - // always use the folder charset - char *encodedString, *decodedString; - encodedString = nakedString.ToNewCString(); - if (encodedString) + nsresult err = NS_OK; + nsCAutoString nakedString; + err = RowCellColumnTonsCString(row, columnToken, nakedString); + if (NS_SUCCEEDED(err) && nakedString.Length() > 0) + { + GetMimeConverter(); + if (m_mimeConverter) { - // do MIME decoding only, ignore charset, no charset conversion - err = m_mimeConverter->DecodeMimePartIIStr(encodedString, nsnull, &decodedString); - if (NS_SUCCEEDED(err)) - { - nakedString.AssignWithConversion(decodedString); - // call again only for charset conversion with the folder charset - err = m_mimeConverter->DecodeMimePartIIStr(nakedString, charset, resultStr); - } - PR_FREEIF(decodedString); - PR_FREEIF(encodedString); + char *charset; + nsAutoString decodedStr; + PRBool characterSetOverride; + m_dbFolderInfo->GetCharPtrCharacterSet(&charset); + m_dbFolderInfo->GetCharacterSetOverride(&characterSetOverride); + + err = m_mimeConverter->DecodeMimeHeader(nakedString, resultStr, charset, characterSetOverride); + PR_FREEIF(charset); } - } - } - } - return err; + } + return err; } nsresult nsMsgDatabase::RowCellColumnToAddressCollationKey(nsIMdbRow *row, mdb_token colToken, PRUint8 **result, PRUint32 *len) { - nsCAutoString cSender; - nsXPIDLCString name; + nsCAutoString cSender; + nsXPIDLCString name; - nsresult ret = RowCellColumnTonsCString(row, colToken, cSender); - if (NS_SUCCEEDED(ret)) - { - nsIMsgHeaderParser *headerParser = GetHeaderParser(); - if (headerParser) - { - // apply mime decode - nsIMimeConverter *converter = GetMimeConverter(); + nsresult ret = RowCellColumnTonsCString(row, colToken, cSender); + if (NS_SUCCEEDED(ret)) + { + nsIMsgHeaderParser *headerParser = GetHeaderParser(); + if (headerParser) + { + // apply mime decode + nsIMimeConverter *converter = GetMimeConverter(); - if (NS_SUCCEEDED(ret) && nsnull != converter) - { - char *resultStr = nsnull; - char *charset = nsnull; - m_dbFolderInfo->GetCharPtrCharacterSet(&charset); - char charsetName[128]; - PL_strncpy(charsetName, charset, sizeof(charsetName)); + if (NS_SUCCEEDED(ret) && nsnull != converter) + { + char *resultStr = nsnull; + char *charset; + PRBool characterSetOverride; + m_dbFolderInfo->GetCharPtrCharacterSet(&charset); + m_dbFolderInfo->GetCharacterSetOverride(&characterSetOverride); - ret = converter->DecodeMimePartIIStr(cSender.get(), charsetName, &resultStr); - if (NS_SUCCEEDED(ret)) - { - ret = headerParser->ExtractHeaderAddressName (charsetName, resultStr, getter_Copies(name)); - } - PR_FREEIF(resultStr); - PR_FREEIF(charset); - } + ret = converter->DecodeMimeHeader(cSender.get(), &resultStr, + charset, characterSetOverride); + if (NS_SUCCEEDED(ret)) + { + ret = headerParser->ExtractHeaderAddressName ("UTF-8", resultStr, getter_Copies(name)); + } + PR_FREEIF(resultStr); + PR_FREEIF(charset); + } - } - } - if (NS_SUCCEEDED(ret)) - { - nsAutoString nameStr; - nameStr.AssignWithConversion(name); - ret = CreateCollationKey(nameStr.GetUnicode(), result, len); - } + } + } + if (NS_SUCCEEDED(ret)) + { + nsAutoString nameStr; + nameStr.AssignWithConversion(name); + ret = CreateCollationKey(nameStr.GetUnicode(), result, len); + } - return ret; + return ret; } nsresult nsMsgDatabase::GetCollationKeyGenerator() diff --git a/mailnews/mime/emitters/src/nsMimeBaseEmitter.cpp b/mailnews/mime/emitters/src/nsMimeBaseEmitter.cpp index 0dfc3fe100c..69ee2403902 100644 --- a/mailnews/mime/emitters/src/nsMimeBaseEmitter.cpp +++ b/mailnews/mime/emitters/src/nsMimeBaseEmitter.cpp @@ -624,7 +624,7 @@ nsMimeBaseEmitter::WriteHeaderFieldHTML(const char *field, const char *value) nsXPIDLCString tValue; // we're going to need a converter to convert - nsresult rv = mUnicodeConverter->DecodeMimePartIIStr(value, "UTF-8", getter_Copies(tValue)); + nsresult rv = mUnicodeConverter->DecodeMimeHeader(value, getter_Copies(tValue)); if (NS_SUCCEEDED(rv)) { if (!tValue) diff --git a/mailnews/mime/public/nsIMimeConverter.h b/mailnews/mime/public/nsIMimeConverter.h index a2e232bfbfd..f9fbad4de22 100644 --- a/mailnews/mime/public/nsIMimeConverter.h +++ b/mailnews/mime/public/nsIMimeConverter.h @@ -37,10 +37,10 @@ #include "prtypes.h" #include "nsString.h" -// {C09EDB23-B7AF-11d2-B35E-525400E2D63A} +// {ea5b631e-1dd1-11b2-be0d-e02825f300d0} #define NS_IMIME_CONVERTER_IID \ - { 0xfb953da, 0xd0b5, 0x11d2, \ - { 0xb3, 0x73, 0x52, 0x54, 0x0, 0xe2, 0xd6, 0x3a } } + { 0xea5b631e, 0x1dd1, 0x11b2, \ + { 0xbe, 0x0d, 0xe0, 0x28, 0x25, 0xf3, 0x00, 0xd0 } } // default line length for calling the encoder #define kMIME_ENCODED_WORD_SIZE 72 @@ -59,17 +59,21 @@ public: // These methods are all implemented by libmime to be used by // modules that need to encode/decode mail headers - // Decode routine - NS_IMETHOD DecodeMimePartIIStr(const char *header, - char *charset, - char **decodedString, - PRBool eatContinuations = PR_TRUE) = 0; + // Decode routine. + // If header does not need decoding, places nsnull in decodedString + NS_IMETHOD DecodeMimeHeader(const char *header, + char **decodedString, + const char *default_charset = nsnull, + PRBool override_charset = PR_FALSE, + PRBool eatContinuations = PR_TRUE) = 0; // Decode routine (also converts output to unicode) - NS_IMETHOD DecodeMimePartIIStr(const nsCString& header, - nsCString& charset, - nsString& decodedString, - PRBool eatContinuations = PR_TRUE) = 0; + // On success, decodedString is never null + NS_IMETHOD DecodeMimeHeader(const nsCString& header, + PRUnichar **decodedString, + const char *default_charset = nsnull, + PRBool override_charset = PR_FALSE, + PRBool eatContinuations = PR_TRUE) = 0; // OBSOLESCENT Decode routine (also converts output to unicode) NS_IMETHOD DecodeMimePartIIStr(const nsString& header, diff --git a/mailnews/mime/src/nsMimeConverter.cpp b/mailnews/mime/src/nsMimeConverter.cpp index 9330d3f7c37..26303792c32 100644 --- a/mailnews/mime/src/nsMimeConverter.cpp +++ b/mailnews/mime/src/nsMimeConverter.cpp @@ -48,42 +48,6 @@ nsMimeConverter::~nsMimeConverter() { } -nsresult -nsMimeConverter::DecodeMimePartIIStr(const nsCString& header, - nsCString& charset, - nsString& decodedString, - PRBool eatContinuations) -{ - char charsetNameBuffer[kMAX_CSNAME+1]; - char *decodedCstr = nsnull; - nsresult res = NS_OK; - - // initialize the charset buffer - PL_strcpy(charsetNameBuffer, "us-ascii"); - - // apply MIME decode. - decodedCstr = MIME_DecodeMimePartIIStr(header, - charsetNameBuffer, eatContinuations); - if (nsnull == decodedCstr) { - // no decode needed and no default charset was specified - if (charset.IsEmpty()) { - decodedString.AssignWithConversion(header); - } - else { - // no MIME encoded, convert default charset to unicode - res = ConvertToUnicode(NS_ConvertASCIItoUCS2(charset), header, decodedString); - } - } - else { - // assign the charset encoded in MIME header - charset.Assign(charsetNameBuffer); - // convert MIME charset to unicode - res = ConvertToUnicode(NS_ConvertASCIItoUCS2(charset), (const char *) decodedCstr, decodedString); - PR_FREEIF(decodedCstr); - } - return res; -} - nsresult nsMimeConverter::DecodeMimePartIIStr(const nsString& header, nsString& charset, @@ -160,30 +124,47 @@ nsMimeConverter::DecodeMimePartIIStr(const nsString& header, } nsresult -nsMimeConverter::DecodeMimePartIIStr(const char *header, - char *charset, - char **decodedString, - PRBool eatContinuations) +nsMimeConverter::DecodeMimeHeader(const char *header, + char **decodedString, + const char *default_charset, + PRBool override_charset, + PRBool eatContinuations) { - char *retString; - if (charset) - { - retString = MIME_DecodeMimePartIIStr(header, charset, eatContinuations); - } - else - { - // the callder does not care about the charset, pass the local buffer - char charsetCstr[kMAX_CSNAME+1]; - *charsetCstr = '\0'; - retString = MIME_DecodeMimePartIIStr(header, charsetCstr, eatContinuations); - } + char *retString = MIME_DecodeMimeHeader(header, default_charset, + override_charset, + eatContinuations); if (retString == NULL) return NS_ERROR_FAILURE; - else - { - *decodedString = retString; - return NS_OK; + + *decodedString = retString; + return NS_OK; +} + +// Decode routine (also converts output to unicode) +nsresult +nsMimeConverter::DecodeMimeHeader(const nsCString& header, + PRUnichar **decodedString, + const char *default_charset, + PRBool override_charset, + PRBool eatContinuations) +{ + char *decodedCstr = nsnull; + nsresult res = NS_OK; + + // apply MIME decode. + decodedCstr = MIME_DecodeMimeHeader(header, default_charset, + override_charset, eatContinuations); + if (nsnull == decodedCstr) { + // no decode or conversion needed + *decodedString = header.ToNewUnicode(); } + else { + *decodedString = NS_ConvertUTF8toUCS2(decodedCstr).ToNewUnicode(); + if (!(*decodedString)) + res = NS_ERROR_OUT_OF_MEMORY; + PR_FREEIF(decodedCstr); + } + return res; } nsresult diff --git a/mailnews/mime/src/nsMimeConverter.h b/mailnews/mime/src/nsMimeConverter.h index bba466253c5..b783a0e35ad 100644 --- a/mailnews/mime/src/nsMimeConverter.h +++ b/mailnews/mime/src/nsMimeConverter.h @@ -54,16 +54,18 @@ public: // content type handler plugins for processing stream data. // Decode routine - NS_IMETHOD DecodeMimePartIIStr(const char *header, - char *charset, - char **decodedString, - PRBool eatContinuations = PR_TRUE); + NS_IMETHOD DecodeMimeHeader(const char *header, + char **decodedString, + const char *default_charset = 0, + PRBool override_charset = PR_FALSE, + PRBool eatContinuations = PR_TRUE); // Decode routine (also converts output to unicode) - NS_IMETHOD DecodeMimePartIIStr(const nsCString& header, - nsCString& charset, - nsString& decodedString, - PRBool eatContinuations = PR_TRUE); + NS_IMETHOD DecodeMimeHeader(const nsCString& header, + PRUnichar **decodedString, + const char *default_charset = 0, + PRBool override_charset = PR_FALSE, + PRBool eatContinuations = PR_TRUE); // OBSOLESCENT Decode routine (also converts output to unicode) NS_IMETHOD DecodeMimePartIIStr(const nsString& header,