diff --git a/mail/components/MessengerContentHandler.jsm b/mail/components/MessengerContentHandler.jsm index 63b8a0d40a..9372275aa9 100644 --- a/mail/components/MessengerContentHandler.jsm +++ b/mail/components/MessengerContentHandler.jsm @@ -431,9 +431,21 @@ MailDefaultHandler.prototype = { inputStream, inputStream.available() ); + + // Try to detect the character set and decode. Only UTF-8 is + // valid from vCard 4.0, but we support older versions, so other + // charsets are possible. + let charset = Cc["@mozilla.org/messengercompose/computils;1"] + .createInstance(Ci.nsIMsgCompUtils) + .detectCharset(data); + let buffer = new Uint8Array( + Array.from(data, c => c.charCodeAt(0)) + ); + data = new TextDecoder(charset).decode(buffer); + let card = Cc["@mozilla.org/addressbook/msgvcardservice;1"] .getService(Ci.nsIMsgVCardService) - .escapedVCardToAbCard(data); + .vCardToAbCard(data); Services.ww.openWindow( null, "chrome://messenger/content/addressbook/abNewCardDialog.xhtml", diff --git a/mailnews/addrbook/modules/VCardUtils.jsm b/mailnews/addrbook/modules/VCardUtils.jsm index 6b1d494aaf..9e131943ab 100644 --- a/mailnews/addrbook/modules/VCardUtils.jsm +++ b/mailnews/addrbook/modules/VCardUtils.jsm @@ -263,6 +263,9 @@ VCardService.prototype = { QueryInterface: ChromeUtils.generateQI(["nsIMsgVCardService"]), classID: Components.ID("{e2e0f615-bc5a-4441-a16b-a26e75949376}"), + vCardToAbCard(vCard) { + return vCard ? VCardUtils.vCardToAbCard(vCard) : null; + }, escapedVCardToAbCard(vCard) { return vCard ? VCardUtils.vCardToAbCard(decodeURIComponent(vCard)) : null; }, diff --git a/mailnews/addrbook/public/nsAbBaseCID.h b/mailnews/addrbook/public/nsAbBaseCID.h index 0b0338be18..a2695c2587 100644 --- a/mailnews/addrbook/public/nsAbBaseCID.h +++ b/mailnews/addrbook/public/nsAbBaseCID.h @@ -27,16 +27,6 @@ // #define NS_ABMANAGER_CONTRACTID "@mozilla.org/abmanager;1" -// -// nsAbContentHandler -// -#define NS_ABCONTENTHANDLER_CID \ - { \ - 0xa72ad552, 0x0484, 0x4b5f, { \ - 0x8d, 0x45, 0x2d, 0x79, 0x15, 0x8d, 0x22, 0xe3 \ - } \ - } - // // JS/SQLite address book // diff --git a/mailnews/addrbook/public/nsIMsgVCardService.idl b/mailnews/addrbook/public/nsIMsgVCardService.idl index b94096db57..b2d542f14c 100644 --- a/mailnews/addrbook/public/nsIMsgVCardService.idl +++ b/mailnews/addrbook/public/nsIMsgVCardService.idl @@ -10,13 +10,21 @@ interface nsIAbCard; [scriptable, uuid(8b6ae917-676d-4f1f-bbad-2ecc9be0d9b1)] interface nsIMsgVCardService : nsISupports { + /** + * Translates a vCard string into a nsIAbCard. + * + * @param vCardStr - The string containing the vCard data. + * @return - A card containing the translated vCard data. + */ + nsIAbCard vCardToAbCard(in AString vCardStr); + /** * Translates an URL-encoded vCard string into a nsIAbCard. * * @param escapedVCardStr - The string containing the vCard data. * @return - A card containing the translated vCard data. */ - nsIAbCard escapedVCardToAbCard(in string escapedVCardStr); + nsIAbCard escapedVCardToAbCard(in AString escapedVCardStr); /** * Translates a nsIAbCard into an URL-encoded vCard. @@ -24,5 +32,5 @@ interface nsIMsgVCardService : nsISupports { * @param abCard - A card to be translated. * @return - The string containing the vCard data. */ - ACString abCardToEscapedVCard(in nsIAbCard abCard); + AString abCardToEscapedVCard(in nsIAbCard abCard); }; diff --git a/mailnews/addrbook/src/moz.build b/mailnews/addrbook/src/moz.build index 9160ebde4f..e6da46c261 100644 --- a/mailnews/addrbook/src/moz.build +++ b/mailnews/addrbook/src/moz.build @@ -12,7 +12,6 @@ SOURCES += [ "nsAbBooleanExpression.cpp", "nsAbBoolExprToLDAPFilter.cpp", "nsAbCardProperty.cpp", - "nsAbContentHandler.cpp", "nsAbDirectoryQuery.cpp", "nsAbDirectoryQueryProxy.cpp", "nsAbDirProperty.cpp", diff --git a/mailnews/addrbook/src/nsAbCardProperty.cpp b/mailnews/addrbook/src/nsAbCardProperty.cpp index 13d2b4df8c..2c3d5ab878 100644 --- a/mailnews/addrbook/src/nsAbCardProperty.cpp +++ b/mailnews/addrbook/src/nsAbCardProperty.cpp @@ -491,8 +491,12 @@ nsresult nsAbCardProperty::ConvertToEscapedVCard(nsACString& aResult) { do_GetService(NS_MSGVCARDSERVICE_CONTRACTID, &rv); NS_ENSURE_SUCCESS(rv, rv); - nsCOMPtr cardFromVCard; - return vCardService->AbCardToEscapedVCard(this, aResult); + nsAutoString result; + rv = vCardService->AbCardToEscapedVCard(this, result); + NS_ENSURE_SUCCESS(rv, rv); + + aResult = NS_ConvertUTF16toUTF8(result); + return NS_OK; } nsresult nsAbCardProperty::ConvertToBase64EncodedXML(nsACString& result) { diff --git a/mailnews/addrbook/src/nsAbContentHandler.cpp b/mailnews/addrbook/src/nsAbContentHandler.cpp deleted file mode 100644 index 39d8e7f0f1..0000000000 --- a/mailnews/addrbook/src/nsAbContentHandler.cpp +++ /dev/null @@ -1,103 +0,0 @@ -/* -*- 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 "nsAbContentHandler.h" -#include "nsAbBaseCID.h" -#include "nsNetUtil.h" -#include "nsCOMPtr.h" -#include "mozilla/NullPrincipal.h" -#include "mozilla/dom/BrowsingContext.h" -#include "mozilla/UniquePtr.h" -#include "nsISupportsPrimitives.h" -#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 "nsIChannel.h" -// -// nsAbContentHandler -// -nsAbContentHandler::nsAbContentHandler() {} - -nsAbContentHandler::~nsAbContentHandler() {} - -NS_IMPL_ISUPPORTS(nsAbContentHandler, nsIContentHandler, - nsIStreamLoaderObserver) - -NS_IMETHODIMP -nsAbContentHandler::HandleContent(const char* aContentType, - nsIInterfaceRequestor* aWindowContext, - nsIRequest* request) { - NS_ENSURE_ARG_POINTER(request); - - nsresult rv = NS_OK; - - if (PL_strcasecmp(aContentType, "text/x-vcard") == 0) { - // create a vcard stream listener that can parse the data stream - // and bring up the appropriate UI - - // (1) cancel the current load operation. We'll restart it - request->Cancel(NS_ERROR_ABORT); - // get the url we were trying to open - nsCOMPtr uri; - nsCOMPtr channel = do_QueryInterface(request); - NS_ENSURE_TRUE(channel, NS_ERROR_FAILURE); - - rv = channel->GetURI(getter_AddRefs(uri)); - NS_ENSURE_SUCCESS(rv, rv); - - nsCOMPtr nullPrincipal = - do_CreateInstance("@mozilla.org/nullprincipal;1", &rv); - NS_ENSURE_SUCCESS(rv, rv); - - // create a stream loader to handle the v-card data - nsCOMPtr streamLoader; - rv = NS_NewStreamLoader( - getter_AddRefs(streamLoader), uri, this, nullPrincipal, - nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_SEC_CONTEXT_IS_NULL, - nsIContentPolicy::TYPE_OTHER); - NS_ENSURE_SUCCESS(rv, rv); - - } else { - return NS_ERROR_WONT_HANDLE_CONTENT; - } - - return rv; -} - -NS_IMETHODIMP -nsAbContentHandler::OnStreamComplete(nsIStreamLoader* aLoader, - nsISupports* aContext, nsresult aStatus, - uint32_t datalen, const uint8_t* data) { - NS_ENSURE_ARG_POINTER(aContext); - NS_ENSURE_SUCCESS( - aStatus, aStatus); // don't process the vcard if we got a status error - nsresult rv = NS_OK; - - // take our vCard string and open up an address book window based on it - nsCOMPtr vCardService = - do_GetService(NS_MSGVCARDSERVICE_CONTRACTID, &rv); - NS_ENSURE_SUCCESS(rv, rv); - - nsCOMPtr cardFromVCard; - rv = vCardService->EscapedVCardToAbCard((const char*)data, - getter_AddRefs(cardFromVCard)); - NS_ENSURE_SUCCESS(rv, rv); - - nsCOMPtr domWindow = do_GetInterface(aContext); - NS_ENSURE_TRUE(domWindow, NS_ERROR_FAILURE); - nsCOMPtr parentWindow = - nsPIDOMWindowOuter::From(domWindow); - - RefPtr dialogWindow; - return parentWindow->OpenDialog( - u"chrome://messenger/content/addressbook/abNewCardDialog.xhtml"_ns, - EmptyString(), u"chrome,resizable=no,titlebar,modal,centerscreen"_ns, - cardFromVCard, getter_AddRefs(dialogWindow)); -} diff --git a/mailnews/addrbook/src/nsAbContentHandler.h b/mailnews/addrbook/src/nsAbContentHandler.h deleted file mode 100644 index cc6e76a67a..0000000000 --- a/mailnews/addrbook/src/nsAbContentHandler.h +++ /dev/null @@ -1,25 +0,0 @@ -/* -*- 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/. */ - -#ifndef __nsAbContentHandler_h -#define __nsAbContentHandler_h - -#include "nsIStreamLoader.h" -#include "nsIContentHandler.h" - -class nsAbContentHandler : public nsIContentHandler, - public nsIStreamLoaderObserver { - public: - nsAbContentHandler(); - - NS_DECL_THREADSAFE_ISUPPORTS - NS_DECL_NSICONTENTHANDLER - NS_DECL_NSISTREAMLOADEROBSERVER - - private: - virtual ~nsAbContentHandler(); -}; - -#endif diff --git a/mailnews/build/nsMailModule.cpp b/mailnews/build/nsMailModule.cpp index 3d96c36e28..de54ec13d9 100644 --- a/mailnews/build/nsMailModule.cpp +++ b/mailnews/build/nsMailModule.cpp @@ -108,7 +108,6 @@ //////////////////////////////////////////////////////////////////////////////// #include "nsAbBaseCID.h" #include "nsAbCardProperty.h" -#include "nsAbContentHandler.h" #include "nsAbDirProperty.h" #include "nsAbAddressCollector.h" @@ -397,7 +396,6 @@ NS_DEFINE_NAMED_CID(NS_MAILNEWSDLF_CID); //////////////////////////////////////////////////////////////////////////////// // addrbook factories //////////////////////////////////////////////////////////////////////////////// -NS_GENERIC_FACTORY_CONSTRUCTOR(nsAbContentHandler) NS_GENERIC_FACTORY_CONSTRUCTOR(nsAbDirProperty) NS_GENERIC_FACTORY_CONSTRUCTOR(nsAbCardProperty) NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsAbAddressCollector, Init) @@ -428,7 +426,6 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(nsAbOSXCard) NS_DEFINE_NAMED_CID(NS_ABCARDPROPERTY_CID); NS_DEFINE_NAMED_CID(NS_ABDIRPROPERTY_CID); NS_DEFINE_NAMED_CID(NS_ABADDRESSCOLLECTOR_CID); -NS_DEFINE_NAMED_CID(NS_ABCONTENTHANDLER_CID); NS_DEFINE_NAMED_CID(NS_ABDIRECTORYQUERYARGUMENTS_CID); NS_DEFINE_NAMED_CID(NS_BOOLEANCONDITIONSTRING_CID); NS_DEFINE_NAMED_CID(NS_BOOLEANEXPRESSION_CID); @@ -785,7 +782,6 @@ const mozilla::Module::CIDEntry kMailNewsCIDs[] = { {&kNS_ABCARDPROPERTY_CID, false, NULL, nsAbCardPropertyConstructor}, {&kNS_ABDIRPROPERTY_CID, false, NULL, nsAbDirPropertyConstructor}, {&kNS_ABADDRESSCOLLECTOR_CID, false, NULL, nsAbAddressCollectorConstructor}, - {&kNS_ABCONTENTHANDLER_CID, false, NULL, nsAbContentHandlerConstructor}, #if defined(MOZ_MAPI_SUPPORT) {&kNS_ABOUTLOOKDIRECTORY_CID, false, NULL, nsAbOutlookDirectoryConstructor}, {&kNS_ABOUTLOOKINTERFACE_CID, false, NULL, nsAbOutlookInterfaceConstructor}, @@ -996,10 +992,6 @@ const mozilla::Module::ContractIDEntry kMailNewsContracts[] = { {NS_ABCARDPROPERTY_CONTRACTID, &kNS_ABCARDPROPERTY_CID}, {NS_ABDIRPROPERTY_CONTRACTID, &kNS_ABDIRPROPERTY_CID}, {NS_ABADDRESSCOLLECTOR_CONTRACTID, &kNS_ABADDRESSCOLLECTOR_CID}, - {NS_CONTENT_HANDLER_CONTRACTID_PREFIX "application/x-addvcard", - &kNS_ABCONTENTHANDLER_CID}, - {NS_CONTENT_HANDLER_CONTRACTID_PREFIX "text/x-vcard", - &kNS_ABCONTENTHANDLER_CID}, #if defined(MOZ_MAPI_SUPPORT) {NS_ABOUTLOOKDIRECTORY_CONTRACTID, &kNS_ABOUTLOOKDIRECTORY_CID}, {NS_ABOUTLOOKINTERFACE_CONTRACTID, &kNS_ABOUTLOOKINTERFACE_CID}, diff --git a/mailnews/import/src/nsVCardAddress.cpp b/mailnews/import/src/nsVCardAddress.cpp index 0dcc411956..c766f9de18 100644 --- a/mailnews/import/src/nsVCardAddress.cpp +++ b/mailnews/import/src/nsVCardAddress.cpp @@ -11,7 +11,8 @@ #include "nsIAbDirectory.h" #include "nsIFile.h" #include "nsIInputStream.h" -#include "nsILineInputStream.h" +#include "nsIUnicharLineInputStream.h" +#include "nsIConverterInputStream.h" #include "nsIMsgVCardService.h" #include "plstr.h" @@ -46,9 +47,26 @@ nsresult nsVCardAddress::ImportAddresses(bool* pAbort, const char16_t* pName, inputStream->Close(); return rv; } - uint64_t totalBytes = bytesLeft; - nsCOMPtr lineStream(do_QueryInterface(inputStream, &rv)); + + // Try to detect the character set and decode. Only UTF-8 is valid from + // vCard 4.0, but we support older versions, so other charsets are possible. + + nsAutoCString sourceCharset; + rv = MsgDetectCharsetFromFile(pSrc, sourceCharset); + NS_ENSURE_SUCCESS(rv, rv); + + nsCOMPtr converterStream = + do_CreateInstance("@mozilla.org/intl/converter-input-stream;1"); + NS_ENSURE_TRUE(converterStream, NS_ERROR_FAILURE); + + rv = converterStream->Init( + inputStream, sourceCharset.get(), 8192, + nsIConverterInputStream::DEFAULT_REPLACEMENT_CHARACTER); + NS_ENSURE_SUCCESS(rv, rv); + + nsCOMPtr lineStream( + do_QueryInterface(converterStream, &rv)); NS_ENSURE_SUCCESS(rv, rv); nsCOMPtr vCardService = @@ -56,14 +74,13 @@ nsresult nsVCardAddress::ImportAddresses(bool* pAbort, const char16_t* pName, NS_ENSURE_SUCCESS(rv, rv); bool more = true; - nsCString record; + nsAutoString 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 cardFromVCard; - rv = vCardService->EscapedVCardToAbCard(record.get(), - getter_AddRefs(cardFromVCard)); + rv = vCardService->VCardToAbCard(record, getter_AddRefs(cardFromVCard)); NS_ENSURE_SUCCESS(rv, rv); nsIAbCard* outCard; @@ -76,7 +93,7 @@ nsresult nsVCardAddress::ImportAddresses(bool* pAbort, const char16_t* pName, } if (NS_SUCCEEDED(rv) && pProgress) { // This won't be totally accurate, but its the best we can do - // considering that lineStream won't give us how many bytes + // considering that converterStream won't give us how many bytes // are actually left. bytesLeft -= record.Length(); *pProgress = totalBytes - bytesLeft; @@ -93,11 +110,11 @@ nsresult nsVCardAddress::ImportAddresses(bool* pAbort, const char16_t* pName, return NS_OK; } -nsresult nsVCardAddress::ReadRecord(nsILineInputStream* aLineStream, - nsCString& aRecord, bool* aMore) { +nsresult nsVCardAddress::ReadRecord(nsIUnicharLineInputStream* aLineStream, + nsString& aRecord, bool* aMore) { bool more = true; nsresult rv; - nsCString line; + nsAutoString line; aRecord.Truncate(); diff --git a/mailnews/import/src/nsVCardAddress.h b/mailnews/import/src/nsVCardAddress.h index d77ce9ad62..4cdb4de2b4 100644 --- a/mailnews/import/src/nsVCardAddress.h +++ b/mailnews/import/src/nsVCardAddress.h @@ -9,7 +9,7 @@ class nsIAbDirectory; class nsIFile; -class nsILineInputStream; +class nsIUnicharLineInputStream; class nsVCardAddress { public: @@ -21,8 +21,8 @@ class nsVCardAddress { uint32_t* pProgress); private: - static nsresult ReadRecord(nsILineInputStream* aLineStream, - nsCString& aRecord, bool* aMore); + static nsresult ReadRecord(nsIUnicharLineInputStream* aLineStream, + nsString& aRecord, bool* aMore); }; #endif /* nsVCardAddress_h__ */