From 22075222e758ee69f9f9cf69291ff83f5924f7fb Mon Sep 17 00:00:00 2001 From: ximsfei <550616352@qq.com> Date: Tue, 8 Oct 2019 22:28:05 +0800 Subject: [PATCH] fixes a bug of ClassFile#renameClass(), some imports could not be successfully renamed --- .../bytecode/AnnotationDefaultAttribute.java | 22 ++++++++++++ .../javassist/bytecode/AttributeInfo.java | 2 +- .../bytecode/SignatureAttribute.java | 34 +++++++++---------- .../bytecode/annotation/ArrayMemberValue.java | 25 ++++++++++++++ .../bytecode/annotation/ClassMemberValue.java | 15 ++++++++ .../bytecode/annotation/EnumMemberValue.java | 15 ++++++++ .../bytecode/annotation/MemberValue.java | 9 +++++ 7 files changed, 104 insertions(+), 18 deletions(-) diff --git a/src/main/javassist/bytecode/AnnotationDefaultAttribute.java b/src/main/javassist/bytecode/AnnotationDefaultAttribute.java index 43021ecf..8c7084c0 100644 --- a/src/main/javassist/bytecode/AnnotationDefaultAttribute.java +++ b/src/main/javassist/bytecode/AnnotationDefaultAttribute.java @@ -117,6 +117,28 @@ public class AnnotationDefaultAttribute extends AttributeInfo { } } + @Override + void renameClass(String oldname, String newname) { + try { + MemberValue defaultValue = getDefaultValue(); + defaultValue.renameClass(oldname, newname); + setDefaultValue(defaultValue); + } catch (Exception e) { + // ignore + } + } + + @Override + void renameClass(Map classnames) { + try { + MemberValue defaultValue = getDefaultValue(); + defaultValue.renameClass(classnames); + setDefaultValue(defaultValue); + } catch (Exception e) { + // ignore + } + } + /** * Obtains the default value represented by this attribute. */ diff --git a/src/main/javassist/bytecode/AttributeInfo.java b/src/main/javassist/bytecode/AttributeInfo.java index be6e2a21..3aa0bd31 100644 --- a/src/main/javassist/bytecode/AttributeInfo.java +++ b/src/main/javassist/bytecode/AttributeInfo.java @@ -254,7 +254,7 @@ public class AttributeInfo { /* The following two methods are used to implement * ClassFile.renameClass(). * Only CodeAttribute, LocalVariableAttribute, - * AnnotationsAttribute, and SignatureAttribute + * AnnotationDefaultAttribute, AnnotationsAttribute, and SignatureAttribute * override these methods. */ void renameClass(String oldname, String newname) {} diff --git a/src/main/javassist/bytecode/SignatureAttribute.java b/src/main/javassist/bytecode/SignatureAttribute.java index 1a8a62dc..6a483057 100644 --- a/src/main/javassist/bytecode/SignatureAttribute.java +++ b/src/main/javassist/bytecode/SignatureAttribute.java @@ -121,29 +121,29 @@ public class SignatureAttribute extends AttributeInfo { if (j < 0) break; - StringBuilder nameBuf = new StringBuilder(); - int k = j; - char c; - try { - while ((c = desc.charAt(++k)) != ';') { - nameBuf.append(c); - if (c == '<') { - while ((c = desc.charAt(++k)) != '>') - nameBuf.append(c); - - nameBuf.append(c); - } - } + int k = desc.indexOf(';', j); + if (k < 0) + break; + + int l = desc.indexOf('<', j); + int classEndIndex; + char classEndChar; + if (l < 0 || k < l) { + classEndIndex = k; + classEndChar = ';'; + } else { + classEndIndex = l; + classEndChar = '<'; } - catch (IndexOutOfBoundsException e) { break; } - i = k + 1; - String name = nameBuf.toString(); + i = classEndIndex + 1; + + String name = desc.substring(j + 1, classEndIndex); String name2 = map.get(name); if (name2 != null) { newdesc.append(desc.substring(head, j)); newdesc.append('L'); newdesc.append(name2); - newdesc.append(c); + newdesc.append(classEndChar); head = i; } } diff --git a/src/main/javassist/bytecode/annotation/ArrayMemberValue.java b/src/main/javassist/bytecode/annotation/ArrayMemberValue.java index d1eeb271..f6bc6150 100644 --- a/src/main/javassist/bytecode/annotation/ArrayMemberValue.java +++ b/src/main/javassist/bytecode/annotation/ArrayMemberValue.java @@ -18,6 +18,7 @@ package javassist.bytecode.annotation; import java.io.IOException; import java.lang.reflect.Array; import java.lang.reflect.Method; +import java.util.Map; import javassist.ClassPool; import javassist.bytecode.ConstPool; @@ -87,6 +88,30 @@ public class ArrayMemberValue extends MemberValue { return a.getClass(); } + @Override + public void renameClass(String oldname, String newname) { + if (type != null) { + type.renameClass(oldname, newname); + } + if (values != null) { + for (MemberValue value : values) { + value.renameClass(oldname, newname); + } + } + } + + @Override + public void renameClass(Map classnames) { + if (type != null) { + type.renameClass(classnames); + } + if (values != null) { + for (MemberValue value : values) { + value.renameClass(classnames); + } + } + } + /** * Obtains the type of the elements. * diff --git a/src/main/javassist/bytecode/annotation/ClassMemberValue.java b/src/main/javassist/bytecode/annotation/ClassMemberValue.java index e9fd7ec4..495a1e2a 100644 --- a/src/main/javassist/bytecode/annotation/ClassMemberValue.java +++ b/src/main/javassist/bytecode/annotation/ClassMemberValue.java @@ -18,6 +18,7 @@ package javassist.bytecode.annotation; import java.io.IOException; import java.lang.reflect.Method; +import java.util.Map; import javassist.ClassPool; import javassist.bytecode.BadBytecode; @@ -95,6 +96,20 @@ public class ClassMemberValue extends MemberValue { return loadClass(cl, "java.lang.Class"); } + @Override + public void renameClass(String oldname, String newname) { + String value = cp.getUtf8Info(valueIndex); + String newValue = Descriptor.rename(value, oldname, newname); + setValue(Descriptor.toClassName(newValue)); + } + + @Override + public void renameClass(Map classnames) { + String value = cp.getUtf8Info(valueIndex); + String newValue = Descriptor.rename(value, classnames); + setValue(Descriptor.toClassName(newValue)); + } + /** * Obtains the value of the member. * diff --git a/src/main/javassist/bytecode/annotation/EnumMemberValue.java b/src/main/javassist/bytecode/annotation/EnumMemberValue.java index a0a4e036..0f37178a 100644 --- a/src/main/javassist/bytecode/annotation/EnumMemberValue.java +++ b/src/main/javassist/bytecode/annotation/EnumMemberValue.java @@ -18,6 +18,7 @@ package javassist.bytecode.annotation; import java.io.IOException; import java.lang.reflect.Method; +import java.util.Map; import javassist.ClassPool; import javassist.bytecode.ConstPool; @@ -76,6 +77,20 @@ public class EnumMemberValue extends MemberValue { return loadClass(cl, getType()); } + @Override + public void renameClass(String oldname, String newname) { + String type = cp.getUtf8Info(typeIndex); + String newType = Descriptor.rename(type, oldname, newname); + setType(Descriptor.toClassName(newType)); + } + + @Override + public void renameClass(Map classnames) { + String type = cp.getUtf8Info(typeIndex); + String newType = Descriptor.rename(type, classnames); + setType(Descriptor.toClassName(newType)); + } + /** * Obtains the enum type name. * diff --git a/src/main/javassist/bytecode/annotation/MemberValue.java b/src/main/javassist/bytecode/annotation/MemberValue.java index da99885c..0f132a83 100644 --- a/src/main/javassist/bytecode/annotation/MemberValue.java +++ b/src/main/javassist/bytecode/annotation/MemberValue.java @@ -18,6 +18,7 @@ package javassist.bytecode.annotation; import java.io.IOException; import java.lang.reflect.Method; +import java.util.Map; import javassist.ClassPool; import javassist.bytecode.ConstPool; @@ -74,6 +75,14 @@ public abstract class MemberValue { return classname; } + /* The following two methods are used to implement + * ClassFile.renameClass(). + * Only ArrayMemberValue, ClassMemberValue, EnumMemberValue + * override these methods. + */ + public void renameClass(String oldname, String newname) {} + public void renameClass(Map classnames) {} + /** * Accepts a visitor. */ -- 2.39.5