-
Enhancement
-
Resolution: Won't Fix
-
P3
-
None
-
22
The methods of the class ClassFile: ClassModel parse(byte[] bytes) and ClassModel parse(Path path) throws IOException
state that they throw IllegalArgumentException if the classfile format is unsupported or invalid.
The spec doesn’t clarify which format is interpreted as invalid/unsupported.
It’s necessary to define how strict the class file parser is and which structures could be parsed and altered if needed.
For example, if take a look at API MethodHandles.Lookup.defineHiddenClass(byte[] bytes, boolean initialize, MethodHandles.Lookup.ClassOption... options) throws IllegalAccessException
The specification states that the method throws ClassCircularityError - if any of the superclasses or superinterfaces of C is C itself)
But the file below is correct for ClassFile API although it’s negative for MethodHandles.Lookup.defineHiddenClass:
public super class #7 /* EmptyBad01 */ version 66:0
{
const #1 = Method #2.#3; // java/lang/Object."<init>":"()V"
const #2 = class #4; // java/lang/Object
const #3 = NameAndType #5:#6; // "<init>":"()V"
const #4 = Utf8 "java/lang/Object";
const #5 = Utf8 "<init>";
const #6 = Utf8 "()V";
const #7 = class #8; // EmptyBad01
const #8 = Utf8 "javasoft/sqe/tests/api/java/lang/classfile/resources/EmptyBad01";
const #9 = Utf8 "Code";
super_class #7; // Circular reference: EmptyBad01
Also the class file:
public interface IEmptyBad01 version 1:0 {}
is parsed without exceptions. Although something like *) is expected.
*)UnsupportedClassVersionError - if bytes is not of a supported major or minor version
Next example - corrupted class file that has constant_pool_count == 5 (instead of 7) causes java.lang.ArrayIndexOutOfBoundsException: Index 58676 out of bounds for length 156
Instead of the expected exception: IllegalArgumentException
public interface IEmptyBad00 {
}
:
class javasoft/sqe/tests/api/java/lang/classfile/resources/IEmptyBad00 {
0xCAFEBABE;
0; // minor version
58; // version
[5] { // Constant Pool // 5 is bad number instead of: 7
; // first element is empty
class #2; // #1 at 0x0A
Utf8 "javasoft/sqe/tests/api/java/lang/classfile/resources/IEmptyBad00"; // #2 at 0x0D
class #4; // #3 at 0x4B
Utf8 "java/lang/Object"; // #4 at 0x4E
Utf8 "SourceFile"; // #5 at 0x61
Utf8 "IEmptyBad00.java"; // #6 at 0x6E
} // end of Constant Pool
…
}
state that they throw IllegalArgumentException if the classfile format is unsupported or invalid.
The spec doesn’t clarify which format is interpreted as invalid/unsupported.
It’s necessary to define how strict the class file parser is and which structures could be parsed and altered if needed.
For example, if take a look at API MethodHandles.Lookup.defineHiddenClass(byte[] bytes, boolean initialize, MethodHandles.Lookup.ClassOption... options) throws IllegalAccessException
The specification states that the method throws ClassCircularityError - if any of the superclasses or superinterfaces of C is C itself)
But the file below is correct for ClassFile API although it’s negative for MethodHandles.Lookup.defineHiddenClass:
public super class #7 /* EmptyBad01 */ version 66:0
{
const #1 = Method #2.#3; // java/lang/Object."<init>":"()V"
const #2 = class #4; // java/lang/Object
const #3 = NameAndType #5:#6; // "<init>":"()V"
const #4 = Utf8 "java/lang/Object";
const #5 = Utf8 "<init>";
const #6 = Utf8 "()V";
const #7 = class #8; // EmptyBad01
const #8 = Utf8 "javasoft/sqe/tests/api/java/lang/classfile/resources/EmptyBad01";
const #9 = Utf8 "Code";
super_class #7; // Circular reference: EmptyBad01
Also the class file:
public interface IEmptyBad01 version 1:0 {}
is parsed without exceptions. Although something like *) is expected.
*)UnsupportedClassVersionError - if bytes is not of a supported major or minor version
Next example - corrupted class file that has constant_pool_count == 5 (instead of 7) causes java.lang.ArrayIndexOutOfBoundsException: Index 58676 out of bounds for length 156
Instead of the expected exception: IllegalArgumentException
public interface IEmptyBad00 {
}
:
class javasoft/sqe/tests/api/java/lang/classfile/resources/IEmptyBad00 {
0xCAFEBABE;
0; // minor version
58; // version
[5] { // Constant Pool // 5 is bad number instead of: 7
; // first element is empty
class #2; // #1 at 0x0A
Utf8 "javasoft/sqe/tests/api/java/lang/classfile/resources/IEmptyBad00"; // #2 at 0x0D
class #4; // #3 at 0x4B
Utf8 "java/lang/Object"; // #4 at 0x4E
Utf8 "SourceFile"; // #5 at 0x61
Utf8 "IEmptyBad00.java"; // #6 at 0x6E
} // end of Constant Pool
…
}