Storyyeller / Krakatau

Java decompiler, assembler, and disassembler
GNU General Public License v3.0
1.95k stars 220 forks source link

String annotation values generate incorrect constant types #100

Closed toddATavail closed 7 years ago

toddATavail commented 7 years ago

According to the JVM Specification 4.7.16.1, the constant type of a String annotation value is CONSTANT_Utf8. When specifying a String annotation value in a Krakatau assembly file, however, the generated constant is CONSTANT_String_info.

Consider this pared down version of Q_First_Name.j, one of the generated Krakatau files produced by my compiler:

.version 52 0
.class final public com/mcp/hammurabi/generated/basic_intake/Q_First_Name
    .super com/mcp/hammurabi/StringIntakeStep
    .runtime visible annotations
        .annotation Lcom/mcp/hammurabi/annotations/SubjectMatterExpert;
                abbreviation = string "TLS"
                email = string "todd@example.com"
                name = string "Todd L Smith"
        .end annotation
        .annotation Lcom/mcp/hammurabi/annotations/Classification;
                value = array
                    string "Basic Intake"
                .end array
        .end annotation
    .end runtime
.end class

Here are the relevant excerpts from the generated class file, as reported by javap -c -verbose:

RuntimeVisibleAnnotations:
  0: #55(#56=s#57,#58=s#59,#47=s#60)
  1: #61(#62=[s#63])
   #47 = Utf8               name
   …
   #55 = Utf8               Lcom/mcp/hammurabi/annotations/SubjectMatterExpert;
   #56 = Utf8               abbreviation
   #57 = String             #67           // TLS
   #58 = Utf8               email
   #59 = String             #66           // todd@example.com
   #60 = String             #65           // Todd L Smith
   #61 = Utf8               Lcom/mcp/hammurabi/annotations/Classification;
   #62 = Utf8               value
   #63 = String             #64           // Basic Intake

The constant pool data should instead look like this:

   #47 = Utf8               name
   …
   #55 = Utf8               Lcom/mcp/hammurabi/annotations/SubjectMatterExpert;
   #56 = Utf8               abbreviation
   #57 = Utf8               TLS
   #58 = Utf8               email
   #59 = Utf8               todd@example.com
   #60 = Utf8               Todd L Smith
   #61 = Utf8               Lcom/mcp/hammurabi/annotations/Classification;
   #62 = Utf8               value
   #63 = Utf8               Basic Intake

ASM and the Oracle JVM both treat the generated class file as corrupt. In particular, I cannot getAnnotations() on the generated classes because of the following exception:

java.lang.IllegalArgumentException: Wrong type at constant pool index

My compiler went into production last month, and we are working toward the next version of the software. Our next milestone release is November 16. I'm not trying to pressure anyone into giving my issue priority, but I do need to assess whether I should sit tight and wait for a patch or dive into Krakatau and try to patch it myself.

Thanks!

Storyyeller commented 7 years ago

You can do this instead name = string Utf8 "Todd L Smith"

So technically, there is no bug, it's just that the assembler format encourages you to shoot yourself in the foot here. I'm not sure whether it should be changed and how. Anyway, thanks for reporting this,

Storyyeller commented 7 years ago

I changed it to avoid confusion. It's technically backwards incompatible, but I doubt anyone will care.