Correctly take position into account when wrap a ByteBuffer via ReadOnlyUnsafeDirectByteBuf

Motivation:

We did not correctly take the position into account when wrapping a ByteBuffer via ReadOnlyUnsafeDirectByteBuf as we obtained the memory address from the original ByteBuffer and not the slice we take.

Modifications:

- Correctly use the slice to obtain memory address.
- Add test case.

Result:

Fixes [#7565].
This commit is contained in:
Norman Maurer 2018-01-14 13:59:26 +01:00
parent ccecc20124
commit b817cefa22
3 changed files with 52 additions and 3 deletions

View File

@ -27,8 +27,10 @@ import java.nio.ByteBuffer;
final class ReadOnlyUnsafeDirectByteBuf extends ReadOnlyByteBufferBuf {
private final long memoryAddress;
ReadOnlyUnsafeDirectByteBuf(ByteBufAllocator allocator, ByteBuffer buffer) {
super(allocator, buffer);
ReadOnlyUnsafeDirectByteBuf(ByteBufAllocator allocator, ByteBuffer byteBuffer) {
super(allocator, byteBuffer);
// Use buffer as the super class will slice the passed in ByteBuffer which means the memoryAddress
// may be different if the position != 0.
memoryAddress = PlatformDependent.directBufferAddress(buffer);
}

View File

@ -15,13 +15,18 @@
*/
package io.netty.buffer;
import io.netty.util.internal.PlatformDependent;
import org.junit.Assert;
import org.junit.Test;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.ReadOnlyBufferException;
import java.nio.channels.FileChannel;
public class ReadOnlyDirectByteBufferBufTest {
@ -226,4 +231,47 @@ public class ReadOnlyDirectByteBufferBufTest {
buf.release();
}
@Test
public void testWrapMemoryMapped() throws Exception {
File file = File.createTempFile("netty-test", "tmp");
FileChannel output = null;
FileChannel input = null;
ByteBuf b1 = null;
ByteBuf b2 = null;
try {
output = new FileOutputStream(file).getChannel();
byte[] bytes = new byte[1024];
PlatformDependent.threadLocalRandom().nextBytes(bytes);
output.write(ByteBuffer.wrap(bytes));
input = new FileInputStream(file).getChannel();
ByteBuffer m = input.map(FileChannel.MapMode.READ_ONLY, 0, input.size());
b1 = buffer(m);
ByteBuffer dup = m.duplicate();
dup.position(2);
dup.limit(4);
b2 = buffer(dup);
Assert.assertEquals(b2, b1.slice(2, 2));
} finally {
if (b1 != null) {
b1.release();
}
if (b2 != null) {
b2.release();
}
if (output != null) {
output.close();
}
if (input != null) {
input.close();
}
file.delete();
}
}
}

View File

@ -16,7 +16,6 @@
package io.netty.buffer;
import io.netty.util.internal.PlatformDependent;
import org.junit.Assume;
import org.junit.BeforeClass;
import java.nio.ByteBuffer;