From 839dde1183ee9a0e4f06328b5003df26335e791b Mon Sep 17 00:00:00 2001 From: Norman Maurer Date: Thu, 26 Aug 2021 08:09:43 +0200 Subject: [PATCH] Correctly respect array offset when check for overflow (#11614) Motivation: 232c669fa413a9079ee6216056b57a647143f4b6 did add overflow protection but did miss to take the array offset into account and so could report false-positives Modifications: - Correctly take offset into account when check for overflow. - Add unit tests Result: Correctly take offset into account when overflow check is performed --- .../io/netty/buffer/CompositeByteBuf.java | 2 +- .../buffer/AbstractCompositeByteBufTest.java | 38 +++++++++++++++++++ 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/buffer/src/main/java/io/netty/buffer/CompositeByteBuf.java b/buffer/src/main/java/io/netty/buffer/CompositeByteBuf.java index 7a8a100438..1cde1fff8e 100644 --- a/buffer/src/main/java/io/netty/buffer/CompositeByteBuf.java +++ b/buffer/src/main/java/io/netty/buffer/CompositeByteBuf.java @@ -373,7 +373,7 @@ public class CompositeByteBuf extends AbstractReferenceCountedByteBuf implements int readableBytes = 0; int capacity = capacity(); - for (int i = 0; i < buffers.length; i++) { + for (int i = arrOffset; i < buffers.length; i++) { readableBytes += buffers[i].readableBytes(); // Check if we would overflow. diff --git a/buffer/src/test/java/io/netty/buffer/AbstractCompositeByteBufTest.java b/buffer/src/test/java/io/netty/buffer/AbstractCompositeByteBufTest.java index 70b4b3a647..3d88df0cdf 100644 --- a/buffer/src/test/java/io/netty/buffer/AbstractCompositeByteBufTest.java +++ b/buffer/src/test/java/io/netty/buffer/AbstractCompositeByteBufTest.java @@ -1612,6 +1612,44 @@ public abstract class AbstractCompositeByteBufTest extends AbstractByteBufTest { } } + @Test + public void testOverflowWhileUseConstructorWithOffset() { + int capacity = 1024 * 1024; // 1MB + final ByteBuf buffer = Unpooled.buffer(capacity).writeZero(capacity); + final List buffers = new ArrayList(); + for (long i = 0; i <= Integer.MAX_VALUE; i += capacity) { + buffers.add(buffer.duplicate()); + } + // Add one more + buffers.add(buffer.duplicate()); + + try { + assertThrows(IllegalArgumentException.class, () -> { + ByteBuf[] bufferArray = buffers.toArray(new ByteBuf[0]); + new CompositeByteBuf(ALLOC, false, Integer.MAX_VALUE, bufferArray, 0); + }); + } finally { + buffer.release(); + } + } + + @Test + public void testNotOverflowWhileUseConstructorWithOffset() { + int capacity = 1024 * 1024; // 1MB + final ByteBuf buffer = Unpooled.buffer(capacity).writeZero(capacity); + final List buffers = new ArrayList(); + for (long i = 0; i <= Integer.MAX_VALUE; i += capacity) { + buffers.add(buffer.duplicate()); + } + // Add one more + buffers.add(buffer.duplicate()); + + ByteBuf[] bufferArray = buffers.toArray(new ByteBuf[0]); + CompositeByteBuf compositeByteBuf = + new CompositeByteBuf(ALLOC, false, Integer.MAX_VALUE, bufferArray, bufferArray.length - 1); + compositeByteBuf.release(); + } + @Test public void sliceOfCompositeBufferMustThrowISEAfterDiscardBytes() { CompositeByteBuf composite = compositeBuffer();