From 1e10eb8fdf06944a19aed6162887bef101020c94 Mon Sep 17 00:00:00 2001 From: M66B Date: Fri, 28 Jan 2022 12:21:20 +0100 Subject: [PATCH] X-UIDONLY, really? --- .../java/com/sun/mail/imap/IMAPFolder.java | 34 +++++++++++++ .../java/com/sun/mail/imap/IMAPMessage.java | 21 ++++---- .../sun/mail/imap/protocol/IMAPProtocol.java | 4 +- app/src/main/java/eu/faircode/email/Core.java | 48 ++++--------------- 4 files changed, 59 insertions(+), 48 deletions(-) diff --git a/app/src/main/java/com/sun/mail/imap/IMAPFolder.java b/app/src/main/java/com/sun/mail/imap/IMAPFolder.java index 14e5eac9fb..db5cd48999 100644 --- a/app/src/main/java/com/sun/mail/imap/IMAPFolder.java +++ b/app/src/main/java/com/sun/mail/imap/IMAPFolder.java @@ -1412,6 +1412,22 @@ public class IMAPFolder extends Folder implements UIDFolder, ResponseHandler { synchronized(messageCacheLock) { try { IMAPProtocol p = getProtocol(); + if (p.hasCapability("X-UIDONLY") || + (eu.faircode.email.BuildConfig.DEBUG && p.hasCapability("UIDPLUS"))) { + // Verizon + FetchProfile fp = new FetchProfile(); + fp.add(UIDFolder.FetchProfileItem.UID); + fetch(msgs, fp); + + UIDSet[] uids = Utility.toUIDSet(msgs); + if (uids == null) + return; + Response[] r = p.command("UID STORE " + UIDSet.toString(uids) + + " " + (value ? '+' : '-') + "FLAGS " + p.createFlagList(new Flags(flag)), null); + p.notifyResponseHandlers(r); + p.handleResult(r[r.length - 1]); + return; + } MessageSet[] ms = Utility.toMessageSetSorted(msgs, null); if (ms == null) throw new MessageRemovedException( @@ -2090,6 +2106,24 @@ public class IMAPFolder extends Folder implements UIDFolder, ResponseHandler { synchronized(messageCacheLock) { try { IMAPProtocol p = getProtocol(); + if (p.hasCapability("X-UIDONLY") || + (eu.faircode.email.BuildConfig.DEBUG && p.hasCapability("UIDPLUS"))) { + // Verizon + FetchProfile fp = new FetchProfile(); + fp.add(UIDFolder.FetchProfileItem.UID); + fetch(msgs, fp); + + UIDSet[] uids = Utility.toUIDSet(msgs); + if (uids == null) + return; + Argument args = new Argument(); + args.writeAtom(UIDSet.toString(uids)); + p.writeMailboxName(args, folder.getFullName()); + Response[] r = p.command(move ? "UID MOVE" : "UID COPY", args); + p.notifyResponseHandlers(r); + p.handleResult(r[r.length - 1]); + return; + } MessageSet[] ms = Utility.toMessageSet(msgs, null); if (ms == null) throw new MessageRemovedException( diff --git a/app/src/main/java/com/sun/mail/imap/IMAPMessage.java b/app/src/main/java/com/sun/mail/imap/IMAPMessage.java index bda029c1ff..f01ec71fde 100644 --- a/app/src/main/java/com/sun/mail/imap/IMAPMessage.java +++ b/app/src/main/java/com/sun/mail/imap/IMAPMessage.java @@ -1111,17 +1111,22 @@ public class IMAPMessage extends MimeMessage implements ReadableMime { try { IMAPProtocol p = getProtocol(); checkExpunged(); // Insure that this message is not expunged - if (flag.contains(javax.mail.Flags.Flag.DELETED) && - "imap.mail.yahoo.co.jp".equals(p.getInetAddress().getHostName())) { - // NO [CANNOT] STORE It's not possible to perform specified operation - long uid = ((IMAPFolder) getFolder()).getUID(this); + if (p.hasCapability("X-UIDONLY") || + "imap.mail.yahoo.co.jp".equals(p.getInetAddress().getHostName()) || + (eu.faircode.email.BuildConfig.DEBUG && p.hasCapability("UIDPLUS"))) { + // Verizon + // Yahoo: NO [CANNOT] STORE It's not possible to perform specified operation + long uid = getUID(); + if (uid < 0) { + UID u = p.fetchUID(getSequenceNumber()); + if (u != null) + uid = u.uid; + } Response[] r = p.command("UID STORE " + uid + - " " + (set ? '+' : '-') + "FLAGS (\\Deleted)", null); + " " + (set ? '+' : '-') + "FLAGS " + p.createFlagList(new Flags(flag)), null); p.notifyResponseHandlers(r); p.handleResult(r[r.length - 1]); - flag.remove(javax.mail.Flags.Flag.DELETED); - if (flag.getSystemFlags().length == 0) - return; + return; } p.storeFlags(getSequenceNumber(), flag, set); } catch (ConnectionException cex) { diff --git a/app/src/main/java/com/sun/mail/imap/protocol/IMAPProtocol.java b/app/src/main/java/com/sun/mail/imap/protocol/IMAPProtocol.java index 86960e45e0..d8a6098186 100644 --- a/app/src/main/java/com/sun/mail/imap/protocol/IMAPProtocol.java +++ b/app/src/main/java/com/sun/mail/imap/protocol/IMAPProtocol.java @@ -1167,7 +1167,7 @@ public class IMAPProtocol extends Protocol { * @param name the name to encode * @since JavaMail 1.6.0 */ - protected void writeMailboxName(Argument args, String name) { + public void writeMailboxName(Argument args, String name) { if (utf8) args.writeString(name, StandardCharsets.UTF_8); else @@ -2397,7 +2397,7 @@ public class IMAPProtocol extends Protocol { * @return the IMAP flag_list * @since JavaMail 1.5.4 */ - protected String createFlagList(Flags flags) { + public String createFlagList(Flags flags) { StringBuilder sb = new StringBuilder("("); // start of flag_list Flags.Flag[] sf = flags.getSystemFlags(); // get the system flags diff --git a/app/src/main/java/eu/faircode/email/Core.java b/app/src/main/java/eu/faircode/email/Core.java index 541e775728..b5ddec1d87 100644 --- a/app/src/main/java/eu/faircode/email/Core.java +++ b/app/src/main/java/eu/faircode/email/Core.java @@ -866,9 +866,6 @@ class Core { // Mark message (un)seen DB db = DB.getInstance(context); - SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); - boolean uid_command = prefs.getBoolean("uid_command", false); - if (flag != Flags.Flag.SEEN && flag != Flags.Flag.ANSWERED && flag != Flags.Flag.FLAGGED && @@ -917,42 +914,15 @@ class Core { if (uids.size() == 0) return; - if (uid_command) { - String flags; - if (flag == Flags.Flag.SEEN) - flags = "\\Seen"; - else if (flag == Flags.Flag.ANSWERED) - flags = "\\Answered"; - else if (flag == Flags.Flag.FLAGGED) - flags = "\\Flagged"; - else if (flag == Flags.Flag.DELETED) - flags = "\\Deleted"; - else - throw new IllegalArgumentException("Unknown flag=" + flag); - - ifolder.doCommand(new IMAPFolder.ProtocolCommand() { - @Override - public Object doCommand(IMAPProtocol protocol) throws ProtocolException { - for (long uid : uids) { - Response[] r = protocol.command( - "UID STORE " + uid + (set ? " +" : " -") + "FLAGS " + flags, null); - protocol.notifyResponseHandlers(r); - protocol.handleResult(r[r.length - 1]); - } - return null; - } - }); - } else { - Message[] imessages = ifolder.getMessagesByUID(Helper.toLongArray(uids)); - for (Message imessage : imessages) - if (imessage == null) - if (messages.size() == 1) - throw new MessageRemovedException(); - else - throw new MessagingException("Set flag: message missing"); + Message[] imessages = ifolder.getMessagesByUID(Helper.toLongArray(uids)); + for (Message imessage : imessages) + if (imessage == null) + if (messages.size() == 1) + throw new MessageRemovedException(); + else + throw new MessagingException("Set flag: message missing"); - ifolder.setFlags(imessages, new Flags(flag), set); - } + ifolder.setFlags(imessages, new Flags(flag), set); for (EntityMessage message : messages) if (flag == Flags.Flag.SEEN && !message.seen.equals(set)) @@ -4403,6 +4373,8 @@ class Core { try { if (uid_expunge) uid_expunge = MessageHelper.hasCapability(ifolder, "UIDPLUS"); + if (MessageHelper.hasCapability(ifolder, "X-UIDONLY")) + uid_expunge = true; if (uid_expunge) { FetchProfile fp = new FetchProfile();