Bug 1694264 - Teach nsIMsgVCardService about Unicode. r=mkmelin

Also removes nsAbContentHandler, which used this service but is now dead code.

Differential Revision: https://phabricator.services.mozilla.com/D106068

--HG--
extra : rebase_source : ad3a8cbabb910267696ac0dd9804c5d8b149092d
extra : histedit_source : 4b2eb03b9622205ce1569356137e6969e3b431b6
This commit is contained in:
Geoff Lankow 2021-02-23 16:30:35 +13:00
Родитель 49cfa33e8c
Коммит 6103223ef1
11 изменённых файлов: 62 добавлений и 165 удалений

Просмотреть файл

@ -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",

Просмотреть файл

@ -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;
},

Просмотреть файл

@ -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
//

Просмотреть файл

@ -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);
};

Просмотреть файл

@ -12,7 +12,6 @@ SOURCES += [
"nsAbBooleanExpression.cpp",
"nsAbBoolExprToLDAPFilter.cpp",
"nsAbCardProperty.cpp",
"nsAbContentHandler.cpp",
"nsAbDirectoryQuery.cpp",
"nsAbDirectoryQueryProxy.cpp",
"nsAbDirProperty.cpp",

Просмотреть файл

@ -491,8 +491,12 @@ nsresult nsAbCardProperty::ConvertToEscapedVCard(nsACString& aResult) {
do_GetService(NS_MSGVCARDSERVICE_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIAbCard> 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) {

Просмотреть файл

@ -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<nsIURI> uri;
nsCOMPtr<nsIChannel> channel = do_QueryInterface(request);
NS_ENSURE_TRUE(channel, NS_ERROR_FAILURE);
rv = channel->GetURI(getter_AddRefs(uri));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIPrincipal> nullPrincipal =
do_CreateInstance("@mozilla.org/nullprincipal;1", &rv);
NS_ENSURE_SUCCESS(rv, rv);
// create a stream loader to handle the v-card data
nsCOMPtr<nsIStreamLoader> 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<nsIMsgVCardService> vCardService =
do_GetService(NS_MSGVCARDSERVICE_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIAbCard> cardFromVCard;
rv = vCardService->EscapedVCardToAbCard((const char*)data,
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;
return parentWindow->OpenDialog(
u"chrome://messenger/content/addressbook/abNewCardDialog.xhtml"_ns,
EmptyString(), u"chrome,resizable=no,titlebar,modal,centerscreen"_ns,
cardFromVCard, getter_AddRefs(dialogWindow));
}

Просмотреть файл

@ -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

Просмотреть файл

@ -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},

Просмотреть файл

@ -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<nsILineInputStream> 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<nsIConverterInputStream> 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<nsIUnicharLineInputStream> lineStream(
do_QueryInterface(converterStream, &rv));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIMsgVCardService> 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<nsIAbCard> 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();

Просмотреть файл

@ -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__ */