From 366e481ed087a0cd959a9b7485516f652398c993 Mon Sep 17 00:00:00 2001 From: Marcel May Date: Wed, 14 Dec 2022 10:10:43 +0100 Subject: [PATCH] Quota resource invalid limit closes connection (backport, fixes #508) Backport of #506 --- .../imap/commands/CommandParser.java | 6 +++++- .../imap/commands/SetQuotaCommand.java | 21 ++++++++++++++++--- .../greenmail/test/ImapServerTest.java | 17 +++++++++++++++ 3 files changed, 40 insertions(+), 4 deletions(-) diff --git a/greenmail-core/src/main/java/com/icegreen/greenmail/imap/commands/CommandParser.java b/greenmail-core/src/main/java/com/icegreen/greenmail/imap/commands/CommandParser.java index aabbaf2a08..5445a885e0 100644 --- a/greenmail-core/src/main/java/com/icegreen/greenmail/imap/commands/CommandParser.java +++ b/greenmail-core/src/main/java/com/icegreen/greenmail/imap/commands/CommandParser.java @@ -372,7 +372,11 @@ public void setFlag(String flagString, Flags flags) { */ public long number(ImapRequestLineReader request) throws ProtocolException { String digits = consumeWord(request, new DigitCharValidator()); - return Long.parseLong(digits); + try { + return Long.parseLong(digits); + } catch (NumberFormatException ex) { + throw new ProtocolException("Can not parse '" + digits + "' as number", ex); + } } /** diff --git a/greenmail-core/src/main/java/com/icegreen/greenmail/imap/commands/SetQuotaCommand.java b/greenmail-core/src/main/java/com/icegreen/greenmail/imap/commands/SetQuotaCommand.java index 67a960f617..ad11d42fea 100644 --- a/greenmail-core/src/main/java/com/icegreen/greenmail/imap/commands/SetQuotaCommand.java +++ b/greenmail-core/src/main/java/com/icegreen/greenmail/imap/commands/SetQuotaCommand.java @@ -32,17 +32,32 @@ protected void doProcess(final ImapRequestLineReader request, final ImapResponse Quota quota = new Quota(root); parser.consumeChar(request, ' '); parser.consumeChar(request, '('); - quota.setResourceLimit(parser.astring(request), parser.consumeLong(request)); + parseAndUpdateResourceLimit(request, quota); char c =request.nextWordChar(); if(')' != c) { - quota.setResourceLimit(parser.astring(request), parser.consumeLong(request)); + parseAndUpdateResourceLimit(request, quota); } parser.consumeChar(request, ')'); session.getHost().getStore().setQuota( quota, session.getUser().getQualifiedMailboxName()); response.commandComplete(this); } catch (ProtocolException e) { - response.commandFailed(this, "Can not parse command"+e.getMessage()); + response.commandFailed(this, + "Can not parse command " + getName() +": " + e.getMessage()); + } + } + + private void parseAndUpdateResourceLimit(ImapRequestLineReader request, Quota quota) throws ProtocolException { + final String astring = parser.astring(request); + try { + String value = parser.atomOnly(request); + final long limit = Long.parseLong(value); + if(limit<0) { + throw new ProtocolException("Expected number (positive integer) but got "+limit); + } + quota.setResourceLimit(astring, limit); + } catch(ProtocolException|NumberFormatException ex) { + throw new ProtocolException("Failed to parse quota " + quota.quotaRoot+" resource limit "+astring+" value: "+ex.getMessage(), ex); } } } diff --git a/greenmail-core/src/test/java/com/icegreen/greenmail/test/ImapServerTest.java b/greenmail-core/src/test/java/com/icegreen/greenmail/test/ImapServerTest.java index 4ef896d347..a4ba9b0a0f 100644 --- a/greenmail-core/src/test/java/com/icegreen/greenmail/test/ImapServerTest.java +++ b/greenmail-core/src/test/java/com/icegreen/greenmail/test/ImapServerTest.java @@ -204,6 +204,23 @@ public void testQuota() throws Exception { } } + @Test + public void testQuotaInvalidResourceLimit() throws Exception { + greenMail.setUser("foo@localhost", "pwd"); + + try (IMAPStore store = greenMail.getImap().createStore()) { + store.connect("foo@localhost", "pwd"); + Quota testQuota = new Quota("INBOX"); + testQuota.setResourceLimit("MESSAGES", -5L); + assertThatThrownBy(() -> store.setQuota(testQuota)) + .hasMessageContaining("NO SETQUOTA failed. Can not parse command SETQUOTA: " + + "Failed to parse quota INBOX resource limit MESSAGES value:" + + " Expected number (positive integer) but got -5"); + testQuota.setResourceLimit("MESSAGES", 5L); + store.setQuota(testQuota); + } + } + @Test public void testQuotaCapability() throws MessagingException { greenMail.setUser("foo@localhost", "pwd");