From b03880e33b0d9442a608c9ec911afbe863221bf2 Mon Sep 17 00:00:00 2001 From: Maurizio Cimadamore Date: Tue, 12 Jan 2021 17:09:05 +0000 Subject: [PATCH] 8259634: MemorySegment::asByteBuffer does not respect spatial bounds Reviewed-by: alanb, chegar --- .../share/classes/java/nio/Buffer.java | 2 +- test/jdk/java/foreign/TestByteBuffer.java | 30 ++++++++++++++++++- 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/src/java.base/share/classes/java/nio/Buffer.java b/src/java.base/share/classes/java/nio/Buffer.java index 8e286584b1f..0506078eed8 100644 --- a/src/java.base/share/classes/java/nio/Buffer.java +++ b/src/java.base/share/classes/java/nio/Buffer.java @@ -793,7 +793,7 @@ public ByteBuffer newMappedByteBuffer(UnmapperProxy unmapperProxy, long address, @Override public ByteBuffer newHeapByteBuffer(byte[] hb, int offset, int capacity, MemorySegmentProxy segment) { - return new HeapByteBuffer(hb, offset, capacity, segment); + return new HeapByteBuffer(hb, -1, 0, capacity, capacity, offset, segment); } @Override diff --git a/test/jdk/java/foreign/TestByteBuffer.java b/test/jdk/java/foreign/TestByteBuffer.java index a396ec48ec5..27d7a8a3e00 100644 --- a/test/jdk/java/foreign/TestByteBuffer.java +++ b/test/jdk/java/foreign/TestByteBuffer.java @@ -64,6 +64,7 @@ import java.nio.file.StandardOpenOption; import java.util.ArrayList; import java.util.HashMap; +import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.function.BiConsumer; @@ -71,6 +72,7 @@ import java.util.function.Consumer; import java.util.function.Function; import java.util.function.Predicate; +import java.util.function.Supplier; import java.util.stream.Stream; import jdk.internal.foreign.HeapMemorySegmentImpl; @@ -635,7 +637,8 @@ public void testIOOnClosedConfinedSegmentBuffer() throws IOException { } } - public void testIOOnClosedConfinedSegment() throws IOException { + @Test + public void testIOOnConfinedSegment() throws IOException { File tmp = File.createTempFile("tmp", "txt"); tmp.deleteOnExit(); try (FileChannel channel = FileChannel.open(tmp.toPath(), StandardOpenOption.WRITE)) { @@ -648,6 +651,31 @@ public void testIOOnClosedConfinedSegment() throws IOException { } } + @Test(dataProvider="segments") + public void buffersAndArraysFromSlices(Supplier segmentSupplier) { + try (MemorySegment segment = segmentSupplier.get()) { + int newSize = 8; + var slice = segment.asSlice(4, newSize); + + var bytes = slice.toByteArray(); + assertEquals(newSize, bytes.length); + + var buffer = slice.asByteBuffer(); + // Fails for heap segments, but passes for native segments: + assertEquals(0, buffer.position()); + assertEquals(newSize, buffer.limit()); + assertEquals(newSize, buffer.capacity()); + } + } + + @DataProvider(name = "segments") + public static Object[][] segments() throws Throwable { + return new Object[][] { + { (Supplier) () -> MemorySegment.allocateNative(16) }, + { (Supplier) () -> MemorySegment.ofArray(new byte[16]) } + }; + } + @DataProvider(name = "bufferOps") public static Object[][] bufferOps() throws Throwable { List args = new ArrayList<>();