From d62932c7de1c6bc21a4a83218bf8a731c10cd675 Mon Sep 17 00:00:00 2001 From: Norman Maurer Date: Wed, 5 Nov 2014 14:38:56 +0100 Subject: [PATCH] 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. --- .../io/netty/buffer/PooledHeapByteBuf.java | 1 + .../buffer/PooledUnsafeDirectByteBuf.java | 1 + .../buffer/UnpooledUnsafeDirectByteBuf.java | 1 + .../io/netty/buffer/AbstractByteBufTest.java | 26 +++++++++++++++++++ 4 files changed, 29 insertions(+) diff --git a/buffer/src/main/java/io/netty/buffer/PooledHeapByteBuf.java b/buffer/src/main/java/io/netty/buffer/PooledHeapByteBuf.java index 5f7b2a898a..a417509ee1 100644 --- a/buffer/src/main/java/io/netty/buffer/PooledHeapByteBuf.java +++ b/buffer/src/main/java/io/netty/buffer/PooledHeapByteBuf.java @@ -277,6 +277,7 @@ final class PooledHeapByteBuf extends PooledByteBuf { @Override public byte[] array() { + ensureAccessible(); return memory; } diff --git a/buffer/src/main/java/io/netty/buffer/PooledUnsafeDirectByteBuf.java b/buffer/src/main/java/io/netty/buffer/PooledUnsafeDirectByteBuf.java index c980d72b7a..1ff5b5deec 100644 --- a/buffer/src/main/java/io/netty/buffer/PooledUnsafeDirectByteBuf.java +++ b/buffer/src/main/java/io/netty/buffer/PooledUnsafeDirectByteBuf.java @@ -375,6 +375,7 @@ final class PooledUnsafeDirectByteBuf extends PooledByteBuf { @Override public long memoryAddress() { + ensureAccessible(); return memoryAddress; } diff --git a/buffer/src/main/java/io/netty/buffer/UnpooledUnsafeDirectByteBuf.java b/buffer/src/main/java/io/netty/buffer/UnpooledUnsafeDirectByteBuf.java index 954c320bd5..065deb9907 100644 --- a/buffer/src/main/java/io/netty/buffer/UnpooledUnsafeDirectByteBuf.java +++ b/buffer/src/main/java/io/netty/buffer/UnpooledUnsafeDirectByteBuf.java @@ -211,6 +211,7 @@ public class UnpooledUnsafeDirectByteBuf extends AbstractReferenceCountedByteBuf @Override public long memoryAddress() { + ensureAccessible(); return memoryAddress; } diff --git a/buffer/src/test/java/io/netty/buffer/AbstractByteBufTest.java b/buffer/src/test/java/io/netty/buffer/AbstractByteBufTest.java index d610087400..71f4ae9d42 100644 --- a/buffer/src/test/java/io/netty/buffer/AbstractByteBufTest.java +++ b/buffer/src/test/java/io/netty/buffer/AbstractByteBufTest.java @@ -2430,6 +2430,32 @@ public abstract class AbstractByteBufTest { 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: // https://github.com/netty/netty/issues/2843 @Test