Bug 326809 modernize nsIMsgHeaderParser - |string| and |wstring| vs AString and AUTF8String. Part 2 - fix extractHeaderAddreesName(s). r=Neil,sr=bienvenu
authorMark Banner <bugzilla@standard8.plus.com>
Tue, 28 Oct 2008 09:49:23 +0000
changeset 736 5e0ce752f207f08a6afba8d1d5fe857516a388c9
parent 735 a51c25351cd48f65d47168bbe735b91ab98525f6
child 737 a734a91a43f4f8802508852caa179a6e2587bd18
push idunknown
push userunknown
push dateunknown
reviewersNeil, bienvenu
bugs326809
Bug 326809 modernize nsIMsgHeaderParser - |string| and |wstring| vs AString and AUTF8String. Part 2 - fix extractHeaderAddreesName(s). r=Neil,sr=bienvenu
mailnews/base/src/nsMsgDBView.cpp
mailnews/compose/src/nsMsgCompose.cpp
mailnews/db/msgdb/src/nsMsgDatabase.cpp
mailnews/local/src/nsParseMailbox.cpp
mailnews/local/src/nsParseMailbox.h
mailnews/mime/public/nsIMsgHeaderParser.idl
mailnews/mime/src/nsMsgHeaderParser.cpp
mailnews/mime/test/unit/test_nsIMsgHeaderParser2.js
--- a/mailnews/base/src/nsMsgDBView.cpp
+++ b/mailnews/base/src/nsMsgDBView.cpp
@@ -380,17 +380,18 @@ nsresult nsMsgDBView::FetchAuthor(nsIMsg
   nsresult rv = aHdr->GetMime2DecodedAuthor(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).get(), getter_Copies(name));
+    rv = mHeaderParser->ExtractHeaderAddressName(NS_ConvertUTF16toUTF8(unparsedAuthor),
+                                                 name);
     if (NS_SUCCEEDED(rv) && !name.IsEmpty())
     {
       CopyUTF8toUTF16(name, aSenderString);
       return NS_OK;
     }
   }
   // if we got here then just return the original string
   aSenderString = unparsedAuthor;
@@ -430,17 +431,18 @@ nsresult nsMsgDBView::FetchRecipients(ns
   nsresult rv = aHdr->GetMime2DecodedRecipients(unparsedRecipients);
 
   // *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 names;
-    rv = mHeaderParser->ExtractHeaderAddressNames(NS_ConvertUTF16toUTF8(unparsedRecipients).get(), getter_Copies(names));
+    rv = mHeaderParser->ExtractHeaderAddressNames(NS_ConvertUTF16toUTF8(unparsedRecipients),
+                                                  names);
     if (NS_SUCCEEDED(rv) && !names.IsEmpty())
     {
       CopyUTF8toUTF16(names, aRecipientsString);
       return NS_OK;
     }
   }
 
   aRecipientsString = unparsedRecipients;
--- a/mailnews/compose/src/nsMsgCompose.cpp
+++ b/mailnews/compose/src/nsMsgCompose.cpp
@@ -2278,18 +2278,19 @@ QuotingOutputStreamListener::QuotingOutp
           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.get() : author.get(),
-                                                getter_Copies(authorName));
+          rv = parser->ExtractHeaderAddressName(!decodedCString.IsEmpty() ?
+                                                decodedCString : 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)
           {
--- a/mailnews/db/msgdb/src/nsMsgDatabase.cpp
+++ b/mailnews/db/msgdb/src/nsMsgDatabase.cpp
@@ -3145,55 +3145,59 @@ nsresult nsMsgDatabase::RowCellColumnToM
         characterSetOverride, PR_TRUE, resultStr);
     }
   }
   return err;
 }
 
 nsresult nsMsgDatabase::RowCellColumnToAddressCollationKey(nsIMdbRow *row, mdb_token colToken, PRUint8 **result, PRUint32 *len)
 {
-  const char *cSender;
+  const char *cSender = nsnull;
   nsCString name;
 
-  nsresult ret = RowCellColumnToConstCharPtr(row, colToken, &cSender);
-  if (NS_SUCCEEDED(ret))
+  nsresult rv = RowCellColumnToConstCharPtr(row, colToken, &cSender);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  // Just in case this is null
+  if (!cSender)
+    return NS_ERROR_FAILURE;
+
+  nsIMsgHeaderParser *headerParser = GetHeaderParser();
+  if (!headerParser)
+    return NS_ERROR_FAILURE;
+
+  // apply mime decode
+  nsIMimeConverter *converter = GetMimeConverter();
+  if (!converter)
+    return NS_ERROR_FAILURE;
+
+  nsCString resultStr;
+  nsCString charset;
+  PRBool characterSetOverride;
+  m_dbFolderInfo->GetCharacterSetOverride(&characterSetOverride);
+  rv = RowCellColumnToCharPtr(row, m_messageCharSetColumnToken, getter_Copies(charset));
+  if (NS_FAILED(rv) || charset.IsEmpty() || charset.Equals("us-ascii") ||
+      characterSetOverride)
   {
-    nsIMsgHeaderParser *headerParser = GetHeaderParser();
-    if (headerParser)
-    {
-      // apply mime decode
-      nsIMimeConverter *converter = GetMimeConverter();
-
-      if (NS_SUCCEEDED(ret) && nsnull != converter)
-      {
-        nsCString resultStr;
-        nsCString charset;
-        PRBool characterSetOverride;
-        m_dbFolderInfo->GetCharacterSetOverride(&characterSetOverride);
-        ret = RowCellColumnToCharPtr(row, m_messageCharSetColumnToken, getter_Copies(charset));
-        if (NS_FAILED(ret) || charset.IsEmpty() || charset.Equals("us-ascii") ||
-            characterSetOverride)
-        {
-          m_dbFolderInfo->GetEffectiveCharacterSet(charset);
-        }
-
-        ret = converter->DecodeMimeHeaderToCharPtr(cSender, charset.get(),
-          characterSetOverride, PR_TRUE, getter_Copies(resultStr));
-        if (NS_SUCCEEDED(ret) && !resultStr.IsEmpty())
-          ret = headerParser->ExtractHeaderAddressName(resultStr.get(),
-                                                       getter_Copies(name));
-        else
-          ret = headerParser->ExtractHeaderAddressName(cSender,
-                                                       getter_Copies(name));
-      }
-    }
+    m_dbFolderInfo->GetEffectiveCharacterSet(charset);
   }
-  if (NS_SUCCEEDED(ret))
-    ret = CreateCollationKey(NS_ConvertUTF8toUTF16(name), result, len);
-  return ret;
+
+  rv = converter->DecodeMimeHeaderToCharPtr(cSender, charset.get(),
+                                            characterSetOverride, PR_TRUE,
+                                            getter_Copies(resultStr));
+  if (NS_SUCCEEDED(rv) && !resultStr.IsEmpty())
+    rv = headerParser->ExtractHeaderAddressName(resultStr, name);
+  else
+    rv = headerParser->ExtractHeaderAddressName(nsDependentCString(cSender),
+                                                     name);
+
+  if (NS_SUCCEEDED(rv))
+    return CreateCollationKey(NS_ConvertUTF8toUTF16(name), result, len);
+
+  return rv;
 }
 
 nsresult nsMsgDatabase::GetCollationKeyGenerator()
 {
   nsresult err = NS_OK;
   if (!m_collationKeyGenerator)
   {
     nsCOMPtr <nsILocale> locale;
--- a/mailnews/local/src/nsParseMailbox.cpp
+++ b/mailnews/local/src/nsParseMailbox.cpp
@@ -1163,42 +1163,16 @@ int nsParseMailMessageState::InternSubje
 #endif
   m_newMsgHdr->SetSubject(condensedKey ? condensedKey :
   (modifiedSubject.IsEmpty() ? key : modifiedSubject.get()));
   PR_FREEIF(condensedKey);
 
   return 0;
 }
 
-/* Like mbox_intern() but for headers which contain email addresses:
-we extract the "name" component of the first address, and discard
-the rest. */
-nsresult nsParseMailMessageState::InternRfc822 (struct message_header *header,
-                                                char **ret_name)
-{
-  char  *s;
-  nsresult ret=NS_OK;
-
-  if (!header || header->length == 0)
-    return NS_OK;
-
-  NS_ASSERTION (header->length == (short) strlen (header->value), "invalid message_header");
-  NS_ASSERTION (ret_name != nsnull, "null ret_name");
-
-  if (m_HeaderAddressParser)
-  {
-    ret = m_HeaderAddressParser->ExtractHeaderAddressName(header->value, &s);
-    if (! s)
-      return NS_ERROR_OUT_OF_MEMORY;
-
-    *ret_name = s;
-  }
-  return ret;
-}
-
 // we've reached the end of the envelope, and need to turn all our accumulated message_headers
 // into a single nsIMsgDBHdr to store in a database.
 int nsParseMailMessageState::FinalizeHeaders()
 {
   int status = 0;
   struct message_header *sender;
   struct message_header *recipient;
   struct message_header *subject;
--- a/mailnews/local/src/nsParseMailbox.h
+++ b/mailnews/local/src/nsParseMailbox.h
@@ -88,17 +88,16 @@ public:
 
   void                  Init(PRUint32 fileposition);
   virtual PRInt32       ParseFolderLine(const char *line, PRUint32 lineLength);
   virtual int           StartNewEnvelope(const char *line, PRUint32 lineLength);
   int                   ParseHeaders();
   int                   FinalizeHeaders();
   int                   ParseEnvelope (const char *line, PRUint32 line_size);
   int                   InternSubject (struct message_header *header);
-  nsresult  InternRfc822 (struct message_header *header, char **ret_name);
 
   static PRBool  IsEnvelopeLine(const char *buf, PRInt32 buf_size);
   static int  msg_UnHex(char C);
 
   nsCOMPtr<nsIMsgHeaderParser> m_HeaderAddressParser;
 
   nsCOMPtr<nsIMsgDBHdr> m_newMsgHdr; /* current message header we're building */
   nsCOMPtr<nsIMsgDatabase>  m_mailDB;
--- a/mailnews/mime/public/nsIMsgHeaderParser.idl
+++ b/mailnews/mime/public/nsIMsgHeaderParser.idl
@@ -44,17 +44,17 @@ interface nsISimpleEnumerator;
 
 #define NS_MAILNEWS_MIME_HEADER_PARSER_CONTRACTID \
   "@mozilla.org/messenger/headerparser;1"
 %}
 
 /* 
  * nsIMsgRFCParser Interface declaration 
  */ 
-[scriptable, uuid(96502670-07dd-4dd3-987a-ee6cafa8afa3)]
+[scriptable, uuid(392ba09d-5a3a-4f24-bd15-782cab25fdb2)]
 interface nsIMsgHeaderParser : nsISupports {
 
   void parseHeadersWithArray(in wstring aLine, 
                              [array, size_is(count)] out wstring aEmailAddresses,
                              [array, size_is(count)] out wstring aNames,
                              [array, size_is(count)] out wstring aFullNames,
                              [retval] out unsigned long count);
 
@@ -94,26 +94,27 @@ interface nsIMsgHeaderParser : nsISuppor
    * Given a string which contains a list of Header addresses, returns a
    * comma-separated list of just the `user name' portions.  If any of
    * the addresses doesn't have a name, then the mailbox is used instead.
    *
    * @param aLine          The header line to parse.
    * @return               A comma-separated list of just the name parts
    *                       of the addresses.
    */
-  [noscript] string extractHeaderAddressNames(in string aLine);
+  AUTF8String extractHeaderAddressNames(in AUTF8String aLine);
 
   /*
    * Like extractHeaderAddressNames, but only returns the first name in the
-   * header if there is one.
+   * header if there is one. This function will return unquoted strings suitable
+   * for display.
    *
    * @param aLine          The header line to parse.
    * @return               The first name found in the list.
    */
-  [noscript] string extractHeaderAddressName(in string aLine);
+  AUTF8String extractHeaderAddressName(in AUTF8String aLine);
 
   /**
    * Given a string which contains a list of Header addresses, returns a new
    * string with the same data, but inserts missing commas, parses and reformats
    * it, and wraps long lines with newline-tab.
    *
    * @param aLine          The header line to parse.
    * @return               The reformatted header line.
--- a/mailnews/mime/src/nsMsgHeaderParser.cpp
+++ b/mailnews/mime/src/nsMsgHeaderParser.cpp
@@ -65,18 +65,16 @@ nsresult FillResultsArray(const char * a
  * The following are prototypes for the old "C" functions used to support all of the RFC-822 parsing code
  * We could have made these private functions of nsMsgHeaderParser if we wanted...
  */
 static int msg_parse_Header_addresses(const char *line, char **names, char **addresses,
                                       PRBool quote_names_p = PR_TRUE, PRBool quote_addrs_p = PR_TRUE,
                                       PRBool first_only_p = PR_FALSE);
 static int msg_quote_phrase_or_addr(char *address, PRInt32 length, PRBool addr_p);
 static nsresult msg_unquote_phrase_or_addr(const char *line, PRBool strict, char **lineout);
-static char *msg_extract_Header_address_names(const char *line);
-static char *msg_extract_Header_address_name(const char *line);
 #if 0
 static char *msg_format_Header_addresses(const char *addrs, int count,
                                          PRBool wrap_lines_p);
 #endif
 static char *msg_reformat_Header_addresses(const char *line);
 
 static char *msg_remove_duplicate_addresses(const char *addrs, const char *other_addrs,
                                             PRBool removeAliasesToMe);
@@ -195,32 +193,16 @@ nsMsgHeaderParser::ParseHeaderAddresses(
                                         PRUint32 *aNumAddresses)
 {
   NS_ENSURE_ARG_POINTER(aNumAddresses);
   *aNumAddresses = msg_parse_Header_addresses(aLine, aNames, aAddresses);
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsMsgHeaderParser::ExtractHeaderAddressNames(const char *aLine, char **aNames)
-{
-  NS_ENSURE_ARG_POINTER(aNames);
-  *aNames = msg_extract_Header_address_names(aLine);
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsMsgHeaderParser::ExtractHeaderAddressName(const char *aLine, char **aName)
-{
-  NS_ENSURE_ARG_POINTER(aName);
-  *aName = msg_extract_Header_address_name(aLine);
-  return NS_OK;
-}
-
-NS_IMETHODIMP
 nsMsgHeaderParser::ReformatHeaderAddresses(const char *aLine,
                                            char **aReformattedAddress)
 {
   NS_ENSURE_ARG_POINTER(aReformattedAddress);
   *aReformattedAddress = msg_reformat_Header_addresses(aLine);
   return NS_OK;
 }
 
@@ -1108,29 +1090,28 @@ nsMsgHeaderParser::ExtractHeaderAddressM
     aResult.Truncate();
     return NS_OK;
   }
 
   char *addrs = 0;
   int status = msg_parse_Header_addresses(PromiseFlatCString(aLine).get(),
                                           NULL, &addrs);
   if (status <= 0)
-    return NS_ERROR_FAILURE;
+    return NS_ERROR_OUT_OF_MEMORY;
 
   char *s = addrs;
   PRUint32 i, size = 0;
 
   for (i = 0; (int) i < status; i++)
   {
     PRUint32 j = strlen(s);
     s += j + 1;
+    size += j;
     if ((int)(i + 1) < status)
-      size += j + 2;
-    else
-      size += j;
+      size += 2;
   }
 
   nsCString result;
   result.SetLength(size);
   s = addrs;
   char* out = result.BeginWriting();
   for (i = 0; (int)i < status; i++)
   {
@@ -1146,57 +1127,62 @@ nsMsgHeaderParser::ExtractHeaderAddressM
   }
 
   PR_Free(addrs);
   aResult = result;
   return NS_OK;
 }
 
 
-/* msg_extract_Header_address_names
- *
+/**
  * Given a string which contains a list of Header addresses, returns a
  * comma-separated list of just the `user name' portions.  If any of
  * the addresses doesn't have a name, then the mailbox is used instead.
  *
  * The names are *unquoted* and therefore cannot be re-parsed in any way.
  * They are, however, nice and human-readable.
  */
-static char *
-msg_extract_Header_address_names(const char *line)
+NS_IMETHODIMP
+nsMsgHeaderParser::ExtractHeaderAddressNames(const nsACString &aLine,
+                                             nsACString &aResult)
 {
+  if (aLine.IsEmpty())
+  {
+    aResult.Truncate();
+    return NS_OK;
+  }
+
   char *names = 0;
   char *addrs = 0;
-  char *result, *s1, *s2, *out;
+  int status = msg_parse_Header_addresses(PromiseFlatCString(aLine).get(),
+                                          &names, &addrs);
+  if (status <= 0)
+    return NS_ERROR_FAILURE;
+
+  PRUint32 len1, len2;
+  char *s1, *s2, *out;
   PRUint32 i, size = 0;
-  int status = msg_parse_Header_addresses(line, &names, &addrs);
-  if (status <= 0)
-    return 0;
-  PRUint32 len1, len2;
 
   s1 = names;
   s2 = addrs;
   for (i = 0; (int)i < status; i++)
   {
     len1 = strlen(s1);
     len2 = strlen(s2);
     s1 += len1 + 1;
     s2 += len2 + 1;
-    size += (len1 ? len1 : len2) + 2;
+    size += (len1 ? len1 : len2);
+    if ((int)(i + 1) < status)
+      size += 2;
   }
 
-  result = (char *)PR_Malloc(size + 1);
-  if (!result)
-  {
-    PR_Free(names);
-    PR_Free(addrs);
-    return 0;
-  }
+  nsCString result;
+  result.SetLength(size);
 
-  out = result;
+  out = result.BeginWriting();
   s1 = names;
   s2 = addrs;
   for (i = 0; (int)i < status; i++)
   {
     len1 = strlen(s1);
     len2 = strlen(s2);
 
     if (len1)
@@ -1205,61 +1191,65 @@ msg_extract_Header_address_names(const c
       out += len1;
     }
     else
     {
       memcpy(out, s2, len2);
       out += len2;
     }
 
-    if ((int)(i+1) < status)
+    if ((int)(i + 1) < status)
     {
       *out++ = ',';
       *out++ = ' ';
     }
     s1 += len1 + 1;
     s2 += len2 + 1;
   }
-  *out = 0;
 
   PR_Free(names);
   PR_Free(addrs);
-  return result;
+  aResult = result;
+  return NS_OK;
 }
 
 /* msg_extract_Header_address_name
  *
  * Like MSG_ExtractHeaderAddressNames(), but only returns the first name
  * in the list, if there is more than one.
  */
-static char *
-msg_extract_Header_address_name(const char *line)
+NS_IMETHODIMP
+nsMsgHeaderParser::ExtractHeaderAddressName(const nsACString &aLine,
+                                            nsACString &aResult)
 {
+  if (aLine.IsEmpty())
+  {
+    aResult.Truncate();
+    return NS_OK;
+  }
+
   char *name = 0;
   char *addr = 0;
-  int status = msg_parse_Header_addresses(line, &name, &addr, PR_FALSE, PR_FALSE, PR_TRUE);
+  int status = msg_parse_Header_addresses(PromiseFlatCString(aLine).get(),
+                                          &name, &addr, PR_FALSE, PR_FALSE,
+                                          PR_TRUE);
   if (status <= 0)
-    return 0;
+    return NS_ERROR_FAILURE;
 
   /* This can happen if there is an address like "From: foo bar" which
    * we parse as two addresses (that's a syntax error.)  In that case,
    * we'll return just the first one (the rest is after the NULL.)
    *
    * NS_ASSERTION(status == 1);
    */
-  if (name && *name)
-  {
-    FREEIF(addr);
-    return name;
-  }
-  else
-  {
-    FREEIF(name);
-    return addr;
-  }
+  aResult = (name && *name) ? name : addr;
+
+  PR_Free(name);
+  PR_Free(addr);
+  return NS_OK;
 }
 
 /* msg_format_Header_addresses
  */
 static char *
 msg_format_Header_addresses (const char *names, const char *addrs,
                int count, PRBool wrap_lines_p)
 {
--- a/mailnews/mime/test/unit/test_nsIMsgHeaderParser2.js
+++ b/mailnews/mime/test/unit/test_nsIMsgHeaderParser2.js
@@ -1,37 +1,68 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /*
- * Test suite for nsIMsgHeaderParser functions.
+ * Test suite for nsIMsgHeaderParser functions:
+ *   extractHeaderAddressMailboxes
+ *   extractHeaderAddressNames
+ *   extractHeaderAddressName
  */
 
 function run_test() {
   var i;
 
   var parser = Components.classes["@mozilla.org/messenger/headerparser;1"]
                          .getService(Components.interfaces.nsIMsgHeaderParser);
 
+  // In this array, the sub arrays consist of the following elements:
+  // 0: input string
+  // 1: expected output from extractHeaderAddressMailboxes
+  // 2: expected output from extractHeaderAddressNames
+  // 3: expected output from extractHeaderAddressName
   const checks =
   [
     ["abc@invalid.com",
+     "abc@invalid.com",
+     "abc@invalid.com",
      "abc@invalid.com" ],
     ["foo <ghj@invalid.com>",
-     "ghj@invalid.com"],
+     "ghj@invalid.com",
+     "foo",
+     "foo" ],
     ["abc@invalid.com, foo <ghj@invalid.com>",
-     "abc@invalid.com, ghj@invalid.com"],
+     "abc@invalid.com, ghj@invalid.com",
+     "abc@invalid.com, foo",
+     "abc@invalid.com" ],
     ["foo bar <foo@bar.invalid>",
-     "foo@bar.invalid"],
+     "foo@bar.invalid",
+     "foo bar",
+     "foo bar" ],
     ["foo bar <foo@bar.invalid>, abc@invalid.com, foo <ghj@invalid.com>",
-     "foo@bar.invalid, abc@invalid.com, ghj@invalid.com"],
+     "foo@bar.invalid, abc@invalid.com, ghj@invalid.com",
+     "foo bar, abc@invalid.com, foo",
+     "foo bar" ],
+    // UTF-8 names
+    ["foo\u00D0 bar <foo@bar.invalid>, \u00F6foo <ghj@invalid.com>",
+     "foo@bar.invalid, ghj@invalid.com",
+     "foo\u00D0 bar, \u00F6foo",
+     "foo\u00D0 bar" ],
     // More complicated examples drawn from RFC 2822
-    ["Test <\"abc!x.yz\"@invalid.com>, Test <test@[xyz!]>,\"Joe Q. Public\" <john.q.public@example.com>,\"Giant; \\\"Big\\\" Box\" <sysservices@example.net>",
-     "\"abc!x.yz\"@invalid.com, test@[xyz!], john.q.public@example.com, sysservices@example.net"],
+    ["\"Joe Q. Public\" <john.q.public@example.com>,Test <\"abc!x.yz\"@invalid.com>, Test <test@[xyz!]>,\"Giant; \\\"Big\\\" Box\" <sysservices@example.net>",
+     "john.q.public@example.com, \"abc!x.yz\"@invalid.com, test@[xyz!], sysservices@example.net",
+     "\"Joe Q. Public\", Test, Test, \"Giant; \\\"Big\\\" Box\"",
+     // extractHeaderAddressName returns unquoted names, hence the difference.
+     "Joe Q. Public" ],
   ];
 
   // Test - empty strings
 
   do_check_eq(parser.extractHeaderAddressMailboxes(""), "");
+  do_check_eq(parser.extractHeaderAddressNames(""), "");
+  do_check_eq(parser.extractHeaderAddressName(""), "");
 
   // Test - extractHeaderAddressMailboxes
 
-  for (i = 0; i < checks.length; ++i)
+  for (i = 0; i < checks.length; ++i) {
     do_check_eq(parser.extractHeaderAddressMailboxes(checks[i][0]), checks[i][1]);
+    do_check_eq(parser.extractHeaderAddressNames(checks[i][0]), checks[i][2]);
+    do_check_eq(parser.extractHeaderAddressName(checks[i][0]), checks[i][3]);
+  }
 }