diff --git a/app/src/main/java/eu/faircode/email/AdapterMessage.java b/app/src/main/java/eu/faircode/email/AdapterMessage.java index 2b4e5a8b00..b9b111ef5d 100644 --- a/app/src/main/java/eu/faircode/email/AdapterMessage.java +++ b/app/src/main/java/eu/faircode/email/AdapterMessage.java @@ -480,7 +480,7 @@ public class AdapterMessage extends RecyclerView.Adapter 0 ? colorAccent : textColorSecondary)); ivFlagged.setVisibility(message.uid == null ? View.INVISIBLE : View.VISIBLE); - tvFrom.setText(MessageHelper.getFormattedAddresses(outgoing ? message.to : message.from, false)); + tvFrom.setText(MessageHelper.formatAddressesShort(outgoing ? message.to : message.from)); tvSize.setText(message.size == null ? null : Helper.humanReadableByteCount(message.size, true)); tvSize.setVisibility(message.size == null || message.content ? View.GONE : View.VISIBLE); tvTime.setText(DateUtils.getRelativeTimeSpanString(context, message.received)); @@ -585,11 +585,11 @@ public class AdapterMessage extends RecyclerView.Adapter"); } return sb.toString(); @@ -812,8 +812,7 @@ public class FragmentCompose extends FragmentBase { final TextView tvMessage = dview.findViewById(R.id.tvMessage); final CheckBox cbNotAgain = dview.findViewById(R.id.cbNotAgain); - tvMessage.setText(getString(R.string.title_ask_send, - MessageHelper.getFormattedAddresses(ato, false))); + tvMessage.setText(getString(R.string.title_ask_send, MessageHelper.formatAddressesShort(ato))); new DialogBuilderLifecycle(getContext(), getViewLifecycleOwner()) .setView(dview) @@ -1083,9 +1082,8 @@ public class FragmentCompose extends FragmentBase { else if (requestCode == ActivityCompose.REQUEST_CONTACT_BCC) text = etBcc.getText().toString(); - InternetAddress address = new InternetAddress(email, name); StringBuilder sb = new StringBuilder(text); - sb.append(address.toString().replace(",", "")).append(", "); + sb.append("\"").append(name).append("\" <").append(email).append(">, "); if (requestCode == ActivityCompose.REQUEST_CONTACT_TO) etTo.setText(sb.toString()); @@ -1417,7 +1415,7 @@ public class FragmentCompose extends FragmentBase { if (ref.from != null && ref.from.length > 0) { String from = Helper.canonicalAddress(((InternetAddress) ref.from[0]).getAddress()); - Log.i("From=" + from + " to=" + MessageHelper.getFormattedAddresses(ref.to, false)); + Log.i("From=" + from + " to=" + MessageHelper.formatAddressesShort(ref.to)); for (EntityIdentity identity : identities) { String email = Helper.canonicalAddress(identity.email); if (from.equals(email)) { @@ -1632,9 +1630,9 @@ public class FragmentCompose extends FragmentBase { Log.i("Loaded draft id=" + result.draft.id + " action=" + action); etExtra.setText(result.draft.extra); - etTo.setText(MessageHelper.getFormattedAddresses(result.draft.to, true)); - etCc.setText(MessageHelper.getFormattedAddresses(result.draft.cc, true)); - etBcc.setText(MessageHelper.getFormattedAddresses(result.draft.bcc, true)); + etTo.setText(MessageHelper.formatAddressesCompose(result.draft.to)); + etCc.setText(MessageHelper.formatAddressesCompose(result.draft.cc)); + etBcc.setText(MessageHelper.formatAddressesCompose(result.draft.bcc)); etSubject.setText(result.draft.subject); long reference = args.getLong("reference", -1); @@ -1835,22 +1833,13 @@ public class FragmentCompose extends FragmentBase { InternetAddress abcc[] = null; if (!TextUtils.isEmpty(to)) - try { - ato = InternetAddress.parse(to); - } catch (AddressException ignored) { - } + ato = InternetAddress.parse(to); if (!TextUtils.isEmpty(cc)) - try { - acc = InternetAddress.parse(cc); - } catch (AddressException ignored) { - } + acc = InternetAddress.parse(cc); if (!TextUtils.isEmpty(bcc)) - try { - abcc = InternetAddress.parse(bcc); - } catch (AddressException ignored) { - } + abcc = InternetAddress.parse(bcc); if (TextUtils.isEmpty(extra)) extra = null; @@ -1979,9 +1968,9 @@ public class FragmentCompose extends FragmentBase { int action = args.getInt("action"); Log.i("Loaded action id=" + (draft == null ? null : draft.id) + " action=" + action); - etTo.setText(MessageHelper.getFormattedAddresses(draft.to, true)); - etCc.setText(MessageHelper.getFormattedAddresses(draft.cc, true)); - etBcc.setText(MessageHelper.getFormattedAddresses(draft.bcc, true)); + etTo.setText(MessageHelper.formatAddressesCompose(draft.to)); + etCc.setText(MessageHelper.formatAddressesCompose(draft.cc)); + etBcc.setText(MessageHelper.formatAddressesCompose(draft.bcc)); if (action == R.id.action_delete) { autosave = false; @@ -2003,7 +1992,7 @@ public class FragmentCompose extends FragmentBase { protected void onException(Bundle args, Throwable ex) { if (ex instanceof MessageRemovedException) finish(); - else if (ex instanceof IllegalArgumentException) + else if (ex instanceof IllegalArgumentException || ex instanceof AddressException) Snackbar.make(view, ex.getMessage(), Snackbar.LENGTH_LONG).show(); else Helper.unexpectedError(getContext(), getViewLifecycleOwner(), ex); diff --git a/app/src/main/java/eu/faircode/email/HtmlHelper.java b/app/src/main/java/eu/faircode/email/HtmlHelper.java index 50c9ca4030..12eba65247 100644 --- a/app/src/main/java/eu/faircode/email/HtmlHelper.java +++ b/app/src/main/java/eu/faircode/email/HtmlHelper.java @@ -253,7 +253,7 @@ public class HtmlHelper { String html = EntityMessage.read(context, id); return String.format("

%s %s:

\n
%s
", Html.escapeHtml(new Date(message.received).toString()), - Html.escapeHtml(MessageHelper.getFormattedAddresses(message.from, true)), + Html.escapeHtml(MessageHelper.formatAddresses(message.from)), sanitize ? sanitize(html, true) : getBody(html)); } diff --git a/app/src/main/java/eu/faircode/email/MessageHelper.java b/app/src/main/java/eu/faircode/email/MessageHelper.java index 0adfb545bf..1e6d7a1975 100644 --- a/app/src/main/java/eu/faircode/email/MessageHelper.java +++ b/app/src/main/java/eu/faircode/email/MessageHelper.java @@ -499,7 +499,22 @@ public class MessageHelper { return (size < 0 ? null : size); } - static String getFormattedAddresses(Address[] addresses, boolean full) { + static String formatAddresses(Address[] addresses) { + return formatAddresses(addresses, true, false); + } + + static String formatAddressesShort(Address[] addresses) { + return formatAddresses(addresses, false, false); + } + + static String formatAddressesCompose(Address[] addresses) { + String result = formatAddresses(addresses, true, true); + if (!TextUtils.isEmpty(result)) + result += ", "; + return result; + } + + private static String formatAddresses(Address[] addresses, boolean full, boolean compose) { if (addresses == null || addresses.length == 0) return ""; @@ -511,7 +526,17 @@ public class MessageHelper { if (TextUtils.isEmpty(personal)) formatted.add(address.toString()); else { - personal = personal.replaceAll("[\\,\\<\\>]", ""); + if (compose) { + boolean quote = false; + for (int i = 0; i < personal.length(); i++) + if ("()<>,;:\\\"[]@".indexOf(personal.charAt(i)) >= 0) { + quote = true; + break; + } + if (quote) + personal = "\"" + personal + "\""; + } + if (full) formatted.add(personal + " <" + a.getAddress() + ">"); else diff --git a/app/src/main/java/eu/faircode/email/ServiceSynchronize.java b/app/src/main/java/eu/faircode/email/ServiceSynchronize.java index f35651f478..320fbde7f8 100644 --- a/app/src/main/java/eu/faircode/email/ServiceSynchronize.java +++ b/app/src/main/java/eu/faircode/email/ServiceSynchronize.java @@ -569,7 +569,7 @@ public class ServiceSynchronize extends LifecycleService { DateFormat df = SimpleDateFormat.getDateTimeInstance(SimpleDateFormat.SHORT, SimpleDateFormat.SHORT); StringBuilder sb = new StringBuilder(); for (EntityMessage message : messages) { - sb.append("").append(MessageHelper.getFormattedAddresses(message.from, false)).append(""); + sb.append("").append(MessageHelper.formatAddressesShort(message.from)).append(""); if (!TextUtils.isEmpty(message.subject)) sb.append(": ").append(message.subject); sb.append(" ").append(df.format(message.received)); @@ -640,7 +640,7 @@ public class ServiceSynchronize extends LifecycleService { mbuilder .addExtras(args) .setSmallIcon(R.drawable.baseline_email_white_24) - .setContentTitle(MessageHelper.getFormattedAddresses(message.from, true)) + .setContentTitle(MessageHelper.formatAddresses(message.from)) .setSubText(message.accountName + " ยท " + folderName) .setContentIntent(piContent) .setWhen(message.received) @@ -1882,13 +1882,13 @@ public class ServiceSynchronize extends LifecycleService { sb.append(sfe.getMessage()); sb.append(' ').append(getString(R.string.title_address_sent)); - sb.append(' ').append(MessageHelper.getFormattedAddresses(sfe.getValidSentAddresses(), true)); + sb.append(' ').append(MessageHelper.formatAddresses(sfe.getValidSentAddresses())); sb.append(' ').append(getString(R.string.title_address_unsent)); - sb.append(' ').append(MessageHelper.getFormattedAddresses(sfe.getValidUnsentAddresses(), true)); + sb.append(' ').append(MessageHelper.formatAddresses(sfe.getValidUnsentAddresses())); sb.append(' ').append(getString(R.string.title_address_invalid)); - sb.append(' ').append(MessageHelper.getFormattedAddresses(sfe.getInvalidAddresses(), true)); + sb.append(' ').append(MessageHelper.formatAddresses(sfe.getInvalidAddresses())); ex = new SendFailedException( sb.toString(),