Incorrect hehavior on the class name (UTF8) in the constant pool of bytecode
Cheng Jin
jincheng at ca.ibm.com
Fri Oct 29 00:25:34 UTC 2021
One or more of the following files ( dumped.class ) violates IBM policy and all attachment(s) have been removed from the message.
**********************************************************************
Hi There,
I created a simple test that loads a class file as follows to see whether a
package name in the constant pool is rejected as invalid for a class name.
However, it surprised me that it just passed without any exception on
Hotspot (e.g. OpenJDK11).
(See attached file: dumped.class)
constant_pool (in dumped.class)
...
3. Utf8
tag: 1
length: 16
bytes: die/verwandlung/ <----- a package name rather than an valid class
name
4. Class
tag: 7
name_index: 3 <------
import java.io.*;
public class CustomClassLoader extends ClassLoader {
@Override
public Class findClass(String fileName) throws ClassNotFoundException {
byte[] b = loadClassBytes(fileName);
return defineClass(null, b, 0, b.length);
}
private byte[] loadClassBytes(String fileName) {
InputStream inputStream =
getClass().getClassLoader().getResourceAsStream(fileName + ".class");
ByteArrayOutputStream byteOutStream = new ByteArrayOutputStream();
try {
int nextByte = 0;
while ((nextByte = inputStream.read()) != -1) {
byteOutStream.write(nextByte);
}
} catch (IOException e) {
e.printStackTrace();
}
return byteOutStream.toByteArray();
}
public static void main(String args[]) {
try {
CustomClassLoader cl = new CustomClassLoader();
cl.findClass("dumped");
System.out.println("DONE.....");
} catch (Exception e) {
e.printStackTrace();
}
}
}
$ jdk11_hotspot/bin/java CustomClassLoader
DONE.....
According to the VM Spec at 4.2.1 Binary Class and Interface Names
Class and interface names that appear in class file structures are always
represented in a fully qualified form known as binary names (JLS §13.1).
...In this internal form, the ASCII periods (.) that normally separate the
identifiers which
make up the binary name are replaced by ASCII forward slashes (/). The
identifiers
themselves must be unqualified names (§4.2.2).
For example, the normal binary name of class Thread is java.lang.Thread. In
the
internal form used in descriptors in the class file format, a reference to
the name of class
Thread is implemented using a CONSTANT_Utf8_info structure representing the
string
java/lang/Thread.
It means a valid class name should be something like "xxx" or
"xxx/yyy/zzz" (where "/" only serves as the separator in between, and "/"
shouldn't occur at the end),
in which case "xxx/yyy/" is treated as invalid for a class name.
So I am wondering why Hotspot doesn't follow the VM Spec to check the
invalid package name in the constant pool.
Thanks and Best Regards
Cheng Jin
More information about the hotspot-dev
mailing list