Skip to content

Commit 9f78665

Browse files
committed
SimpleMergedByteBuffers: ArrayOutOfBoundsFix
This fixes SimpleMergedByteBuffers.getNextBuffer to avoid an ArrayOutOfBounds fix when the buffer has been fully consumed. We must always check the currentBuffer index before we can attempt to access the array. In addition the EMPTY_BUFFER_ARRAY can not contain the empty buffer because it makes logic which compares the array length invalid.
1 parent 7d9d335 commit 9f78665

File tree

3 files changed

+16
-23
lines changed

3 files changed

+16
-23
lines changed

gradle.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
group = org.threadly
2-
version = 4.12-SNAPSHOT
2+
version = 4.12
33
threadlyVersion = 5.41

src/main/java/org/threadly/litesockets/buffers/SimpleMergedByteBuffers.java

Lines changed: 15 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
*
1313
*/
1414
public class SimpleMergedByteBuffers extends AbstractMergedByteBuffers {
15-
private static final ByteBuffer[] EMPTY_BUFFER_ARRAY = new ByteBuffer[] {IOUtils.EMPTY_BYTEBUFFER};
15+
private static final ByteBuffer[] EMPTY_BUFFER_ARRAY = new ByteBuffer[] {};
1616

1717

1818
private final ByteBuffer[] bba;
@@ -66,14 +66,12 @@ private void doGet(final byte[] destBytes, int start, int len) {
6666
}
6767

6868
private ByteBuffer getNextBuffer() {
69-
while(!this.bba[this.currentBuffer].hasRemaining() && bba.length > currentBuffer+1 ) {
70-
this.bba[this.currentBuffer] = null;
69+
ByteBuffer nextBuffer = IOUtils.EMPTY_BYTEBUFFER;
70+
while(bba.length > currentBuffer && ! (nextBuffer = bba[currentBuffer]).hasRemaining()) {
71+
bba[currentBuffer] = null;
7172
currentBuffer++;
7273
}
73-
if(bba[this.currentBuffer].hasRemaining()) {
74-
return bba[currentBuffer];
75-
}
76-
return IOUtils.EMPTY_BYTEBUFFER;
74+
return nextBuffer;
7775
}
7876

7977
@Override
@@ -138,9 +136,11 @@ public int nextBufferSize() {
138136
@Override
139137
public ByteBuffer popBuffer() {
140138
ByteBuffer bb = getNextBuffer();
141-
consumedSize += bb.remaining();
142-
currentBuffer++;
143-
return bb.duplicate();
139+
if (bb.hasRemaining()) {
140+
consumedSize += bb.remaining();
141+
currentBuffer++;
142+
}
143+
return bb;
144144
}
145145

146146
@Override
@@ -154,12 +154,7 @@ public int remaining() {
154154

155155
@Override
156156
public boolean hasRemaining() {
157-
for(int i=currentBuffer; i<bba.length; i++) {
158-
if(bba[i].hasRemaining()) {
159-
return true;
160-
}
161-
}
162-
return false;
157+
return getNextBuffer().hasRemaining();
163158
}
164159

165160
@Override
@@ -236,11 +231,11 @@ public void discardFromEnd(int size) {
236231
@Override
237232
protected byte get(int pos) {
238233
int currentPos = 0;
239-
for(ByteBuffer bb: this.bba) {
240-
if(bb != null && bb.remaining() > pos-currentPos) {
241-
return bb.get(pos-currentPos);
234+
for (int i = currentBuffer; i < this.bba.length; i++) {
235+
if(this.bba[i].remaining() > pos-currentPos) {
236+
return this.bba[i].get(pos-currentPos);
242237
} else {
243-
currentPos+=bb.remaining();
238+
currentPos+=this.bba[i].remaining();
244239
}
245240
}
246241
return 0;

src/test/java/org/threadly/litesockets/buffers/SimpleMergedByteBuffersTests.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,6 @@ public void GetArrayOffset() throws IOException {
6262

6363
@Test
6464
public void getInts() {
65-
6665
ByteBuffer[] bba = new ByteBuffer[200];
6766
for(int i = 0; i<200; i++) {
6867
ByteBuffer bb = ByteBuffer.allocate(4);
@@ -238,7 +237,6 @@ public void popZeroBuffer() {
238237

239238
@Test
240239
public void popBuffer() {
241-
242240
Random rnd = new Random();
243241
int size = Math.abs(rnd.nextInt(300))+10;
244242
MergedByteBuffers mbb = new SimpleMergedByteBuffers(false, ByteBuffer.allocate(size), ByteBuffer.allocate(rnd.nextInt(300)), ByteBuffer.allocate(rnd.nextInt(300)), ByteBuffer.allocate(rnd.nextInt(300)));

0 commit comments

Comments
 (0)