Fix IndexOutOfBoundException when using CompositeChannelBuffer and the readerIndex is at the last position and an empty array is passed to read to. See #474

This commit is contained in:
Norman Maurer 2012-09-22 21:23:58 +02:00
parent 93b34e3856
commit b8ae8be96a
2 changed files with 43 additions and 11 deletions

View File

@ -578,14 +578,19 @@ public class DefaultCompositeByteBuf extends AbstractByteBuf implements Composit
@Override @Override
public void getBytes(int index, byte[] dst, int dstIndex, int length) { public void getBytes(int index, byte[] dst, int dstIndex, int length) {
int componentId = toComponentIndex(index);
if (index > capacity() - length || dstIndex > dst.length - length) { if (index > capacity() - length || dstIndex > dst.length - length) {
throw new IndexOutOfBoundsException("Too many bytes to read - Needs " throw new IndexOutOfBoundsException("Too many bytes to read - Needs "
+ (index + length) + ", maximum is " + capacity() + " or " + (index + length) + ", maximum is " + capacity() + " or "
+ dst.length); + dst.length);
} }
if (index < 0) {
throw new IndexOutOfBoundsException("index must be >= 0");
}
if (length == 0) {
return;
}
int i = toComponentIndex(index);
int i = componentId;
while (length > 0) { while (length > 0) {
Component c = components.get(i); Component c = components.get(i);
ByteBuf s = c.buf; ByteBuf s = c.buf;
@ -601,15 +606,20 @@ public class DefaultCompositeByteBuf extends AbstractByteBuf implements Composit
@Override @Override
public void getBytes(int index, ByteBuffer dst) { public void getBytes(int index, ByteBuffer dst) {
int componentId = toComponentIndex(index);
int limit = dst.limit(); int limit = dst.limit();
int length = dst.remaining(); int length = dst.remaining();
if (index > capacity() - length) { if (index > capacity() - length) {
throw new IndexOutOfBoundsException("Too many bytes to be read - Needs " throw new IndexOutOfBoundsException("Too many bytes to be read - Needs "
+ (index + length) + ", maximum is " + capacity()); + (index + length) + ", maximum is " + capacity());
} }
if (index < 0) {
int i = componentId; throw new IndexOutOfBoundsException("index must be >= 0");
}
if (length == 0) {
return;
}
int i = toComponentIndex(index);
try { try {
while (length > 0) { while (length > 0) {
Component c = components.get(i); Component c = components.get(i);
@ -629,14 +639,18 @@ public class DefaultCompositeByteBuf extends AbstractByteBuf implements Composit
@Override @Override
public void getBytes(int index, ByteBuf dst, int dstIndex, int length) { public void getBytes(int index, ByteBuf dst, int dstIndex, int length) {
int componentId = toComponentIndex(index);
if (index > capacity() - length || dstIndex > dst.capacity() - length) { if (index > capacity() - length || dstIndex > dst.capacity() - length) {
throw new IndexOutOfBoundsException("Too many bytes to be read - Needs " throw new IndexOutOfBoundsException("Too many bytes to be read - Needs "
+ (index + length) + " or " + (dstIndex + length) + ", maximum is " + (index + length) + " or " + (dstIndex + length) + ", maximum is "
+ capacity() + " or " + dst.capacity()); + capacity() + " or " + dst.capacity());
} }
if (index < 0) {
int i = componentId; throw new IndexOutOfBoundsException("index must be >= 0");
}
if (length == 0) {
return;
}
int i = toComponentIndex(index);
while (length > 0) { while (length > 0) {
Component c = components.get(i); Component c = components.get(i);
ByteBuf s = c.buf; ByteBuf s = c.buf;
@ -670,13 +684,18 @@ public class DefaultCompositeByteBuf extends AbstractByteBuf implements Composit
@Override @Override
public void getBytes(int index, OutputStream out, int length) public void getBytes(int index, OutputStream out, int length)
throws IOException { throws IOException {
int componentId = toComponentIndex(index);
if (index > capacity() - length) { if (index > capacity() - length) {
throw new IndexOutOfBoundsException("Too many bytes to be read - needs " throw new IndexOutOfBoundsException("Too many bytes to be read - needs "
+ (index + length) + ", maximum of " + capacity()); + (index + length) + ", maximum of " + capacity());
} }
if (index < 0) {
throw new IndexOutOfBoundsException("index must be >= 0");
}
if (length == 0) {
return;
}
int i = componentId; int i = toComponentIndex(index);
while (length > 0) { while (length > 0) {
Component c = components.get(i); Component c = components.get(i);
ByteBuf s = c.buf; ByteBuf s = c.buf;
@ -1031,11 +1050,17 @@ public class DefaultCompositeByteBuf extends AbstractByteBuf implements Composit
@Override @Override
public ByteBuffer[] nioBuffers(int index, int length) { public ByteBuffer[] nioBuffers(int index, int length) {
int componentId = toComponentIndex(index);
if (index + length > capacity()) { if (index + length > capacity()) {
throw new IndexOutOfBoundsException("Too many bytes to convert - Needs" throw new IndexOutOfBoundsException("Too many bytes to convert - Needs"
+ (index + length) + ", maximum is " + capacity()); + (index + length) + ", maximum is " + capacity());
} }
if (index < 0) {
throw new IndexOutOfBoundsException("index must be >= 0");
}
if (length == 0) {
return new ByteBuffer[0];
}
int componentId = toComponentIndex(index);
List<ByteBuffer> buffers = new ArrayList<ByteBuffer>(components.size()); List<ByteBuffer> buffers = new ArrayList<ByteBuffer>(components.size());

View File

@ -410,4 +410,11 @@ public abstract class AbstractCompositeChannelBufferTest extends
wrappedBuffer(new byte[] { 0, 1, 2, 3, 4, 6, 7, 8, 5, 9, 10, 11 }, 6, 5).order(order)); wrappedBuffer(new byte[] { 0, 1, 2, 3, 4, 6, 7, 8, 5, 9, 10, 11 }, 6, 5).order(order));
assertFalse(ByteBufUtil.equals(a, b)); assertFalse(ByteBufUtil.equals(a, b));
} }
@Test
public void testEmptyBuffer() {
ByteBuf b = wrappedBuffer(new byte[] {1, 2}, new byte[] {3, 4});
b.readBytes(new byte[4]);
b.readBytes(new byte[0]);
}
} }