This is an automated email from the ASF dual-hosted git repository. btellier pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/james-project.git
commit ea7bb21c609abb3e121cc717cdfe860fea9e61d7 Author: Benoit Tellier <[email protected]> AuthorDate: Wed Feb 26 14:56:06 2020 +0700 JAMES-3074 UidValidity sanitizing at the IMAP level --- .../parser/AbstractSelectionCommandParser.java | 19 +++++-- .../decode/parser/SelectCommandParserTest.java | 58 ++++++++++++++++++++++ 2 files changed, 74 insertions(+), 3 deletions(-) diff --git a/protocols/imap/src/main/java/org/apache/james/imap/decode/parser/AbstractSelectionCommandParser.java b/protocols/imap/src/main/java/org/apache/james/imap/decode/parser/AbstractSelectionCommandParser.java index 71b41d0..1bd3841 100644 --- a/protocols/imap/src/main/java/org/apache/james/imap/decode/parser/AbstractSelectionCommandParser.java +++ b/protocols/imap/src/main/java/org/apache/james/imap/decode/parser/AbstractSelectionCommandParser.java @@ -80,8 +80,9 @@ public abstract class AbstractSelectionCommandParser extends AbstractImapCommand // Consume enclosing paren request.consumeChar('('); - lastKnownUidValidity = UidValidity.of(request.number()); - + long uidValidityAsNumber = request.number(); + lastKnownUidValidity = sanitizeUidValidity(uidValidityAsNumber); + // Consume the SP request.consumeChar(' '); knownModSeq = request.number(true); @@ -129,7 +130,19 @@ public abstract class AbstractSelectionCommandParser extends AbstractImapCommand request.eol(); return createRequest(mailboxName, condstore, lastKnownUidValidity, knownModSeq, uidSet, knownUidSet, knownSequenceSet, tag); } - + + private UidValidity sanitizeUidValidity(long uidValidityAsNumber) { + if (UidValidity.isValid(uidValidityAsNumber)) { + return UidValidity.ofValid(uidValidityAsNumber); + } else { + // The UidValidity cached by the client is invalid + // We know that the backend will regenerate it + // Hence we force the mismatch + // QRSYNC command will be ignored + return UidValidity.random(); + } + } + /** * Check if the {@link IdRange}'s are formatted like stated in the QRESYNC RFC. * diff --git a/protocols/imap/src/test/java/org/apache/james/imap/decode/parser/SelectCommandParserTest.java b/protocols/imap/src/test/java/org/apache/james/imap/decode/parser/SelectCommandParserTest.java new file mode 100644 index 0000000..683385b --- /dev/null +++ b/protocols/imap/src/test/java/org/apache/james/imap/decode/parser/SelectCommandParserTest.java @@ -0,0 +1,58 @@ +/**************************************************************** + * Licensed to the Apache Software Foundation (ASF) under one * + * or more contributor license agreements. See the NOTICE file * + * distributed with this work for additional information * + * regarding copyright ownership. The ASF licenses this file * + * to you under the Apache License, Version 2.0 (the * + * "License"); you may not use this file except in compliance * + * with the License. You may obtain a copy of the License at * + * * + * http://www.apache.org/licenses/LICENSE-2.0 * + * * + * Unless required by applicable law or agreed to in writing, * + * software distributed under the License is distributed on an * + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * + * KIND, either express or implied. See the License for the * + * specific language governing permissions and limitations * + * under the License. * + ****************************************************************/ + +package org.apache.james.imap.decode.parser; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.nio.charset.StandardCharsets; + +import org.apache.james.imap.api.Tag; +import org.apache.james.imap.api.message.response.StatusResponseFactory; +import org.apache.james.imap.api.process.ImapSession; +import org.apache.james.imap.decode.ImapRequestStreamLineReader; +import org.apache.james.imap.message.request.SelectRequest; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +class SelectCommandParserTest { + private SelectCommandParser testee; + + @BeforeEach + void setUp() { + testee = new SelectCommandParser(mock(StatusResponseFactory.class)); + } + + @Test + void decodeShouldSanitizeUidValidity() throws Exception { + ImapRequestStreamLineReader request = toRequest("mailbox (QRESYNC (0 42))\n"); + + SelectRequest selectRequest = (SelectRequest) testee.decode(request, new Tag("0001"), mock(ImapSession.class)); + + assertThat(selectRequest.getLastKnownUidValidity().isValid()) + .isTrue(); + } + + private ImapRequestStreamLineReader toRequest(String input) { + return new ImapRequestStreamLineReader(new ByteArrayInputStream(input.getBytes(StandardCharsets.UTF_8)), new ByteArrayOutputStream()); + } +} \ No newline at end of file --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
