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 9c4c26d5a0f0039150786f78f40102b296d231e1 Author: Benoit Tellier <btell...@linagora.com> AuthorDate: Thu Dec 19 14:35:58 2019 +0700 [Refactoring] Improve StringValidator --- .../james/imap/decode/ImapRequestLineReader.java | 26 ++++++++--- .../parser/AbstractSelectionCommandParser.java | 4 +- .../imap/decode/parser/FetchCommandParser.java | 4 +- .../imap/decode/parser/StoreCommandParser.java | 2 +- .../james/imap/decode/StringValidatorTest.java | 54 ++++++++++++++++++++++ 5 files changed, 79 insertions(+), 11 deletions(-) diff --git a/protocols/imap/src/main/java/org/apache/james/imap/decode/ImapRequestLineReader.java b/protocols/imap/src/main/java/org/apache/james/imap/decode/ImapRequestLineReader.java index 1501634..79f5a1b 100644 --- a/protocols/imap/src/main/java/org/apache/james/imap/decode/ImapRequestLineReader.java +++ b/protocols/imap/src/main/java/org/apache/james/imap/decode/ImapRequestLineReader.java @@ -28,10 +28,10 @@ import java.nio.charset.Charset; import java.nio.charset.CharsetDecoder; import java.nio.charset.CoderResult; import java.nio.charset.CodingErrorAction; -import java.nio.charset.StandardCharsets; import java.time.LocalDateTime; import java.util.ArrayList; import java.util.List; +import java.util.function.BiPredicate; import javax.mail.Flags; @@ -815,20 +815,34 @@ public abstract class ImapRequestLineReader { boolean isValid(char chr); } + /** + * Verifies subsequent characters match a specified string + */ public static class StringValidator implements CharacterValidator { - private final byte[] expectedStringAsBytes; + public static StringValidator caseIncentive(String expectedString) { + return new StringValidator(expectedString, + (c1, c2) -> isaBoolean(c1, c2)); + } + + public static boolean isaBoolean(Character c1, Character c2) { + return Character.toUpperCase(c1) == Character.toUpperCase(c2); + } + + private final String expectedString; + private final BiPredicate<Character, Character> equalityTester; private int position = 0; - public StringValidator(String expectedString) { - this.expectedStringAsBytes = expectedString.getBytes(StandardCharsets.US_ASCII); + private StringValidator(String expectedString, BiPredicate<Character, Character> equalityTester) { + this.expectedString = expectedString; + this.equalityTester = equalityTester; } @Override public boolean isValid(char chr) { - if (position >= expectedStringAsBytes.length) { + if (position >= expectedString.length()) { return false; } else { - return ImapRequestLineReader.cap(chr) == expectedStringAsBytes[position++]; + return equalityTester.test(chr, expectedString.charAt(position++)); } } } 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 812cdfc..758cb8b 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 @@ -67,12 +67,12 @@ public abstract class AbstractSelectionCommandParser extends AbstractImapCommand switch (n) { case 'C': // It starts with C so it should be CONDSTORE - request.consumeWord(new StringValidator(CONDSTORE)); + request.consumeWord(StringValidator.caseIncentive(CONDSTORE)); condstore = true; break; case 'Q': // It starts with Q so it should be QRESYNC - request.consumeWord(new StringValidator(QRESYNC)); + request.consumeWord(StringValidator.caseIncentive(QRESYNC)); // Consume the SP request.consumeChar(' '); diff --git a/protocols/imap/src/main/java/org/apache/james/imap/decode/parser/FetchCommandParser.java b/protocols/imap/src/main/java/org/apache/james/imap/decode/parser/FetchCommandParser.java index 1fc1412..6844374 100644 --- a/protocols/imap/src/main/java/org/apache/james/imap/decode/parser/FetchCommandParser.java +++ b/protocols/imap/src/main/java/org/apache/james/imap/decode/parser/FetchCommandParser.java @@ -89,12 +89,12 @@ public class FetchCommandParser extends AbstractUidCommandParser { switch (next) { case 'C': // Now check for the CHANGEDSINCE option which is part of CONDSTORE - request.consumeWord(new StringValidator(CHANGEDSINCE)); + request.consumeWord(StringValidator.caseIncentive(CHANGEDSINCE)); fetch.changedSince(request.number(true)); break; case 'V': // Check for the VANISHED option which is part of QRESYNC - request.consumeWord(new StringValidator(VANISHED)); + request.consumeWord(StringValidator.caseIncentive(VANISHED)); fetch.vanished(true); break; default: diff --git a/protocols/imap/src/main/java/org/apache/james/imap/decode/parser/StoreCommandParser.java b/protocols/imap/src/main/java/org/apache/james/imap/decode/parser/StoreCommandParser.java index 60c03d3..c8fce8e 100644 --- a/protocols/imap/src/main/java/org/apache/james/imap/decode/parser/StoreCommandParser.java +++ b/protocols/imap/src/main/java/org/apache/james/imap/decode/parser/StoreCommandParser.java @@ -53,7 +53,7 @@ public class StoreCommandParser extends AbstractUidCommandParser { // Seems like we have a CONDSTORE parameter request.consume(); - request.consumeWord(new StringValidator(UNCHANGEDSINCE)); + request.consumeWord(StringValidator.caseIncentive(UNCHANGEDSINCE)); request.consumeChar(' '); unchangedSince = request.number(true); request.consumeChar(')'); diff --git a/protocols/imap/src/test/java/org/apache/james/imap/decode/StringValidatorTest.java b/protocols/imap/src/test/java/org/apache/james/imap/decode/StringValidatorTest.java new file mode 100644 index 0000000..e1220ca --- /dev/null +++ b/protocols/imap/src/test/java/org/apache/james/imap/decode/StringValidatorTest.java @@ -0,0 +1,54 @@ +/**************************************************************** + * 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; + +import static org.apache.james.imap.decode.ImapRequestLineReader.StringValidator; +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.jupiter.api.Test; + +class StringValidatorTest { + @Test + void isValidShouldReturnFalseWhenDifferent() { + StringValidator stringValidator = StringValidator.caseIncentive("expected"); + assertThat( + "different".chars().mapToObj(i -> (char) i) + .allMatch(stringValidator::isValid)) + .isFalse(); + } + + @Test + void isValidShouldReturnTrueWhenSame() { + StringValidator stringValidator = StringValidator.caseIncentive("expected"); + assertThat( + "expected".chars().mapToObj(i -> (char) i) + .allMatch(stringValidator::isValid)) + .isTrue(); + } + + @Test + void isValidShouldShouldReturnTrueOnCaseDifference() { + StringValidator stringValidator = StringValidator.caseIncentive("expected"); + assertThat( + "eXpeCTed".chars().mapToObj(i -> (char) i) + .allMatch(stringValidator::isValid)) + .isTrue(); + } +} \ No newline at end of file --------------------------------------------------------------------- To unsubscribe, e-mail: server-dev-unsubscr...@james.apache.org For additional commands, e-mail: server-dev-h...@james.apache.org