Bug 1528496 - Correctly fix Bug 1023285 and utf8 addressing header display for jsmime.

Tag #1273
This commit is contained in:
Matt A. Tobin 2019-11-11 01:08:45 -05:00 committed by Roy Tam
commit 8a8393dbc4
6 changed files with 50 additions and 18 deletions

View file

@ -600,7 +600,7 @@ nsMsgCompFields::SplitRecipients(const nsAString &aRecipients,
*aLength = 0; *aLength = 0;
*aResult = nullptr; *aResult = nullptr;
nsCOMArray<msgIAddressObject> header(EncodedHeader(NS_ConvertUTF16toUTF8(aRecipients))); nsCOMArray<msgIAddressObject> header(EncodedHeaderW(aRecipients));
nsTArray<nsString> results; nsTArray<nsString> results;
if (aEmailAddressOnly) if (aEmailAddressOnly)
ExtractEmails(header, results); ExtractEmails(header, results);
@ -623,8 +623,7 @@ nsresult nsMsgCompFields::SplitRecipientsEx(const nsAString &recipients,
nsTArray<nsMsgRecipient> &aResult) nsTArray<nsMsgRecipient> &aResult)
{ {
nsTArray<nsString> names, addresses; nsTArray<nsString> names, addresses;
ExtractAllAddresses(EncodedHeader(NS_ConvertUTF16toUTF8(recipients)), names, ExtractAllAddresses(EncodedHeaderW(recipients), names, addresses);
addresses);
uint32_t numAddresses = names.Length(); uint32_t numAddresses = names.Length();
for (uint32_t i = 0; i < numAddresses; ++i) for (uint32_t i = 0; i < numAddresses; ++i)

View file

@ -2646,15 +2646,13 @@ NS_IMETHODIMP QuotingOutputStreamListener::OnStopRequest(nsIRequest *request, ns
} }
nsCString fromEmailAddress; nsCString fromEmailAddress;
ExtractEmail(EncodedHeader(NS_ConvertUTF16toUTF8(from)), fromEmailAddress); ExtractEmail(EncodedHeaderW(from), fromEmailAddress);
nsTArray<nsCString> toEmailAddresses; nsTArray<nsCString> toEmailAddresses;
ExtractEmails(EncodedHeader(NS_ConvertUTF16toUTF8(to)), ExtractEmails(EncodedHeaderW(to), UTF16ArrayAdapter<>(toEmailAddresses));
UTF16ArrayAdapter<>(toEmailAddresses));
nsTArray<nsCString> ccEmailAddresses; nsTArray<nsCString> ccEmailAddresses;
ExtractEmails(EncodedHeader(NS_ConvertUTF16toUTF8(cc)), ExtractEmails(EncodedHeaderW(cc), UTF16ArrayAdapter<>(ccEmailAddresses));
UTF16ArrayAdapter<>(ccEmailAddresses));
nsCOMPtr<nsIPrefBranch> prefs (do_GetService(NS_PREFSERVICE_CONTRACTID, &rv)); nsCOMPtr<nsIPrefBranch> prefs (do_GetService(NS_PREFSERVICE_CONTRACTID, &rv));
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);

View file

@ -31,6 +31,11 @@ nsCOMArray<msgIAddressObject> DecodedHeader(const nsAString &aHeader);
nsCOMArray<msgIAddressObject> EncodedHeader(const nsACString &aHeader, nsCOMArray<msgIAddressObject> EncodedHeader(const nsACString &aHeader,
const char *aCharset = nullptr); const char *aCharset = nullptr);
/**
* Same deal, but we're starting with an nsAString.
*/
nsCOMArray<msgIAddressObject> EncodedHeaderW(const nsAString &aHeader);
namespace detail { namespace detail {
void DoConversion(const nsTArray<nsString> &aUTF16, nsTArray<nsCString> &aUTF8); void DoConversion(const nsTArray<nsString> &aUTF16, nsTArray<nsCString> &aUTF8);
}; };

View file

@ -97,6 +97,18 @@ interface nsIMsgHeaderParser : nsISupports {
out msgIAddressObject addresses); out msgIAddressObject addresses);
/** /**
* Parse an address-based header that has not yet been 2047-decoded and does not
* contain raw octets but instead wide (UTF-16) characters.
*
* @param aEncodedHeader The RFC 2047-encoded header to parse.
* @return An array corresponding to the header description.
*/
void parseEncodedHeaderW(in AString aEncodedHeader,
[optional] out unsigned long length,
[retval, array, size_is(length)]
out msgIAddressObject addresses);
/**
* Parse an address-based header that has been 2047-decoded. * Parse an address-based header that has been 2047-decoded.
* *
* The result of this method is an array of objects described in the above * The result of this method is an array of objects described in the above
@ -178,9 +190,6 @@ interface nsIMsgHeaderParser : nsISupports {
* "Bond, James <agent007@mi5.invalid>" would produce one address object, * "Bond, James <agent007@mi5.invalid>" would produce one address object,
* while the string "webmaster@nowhere.invalid, child@nowhere.invalid" would * while the string "webmaster@nowhere.invalid, child@nowhere.invalid" would
* produce two address objects. * produce two address objects.
*
* Note that the input string is RFC 2231 and RFC 2047 decoded but no UTF-8
* decoding takes place.
*/ */
void makeFromDisplayAddress(in AString aDisplayAddresses, void makeFromDisplayAddress(in AString aDisplayAddresses,
[optional] out unsigned long count, [optional] out unsigned long count,

View file

@ -107,6 +107,24 @@ nsCOMArray<msgIAddressObject> EncodedHeader(const nsACString &aHeader,
return retval; return retval;
} }
nsCOMArray<msgIAddressObject> EncodedHeaderW(const nsAString &aHeader)
{
nsCOMArray<msgIAddressObject> retval;
if (aHeader.IsEmpty()) {
return retval;
}
nsCOMPtr<nsIMsgHeaderParser> headerParser(services::GetHeaderParser());
NS_ENSURE_TRUE(headerParser, retval);
msgIAddressObject **addresses = nullptr;
uint32_t length;
nsresult rv = headerParser->ParseEncodedHeaderW(aHeader, &length, &addresses);
MOZ_ASSERT(NS_SUCCEEDED(rv), "This should never fail!");
if (NS_SUCCEEDED(rv) && length > 0 && addresses) {
retval.Adopt(addresses, length);
}
return retval;
}
void ExtractAllAddresses(const nsCOMArray<msgIAddressObject> &aHeader, void ExtractAllAddresses(const nsCOMArray<msgIAddressObject> &aHeader,
nsTArray<nsString> &names, nsTArray<nsString> &emails) nsTArray<nsString> &names, nsTArray<nsString> &emails)
{ {

View file

@ -269,6 +269,15 @@ MimeAddressParser.prototype = {
MimeParser.HEADER_ADDRESS | MimeParser.HEADER_OPTION_ALL_I18N, aCharset); MimeParser.HEADER_ADDRESS | MimeParser.HEADER_OPTION_ALL_I18N, aCharset);
return fixArray(value, aPreserveGroups, count); return fixArray(value, aPreserveGroups, count);
}, },
parseEncodedHeaderW: function (aHeader, count) {
aHeader = aHeader || "";
let value = MimeParser.parseHeaderField(aHeader,
MimeParser.HEADER_ADDRESS |
MimeParser.HEADER_OPTION_DECODE_2231 |
MimeParser.HEADER_OPTION_DECODE_2047,
undefined);
return fixArray(value, false, count);
},
parseDecodedHeader: function (aHeader, aPreserveGroups, count) { parseDecodedHeader: function (aHeader, aPreserveGroups, count) {
aHeader = aHeader || ""; aHeader = aHeader || "";
let value = MimeParser.parseHeaderField(aHeader, MimeParser.HEADER_ADDRESS); let value = MimeParser.parseHeaderField(aHeader, MimeParser.HEADER_ADDRESS);
@ -390,13 +399,7 @@ MimeAddressParser.prototype = {
parseHeadersWithArray: function (aHeader, aAddrs, aNames, aFullNames) { parseHeadersWithArray: function (aHeader, aAddrs, aNames, aFullNames) {
let addrs = [], names = [], fullNames = []; let addrs = [], names = [], fullNames = [];
// Parse header, but without HEADER_OPTION_ALLOW_RAW. let allAddresses = this.parseEncodedHeader(aHeader, undefined, false);
let value = MimeParser.parseHeaderField(aHeader || "",
MimeParser.HEADER_ADDRESS |
MimeParser.HEADER_OPTION_DECODE_2231 |
MimeParser.HEADER_OPTION_DECODE_2047,
undefined);
let allAddresses = fixArray(value, false);
// Don't index the dummy empty address. // Don't index the dummy empty address.
if (aHeader.trim() == "") if (aHeader.trim() == "")