From b5cba6250909d39934dbc6c21f18ae0fb813bf8a Mon Sep 17 00:00:00 2001 From: Theo Belaire Date: Mon, 24 Jun 2024 15:48:34 -0400 Subject: [PATCH] Add system property to cap memory usage in ResponseInputStream Right now it will consume an unbounded amount of memory if the remote server sends a response with nonsense all on one line. --- .../eclipse/angus/mail/iap/ResponseInputStream.java | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/providers/imap/src/main/java/org/eclipse/angus/mail/iap/ResponseInputStream.java b/providers/imap/src/main/java/org/eclipse/angus/mail/iap/ResponseInputStream.java index 6f0ad2d6..5d49075e 100644 --- a/providers/imap/src/main/java/org/eclipse/angus/mail/iap/ResponseInputStream.java +++ b/providers/imap/src/main/java/org/eclipse/angus/mail/iap/ResponseInputStream.java @@ -31,6 +31,8 @@ public class ResponseInputStream { + private static final Integer INPUT_STREAM_BUFFER_MAX_SIZE = + Integer.parseInt(System.getProperty("org.eclipse.angus.mail.iap.inputStreamBufferMaxSize", "0")); private static final int minIncrement = 256; private static final int maxIncrement = 256 * 1024; private static final int incrementSlop = 16; @@ -86,6 +88,9 @@ public ByteArray readResponse(ByteArray ba) throws IOException { int incr = buffer.length; if (incr > maxIncrement) incr = maxIncrement; + if (INPUT_STREAM_BUFFER_MAX_SIZE > 0 && buffer.length + incr > INPUT_STREAM_BUFFER_MAX_SIZE) { + throw new IOException("Response in ResponseInputStream grows too large."); + } ba.grow(incr); buffer = ba.getBytes(); } @@ -122,7 +127,11 @@ public ByteArray readResponse(ByteArray ba) throws IOException { int avail = buffer.length - idx; // available space in buffer if (count + incrementSlop > avail) { // need count-avail more bytes - ba.grow(Math.max(minIncrement, count + incrementSlop - avail)); + int amountToGrow = Math.max(minIncrement, count + incrementSlop - avail); + if (INPUT_STREAM_BUFFER_MAX_SIZE > 0 && buffer.length + amountToGrow > INPUT_STREAM_BUFFER_MAX_SIZE) { + throw new IOException("Response in ResponseInputStream grows too large while parsing literal."); + } + ba.grow(amountToGrow); buffer = ba.getBytes(); }