Bug 468351 - "display of header values with unencoded special characters broken" - mailnews part [r=bienvenu sr=neil]
This commit is contained in:
Родитель
8002a1caad
Коммит
93ed748f04
|
@ -393,12 +393,22 @@ nsresult nsMsgDBView::FetchAuthor(nsIMsgDBHdr * aHdr, nsAString &aSenderString)
|
|||
if (NS_SUCCEEDED(rv) && !name.IsEmpty())
|
||||
{
|
||||
nsCString charset;
|
||||
rv = aHdr->GetCharset(getter_Copies(charset));
|
||||
nsCOMPtr <nsIMsgFolder> folder;
|
||||
aHdr->GetFolder(getter_AddRefs(folder));
|
||||
PRBool charsetOverride;
|
||||
folder->GetCharsetOverride(&charsetOverride);
|
||||
if (charsetOverride ||
|
||||
NS_FAILED(aHdr->GetCharset(getter_Copies(charset))) ||
|
||||
charset.IsEmpty() ||
|
||||
charset.Equals("us-ascii"))
|
||||
folder->GetCharset(charset);
|
||||
rv = mimeConverter->DecodeMimeHeader(name.get(),
|
||||
charset.get(),
|
||||
PR_FALSE,
|
||||
charsetOverride,
|
||||
PR_TRUE,
|
||||
aSenderString);
|
||||
if (NS_FAILED(rv) || aSenderString.IsEmpty())
|
||||
CopyUTF8toUTF16(name, aSenderString);
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -557,3 +557,61 @@ nsresult nsMsgI18NShrinkUTF8Str(const nsCString &inString,
|
|||
outString.Assign(Substring(inString, 0, len));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void nsMsgI18NConvertRawBytesToUTF16(const nsCString& inString,
|
||||
const char* charset,
|
||||
nsAString& outString)
|
||||
{
|
||||
if (IsUTF8(inString))
|
||||
{
|
||||
CopyUTF8toUTF16(inString, outString);
|
||||
return;
|
||||
}
|
||||
|
||||
nsresult rv = ConvertToUnicode(charset, inString, outString);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
return;
|
||||
|
||||
const char* cur = inString.BeginReading();
|
||||
const char* end = inString.EndReading();
|
||||
outString.Truncate();
|
||||
while (cur < end) {
|
||||
char c = *cur++;
|
||||
if (c & char(0x80))
|
||||
outString.Append(UCS2_REPLACEMENT_CHAR);
|
||||
else
|
||||
outString.Append(c);
|
||||
}
|
||||
}
|
||||
|
||||
void nsMsgI18NConvertRawBytesToUTF8(const nsCString& inString,
|
||||
const char* charset,
|
||||
nsACString& outString)
|
||||
{
|
||||
if (IsUTF8(inString))
|
||||
{
|
||||
outString.Assign(inString);
|
||||
return;
|
||||
}
|
||||
|
||||
nsAutoString utf16Text;
|
||||
nsresult rv = ConvertToUnicode(charset, inString, utf16Text);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
{
|
||||
CopyUTF16toUTF8(utf16Text, outString);
|
||||
return;
|
||||
}
|
||||
|
||||
// EF BF BD (UTF-8 encoding of U+FFFD)
|
||||
NS_NAMED_LITERAL_CSTRING(utf8ReplacementChar, "\357\277\275");
|
||||
const char* cur = inString.BeginReading();
|
||||
const char* end = inString.EndReading();
|
||||
outString.Truncate();
|
||||
while (cur < end) {
|
||||
char c = *cur++;
|
||||
if (c & char(0x80))
|
||||
outString.Append(utf8ReplacementChar);
|
||||
else
|
||||
outString.Append(c);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -167,6 +167,26 @@ NS_MSG_BASE nsresult nsMsgI18NShrinkUTF8Str(const nsCString &inString,
|
|||
PRUint32 aMaxLength,
|
||||
nsACString &outString);
|
||||
|
||||
/*
|
||||
* Convert raw bytes in header to UTF-16
|
||||
*
|
||||
* @param inString [IN] Input raw octets
|
||||
* @param outString [OUT] Output UTF-16 string
|
||||
*/
|
||||
NS_MSG_BASE void nsMsgI18NConvertRawBytesToUTF16(const nsCString& inString,
|
||||
const char* charset,
|
||||
nsAString& outString);
|
||||
|
||||
/*
|
||||
* Convert raw bytes in header to UTF-8
|
||||
*
|
||||
* @param inString [IN] Input raw octets
|
||||
* @param outString [OUT] Output UTF-8 string
|
||||
*/
|
||||
NS_MSG_BASE void nsMsgI18NConvertRawBytesToUTF8(const nsCString& inString,
|
||||
const char* charset,
|
||||
nsACString& outString);
|
||||
|
||||
// inline forwarders to avoid littering with 'x-imap4-.....'
|
||||
inline nsresult CopyUTF16toMUTF7(const nsString &aSrc, nsACString& aDest)
|
||||
{
|
||||
|
@ -198,4 +218,24 @@ inline nsresult ConvertFromUnicode(const char* charset,
|
|||
return nsMsgI18NConvertFromUnicode(charset, aSrc, aDest);
|
||||
}
|
||||
|
||||
inline void ConvertRawBytesToUTF16(const nsCString& inString,
|
||||
const char* charset, nsAString& outString)
|
||||
{
|
||||
return nsMsgI18NConvertRawBytesToUTF16(inString, charset, outString);
|
||||
}
|
||||
|
||||
inline void ConvertRawBytesToUTF16(const char* inString,
|
||||
const char* charset, nsAString& outString)
|
||||
{
|
||||
return nsMsgI18NConvertRawBytesToUTF16(nsDependentCString(inString),
|
||||
charset,
|
||||
outString);
|
||||
}
|
||||
|
||||
inline void ConvertRawBytesToUTF8(const nsCString& inString,
|
||||
const char* charset, nsACString& outString)
|
||||
{
|
||||
return nsMsgI18NConvertRawBytesToUTF8(inString, charset, outString);
|
||||
}
|
||||
|
||||
#endif /* _nsMsgI18N_H_ */
|
||||
|
|
|
@ -2007,7 +2007,8 @@ nsresult nsMsgCompose::CreateMessage(const char * originalMsgURI,
|
|||
else
|
||||
toField.Assign(author);
|
||||
|
||||
m_compFields->SetTo(toField.get());
|
||||
ConvertRawBytesToUTF8(toField, originCharset.get(), decodedCString);
|
||||
m_compFields->SetTo(decodedCString.get());
|
||||
|
||||
// Setup quoting callbacks for later...
|
||||
mWhatHolder = 1;
|
||||
|
@ -2463,17 +2464,21 @@ NS_IMETHODIMP QuotingOutputStreamListener::OnStopRequest(nsIRequest *request, ns
|
|||
if (type == nsIMsgCompType::ReplyAll)
|
||||
{
|
||||
mHeaders->ExtractHeader(HEADER_TO, PR_TRUE, getter_Copies(outCString));
|
||||
CopyUTF8toUTF16(outCString, recipient);
|
||||
ConvertRawBytesToUTF16(outCString, charset.get(), recipient);
|
||||
mHeaders->ExtractHeader(HEADER_CC, PR_TRUE, getter_Copies(outCString));
|
||||
CopyUTF8toUTF16(outCString, cc);
|
||||
ConvertRawBytesToUTF16(outCString, charset.get(), cc);
|
||||
|
||||
// preserve BCC for the reply-to-self case
|
||||
mHeaders->ExtractHeader(HEADER_BCC, PR_TRUE, getter_Copies(outCString));
|
||||
if (!outCString.IsEmpty())
|
||||
compFields->SetBcc(NS_ConvertUTF8toUTF16(outCString));
|
||||
{
|
||||
nsAutoString bcc;
|
||||
ConvertRawBytesToUTF16(outCString, charset.get(), bcc);
|
||||
compFields->SetBcc(bcc);
|
||||
}
|
||||
|
||||
mHeaders->ExtractHeader(HEADER_MAIL_FOLLOWUP_TO, PR_TRUE, getter_Copies(outCString));
|
||||
CopyUTF8toUTF16(outCString, mailFollowupTo);
|
||||
ConvertRawBytesToUTF16(outCString, charset.get(), mailFollowupTo);
|
||||
|
||||
if (! mailFollowupTo.IsEmpty())
|
||||
{ // handle Mail-Followup-To (http://cr.yp.to/proto/replyto.html)
|
||||
|
@ -2507,9 +2512,9 @@ NS_IMETHODIMP QuotingOutputStreamListener::OnStopRequest(nsIRequest *request, ns
|
|||
}
|
||||
|
||||
mHeaders->ExtractHeader(HEADER_REPLY_TO, PR_FALSE, getter_Copies(outCString));
|
||||
CopyUTF8toUTF16(outCString, replyTo);
|
||||
ConvertRawBytesToUTF16(outCString, charset.get(), replyTo);
|
||||
mHeaders->ExtractHeader(HEADER_MAIL_REPLY_TO, PR_TRUE, getter_Copies(outCString));
|
||||
CopyUTF8toUTF16(outCString, mailReplyTo);
|
||||
ConvertRawBytesToUTF16(outCString, charset.get(), mailReplyTo);
|
||||
|
||||
mHeaders->ExtractHeader(HEADER_NEWSGROUPS, PR_FALSE, getter_Copies(outCString));
|
||||
if (!outCString.IsEmpty())
|
||||
|
@ -2575,7 +2580,9 @@ NS_IMETHODIMP QuotingOutputStreamListener::OnStopRequest(nsIRequest *request, ns
|
|||
mHeaders->ExtractHeader(HEADER_FROM, PR_FALSE, getter_Copies(outCString));
|
||||
if (!outCString.IsEmpty())
|
||||
{
|
||||
compFields->SetTo(NS_ConvertUTF8toUTF16(outCString));
|
||||
nsAutoString from;
|
||||
ConvertRawBytesToUTF16(outCString, charset.get(), from);
|
||||
compFields->SetTo(from);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -293,9 +293,11 @@ CreateCompositionFields(const char *from,
|
|||
cFields->SetCharacterSet(!PL_strcasecmp("us-ascii", charset) ? "ISO-8859-1" : charset);
|
||||
|
||||
char *val;
|
||||
nsAutoString outString;
|
||||
|
||||
if (from) {
|
||||
cFields->SetFrom(NS_ConvertUTF8toUTF16(from));
|
||||
ConvertRawBytesToUTF16(from, charset, outString);
|
||||
cFields->SetFrom(outString);
|
||||
}
|
||||
|
||||
if (subject) {
|
||||
|
@ -305,19 +307,23 @@ CreateCompositionFields(const char *from,
|
|||
}
|
||||
|
||||
if (reply_to) {
|
||||
cFields->SetReplyTo(NS_ConvertUTF8toUTF16(reply_to));
|
||||
ConvertRawBytesToUTF16(reply_to, charset, outString);
|
||||
cFields->SetReplyTo(outString);
|
||||
}
|
||||
|
||||
if (to) {
|
||||
cFields->SetTo(NS_ConvertUTF8toUTF16(to));
|
||||
ConvertRawBytesToUTF16(to, charset, outString);
|
||||
cFields->SetTo(outString);
|
||||
}
|
||||
|
||||
if (cc) {
|
||||
cFields->SetCc(NS_ConvertUTF8toUTF16(cc));
|
||||
ConvertRawBytesToUTF16(cc, charset, outString);
|
||||
cFields->SetCc(outString);
|
||||
}
|
||||
|
||||
if (bcc) {
|
||||
cFields->SetBcc(NS_ConvertUTF8toUTF16(bcc));
|
||||
ConvertRawBytesToUTF16(bcc, charset, outString);
|
||||
cFields->SetBcc(outString);
|
||||
}
|
||||
|
||||
if (fcc) {
|
||||
|
|
|
@ -61,13 +61,22 @@
|
|||
PRInt32 MimeHeaders_build_heads_list(MimeHeaders *hdrs);
|
||||
|
||||
static void
|
||||
MimeHeaders_convert_header_value(MimeDisplayOptions *opt, nsCString &value)
|
||||
MimeHeaders_convert_header_value(MimeDisplayOptions *opt, nsCString &value,
|
||||
PRBool convert_charset_only)
|
||||
{
|
||||
char *converted;
|
||||
|
||||
if (value.IsEmpty())
|
||||
return;
|
||||
|
||||
if (convert_charset_only)
|
||||
{
|
||||
nsCAutoString output;
|
||||
ConvertRawBytesToUTF8(value, opt->default_charset, output);
|
||||
value.Assign(output);
|
||||
return;
|
||||
}
|
||||
|
||||
if (opt && opt->rfc1522_conversion_p)
|
||||
{
|
||||
converted = MIME_DecodeMimeHeader(value.get(), opt->default_charset,
|
||||
|
@ -590,19 +599,20 @@ MimeHeaders_write_all_headers (MimeHeaders *hdrs, MimeDisplayOptions *opt, PRBoo
|
|||
}
|
||||
|
||||
// MW Fixme: more?
|
||||
PRBool convert_charset_only =
|
||||
#ifdef MOZILLA_INTERNAL_API
|
||||
if (!(name.LowerCaseEqualsLiteral("to") || name.LowerCaseEqualsLiteral("from") ||
|
||||
name.LowerCaseEqualsLiteral("to") || name.LowerCaseEqualsLiteral("from") ||
|
||||
name.LowerCaseEqualsLiteral("cc") || name.LowerCaseEqualsLiteral("bcc") ||
|
||||
name.LowerCaseEqualsLiteral("reply-to") || name.LowerCaseEqualsLiteral("sender")))
|
||||
name.LowerCaseEqualsLiteral("reply-to") || name.LowerCaseEqualsLiteral("sender");
|
||||
#else
|
||||
if (!(name.Equals("to", CaseInsensitiveCompare) ||
|
||||
name.Equals("to", CaseInsensitiveCompare) ||
|
||||
name.Equals("from", CaseInsensitiveCompare) ||
|
||||
name.Equals("cc", CaseInsensitiveCompare) ||
|
||||
name.Equals("bcc", CaseInsensitiveCompare) ||
|
||||
name.Equals("reply-to", CaseInsensitiveCompare) ||
|
||||
name.Equals("sender", CaseInsensitiveCompare)))
|
||||
name.Equals("sender", CaseInsensitiveCompare);
|
||||
#endif
|
||||
MimeHeaders_convert_header_value(opt, hdr_value);
|
||||
MimeHeaders_convert_header_value(opt, hdr_value, convert_charset_only);
|
||||
// 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)
|
||||
{
|
||||
|
|
Загрузка…
Ссылка в новой задаче