Skip to content

Commit

Permalink
Merge pull request #278 from ximsfei/master
Browse files Browse the repository at this point in the history
fixes a bug of ClassFile#renameClass(), some imports could not be successfully renamed.
  • Loading branch information
chibash committed May 10, 2022
2 parents b846257 + 27999ee commit 01c788f
Show file tree
Hide file tree
Showing 8 changed files with 112 additions and 22 deletions.
22 changes: 22 additions & 0 deletions src/main/javassist/bytecode/AnnotationDefaultAttribute.java
Expand Up @@ -117,6 +117,28 @@ public AttributeInfo copy(ConstPool newCp, Map<String,String> classnames) {
}
}

@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<String, String> classnames) {
try {
MemberValue defaultValue = getDefaultValue();
defaultValue.renameClass(classnames);
setDefaultValue(defaultValue);
} catch (Exception e) {
// ignore
}
}

/**
* Obtains the default value represented by this attribute.
*/
Expand Down
2 changes: 1 addition & 1 deletion src/main/javassist/bytecode/AttributeInfo.java
Expand Up @@ -254,7 +254,7 @@ static List<AttributeInfo> copyAll(List<AttributeInfo> attributes, ConstPool cp)
/* 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) {}
Expand Down
34 changes: 17 additions & 17 deletions src/main/javassist/bytecode/SignatureAttribute.java
Expand Up @@ -121,29 +121,29 @@ static String renameClass(String desc, Map<String,String> map) {
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;
}
}
Expand Down
25 changes: 25 additions & 0 deletions src/main/javassist/bytecode/annotation/ArrayMemberValue.java
Expand Up @@ -18,6 +18,7 @@
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;
Expand Down Expand Up @@ -87,6 +88,30 @@ Class<?> getType(ClassLoader cl) throws ClassNotFoundException {
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<String, String> classnames) {
if (type != null) {
type.renameClass(classnames);
}
if (values != null) {
for (MemberValue value : values) {
value.renameClass(classnames);
}
}
}

/**
* Obtains the type of the elements.
*
Expand Down
15 changes: 15 additions & 0 deletions src/main/javassist/bytecode/annotation/ClassMemberValue.java
Expand Up @@ -18,6 +18,7 @@

import java.io.IOException;
import java.lang.reflect.Method;
import java.util.Map;

import javassist.ClassPool;
import javassist.bytecode.BadBytecode;
Expand Down Expand Up @@ -95,6 +96,20 @@ Class<?> getType(ClassLoader cl) throws ClassNotFoundException {
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<String, String> classnames) {
String value = cp.getUtf8Info(valueIndex);
String newValue = Descriptor.rename(value, classnames);
setValue(Descriptor.toClassName(newValue));
}

/**
* Obtains the value of the member.
*
Expand Down
15 changes: 15 additions & 0 deletions src/main/javassist/bytecode/annotation/EnumMemberValue.java
Expand Up @@ -18,6 +18,7 @@

import java.io.IOException;
import java.lang.reflect.Method;
import java.util.Map;

import javassist.ClassPool;
import javassist.bytecode.ConstPool;
Expand Down Expand Up @@ -76,6 +77,20 @@ Class<?> getType(ClassLoader cl) throws ClassNotFoundException {
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<String, String> classnames) {
String type = cp.getUtf8Info(typeIndex);
String newType = Descriptor.rename(type, classnames);
setType(Descriptor.toClassName(newType));
}

/**
* Obtains the enum type name.
*
Expand Down
9 changes: 9 additions & 0 deletions src/main/javassist/bytecode/annotation/MemberValue.java
Expand Up @@ -18,6 +18,7 @@

import java.io.IOException;
import java.lang.reflect.Method;
import java.util.Map;

import javassist.ClassPool;
import javassist.bytecode.ConstPool;
Expand Down Expand Up @@ -74,6 +75,14 @@ private static String convertFromArray(String classname)
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<String, String> classnames) {}

/**
* Accepts a visitor.
*/
Expand Down
12 changes: 8 additions & 4 deletions src/test/javassist/bytecode/BytecodeTest.java
Expand Up @@ -475,10 +475,14 @@ public void testSignatureChange() throws Exception {
changeMsig2("<S:Ljava/lang/Object;>(TS;[TS;)Ljava/lang/Objec;", "java/lang/Object",
"<S:Ljava/lang/Object2;>(TS;[TS;)Ljava/lang/Objec;", "java/lang/Object2");
String sig = "<T:Ljava/lang/Exception;>LPoi$Foo<Ljava/lang/String;>;LBar;LBar2;";
//String res = "<T:Ljava/lang/Exception;>LPoi$Foo<Ljava/lang/String2;>;LBar;LBar2;";
changeMsig(sig, "java/lang/String", sig, "java/lang/String2");
changeMsig2(sig, "java/lang/String", sig, "java/lang/String2");
changeMsig("Ltest<TE;>.List;", "ist", "Ltest<TE;>.List;", "IST");
String res = "<T:Ljava/lang/Exception;>LPoi$Foo<Ljava/lang/String2;>;LBar;LBar2;";
changeMsig(sig, "java/lang/String", res, "java/lang/String2");
changeMsig2(sig, "java/lang/String", res, "java/lang/String2");
//changeMsig("Ltest<TE;>.List;", "ist", "Ltest<TE;>.List;", "IST");
changeMsig("Ljava/lang/String<Ljava/lang/Object;>;", "java/lang/String",
"Ljava/lang/String2<Ljava/lang/Object;>;", "java/lang/String2");
changeMsig2("Ljava/lang/String<Ljava/lang/Object;>;", "java/lang/String",
"Ljava/lang/String2<Ljava/lang/Object;>;", "java/lang/String2");
}

private void changeMsig(String old, String oldname, String result, String newname) {
Expand Down

0 comments on commit 01c788f

Please sign in to comment.