parent
432fdad7d0
commit
d29d4d45aa
|
|
@ -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;
|
||||
|
||||
|
|
@ -310,13 +313,19 @@ public class ClassReader {
|
|||
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,20 @@ public class ClassReader {
|
|||
}
|
||||
}
|
||||
|
||||
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
|
||||
// -----------------------------------------------------------------------------------------------
|
||||
|
|
@ -3456,7 +3479,6 @@ public class ClassReader {
|
|||
private int[] readBootstrapMethodsAttribute(final int maxStringLength) {
|
||||
char[] charBuffer = new char[maxStringLength];
|
||||
int currentAttributeOffset = getFirstAttributeOffset();
|
||||
int[] currentBootstrapMethodOffsets = null;
|
||||
for (int i = readUnsignedShort(currentAttributeOffset - 2); i > 0; --i) {
|
||||
// Read the attribute_info's attribute_name and attribute_length fields.
|
||||
String attributeName = readUTF8(currentAttributeOffset, charBuffer);
|
||||
|
|
@ -3464,17 +3486,17 @@ public class ClassReader {
|
|||
currentAttributeOffset += 6;
|
||||
if (Constants.BOOTSTRAP_METHODS.equals(attributeName)) {
|
||||
// Read the num_bootstrap_methods field and create an array of this size.
|
||||
currentBootstrapMethodOffsets = new int[readUnsignedShort(currentAttributeOffset)];
|
||||
int[] result = new int[readUnsignedShort(currentAttributeOffset)];
|
||||
// Compute and store the offset of each 'bootstrap_methods' array field entry.
|
||||
int currentBootstrapMethodOffset = currentAttributeOffset + 2;
|
||||
for (int j = 0; j < currentBootstrapMethodOffsets.length; ++j) {
|
||||
currentBootstrapMethodOffsets[j] = currentBootstrapMethodOffset;
|
||||
for (int j = 0; j < result.length; ++j) {
|
||||
result[j] = currentBootstrapMethodOffset;
|
||||
// Skip the bootstrap_method_ref and num_bootstrap_arguments fields (2 bytes each),
|
||||
// as well as the bootstrap_arguments array field (of size num_bootstrap_arguments * 2).
|
||||
currentBootstrapMethodOffset +=
|
||||
4 + readUnsignedShort(currentBootstrapMethodOffset + 2) * 2;
|
||||
}
|
||||
return currentBootstrapMethodOffsets;
|
||||
return result;
|
||||
}
|
||||
currentAttributeOffset += attributeLength;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Reference in New Issue