SYNOPSIS
--------
Class verifier accepts an invalid class file
OPERATING SYSTEM
----------------
All
FULL JDK VERSION
----------------
Java 7
PROBLEM DESCRIPTION
-------------------
A class file is attached to this bug report, which is actually invalid. However, the HotSpot VM class verifier does not detect the problem, and loads the class.
The class is invalid because the StackMap for bytecode index 45 is incorrect. The stack maps for bytecode indexes 45 and 49 are incompatible because 45 doesn't supply enough locals to satisfy 49:
frame_type = 255 /* full_frame */
offset_delta = 2 // bytecode index = 45
locals = [ class java/lang/Object, class java/lang/Object ]
stack = [ class java/lang/Exception ]
frame_type = 255 /* full_frame */
offset_delta = 3 // bytecode index = 49
locals = [ class java/lang/Object, class java/lang/Object, class java/lang/Object ]
stack = [ class java/lang/Throwable ]
Bytecode index 45 represents an exception handler that is only reachable if an exception occurs between index 37 and 42. The StackMap for bytecode index 37 is:
frame_type = 255 /* full_frame */
offset_delta = 1 // bytecode index = 37
locals = [ class java/lang/Object, class java/lang/Object, class java/lang/Object ]
stack = []
If an exception occurs at bytecode index 37, 3 locals will be provided to index 45. Bytecode index 45 is, in turn, protected by a handler at index 49. If an exception occurs during the execution of the bytecode at index 45, the stack must be compatible with index 49. This is not the case here because it doesn't provide enough locals.
The issue should be exposed by the strict class file checking feature in Java 7:
http://openjdk.java.net/projects/jdk7/features/#fa535991
One aspect of this feature is that correct StackMapTable attributes are mandatory for methods in Java 7. In earlier releases, the JVM is allowed to fallback to the old flow verification, so this isn't a problem on Java 6.
TESTCASE
--------
See attached file "BadMap.class".
REPRODUCTION INSTRUCTIONS
-------------------------
Simply run: java BadMap
Expected result:
A java.lang.VerifyError should be thrown, describing the problem.
Actual Result:
The class is loaded successfully.
WORKAROUND
----------
None