Discuz! Board

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 2440|回复: 3
打印 上一主题 下一主题

读信页标题的解码

[复制链接]

388

主题

602

帖子

2218

积分

金牌会员

Rank: 6Rank: 6

积分
2218
跳转到指定楼层
楼主
发表于 2016-3-23 16:02:24 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 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


回复

使用道具 举报

437

主题

566

帖子

2381

积分

金牌会员

Rank: 6Rank: 6

积分
2381
沙发
发表于 2016-3-24 12:37:02 | 只看该作者
导入不标准邮件,对邮件标题按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. }
复制代码
回复 支持 反对

使用道具 举报

388

主题

602

帖子

2218

积分

金牌会员

Rank: 6Rank: 6

积分
2218
板凳
 楼主| 发表于 2016-4-5 16:11:44 | 只看该作者
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)."?=";

  将上面一句添加到代码之中,这样,发送的中文邮件标题就不是乱码了。
回复 支持 反对

使用道具 举报

388

主题

602

帖子

2218

积分

金牌会员

Rank: 6Rank: 6

积分
2218
地板
 楼主| 发表于 2016-4-8 10:23:33 | 只看该作者
本帖最后由 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.     }
复制代码
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|firemail ( 粤ICP备15085507号-1 )

GMT+8, 2024-11-29 15:44 , Processed in 0.060168 second(s), 18 queries .

Powered by Discuz! X3

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表