From 2a6731251b543e3310cb422b760830796f26ff65 Mon Sep 17 00:00:00 2001 From: Eric Bruneton Date: Sat, 16 Jun 2018 15:32:53 +0200 Subject: [PATCH] Add failing test showing the issue. --- .../org/objectweb/asm/ClassVisitorTest.java | 59 +++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/asm/src/test/java/org/objectweb/asm/ClassVisitorTest.java b/asm/src/test/java/org/objectweb/asm/ClassVisitorTest.java index 03db5fac..fcb6dfb1 100644 --- a/asm/src/test/java/org/objectweb/asm/ClassVisitorTest.java +++ b/asm/src/test/java/org/objectweb/asm/ClassVisitorTest.java @@ -29,6 +29,10 @@ package org.objectweb.asm; import static org.junit.jupiter.api.Assertions.assertThrows; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.CsvSource; @@ -157,6 +161,34 @@ public class ClassVisitorTest extends AsmTest { assertThatClass(copyPoolClassWriter.toByteArray()).isEqualTo(classWriter.toByteArray()); } + /** + * Tests that a ClassReader -> class adapter -> ClassWriter chain give the same result when the + * descriptor of a method is changed. + */ + @Test + public void testReadAndWriteWithCopyPoolAndChangeDescriptor() { + ClassWriter sourceClassWriter = new ClassWriter(ClassWriter.COMPUTE_MAXS); + sourceClassWriter.visit( + Opcodes.V1_7, Opcodes.ACC_ABSTRACT, "C", null, "java/lang/Object", null); + MethodVisitor methodVisitor = + sourceClassWriter.visitMethod(Opcodes.ACC_PUBLIC, "", "()V", null, null); + methodVisitor.visitCode(); + methodVisitor.visitVarInsn(Opcodes.ALOAD, 0); + methodVisitor.visitMethodInsn( + Opcodes.INVOKESPECIAL, "java/lang/Object", "", "()V", false); + methodVisitor.visitInsn(Opcodes.RETURN); + methodVisitor.visitMaxs(0, 0); + methodVisitor.visitEnd(); + sourceClassWriter.visitEnd(); + + ClassReader classReader = new ClassReader(sourceClassWriter.toByteArray()); + ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_MAXS); + ClassWriter copyPoolClassWriter = new ClassWriter(classReader, ClassWriter.COMPUTE_MAXS); + classReader.accept(new AddParameterAdapter(classWriter), 0); + classReader.accept(new AddParameterAdapter(copyPoolClassWriter), 0); + assertThatClass(copyPoolClassWriter.toByteArray()).isEqualTo(classWriter.toByteArray()); + } + /** Test that classes with only visible or only invisible annotations can be read correctly. */ @ParameterizedTest @ValueSource(strings = {"true", "false"}) @@ -535,4 +567,31 @@ public class ClassVisitorTest extends AsmTest { }; } } + + /** A class visitor which adds a parameter to the declared method descriptors. */ + private static class AddParameterAdapter extends ClassVisitor { + + public AddParameterAdapter(final ClassVisitor classVisitor) { + super(Opcodes.ASM7_EXPERIMENTAL, classVisitor); + } + + @Override + public MethodVisitor visitMethod( + final int access, + final String name, + final String descriptor, + final String signature, + final String[] exceptions) { + List argumentTypes = new ArrayList<>(Arrays.asList(Type.getArgumentTypes(descriptor))); + argumentTypes.add(Type.INT_TYPE); + Type returnType = Type.getReturnType(descriptor); + return super.visitMethod( + access, + name, + Type.getMethodDescriptor( + returnType, argumentTypes.toArray(new Type[argumentTypes.size()])), + signature, + exceptions); + } + } } -- GitLab