|
1 | 1 | /* |
2 | | - * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved. |
| 2 | + * Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved. |
3 | 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 | 4 | * |
5 | 5 | * This code is free software; you can redistribute it and/or modify it |
|
41 | 41 | import java.lang.reflect.Array; |
42 | 42 | import java.util.List; |
43 | 43 |
|
44 | | -import static org.junit.Assert.assertEquals; |
45 | | -import static org.junit.Assert.assertFalse; |
46 | | -import static org.junit.Assert.assertNotNull; |
47 | | -import static org.junit.Assert.assertNull; |
48 | | -import static org.junit.Assert.assertTrue; |
| 44 | +import static org.junit.Assert.*; |
49 | 45 |
|
50 | 46 | /** |
51 | 47 | * Tests for {@link ConstantReflectionProvider}. It assumes an implementation of the interface that |
@@ -138,4 +134,42 @@ public void unboxTest() { |
138 | 134 |
|
139 | 135 | assertNull(constantReflection.unboxPrimitive(JavaConstant.NULL_POINTER)); |
140 | 136 | } |
| 137 | + |
| 138 | + static class ArrayConstants { |
| 139 | + static final byte[] BYTE_ARRAY_CONST = new byte[]{0}; |
| 140 | + static final Object[] OBJECT_ARRAY_CONST = new Object[]{null}; |
| 141 | + } |
| 142 | + |
| 143 | + @Test |
| 144 | + public void readOnePastLastArrayElementTest() { |
| 145 | + for (ConstantValue cv : readConstants(ArrayConstants.class)) { |
| 146 | + if (cv.boxed != null && cv.boxed.getClass().isArray()) { |
| 147 | + JavaKind kind = metaAccess.lookupJavaType(cv.value).getComponentType().getJavaKind(); |
| 148 | + long offset = metaAccess.getArrayBaseOffset(kind) + (long) metaAccess.getArrayIndexScale(kind) * Array.getLength(cv.boxed); |
| 149 | + // read array[array.length] |
| 150 | + assertThrows(IllegalArgumentException.class, () -> { |
| 151 | + if (kind == JavaKind.Object) { |
| 152 | + constantReflection.getMemoryAccessProvider().readObjectConstant(cv.value, offset); |
| 153 | + } else { |
| 154 | + constantReflection.getMemoryAccessProvider().readPrimitiveConstant(kind, cv.value, offset, kind.getBitCount()); |
| 155 | + } |
| 156 | + }); |
| 157 | + } |
| 158 | + } |
| 159 | + } |
| 160 | + |
| 161 | + static class IntArrayConstants { |
| 162 | + static final int[] INT_ARRAY_CONST = new int[]{0}; |
| 163 | + } |
| 164 | + |
| 165 | + @Test |
| 166 | + public void readPartiallyOutOfBoundsTest() { |
| 167 | + for (ConstantValue cv : readConstants(IntArrayConstants.class)) { |
| 168 | + JavaKind kind = metaAccess.lookupJavaType(cv.value).getComponentType().getJavaKind(); |
| 169 | + long offset = metaAccess.getArrayBaseOffset(kind) + (long) metaAccess.getArrayIndexScale(kind) * (Array.getLength(cv.boxed) - 1); |
| 170 | + // read a long from array[array.length - 1], which is partially out of bounds |
| 171 | + JavaKind accessKind = JavaKind.Long; |
| 172 | + assertThrows(IllegalArgumentException.class, () -> constantReflection.getMemoryAccessProvider().readPrimitiveConstant(accessKind, cv.value, offset, accessKind.getBitCount())); |
| 173 | + } |
| 174 | + } |
141 | 175 | } |
0 commit comments