From da228e069359bbab0e5c54f8cb2e20d67693b87c Mon Sep 17 00:00:00 2001 From: Per Minborg Date: Tue, 27 May 2025 19:15:40 +0000 Subject: [PATCH] 8357145: CRC/Inflater/Deflater/Adler32 methods that take a ByteBuffer throw UOE if backed by shared memory segment Reviewed-by: alanb --- .../share/classes/java/util/zip/Adler32.java | 5 ++--- .../share/classes/java/util/zip/CRC32.java | 5 ++--- .../share/classes/java/util/zip/CRC32C.java | 4 ++-- .../share/classes/java/util/zip/Deflater.java | 13 ++++++------- .../share/classes/java/util/zip/Inflater.java | 13 ++++++------- test/jdk/java/util/zip/ChecksumBase.java | 17 +++++++++++++---- test/jdk/java/util/zip/DeInflate.java | 15 +++++++++++++-- 7 files changed, 44 insertions(+), 28 deletions(-) diff --git a/src/java.base/share/classes/java/util/zip/Adler32.java b/src/java.base/share/classes/java/util/zip/Adler32.java index 807c08ced8a..fa2fdb1f4c3 100644 --- a/src/java.base/share/classes/java/util/zip/Adler32.java +++ b/src/java.base/share/classes/java/util/zip/Adler32.java @@ -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); } diff --git a/src/java.base/share/classes/java/util/zip/CRC32.java b/src/java.base/share/classes/java/util/zip/CRC32.java index 944ccaa7e21..80b4f05a3c1 100644 --- a/src/java.base/share/classes/java/util/zip/CRC32.java +++ b/src/java.base/share/classes/java/util/zip/CRC32.java @@ -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); } diff --git a/src/java.base/share/classes/java/util/zip/CRC32C.java b/src/java.base/share/classes/java/util/zip/CRC32C.java index 36d37f3fe26..5b4b3597e9c 100644 --- a/src/java.base/share/classes/java/util/zip/CRC32C.java +++ b/src/java.base/share/classes/java/util/zip/CRC32C.java @@ -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); diff --git a/src/java.base/share/classes/java/util/zip/Deflater.java b/src/java.base/share/classes/java/util/zip/Deflater.java index 97a2a2d10ec..c3ce84263b2 100644 --- a/src/java.base/share/classes/java/util/zip/Deflater.java +++ b/src/java.base/share/classes/java/util/zip/Deflater.java @@ -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, diff --git a/src/java.base/share/classes/java/util/zip/Inflater.java b/src/java.base/share/classes/java/util/zip/Inflater.java index 7c439ec812d..5ced5a4879a 100644 --- a/src/java.base/share/classes/java/util/zip/Inflater.java +++ b/src/java.base/share/classes/java/util/zip/Inflater.java @@ -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); diff --git a/test/jdk/java/util/zip/ChecksumBase.java b/test/jdk/java/util/zip/ChecksumBase.java index 6c4f1edf45c..1df1f8203c9 100644 --- a/test/jdk/java/util/zip/ChecksumBase.java +++ b/test/jdk/java/util/zip/ChecksumBase.java @@ -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(); diff --git a/test/jdk/java/util/zip/DeInflate.java b/test/jdk/java/util/zip/DeInflate.java index d3785f0360e..226d4ed4ae3 100644 --- a/test/jdk/java/util/zip/DeInflate.java +++ b/test/jdk/java/util/zip/DeInflate.java @@ -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,