Skip to content
This repository was archived by the owner on Dec 12, 2022. It is now read-only.

Commit 2dee6f8

Browse files
committed
Fix bounds checking bugs when setting bytes
These should not take the read offset into account.
1 parent da70f29 commit 2dee6f8

File tree

3 files changed

+58
-30
lines changed

3 files changed

+58
-30
lines changed

src/main/java/io/netty/buffer/api/CompositeBuffer.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1279,7 +1279,7 @@ private RuntimeException indexOutOfBounds(int index, boolean write) {
12791279
}
12801280
return new IndexOutOfBoundsException(
12811281
"Index " + index + " is out of bounds: [read 0 to " + woff + ", write 0 to " +
1282-
(capacity - 1) + "].");
1282+
capacity + "].");
12831283
}
12841284

12851285
private static IllegalStateException bufferIsClosed() {

src/main/java/io/netty/buffer/api/memseg/MemSegBuffer.java

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ public MemSegBuffer writerOffset(int index) {
133133

134134
@Override
135135
public Buffer fill(byte value) {
136-
checkWrite(0, capacity());
136+
checkSet(0, capacity());
137137
seg.fill(value);
138138
return this;
139139
}
@@ -281,7 +281,7 @@ private void copyInto(int srcPos, MemorySegment dest, int destPos, int length) {
281281
public void copyInto(int srcPos, Buffer dest, int destPos, int length) {
282282
if (dest instanceof MemSegBuffer) {
283283
var memSegBuf = (MemSegBuffer) dest;
284-
memSegBuf.checkWrite(destPos, length);
284+
memSegBuf.checkSet(destPos, length);
285285
copyInto(srcPos, memSegBuf.seg, destPos, length);
286286
return;
287287
}
@@ -824,7 +824,7 @@ public Buffer writeMedium(int value) {
824824

825825
@Override
826826
public Buffer setMedium(int woff, int value) {
827-
checkWrite(woff, 3);
827+
checkSet(woff, 3);
828828
if (order == ByteOrder.BIG_ENDIAN) {
829829
setByteAtOffset(wseg, woff, (byte) (value >> 16));
830830
setByteAtOffset(wseg, woff + 1, (byte) (value >> 8 & 0xFF));
@@ -855,7 +855,7 @@ public Buffer writeUnsignedMedium(int value) {
855855

856856
@Override
857857
public Buffer setUnsignedMedium(int woff, int value) {
858-
checkWrite(woff, 3);
858+
checkSet(woff, 3);
859859
if (order == ByteOrder.BIG_ENDIAN) {
860860
setByteAtOffset(wseg, woff, (byte) (value >> 16));
861861
setByteAtOffset(wseg, woff + 1, (byte) (value >> 8 & 0xFF));
@@ -1100,6 +1100,12 @@ private void checkGet(int index, int size) {
11001100
}
11011101

11021102
private void checkWrite(int index, int size) {
1103+
if (index < roff || wseg.byteSize() < index + size) {
1104+
throw writeAccessCheckException(index);
1105+
}
1106+
}
1107+
1108+
private void checkSet(int index, int size) {
11031109
if (index < 0 || wseg.byteSize() < index + size) {
11041110
throw writeAccessCheckException(index);
11051111
}
@@ -1143,7 +1149,7 @@ private static IllegalStateException bufferIsReadOnly() {
11431149
private IndexOutOfBoundsException outOfBounds(int index) {
11441150
return new IndexOutOfBoundsException(
11451151
"Index " + index + " is out of bounds: [read 0 to " + woff + ", write 0 to " +
1146-
(seg.byteSize() - 1) + "].");
1152+
seg.byteSize() + "].");
11471153
}
11481154

11491155
Object recoverableMemory() {

src/test/java/io/netty/buffer/api/BufferTest.java

Lines changed: 46 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -582,6 +582,28 @@ void setReaderOffsetMustThrowOnOversizedIndex(Fixture fixture) {
582582
}
583583
}
584584

585+
@ParameterizedTest
586+
@MethodSource("allocators")
587+
public void setWriterOffsetMustThrowOutsideOfWritableRegion(Fixture fixture) {
588+
try (BufferAllocator allocator = fixture.createAllocator();
589+
Buffer buf = allocator.allocate(8)) {
590+
// Writer offset cannot be negative.
591+
assertThrows(IndexOutOfBoundsException.class, () -> buf.writerOffset(-1));
592+
593+
buf.writerOffset(4);
594+
buf.readerOffset(4);
595+
596+
// Cannot set writer offset before reader offset.
597+
assertThrows(IndexOutOfBoundsException.class, () -> buf.writerOffset(3));
598+
assertThrows(IndexOutOfBoundsException.class, () -> buf.writerOffset(0));
599+
600+
buf.writerOffset(buf.capacity());
601+
602+
// Cannot set writer offset beyond capacity.
603+
assertThrows(IndexOutOfBoundsException.class, () -> buf.writerOffset(buf.capacity() + 1));
604+
}
605+
}
606+
585607
@ParameterizedTest
586608
@MethodSource("allocators")
587609
void setReaderOffsetMustNotThrowWithinBounds(Fixture fixture) {
@@ -2454,30 +2476,30 @@ public void readOnlyBufferMustBecomeWritableAgainAfterTogglingReadOnlyOff(Fixtur
24542476
}
24552477

24562478
private static void verifyWriteAccessible(Buffer buf) {
2457-
buf.writerOffset(0).writeByte((byte) 32);
2458-
assertThat(buf.readerOffset(0).readByte()).isEqualTo((byte) 32);
2459-
buf.writerOffset(0).writeUnsignedByte(32);
2460-
assertThat(buf.readerOffset(0).readUnsignedByte()).isEqualTo(32);
2461-
buf.writerOffset(0).writeChar('3');
2462-
assertThat(buf.readerOffset(0).readChar()).isEqualTo('3');
2463-
buf.writerOffset(0).writeShort((short) 32);
2464-
assertThat(buf.readerOffset(0).readShort()).isEqualTo((short) 32);
2465-
buf.writerOffset(0).writeUnsignedShort(32);
2466-
assertThat(buf.readerOffset(0).readUnsignedShort()).isEqualTo(32);
2467-
buf.writerOffset(0).writeMedium(32);
2468-
assertThat(buf.readerOffset(0).readMedium()).isEqualTo(32);
2469-
buf.writerOffset(0).writeUnsignedMedium(32);
2470-
assertThat(buf.readerOffset(0).readUnsignedMedium()).isEqualTo(32);
2471-
buf.writerOffset(0).writeInt(32);
2472-
assertThat(buf.readerOffset(0).readInt()).isEqualTo(32);
2473-
buf.writerOffset(0).writeUnsignedInt(32);
2474-
assertThat(buf.readerOffset(0).readUnsignedInt()).isEqualTo(32L);
2475-
buf.writerOffset(0).writeFloat(3.2f);
2476-
assertThat(buf.readerOffset(0).readFloat()).isEqualTo(3.2f);
2477-
buf.writerOffset(0).writeLong(32);
2478-
assertThat(buf.readerOffset(0).readLong()).isEqualTo(32L);
2479-
buf.writerOffset(0).writeDouble(3.2);
2480-
assertThat(buf.readerOffset(0).readDouble()).isEqualTo(3.2);
2479+
buf.reset().writeByte((byte) 32);
2480+
assertThat(buf.readByte()).isEqualTo((byte) 32);
2481+
buf.reset().writerOffset(0).writeUnsignedByte(32);
2482+
assertThat(buf.readUnsignedByte()).isEqualTo(32);
2483+
buf.reset().writerOffset(0).writeChar('3');
2484+
assertThat(buf.readChar()).isEqualTo('3');
2485+
buf.reset().writerOffset(0).writeShort((short) 32);
2486+
assertThat(buf.readShort()).isEqualTo((short) 32);
2487+
buf.reset().writerOffset(0).writeUnsignedShort(32);
2488+
assertThat(buf.readUnsignedShort()).isEqualTo(32);
2489+
buf.reset().writerOffset(0).writeMedium(32);
2490+
assertThat(buf.readMedium()).isEqualTo(32);
2491+
buf.reset().writerOffset(0).writeUnsignedMedium(32);
2492+
assertThat(buf.readUnsignedMedium()).isEqualTo(32);
2493+
buf.reset().writerOffset(0).writeInt(32);
2494+
assertThat(buf.readInt()).isEqualTo(32);
2495+
buf.reset().writerOffset(0).writeUnsignedInt(32);
2496+
assertThat(buf.readUnsignedInt()).isEqualTo(32L);
2497+
buf.reset().writerOffset(0).writeFloat(3.2f);
2498+
assertThat(buf.readFloat()).isEqualTo(3.2f);
2499+
buf.reset().writerOffset(0).writeLong(32);
2500+
assertThat(buf.readLong()).isEqualTo(32L);
2501+
buf.reset().writerOffset(0).writeDouble(3.2);
2502+
assertThat(buf.readDouble()).isEqualTo(3.2);
24812503

24822504
buf.setByte(0, (byte) 32);
24832505
assertThat(buf.getByte(0)).isEqualTo((byte) 32);

0 commit comments

Comments
 (0)