Bug 1614265 - Move escapedVCardToAbCard from nsIAbManager to nsIMsgVCardService. r=mkmelin
authorGeoff Lankow <geoff@darktrojan.net>
Wed, 12 Feb 2020 23:16:44 +0000
changeset 28802 3204b6752a70b3d144ceebdf36bf9414e06281dd
parent 28801 a94a4098acb456ab8ad149007e9732fe6a9cd64e
child 28803 d575c65cb9ea5c7f01c7eedf861f3e0425ab72db
push id17045
push usergeoff@darktrojan.net
push dateWed, 19 Feb 2020 23:43:49 +0000
treeherdercomm-central@a04956310d2f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmkmelin
bugs1614265
Bug 1614265 - Move escapedVCardToAbCard from nsIAbManager to nsIMsgVCardService. r=mkmelin Differential Revision: https://phabricator.services.mozilla.com/D62393
mail/components/MessengerContentHandler.jsm
mail/components/addrbook/content/abCard.js
mail/test/browser/message-window/browser.ini
mailnews/addrbook/jsaddrbook/AddrBookManager.jsm
mailnews/addrbook/public/nsIAbManager.idl
mailnews/addrbook/public/nsIMsgVCardService.idl
mailnews/addrbook/src/nsAbContentHandler.cpp
mailnews/addrbook/src/nsMsgVCardService.cpp
mailnews/addrbook/test/unit/test_bug387403.js
mailnews/addrbook/test/unit/xpcshell.ini
mailnews/import/test/unit/xpcshell.ini
mailnews/import/vcard/src/nsVCardAddress.cpp
suite/mailnews/components/addrbook/content/abCardOverlay.js
--- a/mail/components/MessengerContentHandler.jsm
+++ b/mail/components/MessengerContentHandler.jsm
@@ -412,17 +412,19 @@ MailDefaultHandler.prototype = {
               if (!Components.isSuccessCode(status)) {
                 return;
               }
 
               let data = NetUtil.readInputStreamToString(
                 inputStream,
                 inputStream.available()
               );
-              let card = MailServices.ab.escapedVCardToAbCard(data);
+              let card = Cc["@mozilla.org/addressbook/msgvcardservice;1"]
+                .getService(Ci.nsIMsgVCardService)
+                .escapedVCardToAbCard(data);
               Services.ww.openWindow(
                 null,
                 "chrome://messenger/content/addressbook/abNewCardDialog.xhtml",
                 "_blank",
                 "chrome,resizable=no,titlebar,modal,centerscreen",
                 card
               );
             }
--- a/mail/components/addrbook/content/abCard.js
+++ b/mail/components/addrbook/content/abCard.js
@@ -152,19 +152,19 @@ function OnLoadNewCard() {
 
     if ("okCallback" in window.arguments[0]) {
       gOkCallback = window.arguments[0].okCallback;
     }
 
     if ("escapedVCardStr" in window.arguments[0]) {
       // hide non vcard values
       HideNonVcardFields();
-      gEditCard.card = MailServices.ab.escapedVCardToAbCard(
-        window.arguments[0].escapedVCardStr
-      );
+      gEditCard.card = Cc["@mozilla.org/addressbook/msgvcardservice;1"]
+        .getService(Ci.nsIMsgVCardService)
+        .escapedVCardToAbCard(window.arguments[0].escapedVCardStr);
     }
 
     if ("titleProperty" in window.arguments[0]) {
       gEditCard.titleProperty = window.arguments[0].titleProperty;
     }
 
     if ("hideABPicker" in window.arguments[0]) {
       gHideABPicker = window.arguments[0].hideABPicker;
--- a/mail/test/browser/message-window/browser.ini
+++ b/mail/test/browser/message-window/browser.ini
@@ -13,10 +13,9 @@ subsuite = thunderbird
 support-files = data/**
 
 [browser_autohideMenubar.js]
 skip-if = os == "linux" || os = "mac"
 [browser_commands.js]
 [browser_emlSubject.js]
 [browser_messageSidebar.js]
 [browser_vcardActions.js]
-fail-if = true
 [browser_viewPlaintext.js]
--- a/mailnews/addrbook/jsaddrbook/AddrBookManager.jsm
+++ b/mailnews/addrbook/jsaddrbook/AddrBookManager.jsm
@@ -294,15 +294,12 @@ AddrBookManager.prototype = {
     ensureInitialized();
     for (let dir of store.values()) {
       if (dir.hasMailListWithName(name)) {
         return true;
       }
     }
     return false;
   },
-  escapedVCardToAbCard(escapedVCardStr) {
-    throw Cr.NS_ERROR_NOT_IMPLEMENTED;
-  },
   generateUUID(directoryId, localId) {
     return `${directoryId}#${localId}`;
   },
 };
--- a/mailnews/addrbook/public/nsIAbManager.idl
+++ b/mailnews/addrbook/public/nsIAbManager.idl
@@ -145,25 +145,16 @@ interface nsIAbManager : nsISupports
    *
    * @param  aName      The name of the list to try and find.
    *
    * @return            True if the name exists.
    */
   boolean mailListNameExists(in wstring name);
 
   /**
-   * Translates an escaped vcard string into a nsIAbCard.
-   *
-   * @param  escapedVCardStr  The string containing the vcard.
-   *
-   * @return            A card containing the translated vcard data.
-   */
-  nsIAbCard escapedVCardToAbCard(in string escapedVCardStr);
-
-  /**
    * Generates a UUID from a (directory ID, local ID) tuple.
    *
    * Use of this method is preferred in such cases, since it is designed to work
    * with other methods of this interface.
    *
    * @param directoryId The directory ID.
    * @param localId     The per-directory ID.
    * @return            A string to use for the UUID.
--- a/mailnews/addrbook/public/nsIMsgVCardService.idl
+++ b/mailnews/addrbook/public/nsIMsgVCardService.idl
@@ -1,29 +1,40 @@
 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsISupports.idl"
 
+interface nsIAbCard;
+
 %{C++
 #include "nsVCardObj.h"
 %}
 
 [ptr] native VObject_ptr(VObject);
 [ptr] native VObjectIterator_ptr(VObjectIterator);
 [ptr] native const_char_ptr(const char);
 
-[uuid(8b6ae917-676d-4f1f-bbad-2ecc9be0d9b1)]
+[scriptable, builtinclass, uuid(8b6ae917-676d-4f1f-bbad-2ecc9be0d9b1)]
 interface nsIMsgVCardService : nsISupports {
   [noscript, notxpcom] void cleanVObject(in VObject_ptr o);
   [noscript, notxpcom] VObject_ptr nextVObjectInList(in VObject_ptr o);
   [noscript, notxpcom] VObject_ptr parse_MIME(in string input, in unsigned long len);
   [noscript, notxpcom] charPtr fakeCString(in VObject_ptr o);
   [noscript, notxpcom] VObject_ptr isAPropertyOf(in VObject_ptr o, in string id);
   [noscript, notxpcom] charPtr writeMemoryVObjects(in string s, out long len, in VObject_ptr list, in boolean expandSpaces);
   [noscript, notxpcom] VObject_ptr nextVObject(in VObjectIterator_ptr i);
   [noscript, notxpcom] void initPropIterator(in VObjectIterator_ptr i, in VObject_ptr o);
   [noscript, notxpcom] long moreIteration(in VObjectIterator_ptr i);
   [noscript, notxpcom] const_char_ptr vObjectName(in VObject_ptr o);
   [noscript, notxpcom] charPtr vObjectAnyValue(in VObject_ptr o);
+
+  /**
+   * Translates an escaped vcard string into a nsIAbCard.
+   *
+   * @param  escapedVCardStr  The string containing the vcard.
+   *
+   * @return A card containing the translated vcard data.
+   */
+  nsIAbCard escapedVCardToAbCard(in string escapedVCardStr);
 };
--- a/mailnews/addrbook/src/nsAbContentHandler.cpp
+++ b/mailnews/addrbook/src/nsAbContentHandler.cpp
@@ -14,19 +14,19 @@
 #include "plstr.h"
 #include "nsPIDOMWindow.h"
 #include "mozIDOMWindow.h"
 #include "nsIDocShell.h"
 #include "nsIDocShellTreeItem.h"
 #include "nsMsgUtils.h"
 #include "nsIMsgVCardService.h"
 #include "nsIAbCard.h"
-#include "nsIAbManager.h"
 #include "nsVCard.h"
 #include "nsIChannel.h"
+#include "nsIMsgVCardService.h"
 //
 // nsAbContentHandler
 //
 nsAbContentHandler::nsAbContentHandler() {}
 
 nsAbContentHandler::~nsAbContentHandler() {}
 
 NS_IMPL_ISUPPORTS(nsAbContentHandler, nsIContentHandler,
@@ -65,22 +65,23 @@ nsAbContentHandler::HandleContent(const 
         if (!aWindowContext) return NS_ERROR_FAILURE;
 
         nsCOMPtr<mozIDOMWindowProxy> domWindow =
             do_GetInterface(aWindowContext);
         NS_ENSURE_TRUE(domWindow, NS_ERROR_FAILURE);
         nsCOMPtr<nsPIDOMWindowOuter> parentWindow =
             nsPIDOMWindowOuter::From(domWindow);
 
-        nsCOMPtr<nsIAbManager> ab = do_GetService(NS_ABMANAGER_CONTRACTID, &rv);
+        nsCOMPtr<nsIMsgVCardService> vCardService =
+            do_GetService(NS_MSGVCARDSERVICE_CONTRACTID, &rv);
         NS_ENSURE_SUCCESS(rv, rv);
 
         nsCOMPtr<nsIAbCard> cardFromVCard;
-        rv = ab->EscapedVCardToAbCard(unescapedData.get(),
-                                      getter_AddRefs(cardFromVCard));
+        rv = vCardService->EscapedVCardToAbCard(unescapedData.get(),
+                                                getter_AddRefs(cardFromVCard));
         NS_ENSURE_SUCCESS(rv, rv);
 
         nsCOMPtr<nsISupportsInterfacePointer> ifptr =
             do_CreateInstance(NS_SUPPORTS_INTERFACE_POINTER_CONTRACTID, &rv);
         NS_ENSURE_SUCCESS(rv, rv);
 
         ifptr->SetData(cardFromVCard);
         ifptr->SetDataIID(&NS_GET_IID(nsIAbCard));
@@ -151,21 +152,23 @@ nsAbContentHandler::OnStreamComplete(nsI
     mozilla::UniquePtr<VObject> vObj(
         vCardService->Parse_MIME((const char *)data, datalen));
     if (vObj) {
       int32_t len = 0;
       nsCString vCard;
       vCard.Adopt(
           vCardService->WriteMemoryVObjects(0, &len, vObj.get(), false));
 
-      nsCOMPtr<nsIAbManager> ab = do_GetService(NS_ABMANAGER_CONTRACTID, &rv);
+      nsCOMPtr<nsIMsgVCardService> vCardService =
+          do_GetService(NS_MSGVCARDSERVICE_CONTRACTID, &rv);
       NS_ENSURE_SUCCESS(rv, rv);
 
       nsCOMPtr<nsIAbCard> cardFromVCard;
-      rv = ab->EscapedVCardToAbCard(vCard.get(), getter_AddRefs(cardFromVCard));
+      rv = vCardService->EscapedVCardToAbCard(vCard.get(),
+                                              getter_AddRefs(cardFromVCard));
       NS_ENSURE_SUCCESS(rv, rv);
 
       nsCOMPtr<mozIDOMWindowProxy> domWindow = do_GetInterface(aContext);
       NS_ENSURE_TRUE(domWindow, NS_ERROR_FAILURE);
       nsCOMPtr<nsPIDOMWindowOuter> parentWindow =
           nsPIDOMWindowOuter::From(domWindow);
 
       RefPtr<mozilla::dom::BrowsingContext> dialogWindow;
--- a/mailnews/addrbook/src/nsMsgVCardService.cpp
+++ b/mailnews/addrbook/src/nsMsgVCardService.cpp
@@ -1,13 +1,17 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
+#include "nsIAbCard.h"
+#include "nsAbBaseCID.h"
+#include "nsString.h"
+#include "nsMsgUtils.h"
 #include "nsMsgVCardService.h"
 #include "nsVCard.h"
 #include "prmem.h"
 #include "plstr.h"
 
 NS_IMPL_ISUPPORTS(nsMsgVCardService, nsIMsgVCardService)
 
 nsMsgVCardService::nsMsgVCardService() {}
@@ -59,8 +63,131 @@ NS_IMETHODIMP_(const char *) nsMsgVCardS
   return vObjectName(o);
 }
 
 NS_IMETHODIMP_(char *) nsMsgVCardService::VObjectAnyValue(VObject *o) {
   char *retval = (char *)PR_MALLOC(strlen((char *)vObjectAnyValue(o)) + 1);
   if (retval) PL_strcpy(retval, (char *)vObjectAnyValue(o));
   return retval;
 }
+
+char *getCString(VObject *vObj) {
+  if (VALUE_TYPE(vObj) == VCVT_USTRINGZ)
+    return fakeCString(vObjectUStringZValue(vObj));
+  if (VALUE_TYPE(vObj) == VCVT_STRINGZ)
+    return PL_strdup(vObjectStringZValue(vObj));
+  return NULL;
+}
+
+static void convertNameValue(VObject *vObj, nsIAbCard *aCard) {
+  const char *cardPropName = NULL;
+
+  // if the vCard property is not a root property then we need to determine its
+  // exact property. a good example of this is VCTelephoneProp, this prop has
+  // four objects underneath it: fax, work and home and cellular.
+  if (PL_strcasecmp(VCCityProp, vObjectName(vObj)) == 0)
+    cardPropName = kWorkCityProperty;
+  else if (PL_strcasecmp(VCTelephoneProp, vObjectName(vObj)) == 0) {
+    if (isAPropertyOf(vObj, VCFaxProp))
+      cardPropName = kFaxProperty;
+    else if (isAPropertyOf(vObj, VCWorkProp))
+      cardPropName = kWorkPhoneProperty;
+    else if (isAPropertyOf(vObj, VCHomeProp))
+      cardPropName = kHomePhoneProperty;
+    else if (isAPropertyOf(vObj, VCCellularProp))
+      cardPropName = kCellularProperty;
+    else if (isAPropertyOf(vObj, VCPagerProp))
+      cardPropName = kPagerProperty;
+    else
+      return;
+  } else if (PL_strcasecmp(VCEmailAddressProp, vObjectName(vObj)) == 0)
+    cardPropName = kPriEmailProperty;
+  else if (PL_strcasecmp(VCFamilyNameProp, vObjectName(vObj)) == 0)
+    cardPropName = kLastNameProperty;
+  else if (PL_strcasecmp(VCFullNameProp, vObjectName(vObj)) == 0)
+    cardPropName = kDisplayNameProperty;
+  else if (PL_strcasecmp(VCGivenNameProp, vObjectName(vObj)) == 0)
+    cardPropName = kFirstNameProperty;
+  else if (PL_strcasecmp(VCOrgNameProp, vObjectName(vObj)) == 0)
+    cardPropName = kCompanyProperty;
+  else if (PL_strcasecmp(VCOrgUnitProp, vObjectName(vObj)) == 0)
+    cardPropName = kDepartmentProperty;
+  else if (PL_strcasecmp(VCPostalCodeProp, vObjectName(vObj)) == 0)
+    cardPropName = kWorkZipCodeProperty;
+  else if (PL_strcasecmp(VCRegionProp, vObjectName(vObj)) == 0)
+    cardPropName = kWorkStateProperty;
+  else if (PL_strcasecmp(VCStreetAddressProp, vObjectName(vObj)) == 0)
+    cardPropName = kWorkAddressProperty;
+  else if (PL_strcasecmp(VCPostalBoxProp, vObjectName(vObj)) == 0)
+    cardPropName = kWorkAddress2Property;
+  else if (PL_strcasecmp(VCCountryNameProp, vObjectName(vObj)) == 0)
+    cardPropName = kWorkCountryProperty;
+  else if (PL_strcasecmp(VCTitleProp, vObjectName(vObj)) == 0)
+    cardPropName = kJobTitleProperty;
+  else if (PL_strcasecmp(VCUseHTML, vObjectName(vObj)) == 0)
+    cardPropName = kPreferMailFormatProperty;
+  else if (PL_strcasecmp(VCNoteProp, vObjectName(vObj)) == 0)
+    cardPropName = kNotesProperty;
+  else if (PL_strcasecmp(VCURLProp, vObjectName(vObj)) == 0)
+    cardPropName = kWorkWebPageProperty;
+  else
+    return;
+
+  if (!VALUE_TYPE(vObj)) return;
+
+  char *cardPropValue = getCString(vObj);
+  if (PL_strcmp(cardPropName, kPreferMailFormatProperty)) {
+    aCard->SetPropertyAsAUTF8String(cardPropName,
+                                    nsDependentCString(cardPropValue));
+  } else {
+    if (!PL_strcmp(cardPropValue, "TRUE"))
+      aCard->SetPropertyAsUint32(cardPropName, nsIAbPreferMailFormat::html);
+    else if (!PL_strcmp(cardPropValue, "FALSE"))
+      aCard->SetPropertyAsUint32(cardPropName,
+                                 nsIAbPreferMailFormat::plaintext);
+    else
+      aCard->SetPropertyAsUint32(cardPropName, nsIAbPreferMailFormat::unknown);
+  }
+  PR_FREEIF(cardPropValue);
+  return;
+}
+
+static void convertFromVObject(VObject *vObj, nsIAbCard *aCard) {
+  if (vObj) {
+    VObjectIterator t;
+
+    convertNameValue(vObj, aCard);
+
+    initPropIterator(&t, vObj);
+    while (moreIteration(&t)) {
+      VObject *nextObject = nextVObject(&t);
+      convertFromVObject(nextObject, aCard);
+    }
+  }
+  return;
+}
+
+NS_IMETHODIMP nsMsgVCardService::EscapedVCardToAbCard(
+    const char *aEscapedVCardStr, nsIAbCard **aCard) {
+  NS_ENSURE_ARG_POINTER(aEscapedVCardStr);
+  NS_ENSURE_ARG_POINTER(aCard);
+
+  nsCOMPtr<nsIAbCard> cardFromVCard =
+      do_CreateInstance(NS_ABCARDPROPERTY_CONTRACTID);
+  if (!cardFromVCard) return NS_ERROR_FAILURE;
+
+  // aEscapedVCardStr will be "" the first time, before you have a vCard
+  if (*aEscapedVCardStr != '\0') {
+    nsCString unescapedData;
+    MsgUnescapeString(nsDependentCString(aEscapedVCardStr), 0, unescapedData);
+
+    VObject *vObj = parse_MIME(unescapedData.get(), unescapedData.Length());
+    if (vObj) {
+      convertFromVObject(vObj, cardFromVCard);
+
+      cleanVObject(vObj);
+    } else
+      NS_WARNING("Parse of vCard failed");
+  }
+
+  cardFromVCard.forget(aCard);
+  return NS_OK;
+}
--- a/mailnews/addrbook/test/unit/test_bug387403.js
+++ b/mailnews/addrbook/test/unit/test_bug387403.js
@@ -1,12 +1,14 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /**
  * Test for bug 387403 crash when opening e-mail with broken vcard.
  */
 
 function run_test() {
   // Before bug 387403 this would hang, eating up all the memory until it
   // crashed.
-  MailServices.ab.escapedVCardToAbCard(
-    "begin:vcard\nfn;quoted-printable:Xxxx=C5=82xx  Xxx\nn;quoted-printable:Xxx;Xxxx=C5=82xx \nadr;quoted-printable;quoted-printable;dom:;;xx. Xxxxxxxxxxxx X;Xxxxxx=C3=3"
-  );
+  Cc["@mozilla.org/addressbook/msgvcardservice;1"]
+    .getService(Ci.nsIMsgVCardService)
+    .escapedVCardToAbCard(
+      "begin:vcard\nfn;quoted-printable:Xxxx=C5=82xx  Xxx\nn;quoted-printable:Xxx;Xxxx=C5=82xx \nadr;quoted-printable;quoted-printable;dom:;;xx. Xxxxxxxxxxxx X;Xxxxxx=C3=3"
+    );
 }
--- a/mailnews/addrbook/test/unit/xpcshell.ini
+++ b/mailnews/addrbook/test/unit/xpcshell.ini
@@ -1,16 +1,15 @@
 [DEFAULT]
 head = head.js
 support-files = data/*
 
 [test_basic_nsIAbCard.js]
 [test_basic_nsIAbDirectory.js]
 [test_bug387403.js]
-fail-if = true
 [test_bug448165.js]
 [test_bug534822.js]
 fail-if = true
 [test_bug1522453.js]
 [test_cardForEmail.js]
 [test_collection.js]
 [test_collection_2.js]
 [test_db_enumerator.js]
--- a/mailnews/import/test/unit/xpcshell.ini
+++ b/mailnews/import/test/unit/xpcshell.ini
@@ -2,23 +2,21 @@
 head = head_import.js
 tail =
 support-files = resources/*
 
 [test_bug_263304.js]
 [test_bug_437556.js]
 [test_csv_GetSample.js]
 [test_becky_addressbook.js]
-fail-if = true
 run-if = os == 'win'
 [test_becky_filters.js]
 run-if = os == 'win'
 [test_csv_import.js]
 [test_csv_import_quote.js]
 [test_ldif_import.js]
 [test_outlook_settings.js]
 run-if = os == 'win'
 [test_shiftjis_csv.js]
 [test_utf16_csv.js]
 [test_vcard_import.js]
-fail-if = true
 [test_winmail.js]
 run-if = os == 'win'
--- a/mailnews/import/vcard/src/nsVCardAddress.cpp
+++ b/mailnews/import/vcard/src/nsVCardAddress.cpp
@@ -3,21 +3,21 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsAbBaseCID.h"
 #include "nsNativeCharsetUtils.h"
 #include "nsNetUtil.h"
 #include "nsVCardAddress.h"
 
 #include "nsIAbCard.h"
-#include "nsIAbManager.h"
 #include "nsIAbDirectory.h"
 #include "nsIFile.h"
 #include "nsIInputStream.h"
 #include "nsILineInputStream.h"
+#include "nsIMsgVCardService.h"
 
 #include "plstr.h"
 #include "msgCore.h"
 #include "nsMsgUtils.h"
 
 nsVCardAddress::nsVCardAddress() {}
 
 nsVCardAddress::~nsVCardAddress() {}
@@ -46,28 +46,29 @@ nsresult nsVCardAddress::ImportAddresses
     inputStream->Close();
     return rv;
   }
 
   uint64_t totalBytes = bytesLeft;
   nsCOMPtr<nsILineInputStream> lineStream(do_QueryInterface(inputStream, &rv));
   NS_ENSURE_SUCCESS(rv, rv);
 
-  nsCOMPtr<nsIAbManager> ab = do_GetService(NS_ABMANAGER_CONTRACTID, &rv);
+  nsCOMPtr<nsIMsgVCardService> vCardService =
+      do_GetService(NS_MSGVCARDSERVICE_CONTRACTID, &rv);
   NS_ENSURE_SUCCESS(rv, rv);
 
   bool more = true;
   nsCString record;
   while (!(*pAbort) && more && NS_SUCCEEDED(rv)) {
     rv = ReadRecord(lineStream, record, &more);
     if (NS_SUCCEEDED(rv) && !record.IsEmpty()) {
       // Parse the vCard and build an nsIAbCard from it
       nsCOMPtr<nsIAbCard> cardFromVCard;
-      rv =
-          ab->EscapedVCardToAbCard(record.get(), getter_AddRefs(cardFromVCard));
+      rv = vCardService->EscapedVCardToAbCard(record.get(),
+                                              getter_AddRefs(cardFromVCard));
       NS_ENSURE_SUCCESS(rv, rv);
 
       nsIAbCard *outCard;
       rv = pDirectory->AddCard(cardFromVCard, &outCard);
       NS_ENSURE_SUCCESS(rv, rv);
 
       if (NS_FAILED(rv)) {
         IMPORT_LOG0("*** Error processing vCard record.\n");
--- a/suite/mailnews/components/addrbook/content/abCardOverlay.js
+++ b/suite/mailnews/components/addrbook/content/abCardOverlay.js
@@ -111,17 +111,19 @@ function OnLoadNewCard()
                                  window.arguments[0].aimScreenName);
 
     if ("okCallback" in window.arguments[0])
       gOkCallback = window.arguments[0].okCallback;
 
     if ("escapedVCardStr" in window.arguments[0]) {
       // hide non vcard values
       HideNonVcardFields();
-      gEditCard.card = MailServices.ab.escapedVCardToAbCard(window.arguments[0].escapedVCardStr);
+      gEditCard.card = Cc["@mozilla.org/addressbook/msgvcardservice;1"]
+                         .getService(Ci.nsIMsgVCardService)
+                         .escapedVCardToAbCard(window.arguments[0].escapedVCardStr);
     }
 
     if ("titleProperty" in window.arguments[0])
       gEditCard.titleProperty = window.arguments[0].titleProperty;
 
     if ("hideABPicker" in window.arguments[0])
       gHideABPicker = window.arguments[0].hideABPicker;
   }