Implement isWritable and ensureWritable on ReadOnlyByteBufferBuf (#7883)

Motivation:

It should be possible to write a ReadOnlyByteBufferBuf to a channel without errors. However, ReadOnlyByteBufferBuf does not override isWritable and ensureWritable, which can cause some handlers to mistakenly assume they can write to the ReadOnlyByteBufferBuf, resulting in ReadOnlyBufferException.

Modification:

Added isWritable and ensureWritable method overrides on ReadOnlyByteBufferBuf to indicate that it is never writable. Added tests for these methods.

Result:

Can successfully write ReadOnlyByteBufferBuf to a channel with an SslHandler (or any other handler which may attempt to write to the ByteBuf it receives).
This commit is contained in:
Rikki Gibson 2018-04-22 23:31:30 -07:00 committed by Norman Maurer
parent 48fe14402a
commit 1b1f7677ac
2 changed files with 72 additions and 0 deletions

View File

@ -51,6 +51,26 @@ class ReadOnlyByteBufferBuf extends AbstractReferenceCountedByteBuf {
@Override
protected void deallocate() { }
@Override
public boolean isWritable() {
return false;
}
@Override
public boolean isWritable(int numBytes) {
return false;
}
@Override
public ByteBuf ensureWritable(int minWritableBytes) {
throw new ReadOnlyBufferException();
}
@Override
public int ensureWritable(int minWritableBytes, boolean force) {
return 1;
}
@Override
public byte getByte(int index) {
ensureAccessible();

View File

@ -43,6 +43,58 @@ public class ReadOnlyDirectByteBufferBufTest {
buffer(allocate(1));
}
@Test
public void shouldIndicateNotWritable() {
ByteBuf buf = buffer(allocate(8).asReadOnlyBuffer()).clear();
try {
Assert.assertFalse(buf.isWritable());
} finally {
buf.release();
}
}
@Test
public void shouldIndicateNotWritableAnyNumber() {
ByteBuf buf = buffer(allocate(8).asReadOnlyBuffer()).clear();
try {
Assert.assertFalse(buf.isWritable(1));
} finally {
buf.release();
}
}
@Test
public void ensureWritableIntStatusShouldFailButNotThrow() {
ByteBuf buf = buffer(allocate(8).asReadOnlyBuffer()).clear();
try {
int result = buf.ensureWritable(1, false);
Assert.assertEquals(1, result);
} finally {
buf.release();
}
}
@Test
public void ensureWritableForceIntStatusShouldFailButNotThrow() {
ByteBuf buf = buffer(allocate(8).asReadOnlyBuffer()).clear();
try {
int result = buf.ensureWritable(1, true);
Assert.assertEquals(1, result);
} finally {
buf.release();
}
}
@Test(expected = ReadOnlyBufferException.class)
public void ensureWritableShouldThrow() {
ByteBuf buf = buffer(allocate(8).asReadOnlyBuffer()).clear();
try {
buf.ensureWritable(1);
} finally {
buf.release();
}
}
@Test(expected = ReadOnlyBufferException.class)
public void testSetByte() {
ByteBuf buf = buffer(allocate(8).asReadOnlyBuffer());