diff --git a/core-server/src/main/java/jersey/repackaged/org/objectweb/asm/ClassReader.java b/core-server/src/main/java/jersey/repackaged/org/objectweb/asm/ClassReader.java index a46fdad3e1..b0173c8141 100644 --- a/core-server/src/main/java/jersey/repackaged/org/objectweb/asm/ClassReader.java +++ b/core-server/src/main/java/jersey/repackaged/org/objectweb/asm/ClassReader.java @@ -88,6 +88,9 @@ public class ClassReader { */ static final int EXPAND_ASM_INSNS = 256; + /** The maximum size of array to allocate. */ + private static final int MAX_BUFFER_SIZE = 1024 * 1024; + /** The size of the temporary byte array used to read class input streams chunk by chunk. */ private static final int INPUT_STREAM_DATA_CHUNK_SIZE = 4096; @@ -191,7 +194,7 @@ public ClassReader( this.b = classFileBuffer; // Check the class' major_version. This field is after the magic and minor_version fields, which // use 4 and 2 bytes respectively. - if (checkClassVersion && readShort(classFileOffset + 6) > Opcodes.V17) { + if (checkClassVersion && readShort(classFileOffset + 6) > Opcodes.V18) { throw new IllegalArgumentException( "Unsupported class file major version " + readShort(classFileOffset + 6)); } @@ -310,13 +313,19 @@ private static byte[] readStream(final InputStream inputStream, final boolean cl if (inputStream == null) { throw new IOException("Class not found"); } + int bufferSize = calculateBufferSize(inputStream); try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) { - byte[] data = new byte[INPUT_STREAM_DATA_CHUNK_SIZE]; + byte[] data = new byte[bufferSize]; int bytesRead; - while ((bytesRead = inputStream.read(data, 0, data.length)) != -1) { + int readCount = 0; + while ((bytesRead = inputStream.read(data, 0, bufferSize)) != -1) { outputStream.write(data, 0, bytesRead); + readCount++; } outputStream.flush(); + if (readCount == 1) { + return data; + } return outputStream.toByteArray(); } finally { if (close) { @@ -325,6 +334,19 @@ private static byte[] readStream(final InputStream inputStream, final boolean cl } } + private static int calculateBufferSize(final InputStream inputStream) throws IOException { + int expectedLength = inputStream.available(); + /* + * Some implementations can return 0 while holding available data + * (e.g. new FileInputStream("/proc/a_file")) + * Also in some pathological cases a very small number might be returned, + * and in this case we use default size + */ + if (expectedLength < 256) { + return INPUT_STREAM_DATA_CHUNK_SIZE; + } + return Math.min(expectedLength, MAX_BUFFER_SIZE); + } // ----------------------------------------------------------------------------------------------- // Accessors // ----------------------------------------------------------------------------------------------- diff --git a/core-server/src/main/java/jersey/repackaged/org/objectweb/asm/ClassVisitor.java b/core-server/src/main/java/jersey/repackaged/org/objectweb/asm/ClassVisitor.java index b89c7d5be8..e3a5b605f2 100644 --- a/core-server/src/main/java/jersey/repackaged/org/objectweb/asm/ClassVisitor.java +++ b/core-server/src/main/java/jersey/repackaged/org/objectweb/asm/ClassVisitor.java @@ -30,8 +30,8 @@ /** * A visitor to visit a Java class. The methods of this class must be called in the following order: * {@code visit} [ {@code visitSource} ] [ {@code visitModule} ][ {@code visitNestHost} ][ {@code - * visitPermittedSubclass} ][ {@code visitOuterClass} ] ( {@code visitAnnotation} | {@code - * visitTypeAnnotation} | {@code visitAttribute} )* ( {@code visitNestMember} | {@code + * visitOuterClass} ] ( {@code visitAnnotation} | {@code visitTypeAnnotation} | {@code + * visitAttribute} )* ( {@code visitNestMember} | [ {@code * visitPermittedSubclass} ] | {@code * visitInnerClass} | {@code visitRecordComponent} | {@code visitField} | {@code visitMethod} )* * {@code visitEnd}. * diff --git a/core-server/src/main/java/jersey/repackaged/org/objectweb/asm/ClassWriter.java b/core-server/src/main/java/jersey/repackaged/org/objectweb/asm/ClassWriter.java index c3c2fe6467..81176b8cc9 100644 --- a/core-server/src/main/java/jersey/repackaged/org/objectweb/asm/ClassWriter.java +++ b/core-server/src/main/java/jersey/repackaged/org/objectweb/asm/ClassWriter.java @@ -79,7 +79,7 @@ public class ClassWriter extends ClassVisitor { /** * The access_flags field of the JVMS ClassFile structure. This field can contain ASM specific - * access flags, such as {@link Opcodes#ACC_DEPRECATED} or {}@link Opcodes#ACC_RECORD}, which are + * access flags, such as {@link Opcodes#ACC_DEPRECATED} or {@link Opcodes#ACC_RECORD}, which are * removed when generating the ClassFile structure. */ private int accessFlags; diff --git a/core-server/src/main/java/jersey/repackaged/org/objectweb/asm/Opcodes.java b/core-server/src/main/java/jersey/repackaged/org/objectweb/asm/Opcodes.java index 9e9bdd770d..7850f21013 100644 --- a/core-server/src/main/java/jersey/repackaged/org/objectweb/asm/Opcodes.java +++ b/core-server/src/main/java/jersey/repackaged/org/objectweb/asm/Opcodes.java @@ -283,6 +283,7 @@ public interface Opcodes { int V15 = 0 << 16 | 59; int V16 = 0 << 16 | 60; int V17 = 0 << 16 | 61; + int V18 = 0 << 16 | 62; /** * Version flag indicating that the class is using 'preview' features. diff --git a/core-server/src/main/java/org/glassfish/jersey/server/internal/scanning/AnnotationAcceptingListener.java b/core-server/src/main/java/org/glassfish/jersey/server/internal/scanning/AnnotationAcceptingListener.java index 96e840c1c2..99c098134e 100644 --- a/core-server/src/main/java/org/glassfish/jersey/server/internal/scanning/AnnotationAcceptingListener.java +++ b/core-server/src/main/java/org/glassfish/jersey/server/internal/scanning/AnnotationAcceptingListener.java @@ -303,7 +303,7 @@ private Class getClassForName(final String className) { private static class ClassReaderWrapper { private static final Logger LOGGER = Logger.getLogger(ClassReader.class.getName()); - private static final int WARN_VERSION = Opcodes.V17; + private static final int WARN_VERSION = Opcodes.V18; private static final int INPUT_STREAM_DATA_CHUNK_SIZE = 4096; private final byte[] b; diff --git a/pom.xml b/pom.xml index 156cf98b57..7056ca0a48 100644 --- a/pom.xml +++ b/pom.xml @@ -2086,7 +2086,7 @@ ${project.version} - 9.1 + 9.2 2.3.6 1.1 2.0.2