Skip to content

Demonstration of a bug related to the Java type system

Notifications You must be signed in to change notification settings

eaftan/boolean-wat

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

7 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

A boolean that is neither true nor false

Consider this class:

public class B {
  public static void main(String[] args) {
    if (A.A != true && A.A != false) {
      System.out.println("Wat");
    }
  }
}

Is it possible for this program to print "Wat"? If I'm asking this, you already know the answer.

Instructions

Clone this repository and run make (you must have a JVM installed). Then run the following command:

java -cp classes B

Why does it work?

In the JVM spec for class files, boolean constants are represented as integers. Javac always uses 1 for true and 0 for false, but it is legal to have a class file that contains a public static final boolean with a value other than 0 or 1.

If a Java compiler encounters such a constant in a class file, the behavior is undefined.

This trick works because the demo uses ASM to edit the value of the constant field A.A to 2, then compiles B against the edited version. The value of A.A is neither true (1) nor false (0), so the print statement is executed.

What does it mean?

So, is this just a bug in javac, or a real problem with the Java or JVM spec? It's unclear. We asked upstream for clarification, and they gave us this cryptic response:

In Lib.class, the field B contains a ConstantValue attribute that is not ill-formed, since the attribute points to a CONSTANT_Integer c.p. entry that is appropriate for a Z-typed field. A class file reader such as javac must not reject Lib.class on this basis. However, javac should handle an out-of-band value in the CONSTANT_Integer c.p. entry as a quality-of-implementation detail.

We ended up submitting a javac patch for this that issues an error on class files that contain such an out-of-range constant value, which was accepted. Thus, this demo does not work with Java 9.

My take is that this is a problem as it is unspecified what an implementation should do in this case. The spec either should state that such class files are invalid, or it should specify how to interpret such out-of-range constant values.

About

Demonstration of a bug related to the Java type system

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published