Will you look at that. BCEL's verifier actually checks for this
(Pass3aVerifier.java):

public void visitLDC(final LDC ldc) {
    indexValid(ldc, ldc.getIndex());
    final Constant c = constantPoolGen.getConstant(ldc.getIndex());
    if (c instanceof ConstantClass) {
      addMessage("Operand of LDC or LDC_W is CONSTANT_Class '"+c+"' -
this is only supported in JDK 1.5 and higher.");
    }
    else{
      if (! ( c instanceof ConstantInteger    ||
              c instanceof ConstantFloat         ||
        c instanceof ConstantString ) ) {
    constraintViolated(ldc,
        "Operand of LDC or LDC_W must be one of CONSTANT_Integer,
CONSTANT_Float or CONSTANT_String, but is '"+c+"'.");
      }
    }
}

It generates just a warning though, not an actual error.

I quickly checked out LDC.java to see if I can submit a PR, but I think I
don't know enough about BCEL to actually do it. I'll leave it to the
experts.

Greetings

On Fri, 4 Feb 2022 at 15:37, Stefan Reich <
stefan.reich.maker.of....@googlemail.com> wrote:

> Update: They changed it in Java 5. ClassGen.setMajor(49) +
> ClassGen.setMinor(0) works.
>
> On Fri, 4 Feb 2022 at 15:26, Stefan Reich <
> stefan.reich.maker.of....@googlemail.com> wrote:
>
>> Mystery solved, ladies and gentlemen...
>>
>> It was...
>>
>> the byte code version. BCEL outputs version 45.3 by default (JDK 1.1).
>> There were multiple changes to the class file format spec since then.
>>
>> Specifically, they must have allowed ldc to load .class objects directly
>> at some point after JDK 1.1. In fact, I distinctly remember the
>> Class.forName shenanigans that javac produced back then instead of the
>> direct ldc.
>>
>> Apparently the Java verifier is so strict it judges the class file
>> according to its version number and disallows the new version of ldc in a
>> class file written for JDK 1.1.
>>
>> BCEL doesn't check for this though and outputs a broken class file.
>> Changing this might be a good idea.
>>
>> Unfortunately I couldn't find documentation on when the byte code spec
>> change happened. Does anyone know?
>>
>> Neither did I find anything in the HotSpot verifier sources
>> <https://github.com/openjdk/jdk/blob/master/src/hotspot/share/classfile/verifier.cpp>
>> which is odd to me. No mention of a JDK version there. Only in
>> clasfileparser.cpp
>> <https://github.com/openjdk/jdk/blob/master/src/hotspot/share/classfile/classFileParser.cpp>
>> but didn't find the issue in question there either. I'm by no means an
>> expert in the JDK C++ source though.
>>
>> Cheers
>> Stefan
>>
>> On Thu, 3 Feb 2022 at 08:32, Romain Manni-Bucau <rmannibu...@gmail.com>
>> wrote:
>>
>>> Hi,
>>>
>>> Maybe a bit ot of topic but did you check with asm (using classreader for
>>> ex) if it is readable for it? Javap in verbose mode is hard to read
>>> humanly
>>> (and not verbosel does not mean much) so an issue can still be hidden.
>>>
>>> Romain Manni-Bucau
>>> @rmannibucau <https://twitter.com/rmannibucau> |  Blog
>>> <https://rmannibucau.metawerx.net/> | Old Blog
>>> <http://rmannibucau.wordpress.com> | Github <
>>> https://github.com/rmannibucau> |
>>> LinkedIn <https://www.linkedin.com/in/rmannibucau> | Book
>>> <
>>> https://www.packtpub.com/application-development/java-ee-8-high-performance
>>> >
>>>
>>>
>>> Le jeu. 3 févr. 2022 à 01:42, Stefan Reich
>>> <stefan.reich.maker.of....@googlemail.com.invalid> a écrit :
>>>
>>> > I'm mainly curious how it's possible that everything looks completely
>>> > normal in javap (checked a dozen times), but the class verifier
>>> complains
>>> > anyway? Something has to be different. Is there a way to dig deeper
>>> into a
>>> > class file?
>>> >
>>> > Greetings
>>> >
>>> > On Wed, 2 Feb 2022 at 23:14, Stefan Reich <
>>> > stefan.reich.maker.of....@googlemail.com> wrote:
>>> >
>>> > > Hmm, no change with latest version.
>>> > >
>>> > > I did "git clone https://github.com/apache/commons-bcel.git"; and
>>> "mvn
>>> > > package".
>>> > >
>>> > > stefan@lenovo-ThinkPad-X220:~/dev/classreftest$ javac -cp
>>> > > bcel-6.6.0-SNAPSHOT.jar MakeBadClassFile.java
>>> > > stefan@lenovo-ThinkPad-X220:~/dev/classreftest$ java -cp
>>> > > bcel-6.6.0-SNAPSHOT.jar:. MakeBadClassFile
>>> > > Now please try: java BadClassFile
>>> > > stefan@lenovo-ThinkPad-X220:~/dev/classreftest$ java BadClassFile
>>> > > Error: Unable to initialize main class BadClassFile
>>> > > Caused by: java.lang.VerifyError: (class: BadClassFile, method: main
>>> > > signature: ([Ljava/lang/String;)V) Illegal type in constant pool
>>> > > stefan@lenovo-ThinkPad-X220:~/dev/classreftest$
>>> > >
>>> > > On Wed, 2 Feb 2022 at 22:59, Gary Gregory <garydgreg...@gmail.com>
>>> > wrote:
>>> > >
>>> > >> You should try the latest from git master.
>>> > >>
>>> > >> Gary
>>> > >>
>>> > >> On Wed, Feb 2, 2022, 15:41 Stefan Reich
>>> > >> <stefan.reich.maker.of....@googlemail.com.invalid> wrote:
>>> > >>
>>> > >> > Hi again,
>>> > >> >
>>> > >> > actual problem this time...
>>> > >> >
>>> > >> > I think I am doing everything right... Decompilation in javap -v
>>> looks
>>> > >> > just like it should. But I get a VerifyError... I'm using JDK 17.
>>> Full
>>> > >> > program attached. Please advice, thank you :)
>>> > >> >
>>> > >> > # javac -cp bcel-6.5.0.jar MakeBadClassFile.java
>>> > >> > # java -cp bcel-6.5.0.jar:. MakeBadClassFile
>>> > >> > # java BadClassFile
>>> > >> > Error: Unable to initialize main class BadClassFile
>>> > >> > Caused by: java.lang.VerifyError: (class: BadClassFile, method:
>>> main
>>> > >> > signature: ([Ljava/lang/String;)V) Illegal type in constant pool
>>> > >> >
>>> > >> >
>>> > >> >
>>> ---------------------------------------------------------------------
>>> > >> > To unsubscribe, e-mail: dev-unsubscr...@commons.apache.org
>>> > >> > For additional commands, e-mail: dev-h...@commons.apache.org
>>> > >>
>>> > >
>>> > >
>>> >
>>
>>
>

Reply via email to