fix handling of rfc 2047 headers, r=bienvenu, sr=neil, 254519

This commit is contained in:
Martin Wilck martin.wilck@fujitsu-siemens.com 2008-12-05 12:42:24 -08:00
Родитель 5b69c050f5
Коммит 0c9d4953f3
5 изменённых файлов: 77 добавлений и 80 удалений

Просмотреть файл

@ -70,6 +70,7 @@
#include "nsITreeColumns.h"
#include "nsTextFormatter.h"
#include "nsIMutableArray.h"
#include "nsIMimeConverter.h"
nsrefcnt nsMsgDBView::gInstanceCount = 0;
@ -373,28 +374,31 @@ nsresult nsMsgDBView::AppendKeywordProperties(const char *keywords, nsISupportsA
nsresult nsMsgDBView::FetchAuthor(nsIMsgDBHdr * aHdr, nsAString &aSenderString)
{
nsString unparsedAuthor;
nsCString unparsedAuthor;
if (!mHeaderParser)
mHeaderParser = do_GetService(NS_MAILNEWS_MIME_HEADER_PARSER_CONTRACTID);
nsresult rv = aHdr->GetMime2DecodedAuthor(unparsedAuthor);
nsCOMPtr <nsIMimeConverter> mimeConverter = do_GetService(NS_MIME_CONVERTER_CONTRACTID);
nsresult rv = aHdr->GetAuthor(getter_Copies(unparsedAuthor));
// *sigh* how sad, we need to convert our beautiful unicode string to utf8
// so we can extract the name part of the address...then convert it back to
// unicode again.
if (mHeaderParser)
{
nsCString name;
rv = mHeaderParser->ExtractHeaderAddressName(NS_ConvertUTF16toUTF8(unparsedAuthor),
name);
rv = mHeaderParser->ExtractHeaderAddressName(unparsedAuthor, name);
if (NS_SUCCEEDED(rv) && !name.IsEmpty())
{
CopyUTF8toUTF16(name, aSenderString);
nsCString charset;
rv = aHdr->GetCharset(getter_Copies(charset));
rv = mimeConverter->DecodeMimeHeader(name.get(),
charset.get(),
PR_FALSE,
PR_TRUE,
aSenderString);
return NS_OK;
}
}
// if we got here then just return the original string
aSenderString = unparsedAuthor;
CopyUTF8toUTF16(unparsedAuthor, aSenderString);
return NS_OK;
}

Просмотреть файл

@ -47,6 +47,8 @@
#include "nsIFileChannel.h"
#include "nsIMsgMdnGenerator.h"
#include "nsServiceManagerUtils.h"
#include "nsMsgMimeCID.h"
#include "nsIMimeConverter.h"
#include "nsArrayEnumerator.h"
/* the following macro actually implement addref, release and query interface for our component. */
@ -550,6 +552,8 @@ NS_IMETHODIMP nsMsgCompFields::SplitRecipients(const nsAString &aRecipients, PRB
if (NS_SUCCEEDED(rv))
{
nsCOMPtr<nsIMsgHeaderParser> parser = do_GetService(NS_MAILNEWS_MIME_HEADER_PARSER_CONTRACTID);
nsCOMPtr<nsIMimeConverter> converter = do_GetService(NS_MIME_CONVERTER_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
if (parser)
{
nsCAutoString recipientsStr;
@ -572,9 +576,16 @@ NS_IMETHODIMP nsMsgCompFields::SplitRecipients(const nsAString &aRecipients, PRB
{
nsCString fullAddress;
nsAutoString recipient;
if (!aEmailAddressOnly)
rv = parser->MakeFullAddressString(pNames, pAddresses,
if (!aEmailAddressOnly)
{
nsCString decodedName;
converter->DecodeMimeHeaderToCharPtr(pNames, GetCharacterSet(), PR_FALSE, PR_TRUE,
getter_Copies(decodedName));
rv = parser->MakeFullAddressString((!decodedName.IsEmpty() ?
decodedName.get() : pNames),
pAddresses,
getter_Copies(fullAddress));
}
if (NS_SUCCEEDED(rv) && !aEmailAddressOnly)
{
rv = ConvertToUnicode("UTF-8", fullAddress, recipient);
@ -613,6 +624,8 @@ nsresult nsMsgCompFields::SplitRecipientsEx(const nsAString &recipients,
nsCOMPtr<nsIMsgHeaderParser> parser =
do_GetService(NS_MAILNEWS_MIME_HEADER_PARSER_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIMimeConverter> converter = do_GetService(NS_MIME_CONVERTER_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
nsCAutoString recipientsStr;
char *names;
@ -630,7 +643,12 @@ nsresult nsMsgCompFields::SplitRecipientsEx(const nsAString &recipients,
for (PRUint32 i = 0; i < numAddresses; ++i)
{
nsCString fullAddress;
rv = parser->MakeFullAddressString(pNames, pAddresses,
nsCString decodedName;
converter->DecodeMimeHeaderToCharPtr(pNames, GetCharacterSet(), PR_FALSE, PR_TRUE,
getter_Copies(decodedName));
rv = parser->MakeFullAddressString((!decodedName.IsEmpty() ?
decodedName.get() : pNames),
pAddresses,
getter_Copies(fullAddress));
nsMsgRecipient msgRecipient;

Просмотреть файл

@ -1982,13 +1982,7 @@ nsresult nsMsgCompose::CreateMessage(const char * originalMsgURI,
else
toField.Assign(author);
rv = mimeConverter->DecodeMimeHeaderToCharPtr(toField.get(),
originCharset.get(), charsetOverride, PR_TRUE,
getter_Copies(decodedCString));
if (NS_SUCCEEDED(rv) && !decodedCString.IsEmpty())
m_compFields->SetTo(decodedCString.get());
else
m_compFields->SetTo(toField.get());
m_compFields->SetTo(toField.get());
// Setup quoting callbacks for later...
mWhatHolder = 1;
@ -2270,31 +2264,39 @@ QuotingOutputStreamListener::QuotingOutputStreamListener(const char * originalMs
if (NS_SUCCEEDED(rv))
{
nsCString decodedCString;
mMimeConverter = do_GetService(NS_MIME_CONVERTER_CONTRACTID);
// Decode header, the result string is null if the input is non MIME encoded ASCII.
if (mMimeConverter)
mMimeConverter->DecodeMimeHeaderToCharPtr(author.get(), charset,
charetOverride, PR_TRUE, getter_Copies(decodedCString));
nsCOMPtr<nsIMsgHeaderParser> parser (do_GetService(NS_MAILNEWS_MIME_HEADER_PARSER_CONTRACTID));
if (parser)
{
nsCString authorName;
rv = parser->ExtractHeaderAddressName(!decodedCString.IsEmpty() ?
decodedCString : author,
authorName);
rv = parser->ExtractHeaderAddressName(author, authorName);
// take care "%s wrote"
PRUnichar *formatedString = nsnull;
if (NS_SUCCEEDED(rv) && !authorName.IsEmpty())
formatedString = nsTextFormatter::smprintf(replyHeaderAuthorwrote.get(), authorName.get());
else
formatedString = nsTextFormatter::smprintf(replyHeaderAuthorwrote.get(), author.get());
if (formatedString)
PRUnichar *formattedString = nsnull;
if (NS_SUCCEEDED(rv) && !authorName.IsEmpty())
{
citePrefixAuthor.Assign(formatedString);
nsTextFormatter::smprintf_free(formatedString);
nsCString decodedAuthor;
// Decode header, the result string is null
// if the input is not MIME encoded ASCII.
if (mMimeConverter)
mMimeConverter->DecodeMimeHeaderToCharPtr(authorName.get(),
charset,
charetOverride,
PR_TRUE,
getter_Copies(decodedAuthor));
formattedString = nsTextFormatter::smprintf(replyHeaderAuthorwrote.get(),
(!decodedAuthor.IsEmpty() ?
decodedAuthor.get() : authorName.get()));
}
else
{
formattedString = nsTextFormatter::smprintf(replyHeaderAuthorwrote.get(),
author.get());
}
if (formattedString)
{
citePrefixAuthor.Assign(formattedString);
nsTextFormatter::smprintf_free(formattedString);
}
}
@ -2406,7 +2408,6 @@ NS_IMETHODIMP QuotingOutputStreamListener::OnStopRequest(nsIRequest *request, ns
aCharset.AssignLiteral("UTF-8");
nsAutoString recipient;
nsAutoString cc;
nsAutoString bcc;
nsAutoString replyTo;
nsAutoString mailReplyTo;
nsAutoString mailFollowupTo;
@ -2428,29 +2429,17 @@ NS_IMETHODIMP QuotingOutputStreamListener::OnStopRequest(nsIRequest *request, ns
if (type == nsIMsgCompType::ReplyAll)
{
mHeaders->ExtractHeader(HEADER_TO, PR_TRUE, getter_Copies(outCString));
if (!outCString.IsEmpty())
mMimeConverter->DecodeMimeHeader(outCString.get(), charset.get(),
PR_FALSE, PR_TRUE, recipient);
CopyUTF8toUTF16(outCString, recipient);
mHeaders->ExtractHeader(HEADER_CC, PR_TRUE, getter_Copies(outCString));
if (!outCString.IsEmpty())
mMimeConverter->DecodeMimeHeader(outCString.get(), charset.get(),
PR_FALSE, PR_TRUE, cc);
CopyUTF8toUTF16(outCString, cc);
// preserve BCC for the reply-to-self case
mHeaders->ExtractHeader(HEADER_BCC, PR_TRUE, getter_Copies(outCString));
if (!outCString.IsEmpty())
{
mMimeConverter->DecodeMimeHeader(outCString.get(), charset.get(),
PR_FALSE, PR_TRUE, bcc);
if (!bcc.IsEmpty())
compFields->SetBcc(bcc);
}
compFields->SetBcc(NS_ConvertUTF8toUTF16(outCString));
mHeaders->ExtractHeader(HEADER_MAIL_FOLLOWUP_TO, PR_TRUE, getter_Copies(outCString));
if (!outCString.IsEmpty())
mMimeConverter->DecodeMimeHeader(outCString.get(), charset.get(),
PR_FALSE, PR_TRUE, mailFollowupTo);
CopyUTF8toUTF16(outCString, mailFollowupTo);
if (! mailFollowupTo.IsEmpty())
{ // handle Mail-Followup-To (http://cr.yp.to/proto/replyto.html)
@ -2484,14 +2473,9 @@ NS_IMETHODIMP QuotingOutputStreamListener::OnStopRequest(nsIRequest *request, ns
}
mHeaders->ExtractHeader(HEADER_REPLY_TO, PR_FALSE, getter_Copies(outCString));
if (!outCString.IsEmpty())
mMimeConverter->DecodeMimeHeader(outCString.get(), charset.get(),
PR_FALSE, PR_TRUE, replyTo);
CopyUTF8toUTF16(outCString, replyTo);
mHeaders->ExtractHeader(HEADER_MAIL_REPLY_TO, PR_TRUE, getter_Copies(outCString));
if (!outCString.IsEmpty())
mMimeConverter->DecodeMimeHeader(outCString.get(), charset.get(),
PR_FALSE, PR_TRUE, mailReplyTo);
CopyUTF8toUTF16(outCString, mailReplyTo);
mHeaders->ExtractHeader(HEADER_NEWSGROUPS, PR_FALSE, getter_Copies(outCString));
if (!outCString.IsEmpty())
@ -2557,10 +2541,7 @@ NS_IMETHODIMP QuotingOutputStreamListener::OnStopRequest(nsIRequest *request, ns
mHeaders->ExtractHeader(HEADER_FROM, PR_FALSE, getter_Copies(outCString));
if (!outCString.IsEmpty())
{
nsAutoString from;
mMimeConverter->DecodeMimeHeader(outCString.get(), charset.get(),
PR_FALSE, PR_TRUE, from);
compFields->SetTo(from);
compFields->SetTo(NS_ConvertUTF8toUTF16(outCString));
}
}

Просмотреть файл

@ -301,9 +301,7 @@ CreateCompositionFields(const char *from,
char *val;
if (from) {
val = MIME_DecodeMimeHeader(from, charset, PR_FALSE, PR_TRUE);
cFields->SetFrom(NS_ConvertUTF8toUTF16(val ? val : from));
PR_FREEIF(val);
cFields->SetFrom(NS_ConvertUTF8toUTF16(from));
}
if (subject) {
@ -313,27 +311,19 @@ CreateCompositionFields(const char *from,
}
if (reply_to) {
val = MIME_DecodeMimeHeader(reply_to, charset, PR_FALSE, PR_TRUE);
cFields->SetReplyTo(NS_ConvertUTF8toUTF16(val ? val : reply_to));
PR_FREEIF(val);
cFields->SetReplyTo(NS_ConvertUTF8toUTF16(reply_to));
}
if (to) {
val = MIME_DecodeMimeHeader(to, charset, PR_FALSE, PR_TRUE);
cFields->SetTo(NS_ConvertUTF8toUTF16(val ? val : to));
PR_FREEIF(val);
cFields->SetTo(NS_ConvertUTF8toUTF16(to));
}
if (cc) {
val = MIME_DecodeMimeHeader(cc, charset, PR_FALSE, PR_TRUE);
cFields->SetCc(NS_ConvertUTF8toUTF16(val ? val : cc));
PR_FREEIF(val);
cFields->SetCc(NS_ConvertUTF8toUTF16(cc));
}
if (bcc) {
val = MIME_DecodeMimeHeader(bcc, charset, PR_FALSE, PR_TRUE);
cFields->SetBcc(NS_ConvertUTF8toUTF16(val ? val : bcc));
PR_FREEIF(val);
cFields->SetBcc(NS_ConvertUTF8toUTF16(bcc));
}
if (fcc) {

Просмотреть файл

@ -589,7 +589,11 @@ MimeHeaders_write_all_headers (MimeHeaders *hdrs, MimeDisplayOptions *opt, PRBoo
hdr_value = Substring(contents, end);
}
MimeHeaders_convert_header_value(opt, hdr_value);
// MW Fixme: more?
if (!(name.LowerCaseEqualsLiteral("to") || name.LowerCaseEqualsLiteral("from") ||
name.LowerCaseEqualsLiteral("cc") || name.LowerCaseEqualsLiteral("bcc") ||
name.LowerCaseEqualsLiteral("reply-to") || name.LowerCaseEqualsLiteral("sender")))
MimeHeaders_convert_header_value(opt, hdr_value);
// if we're saving as html, we need to convert headers from utf8 to message charset, if any
if (opt->format_out == nsMimeOutput::nsMimeMessageSaveAs && charset)
{