Commit 27ec203e authored by Remi Forax's avatar Remi Forax

Merge branch 'remapper-do-not-remap-constant-dynamic-and-handle-correctly' into 'master'

Remapper do not remap constant dynamic and handle correctly

Closes #317852

See merge request !203
parents 587e6821 a706a3b9
Pipeline #2799 failed with stage
in 1 minute and 53 seconds
...@@ -140,7 +140,7 @@ public class ClassRemapper extends ClassVisitor { ...@@ -140,7 +140,7 @@ public class ClassRemapper extends ClassVisitor {
remapper.mapFieldName(className, name, descriptor), remapper.mapFieldName(className, name, descriptor),
remapper.mapDesc(descriptor), remapper.mapDesc(descriptor),
remapper.mapSignature(signature, true), remapper.mapSignature(signature, true),
remapper.mapValue(value)); (value == null) ? null : remapper.mapValue(value));
return fieldVisitor == null ? null : createFieldRemapper(fieldVisitor); return fieldVisitor == null ? null : createFieldRemapper(fieldVisitor);
} }
......
...@@ -28,7 +28,9 @@ ...@@ -28,7 +28,9 @@
package org.objectweb.asm.commons; package org.objectweb.asm.commons;
import org.objectweb.asm.ConstantDynamic;
import org.objectweb.asm.Handle; import org.objectweb.asm.Handle;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type; import org.objectweb.asm.Type;
import org.objectweb.asm.signature.SignatureReader; import org.objectweb.asm.signature.SignatureReader;
import org.objectweb.asm.signature.SignatureVisitor; import org.objectweb.asm.signature.SignatureVisitor;
...@@ -144,9 +146,13 @@ public abstract class Remapper { ...@@ -144,9 +146,13 @@ public abstract class Remapper {
} }
/** /**
* Returns the given value, remapped with this remapper. * Returns the given value, remapped with this remapper. Possible values are {@link String},
* {@link Boolean}, {@link Byte}, {@link Short}, {@link Character}, {@link Integer}, {@link Long},
* {@link Double}, {@link Float}, {@link String}, {@link Type}, {@link Handle}, {@link
* ConstantDynamic} or arrays of primitive types .
* *
* @param value an object. Only {@link Type} and {@link Handle} values are remapped. * @param value an object. Only {@link Type}, {@link Handle} and {@link ConstantDynamic} values
* are remapped.
* @return the given value, remapped with this remapper. * @return the given value, remapped with this remapper.
*/ */
public Object mapValue(final Object value) { public Object mapValue(final Object value) {
...@@ -159,9 +165,25 @@ public abstract class Remapper { ...@@ -159,9 +165,25 @@ public abstract class Remapper {
handle.getTag(), handle.getTag(),
mapType(handle.getOwner()), mapType(handle.getOwner()),
mapMethodName(handle.getOwner(), handle.getName(), handle.getDesc()), mapMethodName(handle.getOwner(), handle.getName(), handle.getDesc()),
mapMethodDesc(handle.getDesc()), handle.getTag() <= Opcodes.H_PUTSTATIC
? mapDesc(handle.getDesc())
: mapMethodDesc(handle.getDesc()),
handle.isInterface()); handle.isInterface());
} }
if (value instanceof ConstantDynamic) {
ConstantDynamic constantDynamic = (ConstantDynamic) value;
Object[] bootstrapMethodArguments = constantDynamic.getBootstrapMethodArguments();
Object[] remappedBootstrapMethodArguments = new Object[bootstrapMethodArguments.length];
for (int i = 0; i < bootstrapMethodArguments.length; ++i) {
remappedBootstrapMethodArguments[i] = mapValue(bootstrapMethodArguments[i]);
}
String descriptor = constantDynamic.getDescriptor();
return new ConstantDynamic(
mapInvokeDynamicMethodName(constantDynamic.getName(), descriptor),
mapDesc(descriptor),
(Handle) mapValue(constantDynamic.getBootstrapMethod()),
remappedBootstrapMethodArguments);
}
return value; return value;
} }
...@@ -228,8 +250,8 @@ public abstract class Remapper { ...@@ -228,8 +250,8 @@ public abstract class Remapper {
} }
/** /**
* Maps an invokedynamic method name to its new name. The default implementation of this method * Maps an invokedynamic or a constant dynamic method name to its new name. The default
* returns the given name, unchanged. Subclasses can override. * implementation of this method returns the given name, unchanged. Subclasses can override.
* *
* @param name the name of the method. * @param name the name of the method.
* @param descriptor the descriptor of the method. * @param descriptor the descriptor of the method.
......
...@@ -37,9 +37,14 @@ import org.junit.jupiter.params.ParameterizedTest; ...@@ -37,9 +37,14 @@ import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource; import org.junit.jupiter.params.provider.MethodSource;
import org.objectweb.asm.ClassReader; import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassWriter; import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.ConstantDynamic;
import org.objectweb.asm.Handle;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes; import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
import org.objectweb.asm.test.AsmTest; import org.objectweb.asm.test.AsmTest;
import org.objectweb.asm.tree.ClassNode; import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.LdcInsnNode;
import org.objectweb.asm.util.CheckMethodAdapter; import org.objectweb.asm.util.CheckMethodAdapter;
/** /**
...@@ -67,7 +72,7 @@ public class ClassRemapperTest extends AsmTest { ...@@ -67,7 +72,7 @@ public class ClassRemapperTest extends AsmTest {
new Remapper() { new Remapper() {
@Override @Override
public String mapModuleName(String name) { public String mapModuleName(final String name) {
return "new." + name; return "new." + name;
} }
}); });
...@@ -78,6 +83,49 @@ public class ClassRemapperTest extends AsmTest { ...@@ -78,6 +83,49 @@ public class ClassRemapperTest extends AsmTest {
assertEquals("new.pkg.C", ((ModuleHashesAttribute) classNode.attrs.get(0)).modules.get(0)); assertEquals("new.pkg.C", ((ModuleHashesAttribute) classNode.attrs.get(0)).modules.get(0));
} }
@Test
public void testRenameConstantDynamic() {
ClassNode classNode = new ClassNode();
ClassRemapper classRemapper =
new ClassRemapper(
Opcodes.ASM7_EXPERIMENTAL,
classNode,
new Remapper() {
@Override
public String mapInvokeDynamicMethodName(final String name, final String descriptor) {
return "new." + name;
}
@Override
public String map(final String internalName) {
if (internalName.equals("java/lang/String")) {
return "java/lang/Integer";
}
return internalName;
}
}) {
/* inner class so it can access to the protected constructor */
};
classRemapper.visit(Opcodes.V11, Opcodes.ACC_PUBLIC, "C", null, "java/lang/Object", null);
MethodVisitor methodVisitor =
classRemapper.visitMethod(Opcodes.ACC_PUBLIC, "hello", "()V", null, null);
methodVisitor.visitCode();
methodVisitor.visitLdcInsn(
new ConstantDynamic(
"foo",
"Ljava/lang/String;",
new Handle(Opcodes.H_INVOKESTATIC, "BSMHost", "bsm", "()Ljava/lang/String;", false)));
methodVisitor.visitInsn(Opcodes.POP);
methodVisitor.visitMaxs(1, 1);
methodVisitor.visitEnd();
classRemapper.visitEnd();
ConstantDynamic constantDynamic =
(ConstantDynamic) ((LdcInsnNode) classNode.methods.get(0).instructions.get(0)).cst;
assertEquals("new.foo", constantDynamic.getName());
assertEquals("Ljava/lang/Integer;", constantDynamic.getDescriptor());
assertEquals("()Ljava/lang/Integer;", constantDynamic.getBootstrapMethod().getDesc());
}
/** Tests that classes transformed with a ClassRemapper can be loaded and instantiated. */ /** Tests that classes transformed with a ClassRemapper can be loaded and instantiated. */
@ParameterizedTest @ParameterizedTest
@MethodSource(ALL_CLASSES_AND_ALL_APIS) @MethodSource(ALL_CLASSES_AND_ALL_APIS)
...@@ -179,6 +227,27 @@ public class ClassRemapperTest extends AsmTest { ...@@ -179,6 +227,27 @@ public class ClassRemapperTest extends AsmTest {
public String map(final String typeName) { public String map(final String typeName) {
return typeName.equals(internalClassName) ? remappedInternalClassName : typeName; return typeName.equals(internalClassName) ? remappedInternalClassName : typeName;
} }
@Override
public Object mapValue(Object value) {
if (value instanceof String
|| value instanceof Boolean
|| value instanceof Byte
|| value instanceof Short
|| value instanceof Character
|| value instanceof Integer
|| value instanceof Long
|| value instanceof Double
|| value instanceof Float
|| value instanceof Type
|| value instanceof Handle
|| value instanceof ConstantDynamic
|| value.getClass().isArray()) {
return super.mapValue(value);
}
// If this fails, add support for the new type in Remapper.mapValue(), if needed.
throw new IllegalArgumentException("Unsupported type of value: " + value);
}
} }
private static void checkDescriptor(final String descriptor) { private static void checkDescriptor(final String descriptor) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment