Skip to content

Commit

Permalink
Merge pull request #339 from Ladicek/field-primitive-signature
Browse files Browse the repository at this point in the history
allow primitive type signatures on fields
  • Loading branch information
Ladicek authored Nov 27, 2023
2 parents 468cd08 + 34833d6 commit b5618fe
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -286,7 +286,14 @@ Type parseFieldSignature(String signature) {
this.typeParameters = this.elementTypeParameters;
this.pos = 0;

return parseReferenceType();
// the grammar in the JVMS says:
//
// FieldSignature:
// ReferenceTypeSignature
//
// however, there are class files in the wild that contain
// a primitive type signature as a field signature
return parseJavaType();
}

MethodSignature parseMethodSignature(String signature) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package org.jboss.jandex.test;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;

import java.io.IOException;

import org.jboss.jandex.ClassInfo;
import org.jboss.jandex.FieldInfo;
import org.jboss.jandex.Index;
import org.jboss.jandex.PrimitiveType;
import org.junit.jupiter.api.Test;

import net.bytebuddy.ByteBuddy;
import net.bytebuddy.asm.AsmVisitorWrapper;
import net.bytebuddy.description.field.FieldDescription;
import net.bytebuddy.description.field.FieldList;
import net.bytebuddy.description.method.MethodList;
import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.implementation.Implementation;
import net.bytebuddy.jar.asm.ClassVisitor;
import net.bytebuddy.jar.asm.FieldVisitor;
import net.bytebuddy.pool.TypePool;
import net.bytebuddy.utility.OpenedClassReader;

public class FieldWithPrimitiveTypeSignatureTest {
private static final String TEST_CLASS = "org.jboss.jandex.test.TestClass";

// the Oracle JDBC driver in version 23.3.0.23.09 contains a class with a field
// whose generic signature encodes a primitive type, which is invalid per JVMS

@Test
public void test() throws IOException {
byte[] bytecode = new ByteBuddy()
.subclass(Object.class)
.name(TEST_CLASS)
.defineField("foo", boolean.class)
.visit(new AsmVisitorWrapper.AbstractBase() {
@Override
public ClassVisitor wrap(TypeDescription instrumentedType, ClassVisitor classVisitor,
Implementation.Context implementationContext, TypePool typePool,
FieldList<FieldDescription.InDefinedShape> fields, MethodList<?> methods,
int writerFlags, int readerFlags) {
return new ClassVisitor(OpenedClassReader.ASM_API, classVisitor) {
@Override
public FieldVisitor visitField(int access, String name, String descriptor, String signature,
Object value) {
if ("foo".equals(name)) {
signature = "Z"; // boolean
}
return super.visitField(access, name, descriptor, signature, value);
}
};
}
})
.make()
.getBytes();
ClassInfo clazz = Index.singleClass(bytecode);

assertEquals(1, clazz.fields().size());
FieldInfo field = clazz.field("foo");
assertNotNull(field);
assertEquals(PrimitiveType.BOOLEAN, field.type());
}
}

0 comments on commit b5618fe

Please sign in to comment.