diff --git a/app/src/main/java/eu/faircode/email/DB.java b/app/src/main/java/eu/faircode/email/DB.java index 2b2ec686d5..0b53c71f55 100644 --- a/app/src/main/java/eu/faircode/email/DB.java +++ b/app/src/main/java/eu/faircode/email/DB.java @@ -26,12 +26,12 @@ import org.json.JSONObject; import java.io.File; import java.lang.reflect.Field; -import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.ExecutorService; +import java.util.regex.Pattern; import javax.mail.Address; import javax.mail.internet.InternetAddress; @@ -1631,35 +1631,24 @@ public abstract class DB extends RoomDatabase { return jaddresses.toString(); } + private static String JSPLIT = Pattern.quote("}],[{"); + @TypeConverter public static Address[] decodeAddresses(String json) { if (json == null) return null; - List
result = new ArrayList<>(); - try { - JSONArray jroot = new JSONArray(json); - JSONArray jaddresses = new JSONArray(); - for (int i = 0; i < jroot.length(); i++) { - Object item = jroot.get(i); - if (jroot.get(i) instanceof JSONArray) - for (int j = 0; j < ((JSONArray) item).length(); j++) - jaddresses.put(((JSONArray) item).get(j)); - else - jaddresses.put(item); - } - for (int i = 0; i < jaddresses.length(); i++) { - JSONObject jaddress = (JSONObject) jaddresses.get(i); - String email = jaddress.getString("address"); - String personal = jaddress.optString("personal"); - if (TextUtils.isEmpty(personal)) - personal = null; - result.add(new InternetAddress(email, personal, StandardCharsets.UTF_8.name())); - } - } catch (Throwable ex) { - // Compose can store invalid addresses - Log.w(ex); + else if (json.startsWith("[[")) { + // [[{"address":"...","personal":"..."}],[{... ...}]] + // There is a slim chance somebody uses the split pattern in an email address + String[] parts = json.substring(3, json.length() - 3).split(JSPLIT); + Address[] addresses = new Address[parts.length]; + for (int i = 0; i < parts.length; i++) + addresses[i] = InternetAddressJson.from(parts[i]); + return addresses; + } else { + // [{"address":"...","personal":"..."}] + return new Address[]{InternetAddressJson.from(json.substring(2, json.length() - 2))}; } - return result.toArray(new Address[0]); } } } diff --git a/app/src/main/java/eu/faircode/email/InternetAddressJson.java b/app/src/main/java/eu/faircode/email/InternetAddressJson.java new file mode 100644 index 0000000000..a00f5964b3 --- /dev/null +++ b/app/src/main/java/eu/faircode/email/InternetAddressJson.java @@ -0,0 +1,121 @@ +package eu.faircode.email; + +/* + This file is part of FairEmail. + + FairEmail is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + FairEmail is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with FairEmail. If not, see . + + Copyright 2018-2020 by Marcel Bokhorst (M66B) +*/ + +import android.text.TextUtils; + +import org.json.JSONObject; + +import java.io.UnsupportedEncodingException; +import java.nio.charset.StandardCharsets; + +import javax.mail.Address; +import javax.mail.internet.AddressException; +import javax.mail.internet.InternetAddress; + +public class InternetAddressJson extends InternetAddress { + private String json; + + private InternetAddressJson() { + } + + private InternetAddressJson(String address) throws AddressException { + } + + private InternetAddressJson(String address, boolean strict) throws AddressException { + } + + private InternetAddressJson(String address, String personal) throws UnsupportedEncodingException { + } + + private InternetAddressJson(String address, String personal, String charset) throws UnsupportedEncodingException { + } + + public static Address from(String json) { + InternetAddressJson result = new InternetAddressJson(); + result.json = json; + return result; + } + + @Override + public Object clone() { + ensureParsed(); + return super.clone(); + } + + @Override + public String getAddress() { + ensureParsed(); + return super.getAddress(); + } + + @Override + public String getPersonal() { + ensureParsed(); + return super.getPersonal(); + } + + @Override + public String toString() { + ensureParsed(); + return super.toString(); + } + + @Override + public String toUnicodeString() { + ensureParsed(); + return super.toUnicodeString(); + } + + @Override + public boolean equals(Object a) { + ensureParsed(); + return super.equals(a); + } + + @Override + public int hashCode() { + ensureParsed(); + return super.hashCode(); + } + + @Override + public void validate() throws AddressException { + ensureParsed(); + super.validate(); + } + + private void ensureParsed() { + if (this.json != null) { + try { + JSONObject jaddress = new JSONObject("{" + this.json + "}"); + String address = jaddress.getString("address"); + String personal = jaddress.optString("personal"); + if (!TextUtils.isEmpty(address)) + super.setAddress(address); + if (!TextUtils.isEmpty(personal)) + super.setPersonal(personal, StandardCharsets.UTF_8.name()); + } catch (Throwable ex) { + Log.e(ex); + } + this.json = null; + } + } +}