8357145: CRC/Inflater/Deflater/Adler32 methods that take a ByteBuffer throw UOE if backed by shared memory segment

Reviewed-by: alanb
This commit is contained in:
Per Minborg 2025-05-27 19:15:40 +00:00
parent d4b923d175
commit da228e0693
7 changed files with 44 additions and 28 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1996, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1996, 2025, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -29,7 +29,6 @@ import java.nio.ByteBuffer;
import jdk.internal.util.Preconditions;
import jdk.internal.vm.annotation.IntrinsicCandidate;
import sun.nio.ch.DirectBuffer;
import static java.util.zip.ZipUtils.NIO_ACCESS;
@ -100,7 +99,7 @@ public class Adler32 implements Checksum {
if (buffer.isDirect()) {
NIO_ACCESS.acquireSession(buffer);
try {
adler = updateByteBuffer(adler, ((DirectBuffer)buffer).address(), pos, rem);
adler = updateByteBuffer(adler, NIO_ACCESS.getBufferAddress(buffer), pos, rem);
} finally {
NIO_ACCESS.releaseSession(buffer);
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1996, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1996, 2025, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -28,7 +28,6 @@ package java.util.zip;
import java.nio.ByteBuffer;
import java.util.Objects;
import sun.nio.ch.DirectBuffer;
import jdk.internal.util.Preconditions;
import jdk.internal.vm.annotation.IntrinsicCandidate;
@ -99,7 +98,7 @@ public class CRC32 implements Checksum {
if (buffer.isDirect()) {
NIO_ACCESS.acquireSession(buffer);
try {
crc = updateByteBuffer(crc, ((DirectBuffer)buffer).address(), pos, rem);
crc = updateByteBuffer(crc, NIO_ACCESS.getBufferAddress(buffer), pos, rem);
} finally {
NIO_ACCESS.releaseSession(buffer);
}

View File

@ -22,6 +22,7 @@
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.util.zip;
import java.nio.ByteBuffer;
@ -30,7 +31,6 @@ import java.nio.ByteOrder;
import jdk.internal.misc.Unsafe;
import jdk.internal.util.Preconditions;
import jdk.internal.vm.annotation.IntrinsicCandidate;
import sun.nio.ch.DirectBuffer;
import static java.util.zip.ZipUtils.NIO_ACCESS;
@ -176,7 +176,7 @@ public final class CRC32C implements Checksum {
if (buffer.isDirect()) {
NIO_ACCESS.acquireSession(buffer);
try {
crc = updateDirectByteBuffer(crc, ((DirectBuffer)buffer).address(),
crc = updateDirectByteBuffer(crc, NIO_ACCESS.getBufferAddress(buffer),
pos, limit);
} finally {
NIO_ACCESS.releaseSession(buffer);

View File

@ -32,7 +32,6 @@ import java.util.Objects;
import jdk.internal.ref.CleanerFactory;
import jdk.internal.util.Preconditions;
import sun.nio.ch.DirectBuffer;
import static java.util.zip.ZipUtils.NIO_ACCESS;
@ -322,7 +321,7 @@ public class Deflater implements AutoCloseable {
if (dictionary.isDirect()) {
NIO_ACCESS.acquireSession(dictionary);
try {
long address = ((DirectBuffer) dictionary).address();
long address = NIO_ACCESS.getBufferAddress(dictionary);
setDictionaryBuffer(zsRef.address(), address + position, remaining);
} finally {
NIO_ACCESS.releaseSession(dictionary);
@ -577,7 +576,7 @@ public class Deflater implements AutoCloseable {
if (input.isDirect()) {
NIO_ACCESS.acquireSession(input);
try {
long inputAddress = ((DirectBuffer) input).address();
long inputAddress = NIO_ACCESS.getBufferAddress(input);
result = deflateBufferBytes(zsRef.address(),
inputAddress + inputPos, inputRem,
output, off, len,
@ -701,7 +700,7 @@ public class Deflater implements AutoCloseable {
if (output.isDirect()) {
NIO_ACCESS.acquireSession(output);
try {
long outputAddress = ((DirectBuffer) output).address();
long outputAddress = NIO_ACCESS.getBufferAddress(output);
result = deflateBytesBuffer(zsRef.address(),
inputArray, inputPos, inputLim - inputPos,
outputAddress + outputPos, outputRem,
@ -723,11 +722,11 @@ public class Deflater implements AutoCloseable {
if (input.isDirect()) {
NIO_ACCESS.acquireSession(input);
try {
long inputAddress = ((DirectBuffer) input).address();
long inputAddress = NIO_ACCESS.getBufferAddress(input);
if (output.isDirect()) {
NIO_ACCESS.acquireSession(output);
try {
long outputAddress = outputPos + ((DirectBuffer) output).address();
long outputAddress = outputPos + NIO_ACCESS.getBufferAddress(output);
result = deflateBufferBuffer(zsRef.address(),
inputAddress + inputPos, inputRem,
outputAddress, outputRem,
@ -752,7 +751,7 @@ public class Deflater implements AutoCloseable {
if (output.isDirect()) {
NIO_ACCESS.acquireSession(output);
try {
long outputAddress = ((DirectBuffer) output).address();
long outputAddress = NIO_ACCESS.getBufferAddress(output);
result = deflateBytesBuffer(zsRef.address(),
inputArray, inputOffset + inputPos, inputRem,
outputAddress + outputPos, outputRem,

View File

@ -32,7 +32,6 @@ import java.util.Objects;
import jdk.internal.ref.CleanerFactory;
import jdk.internal.util.Preconditions;
import sun.nio.ch.DirectBuffer;
import static java.util.zip.ZipUtils.NIO_ACCESS;
@ -243,7 +242,7 @@ public class Inflater implements AutoCloseable {
if (dictionary.isDirect()) {
NIO_ACCESS.acquireSession(dictionary);
try {
long address = ((DirectBuffer) dictionary).address();
long address = NIO_ACCESS.getBufferAddress(dictionary);
setDictionaryBuffer(zsRef.address(), address + position, remaining);
} finally {
NIO_ACCESS.releaseSession(dictionary);
@ -366,7 +365,7 @@ public class Inflater implements AutoCloseable {
if (input.isDirect()) {
NIO_ACCESS.acquireSession(input);
try {
long inputAddress = ((DirectBuffer) input).address();
long inputAddress = NIO_ACCESS.getBufferAddress(input);
result = inflateBufferBytes(zsRef.address(),
inputAddress + inputPos, inputRem,
output, off, len);
@ -503,7 +502,7 @@ public class Inflater implements AutoCloseable {
if (output.isDirect()) {
NIO_ACCESS.acquireSession(output);
try {
long outputAddress = ((DirectBuffer) output).address();
long outputAddress = NIO_ACCESS.getBufferAddress(output);
result = inflateBytesBuffer(zsRef.address(),
inputArray, inputPos, inputLim - inputPos,
outputAddress + outputPos, outputRem);
@ -528,11 +527,11 @@ public class Inflater implements AutoCloseable {
if (input.isDirect()) {
NIO_ACCESS.acquireSession(input);
try {
long inputAddress = ((DirectBuffer) input).address();
long inputAddress = NIO_ACCESS.getBufferAddress(input);
if (output.isDirect()) {
NIO_ACCESS.acquireSession(output);
try {
long outputAddress = ((DirectBuffer) output).address();
long outputAddress = NIO_ACCESS.getBufferAddress(output);
result = inflateBufferBuffer(zsRef.address(),
inputAddress + inputPos, inputRem,
outputAddress + outputPos, outputRem);
@ -555,7 +554,7 @@ public class Inflater implements AutoCloseable {
if (output.isDirect()) {
NIO_ACCESS.acquireSession(output);
try {
long outputAddress = ((DirectBuffer) output).address();
long outputAddress = NIO_ACCESS.getBufferAddress(output);
result = inflateBytesBuffer(zsRef.address(),
inputArray, inputOffset + inputPos, inputRem,
outputAddress + outputPos, outputRem);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, 2025, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -21,14 +21,15 @@
* questions.
*/
/**
* Base class for Checksum tests
*/
import java.lang.foreign.MemorySegment;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.charset.StandardCharsets;
import java.util.zip.Checksum;
/**
* Base class for Checksum tests
*/
public class ChecksumBase {
private static final byte[] BYTES_123456789 = "123456789".getBytes(StandardCharsets.US_ASCII);
@ -36,6 +37,7 @@ public class ChecksumBase {
public static void testAll(Checksum checksum, long expected) {
testBytes(checksum, expected);
testByteArray(checksum, expected);
testWrappedMemorySegment(checksum, expected);
testWrappedByteBuffer(checksum, expected);
testReadonlyByteBuffer(checksum, expected);
testDirectByteBuffer(checksum, expected);
@ -69,6 +71,13 @@ public class ChecksumBase {
checkChecksum(checksum, expected);
}
private static void testWrappedMemorySegment(Checksum checksum, long expected) {
checksum.reset();
ByteBuffer bb = MemorySegment.ofArray(BYTES_123456789).asByteBuffer();
checksum.update(bb);
checkChecksum(checksum, expected);
}
private static void testReadonlyByteBuffer(Checksum checksum, long expected) {
checksum.reset();
ByteBuffer bb = ByteBuffer.wrap(BYTES_123456789).asReadOnlyBuffer();

View File

@ -21,14 +21,15 @@
* questions.
*/
/**
/*
* @test
* @bug 7110149 8184306 6341887
* @bug 7110149 8184306 6341887 8357145
* @summary Test basic deflater & inflater functionality
* @key randomness
*/
import java.io.*;
import java.lang.foreign.Arena;
import java.nio.*;
import java.util.*;
import java.util.zip.*;
@ -203,6 +204,16 @@ public class DeInflate {
bbOut2 = ByteBuffer.allocateDirect(out2.length);
checkByteBuffer(def, inf, bbIn, bbOut1, bbOut2, in, len, out2, false);
checkByteBufferReadonly(def, inf, bbIn, bbOut1, bbOut2);
// segment
try (var arena = Arena.ofConfined()) {
bbIn = arena.allocate(in.length).asByteBuffer();
bbIn.put(in, 0, n).flip();
bbOut1 = arena.allocate(out1.length).asByteBuffer();
bbOut2 = arena.allocate(out2.length).asByteBuffer();
checkByteBuffer(def, inf, bbIn, bbOut1, bbOut2, in, len, out2, false);
checkByteBufferReadonly(def, inf, bbIn, bbOut1, bbOut2);
}
}
static void checkDict(Deflater def, Inflater inf, byte[] src,