8320360: ClassFile.parse: Some defect class files cause unexpected exceptions to be thrown

Reviewed-by: jpai
This commit is contained in:
Adam Sotona 2024-01-02 12:58:53 +00:00
parent f9aec02f3c
commit a5cf4210cd
2 changed files with 71 additions and 24 deletions
src/java.base/share/classes/jdk/internal/classfile/impl
test/jdk/jdk/classfile

@ -1,5 +1,5 @@
/*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2022, 2024, 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
@ -189,45 +189,73 @@ public final class ClassReaderImpl
return bsmEntries().get(index);
}
private static IllegalArgumentException outOfBoundsError(IndexOutOfBoundsException cause) {
return new IllegalArgumentException("Reading beyond classfile bounds", cause);
}
@Override
public int readU1(int p) {
return buffer[p] & 0xFF;
try {
return buffer[p] & 0xFF;
} catch (IndexOutOfBoundsException e) {
throw outOfBoundsError(e);
}
}
@Override
public int readU2(int p) {
int b1 = buffer[p] & 0xFF;
int b2 = buffer[p + 1] & 0xFF;
return (b1 << 8) + b2;
try {
int b1 = buffer[p] & 0xFF;
int b2 = buffer[p + 1] & 0xFF;
return (b1 << 8) + b2;
} catch (IndexOutOfBoundsException e) {
throw outOfBoundsError(e);
}
}
@Override
public int readS1(int p) {
return buffer[p];
try {
return buffer[p];
} catch (IndexOutOfBoundsException e) {
throw outOfBoundsError(e);
}
}
@Override
public int readS2(int p) {
int b1 = buffer[p];
int b2 = buffer[p + 1] & 0xFF;
return (b1 << 8) + b2;
try {
int b1 = buffer[p];
int b2 = buffer[p + 1] & 0xFF;
return (b1 << 8) + b2;
} catch (IndexOutOfBoundsException e) {
throw outOfBoundsError(e);
}
}
@Override
public int readInt(int p) {
int ch1 = buffer[p] & 0xFF;
int ch2 = buffer[p + 1] & 0xFF;
int ch3 = buffer[p + 2] & 0xFF;
int ch4 = buffer[p + 3] & 0xFF;
return (ch1 << 24) + (ch2 << 16) + (ch3 << 8) + ch4;
try {
int ch1 = buffer[p] & 0xFF;
int ch2 = buffer[p + 1] & 0xFF;
int ch3 = buffer[p + 2] & 0xFF;
int ch4 = buffer[p + 3] & 0xFF;
return (ch1 << 24) + (ch2 << 16) + (ch3 << 8) + ch4;
} catch (IndexOutOfBoundsException e) {
throw outOfBoundsError(e);
}
}
@Override
public long readLong(int p) {
return ((long) buffer[p + 0] << 56) + ((long) (buffer[p + 1] & 255) << 48) +
((long) (buffer[p + 2] & 255) << 40) + ((long) (buffer[p + 3] & 255) << 32) +
((long) (buffer[p + 4] & 255) << 24) + ((buffer[p + 5] & 255) << 16) + ((buffer[p + 6] & 255) << 8) +
(buffer[p + 7] & 255);
try {
return ((long) buffer[p + 0] << 56) + ((long) (buffer[p + 1] & 255) << 48) +
((long) (buffer[p + 2] & 255) << 40) + ((long) (buffer[p + 3] & 255) << 32) +
((long) (buffer[p + 4] & 255) << 24) + ((buffer[p + 5] & 255) << 16) + ((buffer[p + 6] & 255) << 8) +
(buffer[p + 7] & 255);
} catch (IndexOutOfBoundsException e) {
throw outOfBoundsError(e);
}
}
@Override
@ -242,12 +270,20 @@ public final class ClassReaderImpl
@Override
public byte[] readBytes(int p, int len) {
return Arrays.copyOfRange(buffer, p, p + len);
try {
return Arrays.copyOfRange(buffer, p, p + len);
} catch (IndexOutOfBoundsException e) {
throw outOfBoundsError(e);
}
}
@Override
public void copyBytesTo(BufWriter buf, int p, int len) {
buf.writeBytes(buffer, p, len);
try {
buf.writeBytes(buffer, p, len);
} catch (IndexOutOfBoundsException e) {
throw outOfBoundsError(e);
}
}
BootstrapMethodsAttribute bootstrapMethodsAttribute() {
@ -446,8 +482,12 @@ public final class ClassReaderImpl
int bufWriterOffset,
int classReaderOffset,
int length) {
return Arrays.equals(((BufWriterImpl) bufWriter).elems,
bufWriterOffset, bufWriterOffset + length,
buffer, classReaderOffset, classReaderOffset + length);
try {
return Arrays.equals(((BufWriterImpl) bufWriter).elems,
bufWriterOffset, bufWriterOffset + length,
buffer, classReaderOffset, classReaderOffset + length);
} catch (IndexOutOfBoundsException e) {
throw outOfBoundsError(e);
}
}
}

@ -1,5 +1,5 @@
/*
* Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2022, 2024, 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
@ -23,6 +23,7 @@
/*
* @test
* @bug 8320360
* @summary Testing ClassFile limits.
* @run junit LimitsTest
*/
@ -85,4 +86,10 @@ class LimitsTest {
var cf = ClassFile.of();
assertThrows(IllegalArgumentException.class, () -> cf.parse(cf.build(ClassDesc.of("ClassFromFuture"), cb -> cb.withVersion(ClassFile.latestMajorVersion() + 1, 0))));
}
@Test
void testReadingOutOfBounds() {
assertThrows(IllegalArgumentException.class, () -> ClassFile.of().parse(new byte[]{(byte)0xCA, (byte)0xFE, (byte)0xBA, (byte)0xBE}), "reading magic only");
assertThrows(IllegalArgumentException.class, () -> ClassFile.of().parse(new byte[]{(byte)0xCA, (byte)0xFE, (byte)0xBA, (byte)0xBE, 0, 0, 0, 0, 0, 2}), "reading invalid CP size");
}
}