8288761: SegmentAllocator:allocate(long bytesSize) not throwing IAEx when bytesSize < 0

Reviewed-by: psandoz
This commit is contained in:
Maurizio Cimadamore 2022-06-21 20:59:45 +00:00
parent 834d92dd72
commit d7b43af591
5 changed files with 46 additions and 16 deletions

View file

@ -883,9 +883,7 @@ public sealed interface MemorySegment extends Addressable permits AbstractMemory
Reflection.ensureNativeAccess(Reflection.getCallerClass(), MemorySegment.class, "ofAddress"); Reflection.ensureNativeAccess(Reflection.getCallerClass(), MemorySegment.class, "ofAddress");
Objects.requireNonNull(address); Objects.requireNonNull(address);
Objects.requireNonNull(session); Objects.requireNonNull(session);
if (bytesSize < 0) { Utils.checkAllocationSizeAndAlign(bytesSize, 1);
throw new IllegalArgumentException("Invalid size : " + bytesSize);
}
return NativeMemorySegmentImpl.makeNativeSegmentUnchecked(address, bytesSize, session); return NativeMemorySegmentImpl.makeNativeSegmentUnchecked(address, bytesSize, session);
} }
@ -957,15 +955,7 @@ public sealed interface MemorySegment extends Addressable permits AbstractMemory
*/ */
static MemorySegment allocateNative(long bytesSize, long alignmentBytes, MemorySession session) { static MemorySegment allocateNative(long bytesSize, long alignmentBytes, MemorySession session) {
Objects.requireNonNull(session); Objects.requireNonNull(session);
if (bytesSize < 0) { Utils.checkAllocationSizeAndAlign(bytesSize, alignmentBytes);
throw new IllegalArgumentException("Invalid allocation size : " + bytesSize);
}
if (alignmentBytes <= 0 ||
((alignmentBytes & (alignmentBytes - 1)) != 0L)) {
throw new IllegalArgumentException("Invalid alignment constraint : " + alignmentBytes);
}
return NativeMemorySegmentImpl.makeNativeSegment(bytesSize, alignmentBytes, session); return NativeMemorySegmentImpl.makeNativeSegment(bytesSize, alignmentBytes, session);
} }

View file

@ -153,10 +153,7 @@ public abstract non-sealed class AbstractMemorySegmentImpl implements MemorySegm
@Override @Override
public MemorySegment allocate(long bytesSize, long bytesAlignment) { public MemorySegment allocate(long bytesSize, long bytesAlignment) {
if (bytesAlignment <= 0 || Utils.checkAllocationSizeAndAlign(bytesSize, bytesAlignment);
((bytesAlignment & (bytesAlignment - 1)) != 0L)) {
throw new IllegalArgumentException("Invalid alignment constraint : " + bytesAlignment);
}
return asSlice(0, bytesSize); return asSlice(0, bytesSize);
} }

View file

@ -71,6 +71,7 @@ public final class ArenaAllocator implements SegmentAllocator {
@Override @Override
public MemorySegment allocate(long bytesSize, long bytesAlignment) { public MemorySegment allocate(long bytesSize, long bytesAlignment) {
Utils.checkAllocationSizeAndAlign(bytesSize, bytesAlignment);
// try to slice from current segment first... // try to slice from current segment first...
MemorySegment slice = trySlice(bytesSize, bytesAlignment); MemorySegment slice = trySlice(bytesSize, bytesAlignment);
if (slice != null) { if (slice != null) {

View file

@ -162,4 +162,17 @@ public final class Utils {
throw new IllegalArgumentException(msg); throw new IllegalArgumentException(msg);
} }
} }
public static void checkAllocationSizeAndAlign(long bytesSize, long alignmentBytes) {
// size should be >= 0
if (bytesSize < 0) {
throw new IllegalArgumentException("Invalid allocation size : " + bytesSize);
}
// alignment should be > 0, and power of two
if (alignmentBytes <= 0 ||
((alignmentBytes & (alignmentBytes - 1)) != 0L)) {
throw new IllegalArgumentException("Invalid alignment constraint : " + alignmentBytes);
}
}
} }

View file

@ -139,6 +139,26 @@ public class TestSegmentAllocators {
SegmentAllocator.newNativeArena( -1, MemorySession.global()); SegmentAllocator.newNativeArena( -1, MemorySession.global());
} }
@Test(dataProvider = "allocators", expectedExceptions = IllegalArgumentException.class)
public void testBadAllocationSize(SegmentAllocator allocator) {
allocator.allocate(-1);
}
@Test(dataProvider = "allocators", expectedExceptions = IllegalArgumentException.class)
public void testBadAllocationAlignZero(SegmentAllocator allocator) {
allocator.allocate(1, 0);
}
@Test(dataProvider = "allocators", expectedExceptions = IllegalArgumentException.class)
public void testBadAllocationAlignNeg(SegmentAllocator allocator) {
allocator.allocate(1, -1);
}
@Test(dataProvider = "allocators", expectedExceptions = IllegalArgumentException.class)
public void testBadAllocationAlignNotPowerTwo(SegmentAllocator allocator) {
allocator.allocate(1, 3);
}
@Test(dataProvider = "arrayAllocations") @Test(dataProvider = "arrayAllocations")
public <Z> void testArray(AllocationFactory allocationFactory, ValueLayout layout, AllocationFunction<Object, ValueLayout> allocationFunction, ToArrayHelper<Z> arrayHelper) { public <Z> void testArray(AllocationFactory allocationFactory, ValueLayout layout, AllocationFunction<Object, ValueLayout> allocationFunction, ToArrayHelper<Z> arrayHelper) {
Z arr = arrayHelper.array(); Z arr = arrayHelper.array();
@ -444,4 +464,13 @@ public class TestSegmentAllocators {
} }
}; };
} }
@DataProvider(name = "allocators")
static Object[][] allocators() {
return new Object[][] {
{ SegmentAllocator.implicitAllocator() },
{ SegmentAllocator.newNativeArena(MemorySession.global()) },
{ SegmentAllocator.prefixAllocator(MemorySegment.allocateNative(10, MemorySession.global())) },
};
}
} }