读信页标题的解码
本帖最后由 hechengjin 于 2016-3-25 19:39 编辑messageWindow.xul
messageWindow.jsonDisplayingMessage:
function StandaloneMessageDisplayWidget_onDisplayingMessage(aMsgHdr) {
this.__proto__.__proto__.onDisplayingMessage.call(this, aMsgHdr);
// - set the window title to the message subject (and maybe the app name)
let docTitle = aMsgHdr.mime2DecodedSubject;
// If the tab hasn't got a title, or we're on Mac, don't display
// the separator.
if (docTitle && !Application.platformIsMac)
docTitle += document.documentElement
.getAttribute("titlemenuseparator");
// If we haven't got a title at this stage add the modifier, or if
// we are on a non-mac platform, add the modifier.
if (!docTitle || !Application.platformIsMac)
docTitle += document.documentElement
.getAttribute("titlemodifier");
document.title = docTitle;nsMsgI18N.cpp
导入不标准邮件,对邮件标题按GB2312进行处理并编码,尽量保证不出现乱码
mailnews/local/src/nsParseMailbox.cpp
/mailnews/local/src/nsParseMailbox.hint nsParseMailMessageState::InternSubject (struct message_header *header)
{
char *key;
uint32_t L;
if (!header || header->length == 0)
{
m_newMsgHdr->SetSubject("");
return 0;
}
NS_ASSERTION (header->length == (short) strlen(header->value), "subject corrupt while parsing message");
key = (char *) header->value;/* #### const evilness */
L = header->length;
uint32_t flags;
(void)m_newMsgHdr->GetFlags(&flags);
/* strip "Re: " */
/**
We trust the X-Mozilla-Status line to be the smartest in almost
all things.One exception, however, is the HAS_RE flag.Since
we just parsed the subject header anyway, we expect that parsing
to be smartest.(After all, what if someone just went in and
edited the subject line by hand?)
*/
nsCString modifiedSubject;
if (NS_MsgStripRE((const char **) &key, &L, getter_Copies(modifiedSubject)))
flags |= nsMsgMessageFlags::HasRe;
else
flags &= ~nsMsgMessageFlags::HasRe;
m_newMsgHdr->SetFlags(flags); // this *does not* update the mozilla-status header in the local folder
//if (!*key) return 0; /* To catch a subject of "Re:" */
// Condense the subject text into as few MIME-2 encoded words as possible.
#ifdef WE_CONDENSE_MIME_STRINGS
char *condensedKey = msg_condense_mime2_string(modifiedSubject.IsEmpty() ? key : modifiedSubject.get());
#else
char *condensedKey = nullptr;
#endif
// 如果导入的邮件标题不符合标准格式没有编码,自己按GB2312处理并编码
bool bStandard = IsStandardFormat(key, header->length);
if (!bStandard)// 按gb2312处理
{
char *pszFixStr= FixStandardFormat(key, header->length);
if (pszFixStr == nullptr)
{
m_newMsgHdr->SetSubject(condensedKey ? condensedKey :
(modifiedSubject.IsEmpty() ? key : modifiedSubject.get()));
}
else
{
m_newMsgHdr->SetSubject(condensedKey ? condensedKey :
(modifiedSubject.IsEmpty() ? pszFixStr : modifiedSubject.get()));
PR_FREEIF(pszFixStr);
}
}
else // 正常处理
{
m_newMsgHdr->SetSubject(condensedKey ? condensedKey :
(modifiedSubject.IsEmpty() ? key : modifiedSubject.get()));
}
PR_FREEIF(condensedKey);
return 0;
}
bool nsParseMailMessageState::IsStandardFormat(char *pszValue, uint32_t uiLen)
{
for (uint32_t i = 0; i < uiLen; i++)
{
if (pszValue < 0x20 || pszValue > 0x7e)
{
if (pszValue == 0x0d || pszValue == 0x0a)
continue;
return false;
}
}
return true;
}
char* nsParseMailMessageState::FixStandardFormat(char *pszValue, uint32_t uiLen)
{
nsCString UTF8Str;
nsString UTF16Str;
const char *pInternal = nullptr;
ConvertToUnicode("gb2312", pszValue, UTF16Str);
UTF8Str = NS_ConvertUTF16toUTF8(UTF16Str);
uint32_t iLen = UTF8Str.GetData(&pInternal);
char *pBase64 = PL_Base64Encode(pInternal, iLen, nullptr);
if (pBase64 == nullptr)
return nullptr;
char *pszBuffer = (char *)PR_Malloc(PL_strlen(pBase64) + 12 + 10);
if (pszBuffer == nullptr)
{
PR_Free(pBase64);
return nullptr;
}
memset(pszBuffer, 0, PL_strlen(pBase64) + 12 + 10);
PL_strcat(pszBuffer, "=?UTF-8?B?");
PL_strcat(pszBuffer, pBase64);
PL_strcat(pszBuffer, "?=");
return pszBuffer;
}
class nsParseMailMessageState : public nsIMsgParseMailMsgState, public nsIDBChangeListener
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIMSGPARSEMAILMSGSTATE
NS_DECL_NSIDBCHANGELISTENER
nsParseMailMessageState();
virtual ~nsParseMailMessageState();
void Init(uint32_t fileposition);
virtual int32_t ParseFolderLine(const char *line, uint32_t lineLength);
virtual int StartNewEnvelope(const char *line, uint32_t lineLength);
int ParseHeaders();
int FinalizeHeaders();
int ParseEnvelope (const char *line, uint32_t line_size);
int InternSubject (struct message_header *header);
static bool IsEnvelopeLine(const char *buf, int32_t buf_size);
static intmsg_UnHex(char C);
nsCOMPtr<nsIMsgHeaderParser> m_HeaderAddressParser;
nsCOMPtr<nsIMsgDBHdr> m_newMsgHdr; /* current message header we're building */
nsCOMPtr<nsIMsgDatabase>m_mailDB;
nsCOMPtr<nsIMsgDatabase> m_backupMailDB;
nsMailboxParseState m_state;
int64_t m_position;
uint64_t m_envelope_pos;
uint64_t m_headerstartpos;
nsByteArray m_headers;
nsByteArray m_envelope;
struct message_header m_message_id;
struct message_header m_references;
struct message_header m_date;
struct message_header m_delivery_date;
struct message_header m_from;
struct message_header m_sender;
struct message_header m_newsgroups;
struct message_header m_subject;
struct message_header m_status;
struct message_header m_mozstatus;
struct message_header m_mozstatus2;
struct message_header m_in_reply_to;
struct message_header m_replyTo;
struct message_header m_content_type;
struct message_header m_bccList;
// Support for having multiple To or Cc header lines in a message
nsVoidArray m_toList;
nsVoidArray m_ccList;
struct message_header *GetNextHeaderInAggregate (nsVoidArray &list);
void GetAggregateHeader (nsVoidArray &list, struct message_header *);
void ClearAggregateHeader (nsVoidArray &list);
struct message_header m_envelope_from;
struct message_header m_envelope_date;
struct message_header m_priority;
struct message_header m_account_key;
struct message_header m_keywords;
// Mdn support
struct message_header m_mdn_original_recipient;
struct message_header m_return_path;
struct message_header m_mdn_dnt; /* MDN Disposition-Notification-To: header */
PRTime m_receivedTime;
uint16_t m_body_lines;
bool m_IgnoreXMozillaStatus;
// this enables extensions to add the values of particular headers to
// the .msf file as properties of nsIMsgHdr. It is initialized from a
// pref, mailnews.customDBHeaders
nsTArray<nsCString> m_customDBHeaders;
struct message_header *m_customDBHeaderValues;
bool IsStandardFormat(char *pszValue, uint32_t uiLen);
char *FixStandardFormat(char *pszValue, uint32_t uiLen);
protected:
};
// this should go in some utility class.
inline int nsParseMailMessageState::msg_UnHex(char C)
{
return ((C >= '0' && C <= '9') ? C - '0' :
((C >= 'A' && C <= 'F') ? C - 'A' + 10 :
((C >= 'a' && C <= 'f') ? C - 'a' + 10 : 0)));
} http://www.firemail.wang/forum.php?mod=viewthread&tid=24&highlight=%B9%A4%BE%DF
先用函数base64_encode() — 使用 MIME base64 对数据进行编码
标题字符串前加编码类型例如: =?UTF-8?B?
标题字符串后加:?=
例如:
$subject = "=?UTF-8?B?".base64_encode($subject)."?=";
将上面一句添加到代码之中,这样,发送的中文邮件标题就不是乱码了。 本帖最后由 hechengjin 于 2016-4-8 13:59 编辑
(https://www.rfc-editor.org/rfc/pdfrfc/rfc1342.txt.pdf)for (let key in rowHeaderData) {
let headers = []
for (let header of rowHeaderData) {
let headerItem = {
headerName: header.headerName
}
// RFC 1342 - Representation of Non-ASCII Text in Internet Message Headers
// (https://www.rfc-editor.org/rfc/pdfrfc/rfc1342.txt.pdf)
// subject may be an encoded word with format: "=?charset?encoding?encodedText?="
// if subject is not a encoded word, do not decode it.
if (header.headerName.toLowerCase() === 'subject' &&
header.headerValue.match(EncodingTextRegx) === null) {
headerItem.headerValue = header.headerValue
} else {
headerItem.headerValue = this.decodeMimeHeaderValue(header.headerValue)
}
headers.push(headerItem)
}
currentHeaderData = headers
}
页:
[1]