firemail

标题: 读信页标题的解码 [打印本页]

作者: hechengjin    时间: 2016-3-23 16:02
标题: 读信页标题的解码
本帖最后由 hechengjin 于 2016-3-25 19:39 编辑

messageWindow.xul
messageWindow.js
  1. onDisplayingMessage:
  2.       function StandaloneMessageDisplayWidget_onDisplayingMessage(aMsgHdr) {
  3.     this.__proto__.__proto__.onDisplayingMessage.call(this, aMsgHdr);

  4.     // - set the window title to the message subject (and maybe the app name)
  5.     let docTitle = aMsgHdr.mime2DecodedSubject;

  6.     // If the tab hasn't got a title, or we're on Mac, don't display
  7.     // the separator.
  8.     if (docTitle && !Application.platformIsMac)
  9.         docTitle += document.documentElement
  10.                             .getAttribute("titlemenuseparator");

  11.     // If we haven't got a title at this stage add the modifier, or if
  12.     // we are on a non-mac platform, add the modifier.
  13.     if (!docTitle || !Application.platformIsMac)
  14.          docTitle += document.documentElement
  15.                              .getAttribute("titlemodifier");

  16.     document.title = docTitle;
复制代码
nsMsgI18N.cpp



作者: jimu    时间: 2016-3-24 12:37
导入不标准邮件,对邮件标题按GB2312进行处理并编码,尽量保证不出现乱码
mailnews/local/src/nsParseMailbox.cpp
/mailnews/local/src/nsParseMailbox.h
  1. int nsParseMailMessageState::InternSubject (struct message_header *header)
  2. {
  3.   char *key;
  4.   uint32_t L;

  5.   if (!header || header->length == 0)
  6.   {
  7.     m_newMsgHdr->SetSubject("");
  8.     return 0;
  9.   }

  10.   NS_ASSERTION (header->length == (short) strlen(header->value), "subject corrupt while parsing message");

  11.   key = (char *) header->value;  /* #### const evilness */

  12.   L = header->length;


  13.   uint32_t flags;
  14.   (void)m_newMsgHdr->GetFlags(&flags);
  15.   /* strip "Re: " */
  16.   /**
  17.         We trust the X-Mozilla-Status line to be the smartest in almost
  18.         all things.  One exception, however, is the HAS_RE flag.  Since
  19.          we just parsed the subject header anyway, we expect that parsing
  20.          to be smartest.  (After all, what if someone just went in and
  21.         edited the subject line by hand?)
  22.      */
  23.   nsCString modifiedSubject;
  24.   if (NS_MsgStripRE((const char **) &key, &L, getter_Copies(modifiedSubject)))
  25.     flags |= nsMsgMessageFlags::HasRe;
  26.   else
  27.     flags &= ~nsMsgMessageFlags::HasRe;
  28.   m_newMsgHdr->SetFlags(flags); // this *does not* update the mozilla-status header in the local folder

  29.   //  if (!*key) return 0; /* To catch a subject of "Re:" */

  30.   // Condense the subject text into as few MIME-2 encoded words as possible.
  31. #ifdef WE_CONDENSE_MIME_STRINGS
  32.   char *condensedKey = msg_condense_mime2_string(modifiedSubject.IsEmpty() ? key : modifiedSubject.get());
  33. #else
  34.   char *condensedKey = nullptr;
  35. #endif
  36.   
  37.   // 如果导入的邮件标题不符合标准格式没有编码,自己按GB2312处理并编码
  38.   bool bStandard = IsStandardFormat(key, header->length);
  39.   if (!bStandard)// 按gb2312处理
  40.   {
  41.           char *pszFixStr= FixStandardFormat(key, header->length);
  42.           if (pszFixStr == nullptr)
  43.           {
  44.                   m_newMsgHdr->SetSubject(condensedKey ? condensedKey :
  45.                           (modifiedSubject.IsEmpty() ? key : modifiedSubject.get()));
  46.           }
  47.           else
  48.           {
  49.                   m_newMsgHdr->SetSubject(condensedKey ? condensedKey :
  50.                           (modifiedSubject.IsEmpty() ? pszFixStr : modifiedSubject.get()));
  51.                   PR_FREEIF(pszFixStr);
  52.           }
  53.   }
  54.   else // 正常处理
  55.   {
  56.           m_newMsgHdr->SetSubject(condensedKey ? condensedKey :
  57.                   (modifiedSubject.IsEmpty() ? key : modifiedSubject.get()));
  58.   }

  59.   PR_FREEIF(condensedKey);

  60.   return 0;
  61. }

  62. bool nsParseMailMessageState::IsStandardFormat(char *pszValue, uint32_t uiLen)
  63. {
  64.         for (uint32_t i = 0; i < uiLen; i++)
  65.         {
  66.                 if (pszValue[i] < 0x20 || pszValue[i] > 0x7e)
  67.                 {
  68.                         if (pszValue[i] == 0x0d || pszValue[i] == 0x0a)
  69.                                 continue;

  70.                         return false;
  71.                 }
  72.         }

  73.         return true;
  74. }

  75. char* nsParseMailMessageState::FixStandardFormat(char *pszValue, uint32_t uiLen)
  76. {
  77.         nsCString UTF8Str;
  78.         nsString UTF16Str;

  79.         const char *pInternal = nullptr;
  80.         ConvertToUnicode("gb2312", pszValue, UTF16Str);
  81.         UTF8Str = NS_ConvertUTF16toUTF8(UTF16Str);
  82.         uint32_t iLen = UTF8Str.GetData(&pInternal);

  83.         char *pBase64 = PL_Base64Encode(pInternal, iLen, nullptr);
  84.         if (pBase64 == nullptr)
  85.                 return nullptr;

  86.         char *pszBuffer = (char *)PR_Malloc(PL_strlen(pBase64) + 12 + 10);
  87.         if (pszBuffer == nullptr)
  88.         {
  89.                 PR_Free(pBase64);
  90.                 return nullptr;
  91.         }

  92.         memset(pszBuffer, 0, PL_strlen(pBase64) + 12 + 10);
  93.         PL_strcat(pszBuffer, "=?UTF-8?B?");
  94.         PL_strcat(pszBuffer, pBase64);
  95.         PL_strcat(pszBuffer, "?=");

  96.         return pszBuffer;
  97. }

  98. class nsParseMailMessageState : public nsIMsgParseMailMsgState, public nsIDBChangeListener
  99. {
  100. public:
  101.   NS_DECL_ISUPPORTS
  102.   NS_DECL_NSIMSGPARSEMAILMSGSTATE
  103.   NS_DECL_NSIDBCHANGELISTENER

  104.   nsParseMailMessageState();
  105.   virtual               ~nsParseMailMessageState();

  106.   void                  Init(uint32_t fileposition);
  107.   virtual int32_t       ParseFolderLine(const char *line, uint32_t lineLength);
  108.   virtual int           StartNewEnvelope(const char *line, uint32_t lineLength);
  109.   int                   ParseHeaders();
  110.   int                   FinalizeHeaders();
  111.   int                   ParseEnvelope (const char *line, uint32_t line_size);
  112.   int                   InternSubject (struct message_header *header);

  113.   static bool    IsEnvelopeLine(const char *buf, int32_t buf_size);
  114.   static int  msg_UnHex(char C);

  115.   nsCOMPtr<nsIMsgHeaderParser> m_HeaderAddressParser;

  116.   nsCOMPtr<nsIMsgDBHdr> m_newMsgHdr; /* current message header we're building */
  117.   nsCOMPtr<nsIMsgDatabase>  m_mailDB;
  118.   nsCOMPtr<nsIMsgDatabase> m_backupMailDB;

  119.   nsMailboxParseState   m_state;
  120.   int64_t              m_position;
  121.   uint64_t              m_envelope_pos;
  122.   uint64_t              m_headerstartpos;

  123.   nsByteArray           m_headers;

  124.   nsByteArray           m_envelope;

  125.   struct message_header m_message_id;
  126.   struct message_header m_references;
  127.   struct message_header m_date;
  128.   struct message_header m_delivery_date;
  129.   struct message_header m_from;
  130.   struct message_header m_sender;
  131.   struct message_header m_newsgroups;
  132.   struct message_header m_subject;
  133.   struct message_header m_status;
  134.   struct message_header m_mozstatus;
  135.   struct message_header m_mozstatus2;
  136.   struct message_header m_in_reply_to;
  137.   struct message_header m_replyTo;
  138.   struct message_header m_content_type;
  139.   struct message_header m_bccList;

  140.   // Support for having multiple To or Cc header lines in a message
  141.   nsVoidArray m_toList;
  142.   nsVoidArray m_ccList;
  143.   struct message_header *GetNextHeaderInAggregate (nsVoidArray &list);
  144.   void GetAggregateHeader (nsVoidArray &list, struct message_header *);
  145.   void ClearAggregateHeader (nsVoidArray &list);

  146.   struct message_header m_envelope_from;
  147.   struct message_header m_envelope_date;
  148.   struct message_header m_priority;
  149.   struct message_header m_account_key;
  150.   struct message_header m_keywords;
  151.   // Mdn support
  152.   struct message_header m_mdn_original_recipient;
  153.   struct message_header m_return_path;
  154.   struct message_header m_mdn_dnt; /* MDN Disposition-Notification-To: header */

  155.   PRTime m_receivedTime;
  156.   uint16_t              m_body_lines;

  157.   bool                  m_IgnoreXMozillaStatus;

  158.   // this enables extensions to add the values of particular headers to
  159.   // the .msf file as properties of nsIMsgHdr. It is initialized from a
  160.   // pref, mailnews.customDBHeaders
  161.   nsTArray<nsCString>   m_customDBHeaders;
  162.   struct message_header *m_customDBHeaderValues;

  163.   bool IsStandardFormat(char *pszValue, uint32_t uiLen);
  164.   char *FixStandardFormat(char *pszValue, uint32_t uiLen);

  165. protected:
  166. };

  167. // this should go in some utility class.
  168. inline int nsParseMailMessageState::msg_UnHex(char C)
  169. {
  170.   return ((C >= '0' && C <= '9') ? C - '0' :
  171.     ((C >= 'A' && C <= 'F') ? C - 'A' + 10 :
  172.      ((C >= 'a' && C <= 'f') ? C - 'a' + 10 : 0)));
  173. }
复制代码

作者: hechengjin    时间: 2016-4-5 16:11
http://www.firemail.wang/forum.p ... hlight=%B9%A4%BE%DF
先用函数base64_encode() — 使用 MIME base64 对数据进行编码
  标题字符串前加编码类型例如: =?UTF-8?B?
  标题字符串后加:?=

  例如:

  $subject = "=?UTF-8?B?".base64_encode($subject)."?=";

  将上面一句添加到代码之中,这样,发送的中文邮件标题就不是乱码了。
作者: hechengjin    时间: 2016-4-8 10:23
本帖最后由 hechengjin 于 2016-4-8 13:59 编辑

(https://www.rfc-editor.org/rfc/pdfrfc/rfc1342.txt.pdf)
  1. for (let key in rowHeaderData) {
  2.       let headers = []
  3.       for (let header of rowHeaderData[key]) {
  4.         let headerItem = {
  5.           headerName: header.headerName
  6.         }
  7.         // RFC 1342 - Representation of Non-ASCII Text in Internet Message Headers
  8.         // (https://www.rfc-editor.org/rfc/pdfrfc/rfc1342.txt.pdf)
  9.         // subject may be an encoded word with format: "=?charset?encoding?encodedText?="
  10.         // if subject is not a encoded word, do not decode it.
  11.         if (header.headerName.toLowerCase() === 'subject' &&
  12.             header.headerValue.match(EncodingTextRegx) === null) {
  13.           headerItem.headerValue = header.headerValue
  14.         } else {
  15.           headerItem.headerValue = this.decodeMimeHeaderValue(header.headerValue)
  16.         }
  17.         headers.push(headerItem)
  18.       }
  19.       currentHeaderData[key] = headers
  20.     }
复制代码





欢迎光临 firemail (http://firemail.wang:8088/) Powered by Discuz! X3