You are viewing a plain text version of this content. The canonical link for it is here.
Posted to server-dev@james.apache.org by rc...@apache.org on 2020/07/17 10:24:18 UTC

[james-project] 09/09: JAMES-3309 Avoid a NPE in FetchProcessor when SelectedMailbox is unselected

This is an automated email from the ASF dual-hosted git repository.

rcordier pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/james-project.git

commit 8da802ebbb0d6a721529127572da7a88e2f2903b
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Thu Jul 16 12:20:47 2020 +0700

    JAMES-3309 Avoid a NPE in FetchProcessor when SelectedMailbox is unselected
    
    It turns out ImapSession::getSelectedMailbox can return null when the mailbox is deselected.
    
    Furthermore, data races can occurs upon selected mailbox switches.
    
    In FetchReponseBuilder we need to rely on the mailbox selected when the command was first issued.
---
 .../james/imap/processor/fetch/FetchProcessor.java |  7 +++++--
 .../imap/processor/fetch/FetchResponseBuilder.java | 22 ++++++++--------------
 2 files changed, 13 insertions(+), 16 deletions(-)

diff --git a/protocols/imap/src/main/java/org/apache/james/imap/processor/fetch/FetchProcessor.java b/protocols/imap/src/main/java/org/apache/james/imap/processor/fetch/FetchProcessor.java
index 4500155..f60bc02 100644
--- a/protocols/imap/src/main/java/org/apache/james/imap/processor/fetch/FetchProcessor.java
+++ b/protocols/imap/src/main/java/org/apache/james/imap/processor/fetch/FetchProcessor.java
@@ -32,6 +32,7 @@ import org.apache.james.imap.api.message.IdRange;
 import org.apache.james.imap.api.message.response.StatusResponseFactory;
 import org.apache.james.imap.api.process.ImapProcessor;
 import org.apache.james.imap.api.process.ImapSession;
+import org.apache.james.imap.api.process.SelectedMailbox;
 import org.apache.james.imap.message.request.FetchRequest;
 import org.apache.james.imap.message.response.FetchResponse;
 import org.apache.james.imap.processor.AbstractMailboxProcessor;
@@ -159,6 +160,7 @@ public class FetchProcessor extends AbstractMailboxProcessor<FetchRequest> {
     }
 
     private void processMessageRangeForFlags(ImapSession session, MessageManager mailbox, FetchData fetch, MailboxSession mailboxSession, Responder responder, FetchResponseBuilder builder, MessageRange range) {
+        SelectedMailbox selected = session.getSelected();
         Iterator<ComposedMessageIdWithMetaData> results = Flux.from(mailbox.listMessagesMetadata(range, mailboxSession))
             .filter(ids -> !fetch.contains(Item.MODSEQ) || ids.getModSeq().asLong() > fetch.getChangedSince())
             .toStream()
@@ -168,7 +170,7 @@ public class FetchProcessor extends AbstractMailboxProcessor<FetchRequest> {
             ComposedMessageIdWithMetaData result = results.next();
 
             try {
-                final FetchResponse response = builder.build(fetch, result, mailbox, session);
+                final FetchResponse response = builder.build(fetch, result, mailbox, selected, mailboxSession);
                 responder.respond(response);
             } catch (MessageRangeException e) {
                 // we can't for whatever reason find the message so
@@ -186,6 +188,7 @@ public class FetchProcessor extends AbstractMailboxProcessor<FetchRequest> {
 
     private void processMessageRange(ImapSession session, MessageManager mailbox, FetchData fetch, MailboxSession mailboxSession, Responder responder, FetchResponseBuilder builder, FetchGroup resultToFetch, MessageRange range) throws MailboxException {
         MessageResultIterator messages = mailbox.getMessages(range, resultToFetch, mailboxSession);
+        SelectedMailbox selected = session.getSelected();
         while (messages.hasNext()) {
             final MessageResult result = messages.next();
 
@@ -195,7 +198,7 @@ public class FetchProcessor extends AbstractMailboxProcessor<FetchRequest> {
             }
 
             try {
-                final FetchResponse response = builder.build(fetch, result, mailbox, session);
+                final FetchResponse response = builder.build(fetch, result, mailbox, selected, mailboxSession);
                 responder.respond(response);
             } catch (MessageRangeException e) {
                 // we can't for whatever reason find the message so
diff --git a/protocols/imap/src/main/java/org/apache/james/imap/processor/fetch/FetchResponseBuilder.java b/protocols/imap/src/main/java/org/apache/james/imap/processor/fetch/FetchResponseBuilder.java
index 3674f68..fc26dd6 100644
--- a/protocols/imap/src/main/java/org/apache/james/imap/processor/fetch/FetchResponseBuilder.java
+++ b/protocols/imap/src/main/java/org/apache/james/imap/processor/fetch/FetchResponseBuilder.java
@@ -37,7 +37,6 @@ import org.apache.james.imap.api.message.BodyFetchElement;
 import org.apache.james.imap.api.message.FetchData;
 import org.apache.james.imap.api.message.FetchData.Item;
 import org.apache.james.imap.api.message.SectionType;
-import org.apache.james.imap.api.process.ImapSession;
 import org.apache.james.imap.api.process.SelectedMailbox;
 import org.apache.james.imap.message.response.FetchResponse;
 import org.apache.james.mailbox.MailboxSession;
@@ -101,23 +100,20 @@ public final class FetchResponseBuilder {
         return new FetchResponse(msn, flags, uid, modSeq, internalDate, size, envelope, body, bodystructure, elements);
     }
 
-    public FetchResponse build(FetchData fetch, MessageResult result, MessageManager mailbox, ImapSession session) throws MessageRangeException, MailboxException {
-        final SelectedMailbox selected = session.getSelected();
+    public FetchResponse build(FetchData fetch, MessageResult result, MessageManager mailbox, SelectedMailbox selectedMailbox, MailboxSession mailboxSession) throws MessageRangeException, MailboxException {
         final MessageUid resultUid = result.getUid();
-        return selected.msn(resultUid).fold(() -> {
+        return selectedMailbox.msn(resultUid).fold(() -> {
             throw new MessageRangeException("No such message found with uid " + resultUid);
         }, msn -> {
 
             reset(msn);
             // setMsn(resultMsn);
 
+            // FLAGS response
             // Check if this fetch will cause the "SEEN" flag to be set on this
             // message. If so, update the flags, and ensure that a flags response is
             // included in the response.
-            final MailboxSession mailboxSession = session.getMailboxSession();
-
-            // FLAGS response
-            addFlags(fetch, mailbox, selected, resultUid, mailboxSession, result.getFlags());
+            addFlags(fetch, mailbox, selectedMailbox, resultUid, mailboxSession, result.getFlags());
 
             // INTERNALDATE response
             if (fetch.contains(Item.INTERNAL_DATE)) {
@@ -208,22 +204,20 @@ public final class FetchResponseBuilder {
         }
     }
 
-    public FetchResponse build(FetchData fetch, ComposedMessageIdWithMetaData result, MessageManager mailbox, ImapSession session) throws MessageRangeException, MailboxException {
-        final SelectedMailbox selected = session.getSelected();
+    public FetchResponse build(FetchData fetch, ComposedMessageIdWithMetaData result, MessageManager mailbox, SelectedMailbox selectedMailbox, MailboxSession mailboxSession) throws MessageRangeException, MailboxException {
         final MessageUid resultUid = result.getComposedMessageId().getUid();
-        return selected.msn(resultUid).fold(() -> {
+        return selectedMailbox.msn(resultUid).fold(() -> {
             throw new MessageRangeException("No such message found with uid " + resultUid);
         }, msn -> {
 
             reset(msn);
             // setMsn(resultMsn);
 
+            // FLAGS response
             // Check if this fetch will cause the "SEEN" flag to be set on this
             // message. If so, update the flags, and ensure that a flags response is
             // included in the response.
-            final MailboxSession mailboxSession = session.getMailboxSession();
-            // FLAGS response
-            addFlags(fetch, mailbox, selected, resultUid, mailboxSession, result.getFlags());
+            addFlags(fetch, mailbox, selectedMailbox, resultUid, mailboxSession, result.getFlags());
             // UID response
             addUid(fetch, resultUid);
 


---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org