Skip to content

Commit 42bb852

Browse files
committed
8321467: MemorySegment.setString(long, String, Charset) throws IAE(Misaligned access)
Reviewed-by: pminborg
1 parent c087e91 commit 42bb852

File tree

2 files changed

+50
-13
lines changed

2 files changed

+50
-13
lines changed

src/java.base/share/classes/jdk/internal/foreign/StringSupport.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ private static String readShort(MemorySegment segment, long offset, Charset char
8282

8383
private static void writeShort(MemorySegment segment, long offset, Charset charset, String string) {
8484
int bytes = copyBytes(string, segment, charset, offset);
85-
segment.set(JAVA_SHORT, offset + bytes, (short)0);
85+
segment.set(JAVA_SHORT_UNALIGNED, offset + bytes, (short)0);
8686
}
8787

8888
private static String readInt(MemorySegment segment, long offset, Charset charset) {
@@ -94,7 +94,7 @@ private static String readInt(MemorySegment segment, long offset, Charset charse
9494

9595
private static void writeInt(MemorySegment segment, long offset, Charset charset, String string) {
9696
int bytes = copyBytes(string, segment, charset, offset);
97-
segment.set(JAVA_INT, offset + bytes, 0);
97+
segment.set(JAVA_INT_UNALIGNED, offset + bytes, 0);
9898
}
9999

100100
/**
@@ -222,7 +222,7 @@ public static int chunkedStrlenShort(MemorySegment segment, long start) {
222222

223223
int offset = 0;
224224
for (; offset < headCount; offset += Short.BYTES) {
225-
short curr = segment.get(JAVA_SHORT, start + offset);
225+
short curr = segment.get(JAVA_SHORT_UNALIGNED, start + offset);
226226
if (curr == 0) {
227227
return offset;
228228
}

test/jdk/java/foreign/TestStringEncoding.java

Lines changed: 47 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,6 @@
2222
*
2323
*/
2424

25-
import java.io.IOException;
26-
import java.io.RandomAccessFile;
2725
import java.lang.foreign.Arena;
2826
import java.lang.foreign.FunctionDescriptor;
2927
import java.lang.foreign.Linker;
@@ -33,16 +31,12 @@
3331
import java.lang.foreign.ValueLayout;
3432
import java.lang.invoke.MethodHandle;
3533
import java.lang.reflect.Field;
36-
import java.nio.channels.FileChannel;
3734
import java.nio.charset.Charset;
3835
import java.nio.charset.StandardCharsets;
39-
import java.nio.file.Files;
40-
import java.nio.file.Path;
41-
import java.nio.file.Paths;
36+
import java.util.ArrayList;
4237
import java.util.Arrays;
4338
import java.util.List;
4439
import java.util.Random;
45-
import java.util.function.Consumer;
4640
import java.util.function.UnaryOperator;
4741

4842
import jdk.internal.foreign.StringSupport;
@@ -333,6 +327,27 @@ public void strlen_int() {
333327
}
334328
}
335329

330+
@Test(dataProvider = "charsetsAndSegments")
331+
public void testStringGetWithCharset(Charset charset, MemorySegment segment) {
332+
for (int offset = 0 ; offset < Long.BYTES ; offset++) {
333+
segment.getString(offset, charset);
334+
}
335+
}
336+
337+
@Test(dataProvider = "charsetsAndSegments")
338+
public void testStringSetWithCharset(Charset charset, MemorySegment segment) {
339+
for (int offset = 0 ; offset < Long.BYTES ; offset++) {
340+
segment.setString(offset, "H", charset);
341+
}
342+
}
343+
344+
@Test(dataProvider = "charsetsAndSegments")
345+
public void testStringAllocateFromWithCharset(Charset charset, MemorySegment segment) {
346+
for (int offset = 0 ; offset < Long.BYTES ; offset++) {
347+
SegmentAllocator.prefixAllocator(segment.asSlice(offset)).allocateFrom("H", charset);
348+
}
349+
}
350+
336351
@DataProvider
337352
public static Object[][] strings() {
338353
return new Object[][]{
@@ -361,7 +376,7 @@ public static boolean containsOnlyRegularCharacters(String s) {
361376
.allMatch(c -> Character.isLetterOrDigit((char) c));
362377
}
363378

364-
boolean isStandard(Charset charset) {
379+
static boolean isStandard(Charset charset) {
365380
for (Field standardCharset : StandardCharsets.class.getDeclaredFields()) {
366381
try {
367382
if (standardCharset.get(null) == charset) {
@@ -374,9 +389,9 @@ boolean isStandard(Charset charset) {
374389
return false;
375390
}
376391

377-
List<Charset> standardCharsets() {
392+
static List<Charset> standardCharsets() {
378393
return Charset.availableCharsets().values().stream()
379-
.filter(this::isStandard)
394+
.filter(TestStringEncoding::isStandard)
380395
.toList();
381396
}
382397

@@ -456,4 +471,26 @@ public String toString() {
456471
}
457472
}
458473

474+
static MemorySegment[] heapSegments() {
475+
return new MemorySegment[]{
476+
MemorySegment.ofArray(new byte[80]),
477+
MemorySegment.ofArray(new char[40]),
478+
MemorySegment.ofArray(new short[40]),
479+
MemorySegment.ofArray(new int[20]),
480+
MemorySegment.ofArray(new float[20]),
481+
MemorySegment.ofArray(new long[10]),
482+
MemorySegment.ofArray(new double[10])
483+
};
484+
}
485+
486+
@DataProvider
487+
public static Object[][] charsetsAndSegments() {
488+
List<Object[]> values = new ArrayList<>();
489+
for (Charset charset : standardCharsets()) {
490+
for (MemorySegment heapSegment : heapSegments()) {
491+
values.add(new Object[] { charset, heapSegment });
492+
}
493+
}
494+
return values.toArray(Object[][]::new);
495+
}
459496
}

0 commit comments

Comments
 (0)