Ensure buffer is not released when call array() / memoryAddress()

Motivation:

Before we missed to check if a buffer was released before we return the backing byte array or memoryaddress. This could lead to JVM crashes when someone tried various bulk operations on the Unsafe*ByteBuf implementations.

Modifications:

Always check if the buffer is released before all to return the byte array and memoryaddress.

Result:

No more JVM crashes because of released buffers when doing bulk operations on Unsafe*ByteBuf implementations.
This commit is contained in:
Norman Maurer 2014-11-05 14:38:56 +01:00 committed by Norman Maurer
parent d5a24d4f6c
commit 182c91f06c
4 changed files with 29 additions and 0 deletions

View File

@ -277,6 +277,7 @@ final class PooledHeapByteBuf extends PooledByteBuf<byte[]> {
@Override @Override
public byte[] array() { public byte[] array() {
ensureAccessible();
return memory; return memory;
} }

View File

@ -375,6 +375,7 @@ final class PooledUnsafeDirectByteBuf extends PooledByteBuf<ByteBuffer> {
@Override @Override
public long memoryAddress() { public long memoryAddress() {
ensureAccessible();
return memoryAddress; return memoryAddress;
} }

View File

@ -211,6 +211,7 @@ public class UnpooledUnsafeDirectByteBuf extends AbstractReferenceCountedByteBuf
@Override @Override
public long memoryAddress() { public long memoryAddress() {
ensureAccessible();
return memoryAddress; return memoryAddress;
} }

View File

@ -2430,6 +2430,32 @@ public abstract class AbstractByteBufTest {
releasedBuffer().nioBuffers(0, 1); releasedBuffer().nioBuffers(0, 1);
} }
@Test
public void testArrayAfterRelease() {
ByteBuf buf = releasedBuffer();
if (buf.hasArray()) {
try {
buf.array();
fail();
} catch (IllegalReferenceCountException e) {
// expected
}
}
}
@Test
public void testMemoryAddressAfterRelease() {
ByteBuf buf = releasedBuffer();
if (buf.hasMemoryAddress()) {
try {
buf.memoryAddress();
fail();
} catch (IllegalReferenceCountException e) {
// expected
}
}
}
// Test-case trying to reproduce: // Test-case trying to reproduce:
// https://github.com/netty/netty/issues/2843 // https://github.com/netty/netty/issues/2843
@Test @Test